canvas刮刮乐和画笔

  这周有点迷茫,不知道干嘛了,一天天就过去了!我在博客右侧公告栏加了qq交流,各位有好的主题,或者有趣的技术,欢迎交流!今天突发奇想,就写了2个h5 canvas的demo玩玩!

demo一:刮刮乐

  舍不得买2块钱的刮刮乐,就只能写个类似的功能过过彩票瘾了!

布局

<div id="lottery" style="width:300px;height:500px;margin:10px;background-color:lightskyblue;border-radius:5px;float:left;">
         <div style="width:300px;height:100px;line-height:100px;text-align:center;font-size:33px;color:blueviolet;">NICK彩票</div>
         <div id="txt" style="width:300px;height:200px;font-size:40px;color:peachpuff;display:flex;justify-content:center;align-items:center;flex-direction:column;">
             <span></span>
             <span></span>
             <span></span>
             <span></span>
         </div>
         <div id="canvasArea" style="width:300px;height:200px;position:relative;">
             <div style="width:300px;height:200px;position:absolute;top:0;left:0;z-index:1;text-align:center;line-height:200px;font-weight:bold;font-size:56px;color:indianred;">一等奖</div>
             <canvas id="canvas" width="300px" height="200px" style="position:absolute;top:0;left:0;z-index:2;"></canvas>
         </div>
     </div>

这段html要注意的地方有2个:

  1. flex布局,将‘祝君中奖’垂直居中,目前还有兼容问题,不过看我们大前端的发展趋势,应该很快就能搞定了;
  2. canvas和‘一等奖’div的z-index问题,将canvas的z-index设置较高,使其置于一等奖div上面。

设置canvas画布

var canvas = document.getElementById("canvas");
var context = canvas.getContext("2d");

绘制刮奖区域

        context.fillStyle='#A9AB9D';
        context.fillRect(10,10,280,180);
        context.fillStyle='#000';
        context.font='50px Arial';
        context.fillText('刮奖区',75,115);
  1. 填充颜色;
  2. 绘制实心矩形;
  3. 设置字体颜色;
  4. 设置字体大小类型;
  5. 绘制实心字体。

以上都是canvas基础api,看w3c就ok了。

为了好看,我将‘祝君中奖’加个字体变色

        setInterval(function(){
            document.getElementById('txt').style.color = document.getElementById('txt').style.color=='peachpuff' ? 'yellow' : 'peachpuff';
        },500);

刮奖功能函数

        var brush=function(){//刮奖
            context.clearRect(event.offsetX,event.offsetY,20,20);
        };

为canvas元素onmousedown和onmouseup事件

        canvas.onmousedown = function(){
            // 鼠标按下时 - 绑定鼠标跟随事件
            bindHandler(canvas,'mousemove',brush,false);
        }
        canvas.onmouseup = function(){
            // 停止刮奖功能 - 解绑鼠标跟随事件
            removeHandler(canvas,"mousemove",brush,false);
        }

这里的事件绑定与解绑我上篇博文有封装,最后完整代码也有!

刮刮乐happy到底结束!最后附上完整代码,再看看效果吧!

demo二:画笔

布局

     <div style="width:300px;height:500px;margin:10px;border-radius:10px;overflow:hidden;float:right;">
         <canvas id="canvas2" width="300px" height="500px" style="background-color:lightblue;"></canvas>
     </div>

设置canvas画布

        var canvas2 = document.getElementById("canvas2");
        var context2 = canvas2.getContext("2d");

画笔功能函数

        var draw=function(){
            context2.fillRect(event.offsetX,event.offsetY,10,10);
        };

为canvas元素onmousedown和onmouseup事件

        context2.font='20px Arial';
        context2.strokeText('NICK画笔',100,30);//写个头
        //1. 为canvas元素onmousedown和onmouseup事件
        canvas2.onmousedown = function(){
            // 启用画笔功能 - 绑定鼠标跟随事件
            bindHandler(canvas2,'mousemove',draw,false);
        }
        canvas2.onmouseup = function(){
            // 停止画笔功能 - 解绑鼠标跟随事件
            removeHandler(canvas2,"mousemove",draw,false);
        }

画图工具的画笔功能到底结束!

多谢各位老司机的鞭策与提醒,说画笔功能有不连续的现象!

现已改良,并兼容了移动端!

