acud
Version:
acg react 组件库
123 lines • 5.3 kB
JavaScript
import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
/**
* 将一个画布的尺寸转换为对应的物理像素尺寸。
*
* @param width - 需要转换的画布宽度
* @param height - 需要转换的画布高度
* @param ratio - 可选参数,用于缩放画布,默认为1表示不进行缩放。
* @returns 返回包含canvas上下文和实际绘图尺寸的数组,分别对应ctx、canvas、realWidth和realHeight。
*/
function prepareCanvas(width, height) {
var ratio = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 1;
var canvas = document.createElement('canvas');
var ctx = canvas.getContext('2d');
var realWidth = width * ratio;
var realHeight = height * ratio;
canvas.setAttribute('width', "".concat(realWidth, "px"));
canvas.setAttribute('height', "".concat(realHeight, "px"));
ctx.save();
return [ctx, canvas, realWidth, realHeight];
}
/**
* Get the clips of text content.
* This is a lazy hook function since SSR no need this
*/
export default function useClips() {
// Get single clips
function getClips(content, rotate, ratio, width, height, font, gapX, gapY) {
// ================= Text / Image =================
var _prepareCanvas = prepareCanvas(width, height, ratio),
_prepareCanvas2 = _slicedToArray(_prepareCanvas, 4),
ctx = _prepareCanvas2[0],
canvas = _prepareCanvas2[1],
contentWidth = _prepareCanvas2[2],
contentHeight = _prepareCanvas2[3];
if (content instanceof HTMLImageElement) {
// Image
ctx.drawImage(content, 0, 0, contentWidth, contentHeight);
} else {
// Text
var color = font.color,
fontSize = font.fontSize,
fontGap = font.fontGap,
alpha = font.alpha,
fontStyle = font.fontStyle,
fontWeight = font.fontWeight,
fontFamily = font.fontFamily,
textAlign = font.textAlign;
var mergedFontSize = Number(fontSize) * ratio;
ctx.font = "".concat(fontStyle, " normal ").concat(fontWeight, " ").concat(mergedFontSize, "px/").concat(height, "px ").concat(fontFamily);
ctx.fillStyle = color;
ctx.textAlign = textAlign;
ctx.textBaseline = 'top';
ctx.globalAlpha = alpha;
var contents = Array.isArray(content) ? content : [content];
contents === null || contents === void 0 ? void 0 : contents.forEach(function (item, index) {
ctx.fillText(item !== null && item !== void 0 ? item : '', contentWidth / 2, index * (mergedFontSize + fontGap * ratio));
});
}
// ==================== Rotate ====================
var angle = Math.PI / 180 * Number(rotate);
var maxSize = Math.max(width, height);
var _prepareCanvas3 = prepareCanvas(maxSize, maxSize, ratio),
_prepareCanvas4 = _slicedToArray(_prepareCanvas3, 3),
rCtx = _prepareCanvas4[0],
rCanvas = _prepareCanvas4[1],
realMaxSize = _prepareCanvas4[2];
// Copy from `ctx` and rotate
rCtx.translate(realMaxSize / 2, realMaxSize / 2);
rCtx.rotate(angle);
if (contentWidth > 0 && contentHeight > 0) {
rCtx.drawImage(canvas, -contentWidth / 2, -contentHeight / 2);
}
// Get boundary of rotated text
function getRotatePos(x, y) {
var targetX = x * Math.cos(angle) - y * Math.sin(angle);
var targetY = x * Math.sin(angle) + y * Math.cos(angle);
return [targetX, targetY];
}
var left = 0;
var right = 0;
var top = 0;
var bottom = 0;
var halfWidth = contentWidth / 2;
var halfHeight = contentHeight / 2;
var points = [[0 - halfWidth, 0 - halfHeight], [0 + halfWidth, 0 - halfHeight], [0 + halfWidth, 0 + halfHeight], [0 - halfWidth, 0 + halfHeight]];
points.forEach(function (_ref) {
var _ref2 = _slicedToArray(_ref, 2),
x = _ref2[0],
y = _ref2[1];
var _getRotatePos = getRotatePos(x, y),
_getRotatePos2 = _slicedToArray(_getRotatePos, 2),
targetX = _getRotatePos2[0],
targetY = _getRotatePos2[1];
left = Math.min(left, targetX);
right = Math.max(right, targetX);
top = Math.min(top, targetY);
bottom = Math.max(bottom, targetY);
});
var cutLeft = left + realMaxSize / 2;
var cutTop = top + realMaxSize / 2;
var cutWidth = right - left;
var cutHeight = bottom - top;
// ================ Fill Alternate ================
var realGapX = gapX * ratio;
var realGapY = gapY * ratio;
var filledWidth = (cutWidth + realGapX) * 2;
var filledHeight = cutHeight + realGapY;
var _prepareCanvas5 = prepareCanvas(filledWidth, filledHeight),
_prepareCanvas6 = _slicedToArray(_prepareCanvas5, 2),
fCtx = _prepareCanvas6[0],
fCanvas = _prepareCanvas6[1];
function drawImg() {
var targetX = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0;
var targetY = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
fCtx.drawImage(rCanvas, cutLeft, cutTop, cutWidth, cutHeight, targetX, targetY, cutWidth, cutHeight);
}
drawImg();
drawImg(cutWidth + realGapX, -cutHeight / 2 - realGapY / 2);
drawImg(cutWidth + realGapX, +cutHeight / 2 + realGapY / 2);
return [fCanvas.toDataURL(), filledWidth / ratio, filledHeight / ratio];
}
return getClips;
}