canvas实现涂鸦效果--橡皮檫和历史记录 ╰半夏微凉° 2022-02-26 01:26 348阅读 0赞 利用canvas实现涂鸦效果,包括更换笔触大小颜色、换背景图、橡皮檫、历史记录、清屏等功能,并能保存涂鸦图片到本地。 由于篇幅问题,本文主要实现橡皮檫和历史记录功能,该部分功能不操作背景图片,最终效果如下图。 Tips:本文是在《 canvas实现涂鸦效果--基本涂鸦效果》、《canvas实现涂鸦效果--大小颜色背景图》和《canvas实现涂鸦效果--清屏和保存功能》基础上添加功能。 ![watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2tpbmcwOTY0_size_16_color_FFFFFF_t_70][] ### 橡皮擦功能 ### 编写静态样式,html代码和css代码如下图,主要注意一下html代码中input\[type="range"\],橡皮檫的大小就是获取滑动值进行设置,最终效果图3。 ![20190328164620189.jpg][] ![watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2tpbmcwOTY0_size_16_color_FFFFFF_t_70 1][] ![watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2tpbmcwOTY0_size_16_color_FFFFFF_t_70 2][] 声明变量和初始化数据,详细代码如下图,基于前面功能声明修改了红色框的数据: rubberSize设置橡皮檫默认大小,该值跟html中input\[type="range"\]的value值一致,后面用于计算清除区域; flag用于判断是涂鸦还是擦除(true为涂鸦,false为擦除)。 ![watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2tpbmcwOTY0_size_16_color_FFFFFF_t_70 3][] 分析实现橡皮檫功能之前,先分析一下基础操作功能(下图红色框部分): 点击颜色按钮和大小按钮时候,设置flag为true,而点击擦掉按钮时候设置flag为false;因为涂鸦和擦掉都是在滑动时候触发,必须有个明确标识,避免操作混乱。 底部红色框部分,前两个点击触发跟前面基本功能类似,这里不做分析;最后一个作用是滑动过程中获取滑动值,替换rubberSize,且把该值替换到列表的数字,方便用户查看橡皮檫的大小。 ![watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2tpbmcwOTY0_size_16_color_FFFFFF_t_70 4][] 橡皮檫功能实现过程,简单说就是获取滑动过程中的坐标点,然后利用clearRect清除坐标点周围的涂鸦内容;详细分析如下(红色框部分): 跟基本功能代码加了flag区分,else部分为擦掉功能实现代码; 利用了画布清除功能ctx.clearRect对滑动坐标点周围矩形进行清除,因为坐标点是圆心,所以清除的起始坐标(curCoordinate)需要滑动坐标点减去半径(rubberSize/2); 直接用矩形擦除,过程会有锯齿,为了达到更好效果,特意在上面加了圆形(ctx.arc)剪切(ctx.clip),使擦除效果比较光滑。 ![watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2tpbmcwOTY0_size_16_color_FFFFFF_t_70 5][] ### 历史记录功能 ### 编写静态样式,html代码和css代码如下图,主要注意一下html代码中overflow-x: scroll,因为历史记录图片是会超出一屛,所以需要设置可以滚动,最终效果图3。 ![2019032816512799.jpg][] ![watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2tpbmcwOTY0_size_16_color_FFFFFF_t_70 6][] ![watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2tpbmcwOTY0_size_16_color_FFFFFF_t_70 7][] 分析实现历史记录功能之前,先分析一下基础操作功能: 前两个点击触发跟前面基本功能类似,这里不做分析; 最后一个实现原理,就是点击历史记录上的图片时,然后把该图片绘制到画布上面(ctx.drawImage);绘制之前需要清除画布的内容(ctx.clearRect),不然内容会重叠;还有因为历史记录上的图片是js产生的,所以这里的点击事件使用了事件委托。 ![watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2tpbmcwOTY0_size_16_color_FFFFFF_t_70 8][] 历史记录功能实现过程,简单说就是手指离开屏幕时候,把当前画布内容转化为图片地址,然后新增元素img(src为该图片地址)插入历史记录列表;详细分析如下(手指离开屏幕时候(touchend)): 把当前画布内容转化为图片地址,然后新增元素img(src为该图片地址)插入历史记录列表; 当操作次数多了之后,历史记录上的图片会一直增加,为了让超过一屛的图片能正常滑动显示,所以需要实时计算全部图片的宽度(+间隔)的值boxWidth,然后赋值lineBox。 ![20190328165355927.jpg][] [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2tpbmcwOTY0_size_16_color_FFFFFF_t_70]: /images/20220226/8ebc0a05e1e3410bb2ba65857fe61c93.png [20190328164620189.jpg]: /images/20220226/133e69847bf147b5abc91f43bc51e394.png [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2tpbmcwOTY0_size_16_color_FFFFFF_t_70 1]: /images/20220226/de7623827d1244df8151c49731fe6f4a.png [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2tpbmcwOTY0_size_16_color_FFFFFF_t_70 2]: /images/20220226/09921f6112c243e1a139146d0e82b7e7.png [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2tpbmcwOTY0_size_16_color_FFFFFF_t_70 3]: /images/20220226/d60d0ab9797f4ff3b2c025b1c3dafab0.png [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2tpbmcwOTY0_size_16_color_FFFFFF_t_70 4]: /images/20220226/62a15028d41e46cc96cf9dc5c767d194.png [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2tpbmcwOTY0_size_16_color_FFFFFF_t_70 5]: /images/20220226/b17dbd0c3e424890a114a1f5eeafe1b3.png [2019032816512799.jpg]: /images/20220226/8537c442b869451685ebdcee036e6c56.png [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2tpbmcwOTY0_size_16_color_FFFFFF_t_70 6]: /images/20220226/6023f55fcf094d1cbf86ca2c72a4cfbf.png [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2tpbmcwOTY0_size_16_color_FFFFFF_t_70 7]: /images/20220226/7ee0f52aac7c4a05a07e77d351443556.png [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2tpbmcwOTY0_size_16_color_FFFFFF_t_70 8]: /images/20220226/f84f2159beaf40efa4d77497f8899600.png [20190328165355927.jpg]: /images/20220226/ef22cc2813a140f1af59eb7f2ee9317b.png
还没有评论,来说两句吧...