萌新的Canvas笔记(六)

初探clip

context.clip()
clip为裁剪区域,意思就是,当构建了一个封闭的路径后,进行clip操作,这个路径就会把canvas“裁剪”了,只针对这个区域的内容为可见,其余部分为不可见。

        cxt.beginPath();
        cxt.fillStyle = "black";
        cxt.fillRect(0, 0, canvas.width, canvas.height);

        cxt.beginPath();
        cxt.arc(light.x, light.y, light.radius, 0, Math.PI*2);
        cxt.fillStyle = "#fff";
        cxt.fill();

        cxt.clip();

        cxt.font = "bold 150px Arial";
        cxt.textAlign = "center";
        cxt.textBaseline = "middle";
        cxt.fillStyle = "#058";
        cxt.fillText("CANVAS", canvas.width/2, canvas.height/2);

这里写图片描述

一个小demo:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>剪辑区域</title>
    </head>
        <style type="text/css">
            #canvas{
                display: block;
                margin: 0px auto;
                border: 1px black solid;
            }
        </style>
    <body>
        <canvas id="canvas" width="" height=""></canvas>
    </body>
    <script type="text/javascript">
        var canvas = document.getElementById("canvas");
        var context = canvas.getContext("2d");
        canvas.width = 800;
        canvas.height = 700;

        var light = {
            x:400,
            y:400,
            radius:150,
            vx:Math.random()*5+10,
            vy:Math.random()*5+10,
        };
        setInterval(function(){
                draw(context);
                update();
        },40);

        function draw(cxt){

        cxt.clearRect(0, 0, canvas.width, canvas.height);
        cxt.save();

        cxt.beginPath();
        cxt.fillStyle = "black";
        cxt.fillRect(0, 0, canvas.width, canvas.height);

        cxt.beginPath();
        cxt.arc(light.x, light.y, light.radius, 0, Math.PI*2);
        cxt.fillStyle = "#fff";
        cxt.fill();
        cxt.clip();
        cxt.font = "bold 150px Arial";
        cxt.textAlign = "center";
        cxt.textBaseline = "middle";
        cxt.fillStyle = "#058";
        cxt.fillText("CANVAS", canvas.width/2, canvas.height/2);
        cxt.restore();
        }
        function update(){

            light.x = light.x + light.vx;
            light.y = light.y + light.vy;

            if(light.x + light.radius > canvas.width){
                light.vx = -light.vx;
                light.x = canvas.width - light.radius;
            }
            if(light.x < light.radius){
                light.vx = -light.vx;
                light.x = light.radius;
            }
            if(light.y + light.radius > canvas.height){
                light.vy = -light.vy;
                light.y = canvas.height - light.radius;
            }
            if(light.y < light.radius){
                light.vy = -light.vy;
                light.y = light.radius;
            }
        }

    </script>
</html>

运行程序可以得到一个移动探照灯效果。

fill填充的非零环绕原则

非零环绕原则,是用于判断一个区域是属于“里面”还是属于“外面”的一个判断原则。构成一个环绕时,线段的围绕方向是有方向的。假设我们规定一个方向为+1,另一个方向为-1。从某个区域内的一个点,向外面引出一条射线,这个射线会与环绕的线段相交。当相交和不为0时,判断这个区域在“外面”。当相交和为“非0”时,判断这个区域在“里面“,可以进行填充。

图片来自网络
这里写图片描述

比如说一个剪纸效果demo:

        var canvas = document.getElementById("canvas");
        var context = canvas.getContext("2d");
        canvas.width = 800;
        canvas.height = 700;

        context.beginPath();
        context.arc(400, 400, 300, 0, Math.PI*2, false);
        context.arc(400, 400, 150, 0, Math.PI*2, true);

        context.fillStyle = "#058";
        context.shadowColor = "gray";
        context.shadowOffsetX = 10;
        context.shadowOffsetY = 10;
        context.shadowBlur = 10;
        context.fill();

这里写图片描述

由于两个圆绘制的时候,方向是不一样的。根据非零环绕原则,被填充的部分为fill认定的“里面”,而阴影部分为“外面”。
如果两个圆的绘制方向一样,那么结果又将不同。

isPointInPath(x, y)

这个函数用于判断某个点是否在当前所规划的路径内。
做一个demo:随机生成几个小球,鼠标点击小球,改变小球的颜色。

这个demo需要用到获取鼠标点击位置的方法。

            var x = event.clientX - canvas.getBoundingClientRect().left;
            var y = event.clientY - canvas.getBoundingClientRect().top;

其中,event.clientX是指鼠标点击相对于整个DOM文档的位置,减去canvas距离Dom的位置,即为鼠标点击的相对于Canvas的位置,这就是我们想要的。
获取到这个坐标后,用beginPath重新开始绘制路径,逐个绘制小球的路径,并且判断该点是否在当前区域内,如果是,则改变颜色并填充。

var canvas = document.getElementById("canvas");
        var context = canvas.getContext("2d");
        canvas.width = 800;
        canvas.height = 700;

        var balls = [];

        for(var i = 0; i < 10; i ++){

            var aball = {
                x:Math.random() * canvas.width,
                y:Math.random() * canvas.height,
                r:Math.random() * 50 + 20
            };
            balls[i] = aball;
        }

        draw();
        canvas.addEventListener("mouseup", detect);

        function detect(event){
            var x = event.clientX - canvas.getBoundingClientRect().left;
            var y = event.clientY - canvas.getBoundingClientRect().top;

            for(var i = 0; i < balls.length; i ++){
                context.beginPath();
                context.arc(balls[i].x, balls[i].y, balls[i].r, 0, Math.PI*2);

                if( context.isPointInPath(x, y) ){
                    context.fillStyle = "red";
                    context.fill();
                }
            }
        }

        function draw(){

            for(var i = 0; i < 10; i ++){
                context.beginPath();
                context.arc(balls[i].x, balls[i].y, balls[i].r, 0, Math.PI*2);
                context.fillStyle = "#058";
                context.fill();
            }
        }

这里写图片描述

通过一阶段的学习,跟着老师做了几个demo下来,根据视频老师所说的,除了图像处理的部分,Canvas基础已经了解的7788了。而Canvas标准一直在更新,还需要不断的学习。Canvas可以说是HTML5的重头戏,能够帮助开发者将他们的想象力、创意在Web上实现,更加丰富了Web世界,让我们可以见到各种绚丽多彩的效果,这也是Canvas吸引我的地方。不管以后工作中能不能用到这些知识,我都会继续学习Canvas。

2016年8月17日03:09:56

Canvas基础补完。

以上。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值