lilishop-uniapp/js_sdk/u-draw-poster/draw-poster.js

195 lines
8.9 KiB
JavaScript
Raw Permalink Normal View History

2021-05-13 11:03:32 +08:00
import uni from "./utils/global";
import { handleBuildOpts, extendMount } from "./utils/utils";
import { getCanvas2dContext } from "./utils/wx-utils";
// 扩展挂载储存
let drawPosterExtend = {};
let drawCtxPosterExtend = {};
class DrawPoster {
/** 构建器, 构建返回当前实例, 并挂载多个方法 */
constructor(canvas, ctx, canvasId, loading, debugging, loadingText, createText, tips) {
var _a;
this.canvas = canvas;
this.ctx = ctx;
this.canvasId = canvasId;
this.loading = loading;
this.debugging = debugging;
this.loadingText = loadingText;
this.createText = createText;
this.executeOnions = [];
this.stopStatus = false;
/** 提示器, 传入消息与数据 */
this.debuggingLog = (message, data, color = "#3489fd") => {
if (this.debugging) {
if (data) {
console.log(`%c${this.canvasId} -> ${message}`, `color: ${color}`, data);
}
else {
console.log(`%c${this.canvasId} -> ${message}`, `color: ${color}`);
}
}
};
/** 绘制器, 接收执行器函数, 添加到绘制容器中 */
this.draw = (execute) => {
const length = this.executeOnions.length;
this.executeOnions.push(async () => {
var _a, _b;
try {
this.ctx.save();
await execute(this.ctx);
this.ctx.restore();
return true;
}
catch (error) {
const isOutError = ((_b = (_a = error === null || error === void 0 ? void 0 : error.message) === null || _a === void 0 ? void 0 : _a.search) === null || _b === void 0 ? void 0 : _b.call(_a, `'nodeId' of undefined`)) >= 0;
!isOutError && console.error(`${this.canvasId} -> 绘画栈(${length}),绘制错误:`, error);
return false;
}
});
};
/** 等待创建绘画, 成功后清空绘制器容器 */
this.awaitCreate = async () => {
this.debuggingLog('绘制海报中...');
this.loading && uni.showLoading({ title: this.loadingText });
const tips = [];
for (let i = 0; i < this.executeOnions.length; i++) {
const execute = this.executeOnions[i];
tips.push(await execute());
}
this.executeOnions = [];
this.debuggingLog('绘制状况', tips);
// 当前绘制为 type2 绘制
if (this.drawType === 'type2d') {
this.loading && uni.hideLoading();
return tips;
}
// 当前绘制为 context 绘制
return await new Promise((resolve) => {
this.ctx.draw(true, () => {
resolve(tips);
this.loading && uni.hideLoading();
});
});
};
/** 创建canvas本地地址 @returns {string} 本地地址 */
this.createImagePath = async (baseOptions = {}) => {
const { canvas, canvasId, executeOnions, awaitCreate } = this;
executeOnions.length && await awaitCreate();
// 如果当前为停止状态
if (this.stopStatus) {
this.stopStatus = false;
return '---stop createImagePath---';
}
this.loading && uni.showLoading({ title: this.createText });
const options = Object.assign({}, baseOptions);
if (this.drawType === 'context')
options.canvasId = canvasId;
if (this.drawType === 'type2d')
options.canvas = canvas;
console.log(options)
return new Promise((resolve, reject) => {
options.success = (res) => {
resolve(res.tempFilePath);
this.loading && uni.hideLoading();
this.debuggingLog('绘制成功 🎉', res, '#19be6b');
};
options.fail = (err) => {
reject(err);
this.loading && uni.hideLoading();
this.debuggingLog('绘制失败 🌟', err, '#fa3534');
};
uni.canvasToTempFilePath(options);
});
};
/** 停止当前绘画, 调用则停止当前绘画堆栈的绘画 */
this.stop = () => {
this.executeOnions = [];
this.stopStatus = true;
};
if (!canvas || !ctx || !canvasId) {
throw new Error("DrawPoster Error: Use DrawPoster.build(string | ops) to build drawPoster instance objects");
}
// 判断当前绘制类型
ctx.drawType = this.drawType = (ctx.draw) ? 'context' : 'type2d';
// 挂载全局实例, 绘画扩展
extendMount(this.ctx, drawCtxPosterExtend, (extend, target) => {
var _a;
(_a = target === null || target === void 0 ? void 0 : target.init) === null || _a === void 0 ? void 0 : _a.call(target, this.canvas, this.ctx);
return (...args) => extend(this.canvas, this.ctx, ...args);
});
extendMount(this, drawPosterExtend, (extend, target) => {
var _a;
(_a = target === null || target === void 0 ? void 0 : target.init) === null || _a === void 0 ? void 0 : _a.call(target, this);
return (...args) => extend(this, ...args);
});
// 当离开页面时, 自动调用停止绘画
const _this = this;
const pages = getCurrentPages();
const page = pages[pages.length - 1];
// 查询标识, 不存在, 在替换页面卸载回调, 避免产生死循环
if (!((_a = page === null || page === void 0 ? void 0 : page.onUnload) === null || _a === void 0 ? void 0 : _a.identification)) {
page.oldOnUnload = page.onUnload;
page.onUnload = function () {
_this === null || _this === void 0 ? void 0 : _this.stop();
page.oldOnUnload();
};
page.onUnload.identification = true;
}
tips && this.debuggingLog('构建完成', { canvas, ctx, selector: canvasId }, '#19be6b');
}
}
/** 传入挂载配置对象, 添加扩展方法 */
DrawPoster.use = (opts) => {
if (opts.name)
drawPosterExtend[opts.name] = opts;
};
/** 传入挂载配置对象, 添加绘画扩展方法 */
DrawPoster.useCtx = (opts) => {
if (opts.name)
drawCtxPosterExtend[opts.name] = opts;
};
/** 构建绘制海报矩形方法, 传入canvas选择器或配置对象, 返回绘制对象 */
DrawPoster.build = async (options, tips = true) => {
var _a, _b, _c, _d, _e;
const config = handleBuildOpts(options);
// 初始化监测当前页面绘制对象
const pages = getCurrentPages();
const page = pages[pages.length - 1];
const gcanvas = DrawPoster.prototype['gcanvas'];
if (page[config.selector + '__dp']) {
return page[config.selector + '__dp'];
}
if (config.gcanvas) {
if (!gcanvas)
console.error('--- 当前未引入gcanvas扩展, 将自动切换为普通 canvas ---');
else
gcanvas.enable((_b = (_a = config.componentThis) === null || _a === void 0 ? void 0 : _a.$refs) === null || _b === void 0 ? void 0 : _b[config.selector], {
bridge: gcanvas.WeexBridge
});
}
// 获取canvas实例
const canvas = config.gcanvas && gcanvas ?
gcanvas.enable((_d = (_c = config.componentThis) === null || _c === void 0 ? void 0 : _c.$refs) === null || _d === void 0 ? void 0 : _d[config.selector], {
bridge: gcanvas.WeexBridge
}) :
await getCanvas2dContext(config.selector, config.componentThis);
const ctx = (((_e = canvas.getContext) === null || _e === void 0 ? void 0 : _e.call(canvas, "2d")) || uni.createCanvasContext(config.selector, config.componentThis));
const dp = new DrawPoster(canvas, ctx, config.selector, config.loading, config.debugging, config.loadingText, config.createText, tips);
// 储存当前绘制对象
page[config.selector + '__dp'] = dp;
return page[config.selector + '__dp'];
};
/** 构建多个绘制海报矩形方法, 传入选择器或配置对象的数组, 返回多个绘制对象 */
DrawPoster.buildAll = async (optionsAll) => {
const dpsArr = await Promise.all(optionsAll.map(async (options) => {
return await DrawPoster.build(options, false);
}));
const dpsObj = {};
dpsArr.forEach(dp => dpsObj[dp.canvasId] = dp);
console.log("%cdraw-poster 构建完成:", "#E3712A", dpsObj);
return dpsObj;
};
export default DrawPoster;