今天给各网友分享一款基于HTML5 Canvas的画板涂鸦动画。记得之前我们分享过一款HTML5 Canvas画板工具,可以切换不同的笔刷,功能十分强大。本文今天要再来分享一款基于HTML5 Canvas的画板涂鸦动画应用,功能和之前那个类似,但是新增了回撤和清空画板的操作,实现思路也基本类似。实现的效果图如下:
实现的代码。
html代码:
<div class="wrap"> <canvas id="canvas" class="fl" width="600" height="400"> </canvas> <div id="control" class="fl"> <div id="canvas-color"> <h5> 画笔颜色</h5> <ul> <li style="background: #fef4ac"></li> <li style="background: #0018ba"></li> <li style="background: #ffc200"></li> <li style="background: #f32f15"></li> <li style="background: #cccccc"></li> <li style="background: #5ab639"></li> </ul> </div> <div id="canvas-brush"> <h5> 画笔大小</h5> <span class="small-brush"></span><span class="middle-brush"></span><span class="big-brush"> </span> </div> <div id="canvas-control"> <h5> 操作</h5> <span title="上一步" class="return-control"></span><span title="下一步" class="next-control"> </span><span title="清除" class="empty-control"></span> </div> <div id="canvas-drawImage"> <h5> 生成图像</h5> <p> <button class="drawImage"> 生成图像</button></p> </div> </div> </div> <div id="imgDiv"> </div>
css代码:
html, body, canvas, div, ul, li, h5, p { margin: 0; padding: 0; -moz-user-select: none; -webkit-user-select: none; } img { border: 1px #ccc solid; } ul, li { list-style: none; } .wrap { width: 740px; margin: 20px auto 5px; border: 1px #ccc solid; overflow: hidden; } .fl { float: left; display: inline; } #canvas { border-right: 1px #ccc solid; cursor: crosshair; } #control { width: 130px; height: 400px; margin-left: 4px; } #control div { padding: 5px; } #canvas-color ul { overflow: hidden; } #canvas-color ul li { float: left; display: inherit; width: 13px; height: 13px; border: 3px #fff solid; margin: 8px; cursor: pointer; } #canvas-color ul li.js-border-color { border-color: #000; } #canvas-brush span { display: inline-block; width: 10px; height: 10px; margin-left: 10px; background: url(images/brush.png); cursor: pointer; } #canvas-brush span.small-brush { background-position: -6px -6px; } #canvas-brush span.middle-brush { background-position: -31px -6px; } #canvas-brush span.big-brush { background-position: -56px -6px; } #canvas-brush span.js-bg-color { background-color: #aaa; } #canvas-control span { display: inline-block; width: 20px; height: 15px; margin-left: 10px; background: url(images/sketchpad_icons.png); cursor: pointer; } #canvas-control span.return-control { background-position: -2px -148px; } #canvas-control span.next-control { background-position: right -168px; } #canvas-control span.empty-control { background-position: -2px -188px; } #canvas-control span.js-return-control { background-position: -2px -209px; } #canvas-control span.js-next-control { background-position: right -230px; } #canvas-control span.js-empty-control { background-position: -2px -251px; } #imgDiv { text-align: center; }
js代码:
var doc = document, canvas = doc.getElementById('canvas'), colorDiv = doc.getElementById('canvas-color'), brushDiv = doc.getElementById('canvas-brush'), controlDiv = doc.getElementById('canvas-control'), drawImageDiv = doc.getElementById('canvas-drawImage'), imgDiv = doc.getElementById('imgDiv'); function Canvas() { this.init.apply(this, arguments); } Canvas.prototype = { //存储当前表面状态数组-上一步 preDrawAry: [], //存储当前表面状态数组-下一步 nextDrawAry: [], //中间数组 middleAry: [], //配置参数 confing: { lineWidth: 1, lineColor: "blue", shadowBlur: 2 }, init: function (oCanvas, oColor, oBrush, oControl, oDrawImage, imgDiv) { this.canvas = oCanvas; this.context = oCanvas.getContext('2d'); this.colorDiv = oColor; this.brushDiv = oBrush; this.controlDiv = oControl; this.drawImageDiv = oDrawImage; this.imgDiv = imgDiv; this._initDraw(); this._draw(oCanvas); this.setColor(); this.setBrush(); this.preClick(); this.nextClick(); this.clearClick(); this.drawImage(oCanvas); }, _initDraw: function () { var preData = this.context.getImageData(0, 0, 600, 400); //空绘图表面进栈 this.middleAry.push(preData); }, //涂鸦主程序 _draw: function (oCanvas, context) { var _this = this; oCanvas.onmousedown = function (e) { var x = e.clientX, y = e.clientY, left = this.parentNode.offsetLeft, top = this.parentNode.offsetTop, canvasX = x - left, canvasY = y - top; _this._setCanvasStyle(); //清除子路径 _this.context.beginPath(); _this.context.moveTo(canvasX, canvasY); //当前绘图表面状态 var preData = _this.context.getImageData(0, 0, 600, 400); //当前绘图表面进栈 _this.preDrawAry.push(preData); document.onmousemove = function (e) { var x2 = e.clientX, y2 = e.clientY, t = e.target, canvasX2 = x2 - left, canvasY2 = y2 - top; if (t == oCanvas) { _this.context.lineTo(canvasX2, canvasY2); _this.context.stroke(); } else { _this.context.beginPath(); } } document.onmouseup = function (e) { var t = e.target; if (t == oCanvas) { //当前绘图表面状态 var preData = _this.context.getImageData(0, 0, 600, 400); if (_this.nextDrawAry.length == 0) { //当前绘图表面进栈 _this.middleAry.push(preData); } else { _this.middleAry = []; _this.middleAry = _this.middleAry.concat(_this.preDrawAry); _this.middleAry.push(preData); _this.nextDrawAry = []; $('.js-next-control').addClass('next-control'); $('.next-control').removeClass('js-next-control'); } _this._isDraw(); } this.onmousemove = null; } } }, //设置画笔 _setCanvasStyle: function () { this.context.lineWidth = this.confing.lineWidth; this.context.shadowBlur = this.confing.shadowBlur; this.context.shadowColor = this.confing.lineColor; this.context.strokeStyle = this.confing.lineColor; }, //设置颜色 setColor: function () { this.colorDiv.onclick = this.bind(this, this._setColor); }, _setColor: function (e) { var t = e.target; if (t.nodeName.toLowerCase() == "li") { this.confing.lineColor = t.style.backgroundColor; $('.js-border-color').removeClass('js-border-color'); $(t).addClass('js-border-color'); } }, //设置画笔大小 setBrush: function () { this.brushDiv.onclick = this.bind(this, this._setBrush); }, _setBrush: function (e) { var t = e.target; if (t.nodeName.toLowerCase() == "span") { if (t.className.indexOf("small-brush") >= 0) { this.confing.lineWidth = 3; } else if (t.className.indexOf("middle-brush") >= 0) { this.confing.lineWidth = 6; } else if (t.className.indexOf("big-brush") >= 0) { this.confing.lineWidth = 12; } $('.js-bg-color').removeClass('js-bg-color'); $(t).addClass('js-bg-color'); } }, //判断是否已涂鸦,修改按钮状态 _isDraw: function () { if (this.preDrawAry.length) { $('.return-control').addClass('js-return-control'); $('.return-control').removeClass('return-control'); $('.empty-control').addClass('js-empty-control'); $('.empty-control').removeClass('empty-control'); } else { return false; } }, //点击上一步-改变涂鸦当前状态 preClick: function () { var pre = this.controlDiv.getElementsByTagName("span")[0]; pre.onclick = this.bind(this, this._preClick); }, _preClick: function () { if (this.preDrawAry.length > 0) { var popData = this.preDrawAry.pop(); var midData = this.middleAry[this.preDrawAry.length + 1]; this.nextDrawAry.push(midData); this.context.putImageData(popData, 0, 0); } if (this.nextDrawAry.length) { $('.next-control').addClass('js-next-control'); $('.next-control').removeClass('next-control'); } if (this.preDrawAry.length == 0) { $('.js-return-control').addClass('return-control'); $('.return-control').removeClass('js-return-control'); } }, //点击下一步-改变涂鸦当前状态 nextClick: function () { var next = this.controlDiv.getElementsByTagName("span")[1]; next.onclick = this.bind(this, this._nextClick); }, _nextClick: function () { if (this.nextDrawAry.length) { var popData = this.nextDrawAry.pop(); var midData = this.middleAry[this.middleAry.length - this.nextDrawAry.length - 2]; this.preDrawAry.push(midData); this.context.putImageData(popData, 0, 0); } if (this.preDrawAry.length) { $('.return-control').addClass('js-return-control'); $('.return-control').removeClass('return-control'); } if (this.nextDrawAry.length == 0) { $('.js-next-control').addClass('next-control'); $('.next-control').removeClass('js-next-control'); } }, //清空 clearClick: function () { var clear = this.controlDiv.getElementsByTagName("span")[2]; clear.onclick = this.bind(this, this._clearClick); }, _clearClick: function () { var data = this.middleAry[0]; this.context.clearRect(0, 0, this.context.canvas.width, this.context.canvas.height); this.preDrawAry = []; this.nextDrawAry = []; this.middleAry = [this.middleAry[0]]; this.controlDiv.getElementsByTagName("span")[0].className = "return-control"; this.controlDiv.getElementsByTagName("span")[1].className = "next-control"; this.controlDiv.getElementsByTagName("span")[2].className = "empty-control"; }, //生成图像 drawImage: function () { var btn = this.drawImageDiv.getElementsByTagName("button")[0]; btn.onclick = this.bind(this, this._drawImage); }, _drawImage: function () { var url = this.canvas.toDataURL('image/png'), img = new Image(); img.src = url; this.imgDiv.innerHTML = ""; this.imgDiv.appendChild(img); }, bind: function (obj, handler) { return function () { return handler.apply(obj, arguments); } } } new Canvas(canvas, colorDiv, brushDiv, controlDiv, drawImageDiv, imgDiv);