mirror of
https://gitee.com/beijing_hongye_huicheng/lilishop-uniapp.git
synced 2025-12-17 16:05:53 +08:00
commit message
This commit is contained in:
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