zx-editor
Version:
ZxEditor is a HTML5 rich text editor
197 lines (180 loc) • 5.11 kB
JavaScript
/**
* Created by Capricorncd.
* User: https://github.com/capricorncd
* Date: 2019/04/24 21:37
*/
import { document } from 'ssr-window'
import util from "../util";
export function getImageInfo (base64, file, opts, callback) {
let img = document.createElement('img')
img.src = base64
img.setAttribute('alt', file.name)
// 加载图片
img.onload = function () {
let defaultData = {
element: img,
base64,
width: img.naturalWidth || img.width,
height: img.naturalHeight || img.height,
type: file.type,
size: file.size,
name: file.name,
file
}
callback(null, opts.orientation > 1 ? rotateAndToBase64(defaultData, opts.orientation) : defaultData)
}
img.onerror = callback
}
/**
* Decide whether the picture is rotated or not according to 'opts.orientation' value
* @param raw
* @param type
* @returns {Object}
*/
function rotateAndToBase64 (raw, orientation) {
let canvas = document.createElement('canvas')
let ctx = canvas.getContext('2d')
let img = raw.element
let imgWidth = raw.width
let imgHeight = raw.height
canvas.width = imgWidth
canvas.height = imgHeight
// rotate image
switch(orientation) {
// 90deg
case 6:
canvas.width = imgHeight
canvas.height = imgWidth
ctx.rotate(Math.PI / 2)
// (0, -imgHeight)
ctx.drawImage(img, 0, -imgHeight, imgWidth, imgHeight)
break
// 180deg
case 3:
ctx.rotate(Math.PI)
ctx.drawImage(img, -imgWidth, -imgHeight, imgWidth, imgHeight)
break;
// -90(270)deg
case 8:
canvas.width = imgHeight
canvas.height = imgWidth
ctx.rotate(3 * Math.PI / 2)
ctx.drawImage(img, -imgWidth, 0, imgWidth, imgHeight)
break
default:
ctx.drawImage(img, 0, 0, imgWidth, imgHeight)
}
let base64 = canvas.toDataURL(raw.type)
img.src = base64
return Object.assign(raw, {
element: canvas,
base64,
width: canvas.width,
height: canvas.height
})
}
/**
* 创建Canvas
* @param el Image object or Canvas element
* @param p clip options
* @returns {Element}
*/
export function createCanvas (el, p) {
const canvas = document.createElement('canvas')
canvas.width = p.cw
canvas.height = p.ch
const ctx = canvas.getContext('2d')
// 操作过于频繁,iPhone部分手机会获取不到ctx,is null
// 下面代码会抛出异常
ctx.drawImage(el, p.sx, p.sy, p.sw, p.sh, 0, 0, canvas.width, canvas.height)
return canvas
}
/**
* 缩放比列
* @param {Number} numerator
* @param {Number} denominator
*/
function ratio (numerator, denominator) {
return parseInt(numerator / denominator * 10000) / 10000
}
/**
* Calculate the position and size of the generated image clipping
* @param {Number} iw // image width
* @param {Number} ih // image height
* @param {Object} opts
*/
export function computeCropInfo (iw, ih, opts) {
// target image width, height
let targetWidth = util.int(opts.width)
let targetHeight = util.int(opts.height)
// image width or height, less than target width or height
// don't resize
if (!opts.forceImageResize && (targetWidth > 0 && iw < targetWidth)
&& (targetHeight > 0 && ih < targetHeight)) {
return {
sx: 0,
sy: 0,
sw: iw,
sh: ih,
scaling: 1,
cw: iw,
ch: ih
}
}
// scaling
let scaling = 1
// Pictures begin to crop in x, y coordinates
let sx = 0
let sy = 0
// canvas
let canvasWidth = iw
let canvasHieght = ih
// Picture Size after Equal Ratio Scaling
let sw = 0
let sh = 0
// Scale to the right size, then cut in the middle
if (targetWidth > 0 && targetHeight > 0) {
// The size of canvas is to set the size for cutting
canvasWidth = targetWidth
canvasHieght = targetHeight
// Adjust the size of the picture according to the target width: the width of the picture equals the width of the clipping frame
sw = targetWidth
sh = Math.floor(targetWidth * ih / iw)
scaling = ratio(iw, targetWidth)
// Picture height beyond the clipping box, can be normal clipping
if (sh >= targetHeight) {
sx = 0
sy = util.int((sh - targetHeight) / 2 * scaling)
}
// To satisfy the clipping requirement, we need to resize: image height === clipping frame height
else {
scaling = ratio(ih, targetHeight)
sw = Math.floor(targetHeight * iw / ih)
sh = targetHeight
sx = util.int((sw - targetWidth) / 2 * scaling)
sy = 0
}
}
// Zoom Picture Code **********************************
// Only width is set
else if (targetWidth > 0) {
scaling = ratio(iw, targetWidth)
canvasWidth = targetWidth
canvasHieght = Math.floor(targetWidth * ih / iw)
}
// Only height is set
else if (targetHeight > 0) {
scaling = ratio(ih, targetHeight)
canvasWidth = Math.floor(targetHeight * iw / ih)
canvasHieght = targetHeight
}
return {
sx: sx,
sy: sy,
sw: util.int(canvasWidth * scaling),
sh: util.int(canvasHieght * scaling),
scaling: scaling,
cw: canvasWidth,
ch: canvasHieght
}
}