原生帆布制作画图小工具的示例分析

  介绍

小编给大家分享一下原生帆布制作画图小工具的示例分析,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获、下面让我们一起去了解一下吧!

最近在写一个类似截图里的简易画图的小工具,画线,画矩形,画圆,可以选择颜色,就像这样

原生帆布制作画图小工具的示例分析

,写的过程中遇到了一些坑,还好爬出来了,也得到几位大佬的指点,稍微接触了一下zrender,在这里记录一下。

<强>坑1,绘制过程的预览

用帆布画线没什么问题,函数和画线就好了,来一段代码凑字数(快乐:)

鼠标按下,开始绘制,记录初始鼠标的位置   startPaint =, (e)=祝辞{   ,,,this.startPaintFlag =,真的;   ,,,this.paintstartX =, e.clientX;   ,,,this.paintstartY =, e.clientY;   }      鼠标抬起、停止绘制   stopPaint =, (e)=祝辞{   ,,,this.startPaintFlag =,假的,,,,,   }      painting =, (e)=祝辞{   ,,,const  {activeColor, activeShape},=, this.state;   ,,,,   ,,,绘制过程中   ,,,如果(this.startPaintFlag) {   ,,,,,const  ctx =, this.canvas.getContext (“2 d");   ,,,,,ctx.strokeStyle =, activeColor;   ,,,,,ctx.lineWidth =, 2;   ,,,,,ctx.beginPath ();   ,,,,   ,,,,,如果(activeShape ===, & # 39;笔# 39;){   ,,,,,,,ctx.moveTo (this.paintstartY this.paintstartX也);   ,,,,,,,ctx.lineTo (e.clientY e.clientX也);   ,,,,,}   ,,,,,如果(activeShape ===, & # 39;圆# 39;){   ,,,,,,,const  r =, Math.sqrt (Math.pow (e.clientX 安康;this.paintstartX,, 2), +, Math.pow (e.clientY 安康;this.paintstartY,, 2));   ,,,,,,,ctx.arc (this.paintstartX, this.paintstartY,, r,, 0,, 2 * Math.PI)   ,,,,,}   ,,,,,如果(activeShape ===, & # 39;矩形# 39;){   ,,,,,,,ctx.rect (this.paintstartX, this.paintstartY,, e.clientX 作用;this.paintstartX,, e.clientY 作用;this.paintstartY);   ,,,,,}   ,,,,,ctx.stroke ();   ,,,,,   ,,,,,记录此次移动的最后位置,供下一次绘制使用   ,,,,,this.paintstartX =, e.clientX;   ,,,,,this.paintstartY =, e.clientY;   ,,,}   }

但是画矩形和圆就出事了,因为截图工具画矩形和圆的时候,是有预览效果的,就是我一边画,我一边能看到我画出的形状是多大,如果按照画线的思路来,会得到这样的一串图形

原生帆布制作画图小工具的示例分析

很好理解,因为mousemove的时候一直在改变位置和距离,那么如果我一开始就记录下位置,在画矩形和圆的时候不改变初始位置呢,那么会得到以下图形

原生帆布制作画图小工具的示例分析

也很好理解,因为没有擦除,每次绘制的图形都在画布上。那擦除不就好了?不好,因为在画布上画的不是只有一个图形,如果我先画线,再画圆,那么一擦除,之前画的线就没了,令人纠结QAQ

我有过一个思路是,只擦除这个图形内部的形状,比如上面这一堆同心圆,我只擦除最后绘制的那个圆内部的内容,可惜还是不行,一方面内部可能有别的线事先绘制了,一方面图形可以拖动放大,也可以拖动缩小,那么怎么办呢?

在叹了一口大气,喝了一杯,水凝视了一下窗外之后,想出了一个办法,我在画布上再叠一个画布不就好了,我在叠上去的这个画布上就可以为所欲为了不是咩。

来个示意图,黑色框框是我们展示用的画布,黑色形状表示已经绘制上去的内容,红色框框是我们在画有预览效果的图形时所使用的临时画布,红色形状表示我们鼠标拖动过程中绘制的预览内容,每次需要绘制预览内容我们就生成一个临时画布,放在顶层,随心所欲的绘制,绘制完毕(鼠标抬起)将临时画布销毁,在展示用的画布(黑色框框)上绘制最终的图形

原生帆布制作画图小工具的示例分析

来一段代码帮助理解

startPaint =, (e),=祝辞,{   this.startPaintFlag =,才能正确;   时间=this.paintstartX 才能;e.clientX;   时间=this.paintstartY 才能;e.clientY;      画才能矩形和圆形时临时生成一个画布   if 才能;(this.state.activeShape  !==,“pen"), {   ,,,this.tempCanvas =, document.createElement (“canvas");   ,,,this.tempCanvas.width =, this.canvas.width;   ,,,this.tempCanvas.height =, this.canvas.height;   ,,,,   ,,,设置一些定位样式   ,,,this.tempCanvas.style.cssText =,“位置:,绝对的,,:,0;,左:,0;,z - index:, 0;“;   ,,,,   ,,,添加到需要的容器元素里   ,,,document.querySelector (“.contain") .appendChild (this.tempCanvas);   ,,}   };      stopPaint =, (e),=祝辞,{   时间=this.startPaintFlag 才能;假;   const 才能{activeShape的不同之处是,activeColor },=, this.state;   if 才能;(activeShape  !==,“pen"), {   ,,,,   ,,,从容器元素里删除临时画布   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null   null

原生帆布制作画图小工具的示例分析