一款基于HTML5 Canvas的画板涂鸦动画

今天给各网友分享一款基于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);

via:http://www.w2bc.com/Article/15776

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。