//改良后的写法
    var isTouch = "ontouchstart" in window ? true : false;
    var StartDraw = isTouch ? "touchstart" : "mousedown",
            MoveDraw = isTouch ? "touchmove" : "mousemove",
            EndDraw = isTouch ? "touchend" : "mouseup";

    context2.strokeStyle='blue';//线色
    context2.lineCap = "round";//连接处为圆形
    context2.lineWidth =10;//线框

    canvas2.addEventListener(StartDraw, function(ev){
        ev.preventDefault();
        var isX = isTouch ? ev.targetTouches[0].pageX : ev.pageX;
        var isY = isTouch ? ev.targetTouches[0].pageY : ev.pageY;
        var x = isX - canvas2.offsetLeft;
        var y = isY - canvas2.offsetTop;
        context2.beginPath();
        context2.moveTo(x, y);
        function StartMove(ev){
            var isX1 = isTouch ? ev.targetTouches[0].pageX : ev.pageX;
            var isY1 = isTouch ? ev.targetTouches[0].pageY : ev.pageY;
            var x1 = isX1 - canvas2.offsetLeft;
            var y1 = isY1 - canvas2.offsetTop;
            context2.lineTo(x1, y1);

            context2.stroke();
            context2.beginPath();
            context2.moveTo(x1, y1);
        };
        function EndMove(ev){
            var isX1 = isTouch ? ev.changedTouches[0].pageX : ev.pageX;
            var isY1 = isTouch ? ev.changedTouches[0].pageY : ev.pageY;
            var x1 = isX1 - canvas2.offsetLeft;
            var y1 = isY1 - canvas2.offsetTop;
            context2.lineTo(x1, y1);
            context2.stroke();
            canvas2.removeEventListener(MoveDraw, StartMove, false);
            canvas2.removeEventListener(EndDraw, EndMove, false);
        };
        canvas2.addEventListener(MoveDraw, StartMove, false);
        canvas2.addEventListener(EndDraw, EndMove, false);
    }, false);

附上完整代码:

<!DOCTYPE html>
<html>
<head>
    <title>Canvas lottery brush nick</title>
    <meta charset="utf-8"/>
</head>
<body>
<div style="width:640px;margin:auto;">
    <!--刮刮乐-->
    <div id="lottery" style="width:300px;height:500px;margin:10px;background-color:lightskyblue;border-radius:5px;float:left;">
        <div style="width:300px;height:100px;line-height:100px;text-align:center;font-size:33px;color:blueviolet;">NICK彩票</div>
        <div id="txt" style="width:300px;height:200px;font-size:40px;color:peachpuff;display:flex;justify-content:center;align-items:center;flex-direction:column;">
            <span></span>
            <span></span>
            <span></span>
            <span></span>
        </div>
        <div id="canvasArea" style="width:300px;height:200px;position:relative;">
            <div style="width:300px;height:200px;position:absolute;top:0;left:0;z-index:1;text-align:center;line-height:200px;font-weight:bold;font-size:56px;color:indianred;">一等奖</div>
            <canvas id="canvas" width="300px" height="200px" style="position:absolute;top:0;left:0;z-index:2;"></canvas>
        </div>
    </div>

    <!--画图工具画笔功能-->
    <div style="width:300px;height:500px;margin:10px;border-radius:10px;overflow:hidden;float:right;">
        <canvas id="canvas2" width="300px" height="500px" style="background-color:lightblue;"></canvas>
    </div>
</div>

<div style="text-align:center;">
    <p>刮刮乐:鼠标按住不放,拖动开始刮奖!</p>
    <p>画笔:鼠标按住不放,拖动画画!</p>
