手机网站开发介绍,如何做搞笑的视频视频网站,企业文化建设方案,手机代理企业网站前言#xff1a; 在图形编辑器类型的项目当中#xff0c;通过键盘触发想要绘制的图形类型#xff0c;然后通过鼠标在fabric画布上自由绘制你想需要的内容。从画基本的矩形、圆形、直线、文本、三角形、折线等功能中#xff0c;可以扩展出“钢笔path贝塞尔路径”、“多图形组…前言 在图形编辑器类型的项目当中通过键盘触发想要绘制的图形类型然后通过鼠标在fabric画布上自由绘制你想需要的内容。从画基本的矩形、圆形、直线、文本、三角形、折线等功能中可以扩展出“钢笔path贝塞尔路径”、“多图形组合”、图形合并、图形拆分、解析svg文件(符合要求的文件皆可)进行导入等较为复杂的功能等。 虽然上述介绍了很多各个不同的功能但本篇写的内容仅限于文章标题范围 其他提到的本文肯定不可能都写出来实际写出来代码就太多了。但是所有的功能都离不开核心的基础地基打好地基扩展出对应的功能便轻而易举。
主要涉及功能
功能对应的全局键盘快捷键、监听画布事件鼠标按下、鼠标移动、鼠标松开、初始化图形相关数据并添加进画布、更新画布、计算并更新图形坐标、画布框选功能启用/关闭 相关要求
通过界面按钮或键盘快捷键启用对应图形的绘画模式本文所使用的快捷键库若有了解的需要自行搜索我对应文章即可监听fabric鼠标按下事件、移动事件、弹起事件在鼠标按下事件中创建图形并根据不同图形类型声明对应的初始数据。在鼠标移动事件中实时更新对应图形的相关坐标。在鼠标弹起事件中结束绘画恢复相关数据初始值并根据自身业务需求进行额外操作即可。
其他注意事项绘画过程中按其他相关键盘快捷键则结束当前图形绘画。当然也不一定都是结束当前绘画执行新快捷键的功能例如有辅助画正圆 正方的需求处理。所以这些都是根据自身业务需求进行定制功能思维要灵活。
PS: 本文不对相关功能进行拆分一个文件里展示完自己写业务的时候进行相关拆分、封装即可 templatediv classcdie idcdiecanvas idc refcanvas/canvas/div
/templatescript setup langts
import { ref, onMounted, reactive } from vue;
import { fabric } from fabric;
import hotkeys from hotkeys-js;
window.fabric fabric
let f null
let canvas ref();let drawType;
function initHotkey() {hotkeys(r, () {// 矩形drawType r // 简单写个值在业务里建议定义枚举类较好。});hotkeys(l, () {// 直线drawType l // 简单写个值在业务里建议定义枚举类较好。});hotkeys(c, () {// 圆形drawType c // 简单写个值在业务里建议定义枚举类较好。});
}
onMounted(() {window.canvas f new fabric.Canvas(canvas.value, {backgroundColor: grey,width: 1000,height: 500,});initHotkey() // 声明图形绘画的启用快捷键initDrawEvent(f) // 创建图形绘画相关事件
});
function initDrawEvent(canvas) {let shape: fabric.Object | null;let startPoint: fabric.IPoint; // 记录初始坐标canvas.on(mouse:down, (e) {if (e.target || !drawType) {// 如果绘画点击在图片上则不进行绘画return;}if (!shape) {f.selection false;startPoint e.absolutePointerswitch (drawType) {case r:shape new fabric.Rect({ //创建对应图形类型left: startPoint.x,top: startPoint.y,width: 0,height: 0,fill: undefined,stroke: red});break;case c:shape new fabric.Ellipse({left: startPoint.x,top: startPoint.y,rx: 0,ry: 0,fill: undefined,stroke: red});break;case l:shape new fabric.Line([startPoint.x, startPoint.y, startPoint.x, startPoint.y], {fill: undefined,stroke: red});break;default:break;}if (shape) {f.add(shape); //添加图形f.requestRenderAll(); //刷新画布}}window.selected e?.target // 当点击选择到有可选图形时会获得图形的数据。}).on(mouse:move, (e: fabric.IEventMouseEvent) {if (drawType shape) {const p f.getPointer(e.e) || {x: 0,y: 0,};const minX Math.min(p.x, startPoint.x);const minY Math.min(p.y, startPoint.y);let w Math.abs(p.x - startPoint.x);let h Math.abs(p.y - startPoint.y);switch (drawType) {case r:shape.set({left: minX,top: minY,width: w,height: h,});break;case c:shape.set({left: minX,top: minY,rx: w / 2,ry: h / 2,});break;case l:let x1 startPoint.x;let y1 startPoint.y;let x2 p.x;let y2 p.y;console.log(startPoint, p);shape.set({x1,y1,x2,y2,});break;default:break;}f.requestRenderAll();}}).on(mouse:up, (e) {if (drawType shape) {shape.setCoords(); // 更新图像坐标drawType nullf.selection true;shape null;f.requestRenderAll(); }})
}/scriptstyle scoped langless
.cdie {width: 100%;text-align: center;display: flex;justify-content: center;
}
/style