UNPKG

vxe-pc-ui

Version:
161 lines (160 loc) 5.03 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.getContentUrl = getContentUrl; var _xeUtils = _interopRequireDefault(require("xe-utils")); var _dom = require("../../ui/src/dom"); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } let canvasEl = null; let fontEl = null; const fontCacheMaps = {}; function getMarkCanvas() { if (!canvasEl) { canvasEl = document.createElement('canvas'); canvasEl.style.position = 'absolute'; canvasEl.style.top = '0'; canvasEl.style.left = '0'; } return canvasEl; } function removeMarkElement(elem) { if (elem) { const parentEl = elem.parentNode; if (parentEl) { parentEl.removeChild(elem); } } } function calcFontWH(text, fontSize) { const fKey = `${fontSize}_${text}`; if (!fontCacheMaps[fKey]) { if (!fontEl) { fontEl = document.createElement('span'); } if (!fontEl.parentNode) { document.body.append(fontEl); } fontEl.textContent = text; fontEl.style.fontSize = (0, _dom.toCssUnit)(fontSize); const width = fontEl.offsetWidth; const height = fontEl.offsetHeight; fontCacheMaps[fKey] = { width, height }; } return fontCacheMaps[fKey]; } function calcContentWH(contList) { let contentWidth = 0; let contentHeight = 0; contList.forEach(item => { contentWidth = Math.max(item.width, contentWidth); contentHeight = Math.max(item.height, contentHeight); }); return { contentWidth, contentHeight }; } function calcCanvasWH(contentWidth, opts) { const { gap } = opts; const [gapX = 0, gapY = 0] = gap ? _xeUtils.default.isArray(gap) ? gap : [gap, gap] : []; const canvasWidth = contentWidth + _xeUtils.default.toNumber(gapX); const canvasHeight = contentWidth + _xeUtils.default.toNumber(gapY); return { canvasWidth, canvasHeight }; } function getFontConf(item, key, opts) { return (item.font ? item.font[key] : '') || (opts.font ? opts.font[key] : ''); } function createMarkFont(contConf, defaultFontSize, opts) { const { offset } = opts; const text = _xeUtils.default.toValueString(contConf.textContent); const fontSize = _xeUtils.default.toNumber(getFontConf(contConf, 'fontSize', opts) || defaultFontSize) || 14; const [offsetX = 0, offsetY = 0] = offset ? _xeUtils.default.isArray(offset) ? offset : [offset, offset] : []; const { width, height } = calcFontWH(text, fontSize); return { text, fontSize, font: contConf.font, width: width + _xeUtils.default.toNumber(offsetX), height: height + _xeUtils.default.toNumber(offsetY) }; } function drayFont(ctx, item, opts) { const fontWeight = getFontConf(item, 'fontWeight', opts); ctx.fillStyle = `${getFontConf(item, 'color', opts) || 'rgba(0, 0, 0, 0.15)'}`; ctx.font = [getFontConf(item, 'fontStyle', opts) || 'normal', fontWeight === 'bold' || fontWeight === 'bolder' ? 'bold' : '', (0, _dom.toCssUnit)(item.fontSize), getFontConf(item, 'fontFamily', opts) || 'sans-serif'].join(' '); } function getContentUrl(content, defaultFontSize, options) { const opts = Object.assign({}, options); const { rotate } = opts; const deg = _xeUtils.default.toNumber(rotate); const contList = (_xeUtils.default.isArray(content) ? content : [content]).map(item => { if (item) { if (item.textContent) { return createMarkFont(item, defaultFontSize, opts); } return createMarkFont({ textContent: `${item}` }, defaultFontSize, opts); } return createMarkFont({ textContent: '' }, defaultFontSize, opts); }); removeMarkElement(fontEl); return new Promise(resolve => { const canvasEl = getMarkCanvas(); if (!canvasEl.parentNode) { document.body.append(canvasEl); } const ctx = canvasEl.getContext('2d'); if (ctx && contList.length) { const { contentWidth, contentHeight } = calcContentWH(contList); const { canvasWidth, canvasHeight } = calcCanvasWH(contentWidth, opts); canvasEl.width = canvasWidth; canvasEl.height = canvasHeight; const x = (canvasWidth - contentWidth) / 2; const y = (canvasHeight - contentHeight) / 2; const drayX = x + contentWidth / 2; const drayY = y + contentHeight / 2; ctx.save(); ctx.translate(drayX, drayY); ctx.rotate(deg * Math.PI / 180); ctx.translate(-drayX, -drayY); let offsetHeight = 0; contList.forEach(item => { const align = getFontConf(item, 'align', opts); drayFont(ctx, item, opts); ctx.fillText(item.text, x + (align === 'center' ? (contentWidth - item.width) / 2 : 0), y + (contentHeight + contentHeight) / 2 + offsetHeight, contentWidth); offsetHeight += item.height; }); ctx.restore(); resolve(canvasEl.toDataURL()); removeMarkElement(canvasEl); } else { resolve(''); removeMarkElement(canvasEl); } }); }