123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103 |
- "use strict";
- var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault").default;
- Object.defineProperty(exports, "__esModule", {
- value: true
- });
- exports.default = exports.FontGap = void 0;
- var _react = _interopRequireDefault(require("react"));
- var _toList = _interopRequireDefault(require("../_util/toList"));
- const FontGap = exports.FontGap = 3;
- const prepareCanvas = (width, height, ratio = 1) => {
- const canvas = document.createElement('canvas');
- const ctx = canvas.getContext('2d');
- const realWidth = width * ratio;
- const realHeight = height * ratio;
- canvas.setAttribute('width', `${realWidth}px`);
- canvas.setAttribute('height', `${realHeight}px`);
- ctx.save();
- return [ctx, canvas, realWidth, realHeight];
- };
- // Get boundary of rotated text
- const getRotatePos = (x, y, angle) => {
- const targetX = x * Math.cos(angle) - y * Math.sin(angle);
- const targetY = x * Math.sin(angle) + y * Math.cos(angle);
- return [targetX, targetY];
- };
- /**
- * Get the clips of text content.
- * This is a lazy hook function since SSR no need this
- */
- const useClips = () => {
- // Get single clips
- const getClips = (content, rotate, ratio, width, height, font, gapX, gapY) => {
- // ================= Text / Image =================
- const [ctx, canvas, contentWidth, contentHeight] = prepareCanvas(width, height, ratio);
- if (content instanceof HTMLImageElement) {
- // Image
- ctx.drawImage(content, 0, 0, contentWidth, contentHeight);
- } else {
- // Text
- const {
- color,
- fontSize,
- fontStyle,
- fontWeight,
- fontFamily,
- textAlign
- } = font;
- const mergedFontSize = Number(fontSize) * ratio;
- ctx.font = `${fontStyle} normal ${fontWeight} ${mergedFontSize}px/${height}px ${fontFamily}`;
- ctx.fillStyle = color;
- ctx.textAlign = textAlign;
- ctx.textBaseline = 'top';
- const contents = (0, _toList.default)(content);
- contents === null || contents === void 0 ? void 0 : contents.forEach((item, index) => {
- ctx.fillText(item !== null && item !== void 0 ? item : '', contentWidth / 2, index * (mergedFontSize + FontGap * ratio));
- });
- }
- // ==================== Rotate ====================
- const angle = Math.PI / 180 * Number(rotate);
- const maxSize = Math.max(width, height);
- const [rCtx, rCanvas, realMaxSize] = prepareCanvas(maxSize, maxSize, ratio);
- // 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);
- }
- let left = 0;
- let right = 0;
- let top = 0;
- let bottom = 0;
- const halfWidth = contentWidth / 2;
- const halfHeight = contentHeight / 2;
- const points = [[0 - halfWidth, 0 - halfHeight], [0 + halfWidth, 0 - halfHeight], [0 + halfWidth, 0 + halfHeight], [0 - halfWidth, 0 + halfHeight]];
- points.forEach(([x, y]) => {
- const [targetX, targetY] = getRotatePos(x, y, angle);
- left = Math.min(left, targetX);
- right = Math.max(right, targetX);
- top = Math.min(top, targetY);
- bottom = Math.max(bottom, targetY);
- });
- const cutLeft = left + realMaxSize / 2;
- const cutTop = top + realMaxSize / 2;
- const cutWidth = right - left;
- const cutHeight = bottom - top;
- // ================ Fill Alternate ================
- const realGapX = gapX * ratio;
- const realGapY = gapY * ratio;
- const filledWidth = (cutWidth + realGapX) * 2;
- const filledHeight = cutHeight + realGapY;
- const [fCtx, fCanvas] = prepareCanvas(filledWidth, filledHeight);
- const drawImg = (targetX = 0, targetY = 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 _react.default.useCallback(getClips, []);
- };
- var _default = exports.default = useClips;
|