mirror of
https://gitee.com/beijing_hongye_huicheng/lilishop-uniapp.git
synced 2025-12-17 07:55:53 +08:00
commit message
This commit is contained in:
38
js_sdk/u-draw-poster/draw-poster.d.ts
vendored
Normal file
38
js_sdk/u-draw-poster/draw-poster.d.ts
vendored
Normal file
@@ -0,0 +1,38 @@
|
||||
import { Canvas, DrawPosterCanvasCtx, CreateImagePathOptions, DrawPosterBuildOpts, DrawPosterUseOpts, drawPosterExtends, DrawPosterUseCtxOpts } from "./utils/interface";
|
||||
declare type DrawPosterInstanceType = InstanceType<typeof DrawPoster> & drawPosterExtends;
|
||||
declare class DrawPoster {
|
||||
canvas: Canvas;
|
||||
ctx: DrawPosterCanvasCtx;
|
||||
canvasId: string;
|
||||
loading: boolean;
|
||||
debugging: boolean;
|
||||
loadingText: string;
|
||||
createText: string;
|
||||
[key: string]: any;
|
||||
private executeOnions;
|
||||
private stopStatus;
|
||||
private drawType;
|
||||
/** 构建器, 构建返回当前实例, 并挂载多个方法 */
|
||||
constructor(canvas: Canvas, ctx: DrawPosterCanvasCtx, canvasId: string, loading: boolean, debugging: boolean, loadingText: string, createText: string, tips: boolean);
|
||||
/** 提示器, 传入消息与数据 */
|
||||
private debuggingLog;
|
||||
/** 传入挂载配置对象, 添加扩展方法 */
|
||||
static use: (opts: DrawPosterUseOpts) => void;
|
||||
/** 传入挂载配置对象, 添加绘画扩展方法 */
|
||||
static useCtx: (opts: DrawPosterUseCtxOpts) => void;
|
||||
/** 构建绘制海报矩形方法, 传入canvas选择器或配置对象, 返回绘制对象 */
|
||||
static build: (options: string | DrawPosterBuildOpts, tips?: boolean) => Promise<DrawPosterInstanceType>;
|
||||
/** 构建多个绘制海报矩形方法, 传入选择器或配置对象的数组, 返回多个绘制对象 */
|
||||
static buildAll: (optionsAll: (string | DrawPosterBuildOpts)[]) => Promise<{
|
||||
[key: string]: DrawPosterInstanceType;
|
||||
}>;
|
||||
/** 绘制器, 接收执行器函数, 添加到绘制容器中 */
|
||||
draw: (execute: (ctx: DrawPosterCanvasCtx) => Promise<any> | void) => void;
|
||||
/** 等待创建绘画, 成功后清空绘制器容器 */
|
||||
awaitCreate: () => Promise<boolean[]>;
|
||||
/** 创建canvas本地地址 @returns {string} 本地地址 */
|
||||
createImagePath: (baseOptions?: CreateImagePathOptions) => Promise<string>;
|
||||
/** 停止当前绘画, 调用则停止当前绘画堆栈的绘画 */
|
||||
stop: () => void;
|
||||
}
|
||||
export default DrawPoster;
|
||||
194
js_sdk/u-draw-poster/draw-poster.js
Normal file
194
js_sdk/u-draw-poster/draw-poster.js
Normal file
@@ -0,0 +1,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;
|
||||
17
js_sdk/u-draw-poster/extends/create-from-list/index.d.ts
vendored
Normal file
17
js_sdk/u-draw-poster/extends/create-from-list/index.d.ts
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
import { DrawPosterUseOpts } from '../../utils/interface';
|
||||
export interface CreateLayerOpts {
|
||||
background?: string;
|
||||
self?: boolean;
|
||||
line?: boolean;
|
||||
lineHeight?: number;
|
||||
}
|
||||
export interface DrawRowOpt {
|
||||
text?: string;
|
||||
font?: string;
|
||||
color?: string;
|
||||
center?: boolean;
|
||||
width?: number;
|
||||
}
|
||||
declare const _default: DrawPosterUseOpts;
|
||||
/** 绘制表单扩展方法 */
|
||||
export default _default;
|
||||
140
js_sdk/u-draw-poster/extends/create-from-list/index.js
Normal file
140
js_sdk/u-draw-poster/extends/create-from-list/index.js
Normal file
@@ -0,0 +1,140 @@
|
||||
/** 绘制表单扩展方法 */
|
||||
export default {
|
||||
name: 'createLayer',
|
||||
init: (dp) => {
|
||||
dp.from = {
|
||||
height: 0,
|
||||
padding: 8,
|
||||
margin: 0
|
||||
};
|
||||
dp.setFromOptions = (opts) => {
|
||||
if (typeof opts.height !== 'undefined') {
|
||||
dp.from.height = opts.height;
|
||||
}
|
||||
if (typeof opts.margin !== 'undefined') {
|
||||
dp.from.margin = opts.margin;
|
||||
}
|
||||
if (typeof opts.padding !== 'undefined') {
|
||||
dp.from.padding = opts.padding;
|
||||
}
|
||||
};
|
||||
},
|
||||
handle: (dp, afferOpts, rowList) => {
|
||||
// 当前配置(头部偏移量, 列内边距, 表单外边距)
|
||||
const height = dp.from.height;
|
||||
const margin = dp.from.margin;
|
||||
const padding = dp.from.padding;
|
||||
// 当前层宽度
|
||||
const containerWidth = dp.canvas.width - (margin * 2);
|
||||
// 基本层配置
|
||||
const opts = Object.assign({ background: "#fff", columnY: height || margin, self: true, line: true, lineHeight: 0, border: true }, afferOpts);
|
||||
// 基本列配置
|
||||
const baseRowOpts = {
|
||||
text: "",
|
||||
font: "24px sans-serif",
|
||||
color: "#333",
|
||||
center: false,
|
||||
width: 0,
|
||||
};
|
||||
// 累计最高的列为标准定义为层高度
|
||||
let maxRowHeight = 0;
|
||||
// 累计固定栅格列偏移量
|
||||
let columnOffsetX = margin;
|
||||
// 创建行绘制任务
|
||||
const drawLayerInfos = rowList.map((afferRowOpts = {}, index) => {
|
||||
const rowOpts = Object.assign(Object.assign({}, baseRowOpts), afferRowOpts);
|
||||
let columnX = 0; // 每列的X轴
|
||||
let columnW = 0; // 每列的宽度
|
||||
let fontOffsetX = 0; // 字体偏移X轴
|
||||
let fontMaxWidth = 100; // 字体最大宽度
|
||||
opts.lineHeight = opts.lineHeight || Number(rowOpts.font.replace(/[^0-9.]/g, ""));
|
||||
if (opts.self) {
|
||||
// 自适应栅格格子计算
|
||||
columnX = containerWidth - (containerWidth / (index + 1)) + margin;
|
||||
columnW = containerWidth / rowList.length;
|
||||
if (columnX > 0 && columnX < containerWidth - columnW) {
|
||||
columnX = (columnW * index) + margin;
|
||||
}
|
||||
fontOffsetX = rowOpts.center ? columnX + (columnW / 2) : columnX + padding;
|
||||
fontMaxWidth = columnW - (padding * 3);
|
||||
}
|
||||
if (!opts.self) {
|
||||
// 固定栅格格子计算
|
||||
columnW = rowOpts.width;
|
||||
columnX = columnOffsetX;
|
||||
fontMaxWidth = columnW - (padding * 3);
|
||||
fontOffsetX = rowOpts.center ? columnOffsetX + (rowOpts.width / 2) : columnOffsetX + padding;
|
||||
columnOffsetX += rowOpts.width;
|
||||
}
|
||||
dp.ctx.font = rowOpts.font;
|
||||
const drawFontInfos = dp.ctx.fillWarpText({
|
||||
text: rowOpts.text,
|
||||
maxWidth: fontMaxWidth,
|
||||
lineHeight: opts.lineHeight,
|
||||
x: fontOffsetX,
|
||||
y: opts.columnY,
|
||||
layer: 10,
|
||||
notFillText: true
|
||||
});
|
||||
// 当前行的高度
|
||||
const rowHeight = (opts.lineHeight * drawFontInfos.length) + (padding * 3);
|
||||
// 若该列高度大于累计高度, 将累计高度替换
|
||||
if (rowHeight > maxRowHeight) {
|
||||
maxRowHeight = rowHeight;
|
||||
}
|
||||
return {
|
||||
font: rowOpts.font,
|
||||
center: rowOpts.center,
|
||||
color: rowOpts.color,
|
||||
border: opts.border,
|
||||
background: opts.background,
|
||||
lineHeight: opts.lineHeight,
|
||||
line: opts.line,
|
||||
drawFontInfos,
|
||||
columnY: opts.columnY,
|
||||
columnX,
|
||||
columnW,
|
||||
columnH: maxRowHeight,
|
||||
margin,
|
||||
padding
|
||||
};
|
||||
});
|
||||
// 将行绘制任务添加至绘制容器中
|
||||
dp.draw((ctx) => drawLayerInfos.forEach((rowOpts, index) => {
|
||||
ctx.font = rowOpts.font;
|
||||
ctx.fillStyle = rowOpts.background;
|
||||
ctx.strokeStyle = "#333";
|
||||
ctx.textBaseline = "middle";
|
||||
ctx.textAlign = 'left';
|
||||
if (rowOpts.center) {
|
||||
ctx.textAlign = "center";
|
||||
}
|
||||
ctx.fillRect(rowOpts.columnX, rowOpts.columnY, rowOpts.columnW, rowOpts.columnH);
|
||||
if (rowOpts.border) {
|
||||
dp.ctx.strokeRect(margin, rowOpts.columnY, dp.canvas.width - margin, maxRowHeight);
|
||||
}
|
||||
if (rowOpts.line && rowOpts.columnX !== margin) {
|
||||
ctx.moveTo(rowOpts.columnX, rowOpts.columnY);
|
||||
ctx.lineTo(rowOpts.columnX, rowOpts.columnY + rowOpts.columnH);
|
||||
ctx.stroke();
|
||||
ctx.beginPath();
|
||||
}
|
||||
ctx.fillStyle = rowOpts.color;
|
||||
rowOpts.drawFontInfos.forEach(fontInfo => {
|
||||
// 计算每行字体绘制y轴长度
|
||||
// y(当前列置顶轴) + (rowOpts.columnH(当前列最高长度) / 2) - (((总列数-1) * 行高) / 2)
|
||||
const textTotal = rowOpts.drawFontInfos.length - 1;
|
||||
const textMiddleY = (textTotal * rowOpts.lineHeight) / 2;
|
||||
let fontOffsetY = fontInfo.y + (rowOpts.columnH / 2);
|
||||
fontOffsetY -= textMiddleY;
|
||||
ctx.fillText(fontInfo.text, fontInfo.x, fontOffsetY);
|
||||
});
|
||||
}));
|
||||
if (opts.columnY === 0 || opts.columnY === margin) {
|
||||
maxRowHeight += margin;
|
||||
}
|
||||
// 叠加高度
|
||||
dp.from.height += maxRowHeight;
|
||||
return maxRowHeight;
|
||||
},
|
||||
};
|
||||
4
js_sdk/u-draw-poster/extends/create-gcanvas/index.d.ts
vendored
Normal file
4
js_sdk/u-draw-poster/extends/create-gcanvas/index.d.ts
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
import { DrawPosterUseOpts } from '../../utils/interface';
|
||||
export * from './gcanvas';
|
||||
declare const _default: DrawPosterUseOpts;
|
||||
export default _default;
|
||||
9
js_sdk/u-draw-poster/extends/create-gcanvas/index.js
Normal file
9
js_sdk/u-draw-poster/extends/create-gcanvas/index.js
Normal file
@@ -0,0 +1,9 @@
|
||||
import { WeexBridge, enable, Image } from './gcanvas';
|
||||
export * from './gcanvas';
|
||||
import DrawPoster from "../../draw-poster";
|
||||
DrawPoster.prototype['gcanvas'] = {
|
||||
WeexBridge,
|
||||
enable,
|
||||
Image
|
||||
};
|
||||
export default {};
|
||||
12
js_sdk/u-draw-poster/extends/draw-function/draw-image-fit.d.ts
vendored
Normal file
12
js_sdk/u-draw-poster/extends/draw-function/draw-image-fit.d.ts
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
import { DrawPosterUseCtxOpts } from '../../utils/interface';
|
||||
import { ObjectFit, ObjectPosition, Size } from "../../utils/object-sizing";
|
||||
export interface ImageFitOption {
|
||||
radius?: number;
|
||||
objectFit?: ObjectFit;
|
||||
intrinsicSize?: Size;
|
||||
specifiedSize?: Size;
|
||||
intrinsicPosition?: ObjectPosition;
|
||||
specifiedPosition?: [number, number];
|
||||
}
|
||||
declare const _default: DrawPosterUseCtxOpts;
|
||||
export default _default;
|
||||
25
js_sdk/u-draw-poster/extends/draw-function/draw-image-fit.js
Normal file
25
js_sdk/u-draw-poster/extends/draw-function/draw-image-fit.js
Normal file
@@ -0,0 +1,25 @@
|
||||
import { calculateConcreteRect } from "../../utils/object-sizing";
|
||||
import uni from "../../utils/global";
|
||||
export default {
|
||||
name: 'drawImageFit',
|
||||
handle: async (canvas, ctx, url, options) => {
|
||||
var _a, _b, _c;
|
||||
const [error, imageInfo] = await uni.getImageInfo({ src: url });
|
||||
// 配置默认值
|
||||
const style = Object.assign({ radius: 0, objectFit: 'cover', intrinsicSize: { width: (_a = imageInfo === null || imageInfo === void 0 ? void 0 : imageInfo.width) !== null && _a !== void 0 ? _a : 100, height: (_b = imageInfo === null || imageInfo === void 0 ? void 0 : imageInfo.height) !== null && _b !== void 0 ? _b : 100 }, specifiedSize: { width: 100, height: 100 }, intrinsicPosition: ['center', 'center'], specifiedPosition: [0, 0] }, options);
|
||||
// 计算图片尺寸
|
||||
const drawImageInfo = calculateConcreteRect(style, style.intrinsicSize, style.specifiedSize);
|
||||
// 如有圆角, 则进行裁剪
|
||||
if (style.radius > 0) {
|
||||
ctx.save();
|
||||
(_c = ctx.setFillStyle) === null || _c === void 0 ? void 0 : _c.call(ctx, 'transparent');
|
||||
ctx.fillStyle = 'transparent';
|
||||
ctx.fillRoundRect(style.specifiedPosition[0], style.specifiedPosition[1], style.specifiedSize.width, style.specifiedSize.height, style.radius);
|
||||
ctx.clip();
|
||||
}
|
||||
const result = await ctx.drawImage(url, ...Object.values(drawImageInfo));
|
||||
if (style.radius > 0)
|
||||
ctx.restore();
|
||||
return result;
|
||||
}
|
||||
};
|
||||
4
js_sdk/u-draw-poster/extends/draw-function/draw-image.d.ts
vendored
Normal file
4
js_sdk/u-draw-poster/extends/draw-function/draw-image.d.ts
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
import { DrawPosterUseCtxOpts } from '../../utils/interface';
|
||||
declare const _default: DrawPosterUseCtxOpts;
|
||||
/** 等待绘制图片原型方法 */
|
||||
export default _default;
|
||||
42
js_sdk/u-draw-poster/extends/draw-function/draw-image.js
Normal file
42
js_sdk/u-draw-poster/extends/draw-function/draw-image.js
Normal file
@@ -0,0 +1,42 @@
|
||||
import { downloadImgUrl } from '../../utils/wx-utils';
|
||||
/** 等待绘制图片原型方法 */
|
||||
export default {
|
||||
name: 'drawImage',
|
||||
init: (canvas, ctx) => {
|
||||
ctx.drawImageProto = ctx.drawImage;
|
||||
},
|
||||
handle: async (canvas, ctx, url, sx, sy, sh, sw, dx, dy, dh, dw) => {
|
||||
// 下载路径
|
||||
const path = await downloadImgUrl(url);
|
||||
// 标记当前绘画存在图片绘制
|
||||
let result = false;
|
||||
// 基本绘制方法, 如果是 fit 方式, 则传入所有参数, 不然则只传入四个参数
|
||||
const baseDrawImage = (imageResource) => {
|
||||
const isFit = typeof dx === 'number' && typeof dw === 'number';
|
||||
if (isFit) {
|
||||
ctx.drawImageProto(imageResource, sx, sy, sh, sw, dx, dy, dh, dw);
|
||||
}
|
||||
else {
|
||||
ctx.drawImageProto(imageResource, sx, sy, sh, sw);
|
||||
}
|
||||
};
|
||||
// 如果是 context 绘制方式, 则直接绘制
|
||||
if (ctx.drawType === 'context') {
|
||||
baseDrawImage(path);
|
||||
result = true;
|
||||
}
|
||||
// 如果是 type2d 绘制方式, 则等待图片绘制完毕
|
||||
if (ctx.drawType === 'type2d') {
|
||||
result = await new Promise(resolve => {
|
||||
const image = canvas.createImage();
|
||||
image.src = path;
|
||||
image.onload = () => {
|
||||
baseDrawImage(image);
|
||||
resolve(true);
|
||||
};
|
||||
image.onerror = () => resolve(false);
|
||||
});
|
||||
}
|
||||
return result;
|
||||
}
|
||||
};
|
||||
4
js_sdk/u-draw-poster/extends/draw-function/draw-round-image.d.ts
vendored
Normal file
4
js_sdk/u-draw-poster/extends/draw-function/draw-round-image.d.ts
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
import { DrawPosterUseCtxOpts } from '../../utils/interface';
|
||||
declare const _default: DrawPosterUseCtxOpts;
|
||||
/** 绘制圆角图片原型方法 */
|
||||
export default _default;
|
||||
@@ -0,0 +1,15 @@
|
||||
/** 绘制圆角图片原型方法 */
|
||||
export default {
|
||||
name: 'drawRoundImage',
|
||||
handle: async (canvas, ctx, url, x, y, w, h, r = 15) => {
|
||||
var _a;
|
||||
ctx.save();
|
||||
(_a = ctx.setFillStyle) === null || _a === void 0 ? void 0 : _a.call(ctx, 'transparent');
|
||||
ctx.fillStyle = 'transparent';
|
||||
ctx.fillRoundRect(x, y, w, h, r);
|
||||
ctx.clip();
|
||||
const result = await ctx.drawImage(url, x, y, w, h);
|
||||
ctx.restore();
|
||||
return result;
|
||||
}
|
||||
};
|
||||
4
js_sdk/u-draw-poster/extends/draw-function/fill-round-rect.d.ts
vendored
Normal file
4
js_sdk/u-draw-poster/extends/draw-function/fill-round-rect.d.ts
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
import { DrawPosterUseCtxOpts } from '../../utils/interface';
|
||||
declare const _default: DrawPosterUseCtxOpts;
|
||||
/** 绘制填充圆角矩形方法 */
|
||||
export default _default;
|
||||
@@ -0,0 +1,7 @@
|
||||
/** 绘制填充圆角矩形方法 */
|
||||
export default {
|
||||
name: 'fillRoundRect',
|
||||
handle: (canvas, ctx, x, y, w, h, r) => {
|
||||
ctx.roundRect(x, y, w, h, r, true);
|
||||
}
|
||||
};
|
||||
4
js_sdk/u-draw-poster/extends/draw-function/fill-warp-text.d.ts
vendored
Normal file
4
js_sdk/u-draw-poster/extends/draw-function/fill-warp-text.d.ts
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
import { DrawPosterUseCtxOpts } from '../../utils/interface';
|
||||
declare const _default: DrawPosterUseCtxOpts;
|
||||
/** 绘制换行字体原型方法 */
|
||||
export default _default;
|
||||
76
js_sdk/u-draw-poster/extends/draw-function/fill-warp-text.js
Normal file
76
js_sdk/u-draw-poster/extends/draw-function/fill-warp-text.js
Normal file
@@ -0,0 +1,76 @@
|
||||
/** 绘制换行字体原型方法 */
|
||||
export default {
|
||||
name: 'fillWarpText',
|
||||
handle: (canvas, ctx, config) => {
|
||||
const newConfig = config = Object.assign({ maxWidth: 100, layer: 2, lineHeight: Number(ctx.font.replace(/[^0-9.]/g, '')), x: 0, y: Number(ctx.font.replace(/[^0-9.]/g, '')) / 1.2, splitText: '', notFillText: false }, config);
|
||||
const { text, splitText, maxWidth, layer, lineHeight, notFillText, x, y } = newConfig;
|
||||
// 当字符串为空时, 抛出错误
|
||||
if (!text) {
|
||||
throw Error('warpFillText Error: text is empty string');
|
||||
}
|
||||
// 分割所有单个字符串
|
||||
const chr = text.split(splitText);
|
||||
// 存入的每行字体的容器
|
||||
let row = [];
|
||||
// 判断字符串
|
||||
let timp = '';
|
||||
if (splitText) {
|
||||
row = chr;
|
||||
}
|
||||
else {
|
||||
// 遍历所有字符串, 填充行容器
|
||||
for (let i = 0; i < chr.length; i++) {
|
||||
// 当超出行列时, 停止执行遍历, 节省计算时间
|
||||
if (row.length > layer) {
|
||||
break;
|
||||
}
|
||||
if (ctx.measureText(timp).width < maxWidth) {
|
||||
// 如果超出长度, 添加进row数组
|
||||
timp += chr[i];
|
||||
}
|
||||
else {
|
||||
// 如超出一行长度, 则换行, 并清除容器
|
||||
i--;
|
||||
row.push(timp);
|
||||
timp = '';
|
||||
}
|
||||
}
|
||||
// 如有剩下字体, 则在最后时添加一行
|
||||
if (timp) {
|
||||
row.push(timp);
|
||||
}
|
||||
// 如果数组长度大于指定行数
|
||||
if (row.length > layer) {
|
||||
row = row.slice(0, layer);
|
||||
// 结束的索引
|
||||
const end = layer - 1;
|
||||
for (let i = 0; i < row[end].length; i++) {
|
||||
const currentWidth = ctx.measureText(`${row[end]}...`).width;
|
||||
if (currentWidth > maxWidth) {
|
||||
// 加上... 当前宽度大于最大宽度时, 去除一位字符串
|
||||
const strEnd = row[end].length - 1;
|
||||
row[end] = row[end].slice(0, strEnd);
|
||||
}
|
||||
else {
|
||||
row[end] += '...';
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// 储存并返回绘制信息
|
||||
const drawInfos = row.map((item, index) => {
|
||||
const info = {
|
||||
text: item,
|
||||
y: y + index * lineHeight,
|
||||
x: x,
|
||||
};
|
||||
// 默认执行绘制信息
|
||||
if (!notFillText) {
|
||||
ctx.fillText(info.text, info.x, info.y);
|
||||
}
|
||||
return info;
|
||||
});
|
||||
return drawInfos;
|
||||
}
|
||||
};
|
||||
7
js_sdk/u-draw-poster/extends/draw-function/index.d.ts
vendored
Normal file
7
js_sdk/u-draw-poster/extends/draw-function/index.d.ts
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
export { default as drawImage } from "./draw-image";
|
||||
export { default as roundRect } from "./round-rect";
|
||||
export { default as fillRoundRect } from "./fill-round-rect";
|
||||
export { default as strokeRoundRect } from "./stroke-round-rect";
|
||||
export { default as fillWarpText } from "./fill-warp-text";
|
||||
export { default as drawRoundImage } from "./draw-round-image";
|
||||
export { default as drawImageFit } from "./draw-image-fit";
|
||||
15
js_sdk/u-draw-poster/extends/draw-function/index.js
Normal file
15
js_sdk/u-draw-poster/extends/draw-function/index.js
Normal file
@@ -0,0 +1,15 @@
|
||||
/*
|
||||
* @Author: Mr.Mao
|
||||
* @LastEditors: Mr.Mao
|
||||
* @Date: 2020-11-11 20:43:33
|
||||
* @LastEditTime: 2021-01-02 00:16:59
|
||||
* @Description:
|
||||
* @任何一个傻子都能写出让电脑能懂的代码,而只有好的程序员可以写出让人能看懂的代码
|
||||
*/
|
||||
export { default as drawImage } from "./draw-image";
|
||||
export { default as roundRect } from "./round-rect";
|
||||
export { default as fillRoundRect } from "./fill-round-rect";
|
||||
export { default as strokeRoundRect } from "./stroke-round-rect";
|
||||
export { default as fillWarpText } from "./fill-warp-text";
|
||||
export { default as drawRoundImage } from "./draw-round-image";
|
||||
export { default as drawImageFit } from "./draw-image-fit";
|
||||
4
js_sdk/u-draw-poster/extends/draw-function/round-rect.d.ts
vendored
Normal file
4
js_sdk/u-draw-poster/extends/draw-function/round-rect.d.ts
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
import { DrawPosterUseCtxOpts } from '../../utils/interface';
|
||||
declare const _default: DrawPosterUseCtxOpts;
|
||||
/** 绘制圆角矩形原型方法 */
|
||||
export default _default;
|
||||
41
js_sdk/u-draw-poster/extends/draw-function/round-rect.js
Normal file
41
js_sdk/u-draw-poster/extends/draw-function/round-rect.js
Normal file
@@ -0,0 +1,41 @@
|
||||
/** 绘制圆角矩形原型方法 */
|
||||
export default {
|
||||
name: 'roundRect',
|
||||
handle: (canvas, ctx, x, y, w, h, r = 15, fill = false, stroke = false) => {
|
||||
if (r === 0) {
|
||||
if (stroke)
|
||||
ctx.strokeRect(x, y, w, h);
|
||||
if (fill)
|
||||
ctx.fillRect(x, y, w, h);
|
||||
return;
|
||||
}
|
||||
if (w < 2 * r) {
|
||||
r = w / 2;
|
||||
}
|
||||
if (h < 2 * r) {
|
||||
r = h / 2;
|
||||
}
|
||||
// 开始绘制
|
||||
ctx.beginPath();
|
||||
ctx.arc(x + r, y + r, r, Math.PI, Math.PI * 1.5);
|
||||
// 移动复制
|
||||
ctx.moveTo(x + r, y);
|
||||
ctx.lineTo(x + w - r, y);
|
||||
ctx.lineTo(x + w, y + r);
|
||||
// (x,y,z,j,f) x,y圆心z半径,j起始弧度f,终止弧度
|
||||
ctx.arc(x + w - r, y + r, r, Math.PI * 1.5, Math.PI * 2);
|
||||
ctx.lineTo(x + w, y + h - r);
|
||||
ctx.lineTo(x + w - r, y + h);
|
||||
ctx.arc(x + w - r, y + h - r, r, 0, Math.PI * 0.5);
|
||||
ctx.lineTo(x + r, y + h);
|
||||
ctx.lineTo(x, y + h - r);
|
||||
ctx.arc(x + r, y + h - r, r, Math.PI * 0.5, Math.PI);
|
||||
ctx.lineTo(x, y + r);
|
||||
ctx.lineTo(x + r, y);
|
||||
if (stroke)
|
||||
ctx.stroke();
|
||||
if (fill)
|
||||
ctx.fill();
|
||||
ctx.closePath();
|
||||
}
|
||||
};
|
||||
4
js_sdk/u-draw-poster/extends/draw-function/stroke-round-rect.d.ts
vendored
Normal file
4
js_sdk/u-draw-poster/extends/draw-function/stroke-round-rect.d.ts
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
import { DrawPosterUseCtxOpts } from '../../utils/interface';
|
||||
declare const _default: DrawPosterUseCtxOpts;
|
||||
/** 绘制填充圆角矩形方法 */
|
||||
export default _default;
|
||||
@@ -0,0 +1,7 @@
|
||||
/** 绘制填充圆角矩形方法 */
|
||||
export default {
|
||||
name: 'strokeRoundRect',
|
||||
handle: (canvas, ctx, x, y, w, h, r) => {
|
||||
ctx.roundRect(x, y, w, h, r, false, true);
|
||||
}
|
||||
};
|
||||
101
js_sdk/u-draw-poster/extends/draw-painter/index.d.ts
vendored
Normal file
101
js_sdk/u-draw-poster/extends/draw-painter/index.d.ts
vendored
Normal file
@@ -0,0 +1,101 @@
|
||||
import { DrawPosterUseOpts } from '../../utils/interface';
|
||||
import { ImageFitOption } from '../draw-function/draw-image-fit';
|
||||
/** 矩形基本信息 */
|
||||
interface PainterItemSize {
|
||||
/** 容器的宽度,固定值 */
|
||||
width: number;
|
||||
/** 容器的高度,固定值 */
|
||||
height: number;
|
||||
}
|
||||
/** 元素位置信息 */
|
||||
interface PainterItemSite {
|
||||
/** 元素锚点距左边的距离; 默认: 0 */
|
||||
left?: number;
|
||||
/** 元素锚点距上边的距离; 默认: 0 */
|
||||
top?: number;
|
||||
}
|
||||
/** 绘制图片信息 */
|
||||
interface PainterImageInfo extends PainterItemSize, PainterItemSite {
|
||||
/** 绘制图片元素 */
|
||||
type: 'image';
|
||||
/** 图片地址 */
|
||||
src: string;
|
||||
/** 图片自适应, 可参考 css 属性 object-fit */
|
||||
objectFit?: ImageFitOption['objectFit'];
|
||||
/** 图片在元素容器中显示的位置,可参考 css 属性 object-position */
|
||||
position?: ImageFitOption['intrinsicPosition'];
|
||||
/** 圆角尺寸; 默认: 0 */
|
||||
radius?: number;
|
||||
}
|
||||
/** 绘制矩形信息 */
|
||||
interface PainterRectInfo extends PainterItemSize, PainterItemSite {
|
||||
/** 绘制矩形元素 */
|
||||
type: "rect";
|
||||
/** 矩形背景颜色; 默认: "#000" */
|
||||
background?: string;
|
||||
/** 圆角尺寸; 默认: 0 */
|
||||
radius?: number;
|
||||
}
|
||||
/** 绘制单行文字信息 */
|
||||
interface PainterTextInfo extends PainterItemSite {
|
||||
/** 绘制文本元素 */
|
||||
type: "text";
|
||||
/** 文本颜色; 默认: "#000" */
|
||||
color?: string;
|
||||
/** 字体; 默认: "serial" */
|
||||
fontFamily?: string;
|
||||
/** 字号(单位rpx); 默认: 30 rpx */
|
||||
fontSize?: number;
|
||||
/** 字重; 默认: "normal" 可选项: "bold" */
|
||||
fontWeight?: string;
|
||||
/** 字型 默认: "normal" 可选项: "italic" */
|
||||
fontStyle?: string;
|
||||
/** 元素的宽度(单位rpx), 水平排布时影响后一个元素的位置,为 null 时根据文字实际占用的宽度计算 */
|
||||
width?: number;
|
||||
/** 文本内容 */
|
||||
content: string;
|
||||
}
|
||||
/** 绘制多行文字信息 */
|
||||
interface PainterLineFeedTextInfo extends PainterItemSite {
|
||||
/** 绘制换行文本元素 */
|
||||
type: "line-feed-text";
|
||||
/** 文本颜色; 默认: "#000" */
|
||||
color?: string;
|
||||
/** 字体; 默认: "serial" */
|
||||
fontFamily?: string;
|
||||
/** 字号(单位rpx); 默认: 30 rpx */
|
||||
fontSize?: number;
|
||||
/** 字重; 默认: "normal" 可选项: "bold" */
|
||||
fontWeight?: string;
|
||||
/** 字型 默认: "normal" 可选项: "italic" */
|
||||
fontStyle?: string;
|
||||
/** 文本块的宽度,不能为空 */
|
||||
width: number;
|
||||
/** 行高; 默认取当前文字行高 */
|
||||
lineHeight?: number;
|
||||
/** 文本最大行数,超出即显示省略号; 默认3行 */
|
||||
lineClamp?: number;
|
||||
/** 文本内容 */
|
||||
content: string;
|
||||
}
|
||||
/** 绘制二维码信息 */
|
||||
interface PainterQrCodeInfo extends PainterItemSite {
|
||||
/** 绘制换行文本元素 */
|
||||
type: "qr-code";
|
||||
/** 二维码尺寸 */
|
||||
size: number;
|
||||
/** 二维码内容 */
|
||||
content: string;
|
||||
/** 边距,二维码实际尺寸会根据所设边距值进行缩放调整(默认:5) */
|
||||
margin?: number;
|
||||
/** 背景色(默认:'#ffffff')*/
|
||||
backgroundColor?: string;
|
||||
/** 前景色(默认:'#000000') */
|
||||
foregroundColor?: string;
|
||||
}
|
||||
export interface PainterContainerOption extends PainterItemSize {
|
||||
/** 绘制项的数组 */
|
||||
contents: Array<PainterImageInfo | PainterRectInfo | PainterTextInfo | PainterLineFeedTextInfo | PainterQrCodeInfo>;
|
||||
}
|
||||
declare const _default: DrawPosterUseOpts;
|
||||
export default _default;
|
||||
73
js_sdk/u-draw-poster/extends/draw-painter/index.js
Normal file
73
js_sdk/u-draw-poster/extends/draw-painter/index.js
Normal file
@@ -0,0 +1,73 @@
|
||||
export default {
|
||||
name: 'painter',
|
||||
handle: (dp, option) => {
|
||||
dp.canvas.width = option.width;
|
||||
dp.canvas.height = option.height;
|
||||
dp.draw(async (ctx) => {
|
||||
for (let i = 0; i < option.contents.length; i++) {
|
||||
ctx.save();
|
||||
const drawInfo = option.contents[i];
|
||||
const { left = 0, top = 0 } = drawInfo;
|
||||
if (drawInfo.type === 'rect') {
|
||||
ctx.fillStyle = drawInfo.background || '#000000';
|
||||
ctx.fillRoundRect(left, top, drawInfo.width, drawInfo.height, drawInfo.radius || 0);
|
||||
}
|
||||
if (drawInfo.type === 'image') {
|
||||
await ctx.drawImageFit(drawInfo.src, {
|
||||
objectFit: drawInfo.objectFit || 'cover',
|
||||
intrinsicPosition: drawInfo.position || ['center', 'center'],
|
||||
specifiedPosition: [left, top],
|
||||
specifiedSize: {
|
||||
width: drawInfo.width,
|
||||
height: drawInfo.height
|
||||
},
|
||||
radius: drawInfo.radius
|
||||
});
|
||||
}
|
||||
if (drawInfo.type === 'text') {
|
||||
ctx.fillStyle = drawInfo.color || '#000000';
|
||||
ctx.font = `\
|
||||
${drawInfo.fontStyle || 'normal'} \
|
||||
${drawInfo.fontWeight || 'normal'} \
|
||||
${drawInfo.fontSize || 30} \
|
||||
${drawInfo.fontFamily || 'serial'}\
|
||||
`;
|
||||
ctx.fillText(drawInfo.content, left, top, drawInfo.width);
|
||||
}
|
||||
if (drawInfo.type === 'line-feed-text') {
|
||||
ctx.fillStyle = drawInfo.color || '#000000';
|
||||
ctx.font = `\
|
||||
${drawInfo.fontStyle || 'normal'} \
|
||||
${drawInfo.fontWeight || 'normal'} \
|
||||
${drawInfo.fontSize || 30} \
|
||||
${drawInfo.fontFamily || 'serial'}\
|
||||
`;
|
||||
ctx.fillWarpText({
|
||||
x: drawInfo.left,
|
||||
y: drawInfo.top,
|
||||
layer: drawInfo.lineClamp,
|
||||
lineHeight: drawInfo.lineHeight,
|
||||
maxWidth: drawInfo.width,
|
||||
text: drawInfo.content
|
||||
});
|
||||
}
|
||||
if (drawInfo.type === 'qr-code') {
|
||||
if (typeof ctx.drawQrCode !== 'function') {
|
||||
console.error('--- 当前未引入qr-code扩展, 将自动省略该二维码绘制 ---');
|
||||
return false;
|
||||
}
|
||||
ctx.drawQrCode({
|
||||
x: left,
|
||||
y: top,
|
||||
size: drawInfo.size,
|
||||
text: drawInfo.content,
|
||||
margin: drawInfo.margin || 5,
|
||||
backgroundColor: drawInfo.backgroundColor || '#ffffff',
|
||||
foregroundColor: drawInfo.foregroundColor || '#000000',
|
||||
});
|
||||
}
|
||||
ctx.restore();
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
6
js_sdk/u-draw-poster/extends/draw-qr-code/index.d.ts
vendored
Normal file
6
js_sdk/u-draw-poster/extends/draw-qr-code/index.d.ts
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
declare const _default: {
|
||||
name: string;
|
||||
handle: any;
|
||||
errorCorrectLevel: any;
|
||||
};
|
||||
export default _default;
|
||||
6
js_sdk/u-draw-poster/extends/draw-qr-code/index.js
Normal file
6
js_sdk/u-draw-poster/extends/draw-qr-code/index.js
Normal file
@@ -0,0 +1,6 @@
|
||||
import uQRCode from "./uQRCode";
|
||||
export default {
|
||||
name: "drawQrCode",
|
||||
handle: uQRCode.make.bind(uQRCode),
|
||||
errorCorrectLevel: uQRCode.errorCorrectLevel
|
||||
};
|
||||
10
js_sdk/u-draw-poster/extends/draw-qr-code/uQRCode.d.ts
vendored
Normal file
10
js_sdk/u-draw-poster/extends/draw-qr-code/uQRCode.d.ts
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
/*
|
||||
* @Author: Mr.Mao
|
||||
* @LastEditors: Mr.Mao
|
||||
* @Date: 2021-01-02 13:30:58
|
||||
* @LastEditTime: 2021-01-02 13:31:27
|
||||
* @Description:
|
||||
* @任何一个傻子都能写出让电脑能懂的代码,而只有好的程序员可以写出让人能看懂的代码
|
||||
*/
|
||||
declare const uQRCode: any
|
||||
export default uQRCode
|
||||
1355
js_sdk/u-draw-poster/extends/draw-qr-code/uQRCode.js
Normal file
1355
js_sdk/u-draw-poster/extends/draw-qr-code/uQRCode.js
Normal file
File diff suppressed because it is too large
Load Diff
11
js_sdk/u-draw-poster/index.d.ts
vendored
Normal file
11
js_sdk/u-draw-poster/index.d.ts
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
import { DrawPosterBuildOpts } from "./utils/interface";
|
||||
import DrawPoster from "./draw-poster";
|
||||
import drawQrCode from "./extends/draw-qr-code/index";
|
||||
import createFromList from './extends/create-from-list/index';
|
||||
import drawPainter from './extends/draw-painter/index';
|
||||
declare const useDrawPoster: (options: string | DrawPosterBuildOpts) => Promise<DrawPoster & import("./utils/interface").drawPosterExtends>;
|
||||
declare const useDrawPosters: (optionsAll: (string | DrawPosterBuildOpts)[]) => Promise<{
|
||||
[key: string]: DrawPoster & import("./utils/interface").drawPosterExtends;
|
||||
}>;
|
||||
export { DrawPoster, useDrawPoster, useDrawPosters, drawQrCode, drawPainter, createFromList };
|
||||
export default DrawPoster;
|
||||
22
js_sdk/u-draw-poster/index.js
Normal file
22
js_sdk/u-draw-poster/index.js
Normal file
@@ -0,0 +1,22 @@
|
||||
import * as dfucs from "./extends/draw-function/index";
|
||||
import DrawPoster from "./draw-poster";
|
||||
import drawQrCode from "./extends/draw-qr-code/index";
|
||||
import createFromList from './extends/create-from-list/index';
|
||||
import drawPainter from './extends/draw-painter/index';
|
||||
DrawPoster.useCtx(dfucs.drawImage);
|
||||
DrawPoster.useCtx(dfucs.fillWarpText);
|
||||
DrawPoster.useCtx(dfucs.roundRect);
|
||||
DrawPoster.useCtx(dfucs.fillRoundRect);
|
||||
DrawPoster.useCtx(dfucs.strokeRoundRect);
|
||||
DrawPoster.useCtx(dfucs.drawRoundImage);
|
||||
DrawPoster.useCtx(dfucs.drawImageFit);
|
||||
const useDrawPoster = async (options) => {
|
||||
const dp = await DrawPoster.build(options);
|
||||
return dp;
|
||||
};
|
||||
const useDrawPosters = async (optionsAll) => {
|
||||
const dps = await DrawPoster.buildAll(optionsAll);
|
||||
return dps;
|
||||
};
|
||||
export { DrawPoster, useDrawPoster, useDrawPosters, drawQrCode, drawPainter, createFromList };
|
||||
export default DrawPoster;
|
||||
13
js_sdk/u-draw-poster/package.json
Normal file
13
js_sdk/u-draw-poster/package.json
Normal file
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"id": "u-draw-poster",
|
||||
"name": "u-draw-poster uniVue2|3适用 海报绘制工具",
|
||||
"version": "1.1.5",
|
||||
"description": "全端支持,内置多种海报绘制方法、表单绘制、二维码生成,图片裁剪。原生开发体验,上手快,不污染组件数据",
|
||||
"keywords": [
|
||||
"海报",
|
||||
"绘制",
|
||||
"分享",
|
||||
"小程序",
|
||||
"canvas"
|
||||
]
|
||||
}
|
||||
7
js_sdk/u-draw-poster/utils/global.d.ts
vendored
Normal file
7
js_sdk/u-draw-poster/utils/global.d.ts
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
/// <reference types="@dcloudio/types" />
|
||||
/** 当前环境类型 */
|
||||
export declare type UniPlatforms = 'app-plus' | 'app-plus-nvue' | 'h5' | 'mp-weixin' | 'mp-alipay' | 'mp-baidu' | 'mp-toutiao' | 'mp-qq' | 'mp-360' | 'mp' | 'quickapp-webview' | 'quickapp-webview-union' | 'quickapp-webview-huawei' | undefined;
|
||||
export declare const PLATFORM: UniPlatforms;
|
||||
/** 全局对象 */
|
||||
declare const _uni: UniApp.Uni;
|
||||
export default _uni;
|
||||
11
js_sdk/u-draw-poster/utils/global.js
Normal file
11
js_sdk/u-draw-poster/utils/global.js
Normal file
@@ -0,0 +1,11 @@
|
||||
var _a;
|
||||
export const PLATFORM = typeof process !== 'undefined' ? (_a = process === null || process === void 0 ? void 0 : process.env) === null || _a === void 0 ? void 0 : _a.VUE_APP_PLATFORM : undefined;
|
||||
/** 全局对象 */
|
||||
const _uni = (function () {
|
||||
if (typeof uni != "undefined")
|
||||
return uni;
|
||||
if (typeof wx != "undefined")
|
||||
return wx;
|
||||
return uni;
|
||||
})();
|
||||
export default _uni;
|
||||
175
js_sdk/u-draw-poster/utils/interface.d.ts
vendored
Normal file
175
js_sdk/u-draw-poster/utils/interface.d.ts
vendored
Normal file
@@ -0,0 +1,175 @@
|
||||
/// <reference types="@dcloudio/types" />
|
||||
import DrawPoster from "../draw-poster";
|
||||
import { ImageFitOption } from '../extends/draw-function/draw-image-fit';
|
||||
import { CreateLayerOpts, DrawRowOpt } from "../extends/create-from-list";
|
||||
import { PainterContainerOption } from "../extends/draw-painter";
|
||||
/** 绘制容器 */
|
||||
export declare type Execute = Array<() => Promise<boolean>>;
|
||||
export interface drawPosterExtends {
|
||||
from: {
|
||||
height: number;
|
||||
padding: number;
|
||||
margin: number;
|
||||
};
|
||||
createLayer: (afferOpts: CreateLayerOpts, rowList: DrawRowOpt[]) => number;
|
||||
setFromOptions: (opts: Partial<{
|
||||
height: number;
|
||||
padding: number;
|
||||
margin: number;
|
||||
}>) => void;
|
||||
gcanvas: {
|
||||
WeexBridge: any;
|
||||
Image: any;
|
||||
enable: (el: any, options: {
|
||||
bridge?: any;
|
||||
debug?: boolean;
|
||||
disableAutoSwap?: any;
|
||||
disableComboCommands?: any;
|
||||
}) => Canvas;
|
||||
};
|
||||
painter: (option: PainterContainerOption) => void;
|
||||
}
|
||||
/** 构建器配置 */
|
||||
export interface DrawPosterBuildOpts {
|
||||
/** 查询选择器; 注意不需要加# */
|
||||
selector: string;
|
||||
/** 选取组件范围 */
|
||||
componentThis?: any;
|
||||
/** 绘制类型为2d绘制, 默认开启, 在微信小程序的时候动态加载 */
|
||||
type2d?: boolean;
|
||||
/** 是否在绘制时进行加载提示 */
|
||||
loading?: boolean;
|
||||
/** 当存在绘制图片时, 等待绘画完毕的时间(秒)仅App中生效
|
||||
*
|
||||
* 具体查看文档说明:https://github.com/TuiMao233/uni-draw-poster
|
||||
*/
|
||||
drawImageTime?: number;
|
||||
/** 是否开启调试模式 */
|
||||
debugging?: boolean;
|
||||
/** 加载提示文字 */
|
||||
loadingText?: string;
|
||||
/** 创建图片提示文字 */
|
||||
createText?: string;
|
||||
/** 是否启动gcanvas(nvue) */
|
||||
gcanvas?: boolean;
|
||||
}
|
||||
/** 绘制换行配置 */
|
||||
export interface FillWarpTextOpts {
|
||||
text: string;
|
||||
maxWidth?: number;
|
||||
lineHeight?: number;
|
||||
layer?: number;
|
||||
x?: number;
|
||||
y?: number;
|
||||
splitText?: string;
|
||||
notFillText?: boolean;
|
||||
}
|
||||
/** 绘制二维码配置 */
|
||||
export interface DrawQrCodeOpts {
|
||||
text: string;
|
||||
x?: number;
|
||||
y?: number;
|
||||
size?: number;
|
||||
margin?: number;
|
||||
backgroundColor?: string;
|
||||
foregroundColor?: string;
|
||||
}
|
||||
/** 绘制换行, 单行信息 */
|
||||
export interface FillWarpTextItemInfo {
|
||||
text: string;
|
||||
y: number;
|
||||
x: number;
|
||||
}
|
||||
/** 绘制画笔 */
|
||||
export interface DrawPosterCanvasCtx extends UniApp.CanvasContext {
|
||||
[key: string]: any;
|
||||
createImageData: () => ImageData;
|
||||
textAlign: CanvasTextDrawingStyles["textAlign"];
|
||||
textBaseline: CanvasTextDrawingStyles["textBaseline"];
|
||||
transform: CanvasTransform["transform"];
|
||||
/** 绘制图片原型 */
|
||||
drawImageProto: UniApp.CanvasContext['drawImage'];
|
||||
/** 当前绘制类型 */
|
||||
drawType: 'context' | 'type2d';
|
||||
/** 等待绘制图片
|
||||
*
|
||||
* 说明文档: https://tuimao233.gitee.io/mao-blog/my-extends/u-draw-poste
|
||||
*/
|
||||
drawImage(url: string, dx?: number | undefined, dy?: number | undefined, dWidth?: number | undefined, dHeigt?: number | undefined, sx?: number | undefined, sy?: number | undefined, sWidth?: number | undefined, sHeight?: number | undefined): Promise<boolean>;
|
||||
/** 绘制圆角图片
|
||||
*
|
||||
* 说明文档: https://tuimao233.gitee.io/mao-blog/my-extends/u-draw-poste
|
||||
*/
|
||||
drawRoundImage(url: string, x: number, y: number, w: number, h: number, r?: number): Promise<boolean>;
|
||||
/** 绘制 Object-Fit 模式图片
|
||||
*
|
||||
* 说明文档: https://tuimao233.gitee.io/mao-blog/my-extends/u-draw-poste
|
||||
*/
|
||||
drawImageFit(url: string, opts?: ImageFitOption): Promise<boolean>;
|
||||
/** 绘制换行字体
|
||||
*
|
||||
* 说明文档: https://tuimao233.gitee.io/mao-blog/my-extends/u-draw-poste
|
||||
*/
|
||||
fillWarpText(options: FillWarpTextOpts): Array<FillWarpTextItemInfo>;
|
||||
/** 绘制圆角矩形(原型)
|
||||
*
|
||||
*/
|
||||
roundRect(x: number, y: number, w: number, h: number, r: number, fill?: boolean, stroke?: boolean): void;
|
||||
/** 绘制圆角矩形(填充)
|
||||
*
|
||||
* 说明文档: https://tuimao233.gitee.io/mao-blog/my-extends/u-draw-poste
|
||||
*/
|
||||
fillRoundRect(x: number, y: number, w: number, h: number, r: number): void;
|
||||
/** 绘制圆角矩形(边框)
|
||||
*
|
||||
* 说明文档: https://tuimao233.gitee.io/mao-blog/my-extends/u-draw-poste
|
||||
*/
|
||||
strokeRoundRect(x: number, y: number, w: number, h: number, r: number): void;
|
||||
/** 绘制二维码
|
||||
*
|
||||
* 说明文档: https://tuimao233.gitee.io/mao-blog/my-extends/u-draw-poste
|
||||
*/
|
||||
drawQrCode(options: DrawQrCodeOpts): void;
|
||||
}
|
||||
/** Canvas2d实例 */
|
||||
export interface Canvas {
|
||||
width: number;
|
||||
height: number;
|
||||
getContext(contextType: "2d" | "webgl"): DrawPosterCanvasCtx | WebGLRenderingContext;
|
||||
createImage(): {
|
||||
src: string;
|
||||
width: number;
|
||||
height: number;
|
||||
onload: () => void;
|
||||
onerror: () => void;
|
||||
};
|
||||
requestAnimationFrame(callback: Function): number;
|
||||
cancelAnimationFrame(requestID: number): void;
|
||||
createImageData(): ImageData;
|
||||
createPath2D(path: Path2D): Path2D;
|
||||
toDataURL(type: string, encoderOptions: number): string;
|
||||
}
|
||||
/** 创建图片路径配置项 */
|
||||
export interface CreateImagePathOptions {
|
||||
x?: number;
|
||||
y?: number;
|
||||
width?: number;
|
||||
height?: number;
|
||||
destWidth?: number;
|
||||
destHeight?: number;
|
||||
}
|
||||
/** 绘制实例扩展配置 */
|
||||
export interface DrawPosterUseOpts {
|
||||
name: string;
|
||||
init?: (dp: InstanceType<typeof DrawPoster>) => void;
|
||||
handle: (dp: InstanceType<typeof DrawPoster>, ...args: any[]) => any;
|
||||
createImage?: (dp: InstanceType<typeof DrawPoster>) => void;
|
||||
[key: string]: any;
|
||||
}
|
||||
/** 绘制画笔实例扩展配置 */
|
||||
export interface DrawPosterUseCtxOpts {
|
||||
name: string;
|
||||
init?: (canvas: Canvas, ctx: DrawPosterCanvasCtx) => void;
|
||||
handle: (canvas: Canvas, ctx: DrawPosterCanvasCtx, ...args: any[]) => any;
|
||||
[key: string]: any;
|
||||
}
|
||||
1
js_sdk/u-draw-poster/utils/interface.js
Normal file
1
js_sdk/u-draw-poster/utils/interface.js
Normal file
@@ -0,0 +1 @@
|
||||
export {};
|
||||
38
js_sdk/u-draw-poster/utils/object-sizing.d.ts
vendored
Normal file
38
js_sdk/u-draw-poster/utils/object-sizing.d.ts
vendored
Normal file
@@ -0,0 +1,38 @@
|
||||
export declare type ObjectFit = "contain" | "cover";
|
||||
export declare type ObjectPosition = ["left" | "center" | "right", "top" | "center" | "bottom"];
|
||||
export interface Size {
|
||||
width: number;
|
||||
height: number;
|
||||
}
|
||||
/**
|
||||
* 用于计算图片的宽高比例
|
||||
* @see https://drafts.csswg.org/css-images-3/#sizing-terms
|
||||
*
|
||||
* ## 名词解释
|
||||
* ### intrinsic dimensions
|
||||
* 图片本身的尺寸
|
||||
*
|
||||
* ### specified size
|
||||
* 用户指定的元素尺寸
|
||||
*
|
||||
* ### concrete object size
|
||||
* 应用了 `objectFit` 之后图片的显示尺寸
|
||||
*
|
||||
* ### default object size
|
||||
*/
|
||||
export declare function calculateConcreteRect(style: {
|
||||
/** @see https://developer.mozilla.org/zh-CN/docs/Web/CSS/object-fit */
|
||||
objectFit?: ObjectFit;
|
||||
/** @see https://developer.mozilla.org/zh-CN/docs/Web/CSS/object-position */
|
||||
intrinsicPosition?: ObjectPosition;
|
||||
specifiedPosition?: [number, number];
|
||||
}, intrinsicSize: Size, specifiedSize: Size): {
|
||||
sx: number;
|
||||
sy: number;
|
||||
sw: number;
|
||||
sh: number;
|
||||
dx: number;
|
||||
dy: number;
|
||||
dw: number;
|
||||
dh: number;
|
||||
};
|
||||
78
js_sdk/u-draw-poster/utils/object-sizing.js
Normal file
78
js_sdk/u-draw-poster/utils/object-sizing.js
Normal file
@@ -0,0 +1,78 @@
|
||||
/**
|
||||
* 用于计算图片的宽高比例
|
||||
* @see https://drafts.csswg.org/css-images-3/#sizing-terms
|
||||
*
|
||||
* ## 名词解释
|
||||
* ### intrinsic dimensions
|
||||
* 图片本身的尺寸
|
||||
*
|
||||
* ### specified size
|
||||
* 用户指定的元素尺寸
|
||||
*
|
||||
* ### concrete object size
|
||||
* 应用了 `objectFit` 之后图片的显示尺寸
|
||||
*
|
||||
* ### default object size
|
||||
*/
|
||||
export function calculateConcreteRect(style, intrinsicSize, specifiedSize) {
|
||||
var _a, _b;
|
||||
const isContain = style.objectFit === 'contain';
|
||||
const specifiedPosition = style.specifiedPosition || [0, 0];
|
||||
// ratio 越大表示矩形越"扁"
|
||||
let intrinsicRatio = intrinsicSize.width / intrinsicSize.height;
|
||||
let specifiedRatio = specifiedSize.width / specifiedSize.height;
|
||||
/** 图片原始尺寸与最终尺寸之比 */
|
||||
let concreteScale = 1;
|
||||
if (intrinsicRatio > specifiedRatio && style.objectFit == "contain" ||
|
||||
intrinsicRatio <= specifiedRatio && style.objectFit == "cover")
|
||||
// 图片较"胖"时完整显示图片,图片较"瘦"时完全覆盖容器
|
||||
// 这两种情况下有 concreteRect.width = specifiedSize.width
|
||||
// 因为 concreteRect.width = intrinsicSize.width * concreteScale
|
||||
// 所以:
|
||||
concreteScale = specifiedSize.width / intrinsicSize.width;
|
||||
else if (intrinsicRatio > specifiedRatio && style.objectFit == "cover" ||
|
||||
intrinsicRatio <= specifiedRatio && style.objectFit == "contain")
|
||||
// 图片较"瘦"时完整显示图片,图片较"胖"时完全覆盖容器
|
||||
// 这两种情况下有 concreteRect.height = specifiedSize.height
|
||||
// 因为 concreteRect.height = intrinsicSize.height * concreteScale
|
||||
// 所以:
|
||||
concreteScale = specifiedSize.height / intrinsicSize.height;
|
||||
else
|
||||
throw new Error("Unkonwn concreteScale");
|
||||
let concreteRectWidth = intrinsicSize.width * concreteScale;
|
||||
let concreteRectHeight = intrinsicSize.height * concreteScale;
|
||||
// 这里可以把 left top 的计算想象成投影
|
||||
let xRelativeOrigin = { left: 0, center: .5, right: 1 }[((_a = style.intrinsicPosition) === null || _a === void 0 ? void 0 : _a[0]) || "center"];
|
||||
let yRelativeOrigin = { top: 0, center: .5, bottom: 1 }[((_b = style.intrinsicPosition) === null || _b === void 0 ? void 0 : _b[1]) || "center"];
|
||||
let concreteRectLeft = (specifiedSize.width - concreteRectWidth) * xRelativeOrigin;
|
||||
let concreteRectTop = (specifiedSize.height - concreteRectHeight) * yRelativeOrigin;
|
||||
if (isContain) {
|
||||
concreteRectLeft += specifiedPosition[0];
|
||||
concreteRectTop += specifiedPosition[1];
|
||||
}
|
||||
// 这里有两个坐标系,一个是 specified (dist) 的坐标系,一个是 intrinsic (src) 的坐标系
|
||||
// 这里将两个坐标系的点位置进行变换
|
||||
// 例: 带入 x=0, y=0, 得到的结果就是 specifiedRect 的左上角在 intrinsic 坐标系下的坐标位置
|
||||
// 在 specified 坐标系下, intrinsic 的零点在 (concreteRectLeft, concreteRectTop), 缩放为 concreteScale
|
||||
// 所以有 x_dist = x_src * concreteScale + concreteRectLeft
|
||||
// y_dist = y_src * concreteScale + concreteRectTop
|
||||
let dist2src = (distX, distY) => [
|
||||
/* srcX = */ (distX - concreteRectLeft) / concreteScale,
|
||||
/* srcY = */ (distY - concreteRectTop) / concreteScale
|
||||
];
|
||||
let [srcLeft, srcTop] = dist2src(0, 0);
|
||||
// srcRight = 图片 specified 框右边在 src 坐标系下的 x 坐标
|
||||
// srcBottom = 图片 specified 框下边在 src 坐标系下的 y 坐标
|
||||
let [srcRight, srcBottom] = dist2src(specifiedSize.width, specifiedSize.height);
|
||||
// 这里要对 src 和 disc 两个框进行约束
|
||||
return {
|
||||
sx: Math.max(srcLeft, 0),
|
||||
sy: Math.max(srcTop, 0),
|
||||
sw: Math.min(srcRight - srcLeft, intrinsicSize.width),
|
||||
sh: Math.min(srcBottom - srcTop, intrinsicSize.height),
|
||||
dx: isContain ? Math.max(concreteRectLeft, 0) : specifiedPosition[0],
|
||||
dy: isContain ? Math.max(concreteRectTop, 0) : specifiedPosition[1],
|
||||
dw: Math.min(concreteRectWidth, specifiedSize.width),
|
||||
dh: Math.min(concreteRectHeight, specifiedSize.height)
|
||||
};
|
||||
}
|
||||
20
js_sdk/u-draw-poster/utils/utils.d.ts
vendored
Normal file
20
js_sdk/u-draw-poster/utils/utils.d.ts
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
import { DrawPosterBuildOpts } from "./interface";
|
||||
/** 是否是base64本地地址 */
|
||||
export declare const isBaseUrl: (str: string) => boolean;
|
||||
/** 是否是小程序本地地址 */
|
||||
export declare const isTmpUrl: (str: string) => boolean;
|
||||
/** 是否是网络地址 */
|
||||
export declare const isNetworkUrl: (str: string) => boolean;
|
||||
/** 对象target挂载到对象current */
|
||||
export declare const extendMount: (current: Record<any, any>, target: Record<any, any>, handle?: (extend: Function, target?: Record<any, any> | undefined) => any) => void;
|
||||
/** 处理构建配置 */
|
||||
export declare const handleBuildOpts: (options: string | DrawPosterBuildOpts) => {
|
||||
selector: string;
|
||||
componentThis: any;
|
||||
type2d: boolean;
|
||||
loading: boolean;
|
||||
debugging: boolean;
|
||||
loadingText: string;
|
||||
createText: string;
|
||||
gcanvas: boolean;
|
||||
};
|
||||
49
js_sdk/u-draw-poster/utils/utils.js
Normal file
49
js_sdk/u-draw-poster/utils/utils.js
Normal file
@@ -0,0 +1,49 @@
|
||||
import { PLATFORM } from "./global";
|
||||
/** 是否是base64本地地址 */
|
||||
export const isBaseUrl = (str) => {
|
||||
return /^\s*data:(?:[a-z]+\/[a-z0-9-+.]+(?:;[a-z-]+=[a-z0-9-]+)?)?(?:;base64)?,([a-z0-9!$&',()*+;=\-._~:@\/?%\s]*?)\s*$/i.test(str);
|
||||
};
|
||||
/** 是否是小程序本地地址 */
|
||||
export const isTmpUrl = (str) => {
|
||||
return /http:\/\/temp\/wx/.test(str);
|
||||
};
|
||||
/** 是否是网络地址 */
|
||||
export const isNetworkUrl = (str) => {
|
||||
return /^(((ht|f)tps?):\/\/)?[\w-]+(\.[\w-]+)+([\w.,@?^=%&:/~+#-]*[\w@?^=%&/~+#-])?$/.test(str);
|
||||
};
|
||||
/** 对象target挂载到对象current */
|
||||
export const extendMount = (current, target, handle = (extend, target) => undefined) => {
|
||||
for (const key in target) {
|
||||
current[key] = handle(target[key].handle, target[key]) || target[key].handle;
|
||||
}
|
||||
};
|
||||
/** 处理构建配置 */
|
||||
export const handleBuildOpts = (options) => {
|
||||
let defaultOpts = {
|
||||
selector: '',
|
||||
componentThis: undefined,
|
||||
type2d: true,
|
||||
loading: false,
|
||||
debugging: false,
|
||||
loadingText: '绘制海报中...',
|
||||
createText: '生成图片中...',
|
||||
gcanvas: false
|
||||
};
|
||||
if (typeof options === "string") {
|
||||
defaultOpts.selector = options;
|
||||
}
|
||||
else {
|
||||
defaultOpts = Object.assign(Object.assign({}, defaultOpts), options);
|
||||
}
|
||||
const oldSelector = defaultOpts.selector;
|
||||
if (PLATFORM === 'mp-weixin' && defaultOpts.type2d) {
|
||||
defaultOpts.selector = '#' + defaultOpts.selector;
|
||||
}
|
||||
if (!PLATFORM) {
|
||||
console.error('注意! draw-poster未开启uni条件编译! 当环境是微信小程序将不会动态切换为type2d模式');
|
||||
console.error(`请在vue.config.js中的transpileDependencies中添加'uni-draw-poster'`);
|
||||
console.error(`或者可以在选择器字符串前缀中添加#来切换为type2d绘制`);
|
||||
defaultOpts.selector = oldSelector;
|
||||
}
|
||||
return defaultOpts;
|
||||
};
|
||||
3
js_sdk/u-draw-poster/utils/wx-utils.d.ts
vendored
Normal file
3
js_sdk/u-draw-poster/utils/wx-utils.d.ts
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
import { Canvas } from "./interface";
|
||||
export declare const downloadImgUrl: (url: string) => Promise<string>;
|
||||
export declare const getCanvas2dContext: (selector: string, componentThis?: any) => Promise<Canvas | {}>;
|
||||
37
js_sdk/u-draw-poster/utils/wx-utils.js
Normal file
37
js_sdk/u-draw-poster/utils/wx-utils.js
Normal file
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* @Author: Mr.Mao
|
||||
* @LastEditors: Mr.Mao
|
||||
* @Date: 2020-10-12 08:49:27
|
||||
* @LastEditTime: 2020-12-09 13:54:10
|
||||
* @Description:
|
||||
* @任何一个傻子都能写出让电脑能懂的代码,而只有好的程序员可以写出让人能看懂的代码
|
||||
*/
|
||||
import uni from "./global";
|
||||
import { isBaseUrl, isNetworkUrl, isTmpUrl } from './utils';
|
||||
// 下载指定地址图片, 如果不符合下载图片, 则直接返回
|
||||
export const downloadImgUrl = (url) => {
|
||||
const isLocalFile = isBaseUrl(url) || isTmpUrl(url) || !isNetworkUrl(url);
|
||||
return new Promise((resolve, reject) => {
|
||||
if (isLocalFile) {
|
||||
return resolve(url);
|
||||
}
|
||||
uni.downloadFile({
|
||||
url,
|
||||
success: (res) => resolve(res.tempFilePath),
|
||||
fail: reject
|
||||
});
|
||||
});
|
||||
};
|
||||
// 获取当前指定 node 节点
|
||||
export const getCanvas2dContext = (selector, componentThis) => {
|
||||
return new Promise(resolve => {
|
||||
const query = (componentThis ?
|
||||
uni.createSelectorQuery().in(componentThis) :
|
||||
uni.createSelectorQuery());
|
||||
query.select(selector)
|
||||
.fields({ node: true }, res => {
|
||||
const node = res === null || res === void 0 ? void 0 : res.node;
|
||||
resolve(node || {});
|
||||
}).exec();
|
||||
});
|
||||
};
|
||||
Reference in New Issue
Block a user