今天給各網友分享一款基於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);
