vxe-pc-ui
Version:
A vue based PC component library
161 lines (160 loc) • 5.03 kB
JavaScript
;
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);
}
});
}