初探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基础补完。
以上。