萌新的Canvas笔记(六)

来源:互联网 发布:mysql官方下载64位 编辑:程序博客网 时间:2024/05/09 03:31

初探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
原创粉丝点击