Github:https://github.com/friend-nicen/diy.js
DIY.JS是一款专用于DIY定制的Canvas图形库
DIY的可操作区域由两部分组成(两个层叠的Canvas对象):

图层
DIY区域指的是在指定物品上,用户可以进行个性化定制的区域。

DIY区域
DIY区域由Canvas的destination-in的混合模式进行实现(只显示两张图重叠的位置)
对于不同的物品,DIY区域的大小往往是不一致的,导入导出的素材模板,会按照不同的DIY区域来自适应大小和位置。

自适应
添加素材的时候,支持百分比的单位,同时可以自定义百分比转换为实际的大小时,所参照的对象。
假设指定图形的宽度为 50%,DIY区域宽度为 200px,Canvas宽度为500px;
以下是几个配置好的支持DIY的物品:
专为DIY设计增加了多种实用的功能:
支持多种导出方式。

导出
以下收录一些经常被问到的问题。
/* 监听图像选中事件 */
stage.on("active", (e) => {
const shape = e.shape;
if (shape.type === 'Image') {
// 点击的图像
} else if (shape.type === 'Text') {
// 点击的文字
}
});/* 监听图像选中事件 */
stage.on("to-do", (e) => {
const shape = e.shape;
if (shape.type === 'Image') {
// 点击的图像
} else if (shape.type === 'Text') {
// 点击的文字
}
});const active = stage.getActive();
cosnole.log(active.x); // x坐标
cosnole.log(active.y); // y坐标
cosnole.log(active.w); // w宽度
cosnole.log(active.h); // x高度下面介绍一些基础用法,方便快速上手:
首先需要指定一个dom来创建操作区域:
import DIY from "@/diy";
const element = document.querySelector("#stage");
const stage = new DIY.Stage(element);然后设置需要DIY的物品模型,以T恤(https://douyin.nicen.cn/icon/cloth-w.png)举例:
/**
* 初始化图形,设置坐标位置 (0,0),初始宽度 100%
*/
const model = new DIY.Image({
x: 0,
y: 0,
url: "https://douyin.nicen.cn/icon/cloth-w.png",
w: '100%'
});
/* 添加到舞台的背景图层 */
stage.addModel(model)添加后的最终效果如下:

设置模型
设置DIY区域(https://douyin.nicen.cn/icon/rect.png),并添加一个素材:
/* 初始化图形 */
const view = new DIY.Image({
x: 0,
y: 0,
url: "https://douyin.nicen.cn/icon/cloth-w.png",
w: '100%'
});
/* 添加到舞台的背景图层 */
stage.setView(view);
/* 新增素材 */
stage.add(new DIY.Image({
url: 'https://douyin.nicen.cn/assets/24/9b1445639f6ef9ee3c0430605ac651ee.png'
}))添加后,最终效果如下:

效果
假设有一个DIY设计任务如下图:

案例
执行导出JSON的操作:
// 导出JSON
stage.toJson();将输出如下JSON(太长了,点击访问查看): https://nicen.cn/collect/diy.json
导入对应的JSON,复现这个DIY任务:
// 导入指定json
stage.loadJson(json);Stage对象代表整个绘图区域,它是所有图形对象的容器。在用于管理图形对象、处理用户交互、渲染图形以及控制动画等
新增舞台指定事件的事件监听器。
on(type: string, callback: Function): void;Stage支持的事件如下:
移除舞台指定事件的事件监听器。
off(type: string): void;触发指定事件的事件监听器
emit(type: string, event?: any): void;添加指定的图形对象到舞台
add(shape: Shape, index?: number): void;获取指定名称或者索引的图形对象
get(name: string): Shape | undefined; 移除指定的图形对象
remove(shape: Shape | string, flag: boolean): void; 清除舞台上的所有图形对象
clear(): void; 清除模型中的所有图形对象
clearModel(): void; 重置舞台到初始状态,移除模型、素材、DIY区域
reset(): void; 指定舞台的放大缩小倍数,一般是当前设备的DPR值
scale(zoom: number): void; 获取当前的缩放比例
getScale(): number; 获取指定索引处的图形对象数组
shapes(flag: boolean, index: number): Shape[]; 渲染舞台
render(): void; 设置舞台绑定的元素的样式
setElementStyle(style: object): void; 允许图形多选
enableMultiActive(): void; 禁止图形多选
disableMultiActive(): void; 获取指定图形对象在舞台中的索引
getIndex(shape: Shape): number; 渲染模型
renderModel(): void; 获取舞台的中心点坐标
getCenterPoint(): { x: number, y: number } 获取DIY层的Canvas的渲染上下文
getContext(): CanvasRenderingContext2D; 创建一个新的Canvas元素
createCanvas(w: number, h: number, param?: {}): { elem: HTMLCanvasElement, context: CanvasRenderingContext2D } 获取异步任务队列
getQueue(): []; 添加任务到队列
addQueueTask(task: Function): void; 清空任务队列
clearQueue(): void; 重置偏移量
resetOffset(): void; 导出舞台内容
export(config: object): Promise<Blob | string>; 关于config对象:
{
elem: ['model', 'custom', 'view'], //需要导出的元素,canvas,导出整个画布 背景图、所有图形、DIY区域图
view: true, //仅导出view区域
clip: true, //裁剪多余的透明部分
type: 'base64',//输出二进制还是base64
filter: false, //是否过滤不可导出的图形
ratio: 3.5, //导出比例
size: null, //指定导出的图片大小
frame: null //图框{height:null,width:null,fillColor:null}
}添加图形对象到模型
addModel(shape: Shape): void; 获取舞台的边界
bound(): { x: number; y: number; w: number; h: number; _w: number; _h: number; } 获取设备像素比
dpr(): number; 获取可DIY区域的边界范围
getViewBound(): { x: number; y: number; w: number, h: number, _x: number; _y: number; _w: number; _h: number } 获取可DIY区域的图形对象
getView(): Shape; 获取当前激活的图形对象
getActive(): Shape | null; 获取舞台的HTML元素
getElement(): HTMLElement; 获取舞台配置
getConfig(): { maxWidth: number; maxHeight: number; sensitivity: number; minRotatable: number; themeColor: string; activeColor: string; } 设置舞台配置
setConfig(key: any, value: any): void; 加载图形对象
load(json: string | object, flag?: boolean): Shape; 将舞台内容转换为JSON字符串
toJson(): string; 从JSON对象加载图形对象
loadJson(json: object, param: object): void; 加载指定的JSON,但不渲染到舞台,返回舞台的快照。
loadJsonWithSnap(json: object, param: object): object;检查是否允许多图形对象同时激活
canMultiActive(): boolean;记录当前图形的快照
r(snapshot: null | object): void;回滚指定快照到舞台
alter(snapshot : object, flag : boolean): void;撤销上一次操作
undo(): void;重做上一次撤销的操作
redo(): void;记录当前舞台的快照(素材部分)
snap(): object;返回当前快照对象。
清空撤销和恢复的记录
clearSnap(): void;隐藏可DIY区域图形的轮廓线
hiddenOutline(): void;显示可DIY区域图形的轮廓线
showOutline(): void;检查是否可以显示轮廓线
canShowOutline(): void;暂停指定的事件
pauseEvent(event: string): void;恢复指定的事件
resumeEvent(event: string): void;激活指定的图形对象
active(shape: object): void;清除舞台中的所有的素材
clear(): void;获取舞台的所有模型层图形
getModelShapes(flag: boolean, index: number): Shape;停止渲染,不响应任何图形操作
stop(): void;恢复渲染
resume(): void;Shape是所有图形类的父类
初始化图形对象
init(): Promise<boolean>; 处理点击事件
click(x: number, y: number, flag?: boolean): boolean; 触发事件
emit(type: string, event?: any): void; 绑定事件
on(type: string, callback: (event?: any) => void, b: boolean): void; 解绑事件
off(type: string): void; 移动图形
move(pos: { x: number; y: number }[], point: { x: number; y: number }): boolean; 缩放图形
scale(scale: number): void; 旋转图形
rotate(rotate: number, coords: { x: number; y: number }[]): boolean; 处理鼠标弹起事件
up(pos: { x: number; y: number }[]): void; 处理触摸事件
tap(pos: { x: number; y: number }[]): void; 设置图形的激活状态
_active(status: boolean): void; 激活图形
active(): void; 渲染图形
render(): void; 停用图形
deactivate(flag: boolean): void; 切换图形的激活状态
toggle(): void; 保存图形状态
save(config: Object): void; 恢复图形状态
restore(): void; 将图形状态转换为JSON字符串
toJson(): string; 获取图形的边界
bound(): object; 获取图形的坐标
coords(corner: null | number): [] | object; 获取图形所在的舞台
stage(): Stage; 获取图形在舞台中的索引
getIndex(): number; 获取图形的非透明区域边界
ColorBound(): { x: number; y: number; w: number, h: number, _x: number, _y: number, _w: number, _h: number }; 获取图形相对于舞台的位置
relative(): object; 获取图形旋转后的坐标
getRotateCoords(): { x: number, y: number }[]; 获取图形旋转后的边界
getRotateBound(): { x: number; y: number; w: number, h: number, }; 获取图形所在的编组
group(): object; 设置图形的旋转中心点
setPivot(point?: { x: number; y: number }): void;获取图形的非透明区域边界
getColorBound(): { x: number; y: number; w: number, h: number, _x: number, _y: number, _w: number, _h: number }; 获取图形的参考坐标
getReference(): { x: number; y: number; w: number, h: number, _x: number, _y: number, _w: number, _h: number }; 绑定画布上下文
bindContext(context: CanvasRenderingContext2D): void; 获取当前绑定的画布上下文
getContext(): CanvasRenderingContext2D; 移动图形在舞台中的索引
moveIndex(target: number, action: boolean): number; 将图形移动到最底部
moveBottom(): number; 将图形移动到最顶部
moveTop(): number; 将图形向前移动一个位置
forward(): number; 将图形向后移动一个位置
backward(): number; 销毁图形对象
destroy(flag: boolean): void; 设置图形的属性
set(config: Record<string, any>): void; 保存图形状态
save(): void; 恢复图形状态
restore(snap: object): void; 获取或设置图形的属性
props(config: object): object; 调整图形在X轴的位置
adjustX(gap: number): void; 调整图形在Y轴的位置
adjustY(gap: number): void; 按照X轴翻转图形
flipX(): void; 按照Y轴翻转图形
flipY(): void; 复制一个图形
copy(): void; 绑定到指定的图形编组
group(): Shape | null; 从图形编组中解绑出来
ungroup(adjust: boolean, remove: boolean, group?: Shape): void; 获取图形的中心点
getCenterPoint(find?: boolean): { x: number, y: number }; 指定一个新的中心点
getReferCenterCoords(coord: { x: number, y: number }): { x: number, y: number }; 设置图形的指定属性的值
setAttr(attr: string, value: any): void; 属性绑定
each(config: object): void; 原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。