跳到主要内容

简单绘画板(第二版)

阅读需 4 分钟

最近过了一遍 JavaScript 基础,突然想到去年做绘画板的时候,想通过调色板直接获取颜色值,而不是自己设置几个颜色让用户选择,但是因为当时没有接触太多编程语言,基本看不懂 JS,东拼西凑很久,功能还缺斤少两。结果当时看了看代码,立马就实现想法了…进步了。

0. 效果展示

在线体验

GitHub 源码

logo

目前已实现功能:可调整画笔宽度、画笔颜色、整画布背景颜色,橡皮擦,清除画布,保存画布。 下面是遇到的一些问题:

1. onclick 与 onmouse

前提:在每一次绘制时(鼠标按下、移动和松开为一次鼠标活动)获得滑动条的数值,调色板的颜色值,来更改画笔宽度和颜色。但这两项数据的更改次数与鼠标活动次数相比,简直是小巫见大巫,造成浪费。所以计划使用两个变量来分别存储数值,调用方法来直接更新数据。

问题:使用滑动条 input range 能即时更改画笔宽度,但调色板 input color 不能即时更改画笔的颜色,需要再点击一下控件画笔颜色才会改变。

/*问题代码:*/
<input type="range" min="1" max="100" step="1" value="10" id="lineWidth" onclick="changeLineWidth()"><input type="color" id="lineColor" onclick="changeLineColor()">

思考:onclick 是鼠标点击事件,滑动条移动完毕时放松鼠标时, value 数值已经更改,并触发了 changeLineWidth() 方法,所以画笔的宽度成功更改。但是调色板,在点击控件之后才会打开选色面板,当选择好颜色并确认时,已经执行过 changeLineColor() 方法了,调色板的 value 值再改变,而画笔的颜色是上一次调色板的 value 值。

解决方法:将调色板的 onclick 事件改为 onchange 事件。后者是在域的内容改变时发生,符合需求。

<input type="color" id="lineColor" onchange="changeLineColor()">

优化:将滑动条的 onclick 事件改为 onmousemove 事件。在鼠标移动时触发方法,这样线条的宽度数值也可以实时改变了,避免在滑动结束后才能查看具体数值。

<input type="range" min="1" max="100" step="1" value="10" id="lineWidth" onmousemove="changeLineWidth()">

结果预览:

图片

2. 保存图片功能

前提:保存 canvas 为本地图片,之前采用的是提示用户通过右键保存。

问题:如何通过按钮实现功能?

思考:直接搜索 canvas 保存为本地图片的相关资料,发现了 toDataURL() 方法,但是下载后的文件需要手动加上后缀名才能直接打开。牵扯到 dataURL(),base64编码的知识,推荐文章:https://www.cnblogs.com/xuechenlei/p/5940371.html,关于将图片“嵌入”到HTML中。

<button onclick="saveCanvas()" id="saveCanvas">保存画布</button>
function saveCanvas(){     
var image = canvas.toDataURL("image/png").replace("image/png", "image/octet-stream");
window.location.href = image;
}
/*引用文章:http://blog.csdn.net/jia20003/article/details/8948005 */

结果预览:

图片

优化:html5 有 download 属性,可以自定义下载文件的名称,所以我在按钮内嵌入了一个 a 标签,这样下载下来的图片就可以直接打开了。

<button onclick="saveCanvas()"><a id="saveCanvas" download="img.png">保存画布</a></button>
function saveCanvas(){ var image = canvas.toDataURL();
document.getElementById("saveCanvas").href = image;
}

结果预览:

图片

3. 最后

介绍一款热刷新软件:LiveReload (另一篇文章介绍使用方法)

功能:当本地文件保存时,自动刷新网页。此外一些 IDE 或者脚手架自带此功能,或是插件。可以节省不少调试时间。

本来还想着自己写一个监测键盘,ctrl+s,就刷新页面,hh,结果直接找了软件使用了。

这一版 CSS 我没有写多少…设计真是太难了。还没有深入学习设计模式,代码比较简陋,下一版重构,会更兼顾功能和性能。大致想法,增加直线、矩形、圆形和多边形等等图案,填充,文字,变色等等,画布可以随意拉伸,更改背景时不会重绘画布。

暂时未加入评论功能,请在对应公众号文章下或 GitHub Issues下留言反馈。