</div>
<script>
    //插件方法封装区

    ;(function(){
        // 事件绑定
        window.bindHandler = (function() {
            if (window.addEventListener) {// 标准浏览器
                return function(elem, type, handler) {
                    // elem:节点    type:事件类型   handler:事件处理函数
                    // 最后一个参数为true:在捕获阶段调用事件处理程序;为false:在冒泡阶段调用事件处理程序。注意:ie没有这个参数
                    elem.addEventListener(type, handler, false);
                }
            } else if (window.attachEvent) {// IE浏览器
                return function(elem, type, handler) {
                    elem.attachEvent("on" + type, handler);
                }
            }
        }());

        // 事件解除
        window.removeHandler = (function() {
            if (window.removeEventListener) {// 标准浏览器
                return function(elem, type, handler) {
                    elem.removeEventListener(type, handler, false);
                }
            } else if (window.detachEvent) {// IE浏览器
                return function(elem, type, handler) {
                    elem.detachEvent("on" + type, handler);
                }
            }
        }());
    }());

    //命名区

    var canvas = document.getElementById("canvas");
    var context = canvas.getContext("2d");

    var canvas2 = document.getElementById("canvas2");
    var context2 = canvas2.getContext("2d");
    var brush=function(){//刮奖
        context.clearRect(event.offsetX,event.offsetY,20,20);
    };
    var draw=function(){//写字
        context2.fillRect(event.offsetX,event.offsetY,10,10);
    };

    //功能实现区

    //刮刮乐

    // 1. 绘制刮奖区域
    context.fillStyle='#A9AB9D';
    context.fillRect(10,10,280,180);
    context.fillStyle='#000';
    context.font='50px Arial';
    context.fillText('刮奖区',75,115);
    //字体变色
    setInterval(function(){
        document.getElementById('txt').style.color = document.getElementById('txt').style.color=='peachpuff' ? 'yellow' : 'peachpuff';
    },500);
    //2. 为canvas元素onmousedown和onmouseup事件
    canvas.onmousedown = function(){
        // 鼠标按下时 - 绑定鼠标跟随事件
        bindHandler(canvas,'mousemove',brush,false);
    }
    canvas.onmouseup = function(){
        // 停止刮奖功能 - 解绑鼠标跟随事件
        removeHandler(canvas,"mousemove",brush,false);
    }

    //画笔
    context2.font='20px Arial';
    context2.strokeText('NICK画笔',100,30);//写个头
    //为canvas元素onmousedown和onmouseup事件
    /*
    //这是原来的写法
    canvas2.onmousedown = function(){
        // 启用画笔功能 - 绑定鼠标跟随事件
        bindHandler(canvas2,'mousemove',draw,false);
    }
    canvas2.onmouseup = function(){
        // 停止画笔功能 - 解绑鼠标跟随事件
        removeHandler(canvas2,"mousemove",draw,false);
    }
    */
    //改良后的写法
    var isTouch = "ontouchstart" in window ? true : false;
    var StartDraw = isTouch ? "touchstart" : "mousedown",
            MoveDraw = isTouch ? "touchmove" : "mousemove",
            EndDraw = isTouch ? "touchend" : "mouseup";

    context2.strokeStyle='blue';//线色
    context2.lineCap = "round";//连接处为圆形
    context2.lineWidth =10;//线框

    canvas2.addEventListener(StartDraw, function(ev){
        ev.preventDefault();
        var isX = isTouch ? ev.targetTouches[0].pageX : ev.pageX;
        var isY = isTouch ? ev.targetTouches[0].pageY : ev.pageY;
        var x = isX - canvas2.offsetLeft;
        var y = isY - canvas2.offsetTop;
        context2.beginPath();
        context2.moveTo(x, y);
        function StartMove(ev){
            var isX1 = isTouch ? ev.targetTouches[0].pageX : ev.pageX;
            var isY1 = isTouch ? ev.targetTouches[0].pageY : ev.pageY;
            var x1 = isX1 - canvas2.offsetLeft;
            var y1 = isY1 - canvas2.offsetTop;
            context2.lineTo(x1, y1);

            context2.stroke();
            context2.beginPath();
            context2.moveTo(x1, y1);
        };
        function EndMove(ev){
            var isX1 = isTouch ? ev.changedTouches[0].pageX : ev.pageX;
            var isY1 = isTouch ? ev.changedTouches[0].pageY : ev.pageY;
            var x1 = isX1 - canvas2.offsetLeft;
            var y1 = isY1 - canvas2.offsetTop;
            context2.lineTo(x1, y1);
            context2.stroke();
            canvas2.removeEventListener(MoveDraw, StartMove, false);
            canvas2.removeEventListener(EndDraw, EndMove, false);
        };
        canvas2.addEventListener(MoveDraw, StartMove, false);
        canvas2.addEventListener(EndDraw, EndMove, false);
    }, false);
</script>
</body>
</html>
View Code

  代码写完了,我也想说点其他的:

  上面js代码中,有不少注释,我将其分为几个区域:插件方法封装区、命名区、功能实现区、刮刮乐区以及画笔区等,我感觉这样写加上一些注释,能使代码能加简洁,便于以后的维护!当然这只是个人观点,欢迎各位点击我博客右边公告栏的qq交流交流!

最后附上:

上篇博文:事件绑定与解绑!(只是一个简单的封装)

来看看效果,玩玩吧!

 

posted @ 2016-11-03 17:40  webNick  阅读(3580)  评论(3编辑  收藏  举报
好东西!绝不藏私!乐于分享!涨知识、增内涵、共同进步……
Copyright ©2016 webNick
↑返回顶部