绿满眶商城微信小程序-uniapp
xiangpei
2025-05-09 c3e6cdbb29580e77444541c7953aca33581a4267
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
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;