canvas高级内容
一、阴影
context.shadowColor="gray";//指定阴影的颜色
context.shadowOffsetX=-20;//指定阴影的位移值
context.shadowOffsetY=-20;//指定阴影的位移值
context.shadowBlur=5;//描述阴影模糊的程度(值越大越模糊)
示例代码如下:
<script type="text/javascript">
window.onload=function(){
var canvas=document.getElementById('canvas');
canvas.width=1024;
canvas.height=800;
var context=canvas.getContext('2d');
context.fillStyle="#058";
context.shadowColor="gray";//可以使用任意的css可以接受的样式值,包括使用rgba设置半透明色
//context.shadowOffsetX=20;
//context.shadowOffsetY=20;
//负值时阴影方向会相反
context.shadowOffsetX=-20;
context.shadowOffsetY=-20;
context.shadowBlur=5;//越大越模糊
context.fillRect(200,200,400,400);
}
</script>
二、global属性
1.globalAlpha
context.globalAlpha=1;默认值,在这种情况下默认绘制的图形都不具有透明度,即后绘制的图形会盖住之前绘制的图形。示例如下:
<script type="text/javascript">
window.onload=function(){
var canvas=document.getElementById('canvas');
canvas.width=1200;
canvas.height=700;
var context=canvas.getContext('2d');
context.globalAlpha=0.5;//不加此句时后绘制的圆会盖住之前绘制的
//画出100个圆
for(var i=0;i<100;i++){
var R=Math.floor(Math.random()*255);
var G=Math.floor(Math.random()*255);
var B=Math.floor(Math.random()*255);
context.fillStyle="rgb("+R+","+G+","+B+")";
context.beginPath();
context.arc(Math.random()*canvas.width,Math.random()*canvas.height,Math.random()*100,0,Math.PI*2);
context.fill();
}
}
</script>
2.globalCompositeOperation(描述绘制的图形在重叠时所产生的效果)
context.globalCompositeOperation="source-over";//后绘制的图形会盖住之前绘制的图形
context.globalCompositeOperation="destination-over";//之前绘制的图形会盖住之后绘制的图形
示例如下:
<script type="text/javascript">
window.onload=function(){
var canvas=document.getElementById('canvas');
canvas.width=800;
canvas.height=800;
var context=canvas.getContext('2d');
context.fillStyle="blue";
context.fillRect(100,200,400,400);
//context.globalCompositeOperation="source-over";
context.globalCompositeOperation="destination-over";
context.fillStyle="red";
context.beginPath();
context.moveTo(400,300);
context.lineTo(650,700);
context.lineTo(150,700);
context.closePath();
context.fill();
}
</script>
此外,其他globalCompositeOperation属性的属性值如下:
source-over、source-atop、source-in 、source-out ;destination-over 、destination-atop 、destination-in 、destination-out;lighter、 copy、 xor。示例代码如下:
<body >
<canvas id="canvas" style="border: 1px solid #aaa;display: block;margin: 50px auto">
当前浏览器不支持canvas,请更换浏览器后再试
</canvas>
<div id="buttons">
<a href="#">source-over</a>
<a href="#">source-atop</a>
<a href="#">source-in</a>
<a href="#">source-out</a>
<a href="#">destination-over</a>
<a href="#">destination-atop</a>
<a href="#">destination-in</a>
<a href="#">destination-out</a>
<a href="#">lighter</a>
<a href="#">copy</a>
<a href="#">xor</a>
</div>
<script type="text/javascript">
window.onload=function(){
draw("source-over");
var buttons=document.getElementById("buttons").getElementsByTagName("a");
for(var i=0;i<buttons.length;i++){
buttons[i].onclick=function(){
draw(this.text);
return false;
}
}
}
function draw(compositeStyle){
var canvas=document.getElementById('canvas');
canvas.width=1200;
canvas.height=800;
var context=canvas.getContext('2d');
context.clearRect(0,0, canvas.width,canvas.height);
//draw title
context.font="bold 40px Arial";
context.textAlign="center";
context.textBaseline="middle";
context.fillStyle="#058";
context.fillText("globalCompositeOperation="+compositeStyle,canvas.width/2,60);
//draw a rect
context.fillStyle="blue";
context.fillRect(300,150,500,500);
//drae a triangle
context.globalCompositeOperation=compositeStyle;
context.fillStyle="red";
context.beginPath();
context.moveTo(700,250);
context.lineTo(1000,750);
context.lineTo(400,750);
context.closePath();
context.fill();
}
</script>
三、clip和剪辑区域
1. context.clip();此函数与路径规划函数一起使用,例如:lineTo、arc、贝塞尔曲线等等。示例代码如下:
<script type="text/javascript">
window.onload=function(){
var canvas=document.getElementById('canvas');
canvas.width=800;
canvas.height=800;
var context=canvas.getContext('2d');
//设置画布颜色
context.beginPath();
context.fillStyle="black";
context.fillRect(0,0,canvas.width,canvas.height)
context.beginPath();
context.arc(400,400,150,0,Math.PI*2);
context.fillStyle="#fff";
context.fill();
context.clip();
context.font="bold 140px Arial";
context.textAlign="center";
context.textBaseline="middle";
context.fillStyle="#058";
context.fillText("CANVAS",canvas.width/2,canvas.height/2);
}
</script>
2.小实例(圆形探照灯制作)
<script type="text/javascript">
var searchLight={x:400,y:400,radius:150,vx:Math.random()*5+10,vy:Math.random()*5+10,}//vx vy代表移动的速度
window.onload=function(){
var canvas=document.getElementById('canvas');
canvas.width=800;
canvas.height=800;
var context=canvas.getContext('2d');
//动画基础
setInterval(function(){
draw(context);
update(canvas.width,canvas.height);
},40);
}
function draw(cxt){
var canvas=cxt.canvas;
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(searchLight.x,searchLight.y,searchLight.radius,0,Math.PI*2);
cxt.fillStyle="#fff";
cxt.fill();
cxt.clip();
//撰写文字
cxt.font="bold 140px Arial";
cxt.textAlign="center";
cxt.textBaseline="middle";
cxt.fillStyle="#058";
cxt.fillText("CANVAS",canvas.width/2,canvas.height/4);
cxt.fillText("CANVAS",canvas.width/2,canvas.height/2);
cxt.fillText("CANVAS",canvas.width/2,canvas.height*3/4);
cxt.restore();
}
function update(canvasWidth,canvasHeight){
searchLight.x+=-searchLight.vx;
searchLight.y+=searchLight.vy;
if(searchLight.x-searchLight.radius<=0){
searchLight.vx=-searchLight.vx;
searchLight.x=searchLight.radius;
}
if(searchLight.x+searchLight.radius>=canvasWidth){
searchLight.vx=-searchLight.vx;
searchLight.x=canvasWidth-searchLight.radius;
}
if(searchLight.y-searchLight.radius<=0){
searchLight.vy=-searchLight.vy;
searchLight.y=searchLight.radius;
}
if(searchLight.y+searchLight.radius>=canvasHeight){
searchLight.vy=-searchLight.vy;
searchLight.y=canvasHeight-searchLight.radius;
}
}
</script>
四、路径方向和剪纸效果
1.路径方向(非零环绕原则)
如上图,将图形的绘制路径首尾相接并标明方向,然后从某个区域由区域内到外画出一个箭头,两个箭头方向相加不为0则染色,为0则不染色。下面以一个圆环的绘制为例:
示例代码如下:
<script type="text/javascript">
window.onload=function(){
var canvas=document.getElementById('canvas');
canvas.width=800;
canvas.height=800;
var context=canvas.getContext('2d');
//绘制圆环
context.beginPath();
context.arc(400,400,300,0,Math.PI*2,false);
context.arc(400,400,150,0,Math.PI*2,true);
context.closePath();
context.fillStyle="#058";
context.shadowColor="gray";
context.shadowOffsetX=10;
context.shadowOffsetY=10;
context.shadowBlur=10;
context.fill();
}
</script>
2.剪纸效果(需明确哪个位置染色,哪个位置不染色)
示例代码如下:
<script type="text/javascript">
window.onload=function(){
var canvas=document.getElementById('canvas');
canvas.width=800;
canvas.height=800;
var context=canvas.getContext('2d');
//绘制
context.beginPath();
context.rect(100,100,600,600);//顺时针
pathRect(context,200,200,400,200);//逆时针
pathTriangle(context,300,450,150,650,450,650);
context.arc(550,550,100,0,Math.PI*2,true);//逆时针
context.closePath();
context.fillStyle="#058";
context.shadowColor="gray";
context.shadowOffsetX=10;
context.shadowOffsetY=10;
context.shadowBlur=10;
context.fill();
}
function pathRect(cxt,x,y,width,height){
cxt.moveTo(x,y);
cxt.lineTo(x,y+height);
cxt.lineTo(x+width,y+height);
cxt.lineTo(x+width,y);
cxt.lineTo(x,y);
}
function pathTriangle(cxt,x1,y1,x2,y2,x3,y3){
cxt.moveTo(x1,y1);
cxt.lineTo(x2,y2);
cxt.lineTo(x3,y3);
cxt.lineTo(x1,y1);
}
</script>
五、使用canvas交互
isPointInPath 是canvas中内置的点击检测函数
context.isPointInPath(x,y)看传入的点(x,y)是否在当前规划的路径内。下边的例子是绘制10个小球,当点击小球时它的颜色由蓝色变为红色,示例代码如下:
<script type="text/javascript">
var balls=[];
var canvas=document.getElementById('canvas');
var context=canvas.getContext('2d');
window.onload=function(){
canvas.width=800;
canvas.height=800;
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);//用canvas的addEventListener方法创建事件
}
function draw(){
//一次for循环遍历balls数组
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);
context.fillStyle="#058";
context.fill();
}
}
function detect(event){
//获得鼠标点击在canvas中位置的方法
var x=event.clientX-canvas.getBoundingClientRect().left;//鼠标坐标基于Web文档的横向距离减去canvas画布离整个文档左侧的距离
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();
}
}
}
</script>