canvas基础

来源:互联网 发布:颜真卿书法 知乎 编辑:程序博客网 时间:2024/04/30 07:42
  一  初始化


 HTML


 <canvas id="canvas"></canvas>
 如:<canvas id="canvas" width="1024" height="768" style="border:1px solid #aaa; display:block; margin:50px auto;">
 
 Javascript
 
var canvas = document.getElementById('canvas');
var context = canvas.getContext('2d');
canvas的方法:
canvas.width
canvas.height

canvas.getContext('2d')


                                二 画直线




context.moveTo(100,100);
context.lineTo(700,700);
context.stroke()
eg:
context.moveTo(100,100);
context.lineTo(700,700);
context.lineTo(100,700);
context.lineTo(100,100);
context.lineWidth = 5;
context.strokeStyle = "#005588"
context.stroke();

context.fillStyle = "rgb(2,100,30)";
context.fill();

eg2:
context.moveTo(100,100);
context.lineTo(700,700);
context.lineTo(100,700);
context.lineTo(100,100);
context.lineWidth = 5;
context.strokeStyle = "red"
context.stroke();


context.moveTo(200,100);
context.lineTo(700,600);
context.strokeStyle = "black";
context.stroke();
由于绘制是基于状态的,所以结果会出现一个黑色三角形和一条黑色直线。在第二个context.strokeStyle时,前面的context.lineTo(700,700)都在起作用,因此black的三角形会覆盖red三角形。


为了避免上诉情况,可以用beginPath()和closePath().


总结:
1.用context.moveTmo(x,y)和context.lineTo(x,y)来定义路径,而多个路径进行分开处理要在路径的首尾分别加上context.beginPath()和context.closePath();
值得注意的是:beginPath和closePath不一定成对出现,使用closePath时,如果路径未封闭,则会自动封闭。也就是说,对于绘制封闭多边形,成对的出现beginPath和closePath是标准。
对于fill,即使路径没有封闭,也是会先自动封闭,再进行填充。


2. context.lineWidth
context.strokeStyle
context.fillStyle


context.stroke();
context.fill();
注意点:对于需要描边的图形时,要先填充,后描边,已防填充颜色部分覆盖了描边的颜色。

三 绘制弧线


1.context.arc(
centerx,centery,radius,
startingAngle, endingAngle,
anticlockwise = false  //顺时针
)
无论是顺时针还是逆时针,0,0.5PI,PI,1.5PI和2PI的位置都是不变的。如
    context.lineWidth = 5;
context.strokeStyle = "#005588";
context.arc(300,300,200,0,0.5*Math.PI,true);
context.stroke();
2.
context.moveTo(x0,y0);  //首先要用moveTo移动到初始点
context.arcTo(
x1,y1,x2,y2,
radius);
作(x0,y0)到(x1,y1)的直线和(x1,y1)到(x2,y2)的直线。
然后在这两条直线所夹内部作指定的半径的圆弧,使得圆弧和直线相切。


3.贝塞尔曲线
类似arcTo, 
context.moveTo(x0,y0);
context.quadraticCurveTo(x1,y1,x2,y2)  //二次曲线
context.bezierCurveTo(x1,y1,x2,y2,x3,y3)  //三次曲线




                             四  制作动画


两个参数,第一个参数是一个匿名函数,第二个是毫秒。表示每50ms执行一次function函数。
setInterval(
function(){
render();
update();
},
50
);
context.clearRect(x,y,width,height);  //清除
context.canvas //找到画布


五 绘制矩形


context.rect(x,y,width,height)
其他:cxt.fillRect(x,y,width,height) //直接利用当前的fillStyle进行填充。
类似的有:cxt.strokeRect(x,y,width,height).


六 颜色的写法
#ffffff
#620 即为#662200
rgb(100,210,0)
rgba(100,200,10,0.4)  //0.4为不透明度
hsl(20,62%,28%)
hsla(20,62%,28%,0.5)
orange
七   线条绘制的其他属性
1.lineCap
只能用于线段的开始处和结尾处。  3个值:
butt(default),round 和square
如:cxt.lineCap = "round"
会在开始出和结尾处多出一段圆角部分,同理lineCap="square"则会多出一段方角部分。


2 lineJoin
miter(default)   //尖角
 bevel // 斜角和round
 当使用miter时,有个miterLimit属性,表示内角和外角之间距离的最大值。
 一旦超过指定值(如果不写,默认miterLimit为10。一般只有特殊要求角特别尖的情况才需要更改miterLimit的值),则会自动改成bevel的方式。
 eg:
  function drawRect(cxt, r ,R, x , y, rot)
{
cxt.beginPath();
for(var i = 0; i < 5; i++)
{
cxt.lineTo(Math.cos((18+i*72 - rot)/180*Math.PI) * R + x,
-Math.sin((18+i*72 -rot)/180*Math.PI) * R + x)
cxt.lineTo(Math.cos((54+i*72 - rot)/180*Math.PI)* r + y,
-Math.sin((54+i*72 - rot)/180*Math.PI) * r + y)
}

cxt.closePath();
cxt.lineWidth = 5;
cxt.lineJoin = "miter"
cxt.miterLimit = 20;


cxt.stroke();


}




   八  图形变换


基本操作
位移 translate(x,y)
旋转 rotate(deg)
缩放 scale(sx,sy)


显然这种变换操作是叠加的。
为了防止前面的变换操作影响后续的操作,可以使用
cxt.save()和cxt.restore();
其中save会保存当前的图形状态,完成图形绘制后,再使用restore,restore会返回在save这个节点的图形的所有状态。




变换矩阵


transform(a,b,c,d,e,f);
a c e  
b d f
0 0 1


a b :水平缩放和水平倾斜
c d : 垂直倾斜和垂直缩放
e f : 水平位移和垂直位移。
setTransform(a,b,c,d,e,f);
由于transform的效果是相互叠加的,所以可以利用setTransform将变换矩阵直接设置成指定的矩阵。




                              九   填充样式


1:线性渐变
 LinearGradient
 方法:
var grd = context.createLinearGradient(xstart,ystart,xend,yend);
grd.addColorStop(stop,color) stop为关键色的浮点位置,而color为关键色的颜色
注意:stop为0-1的浮点数。
如:
var linearGrad = context.createLinearGradient(0,0,800,800)
linearGrad.addColorStop(0.0,'#f3f');
linearGrad.addColorStop(0.5,'#43f');
linearGrad.addColorStop(1.0,'#2c1')
context.fillStyle = linearGrad;
context.fillRect(0,0,1200,800);
显然这是从(0,0)到(800,800)的倾斜渐变线。当渐变线在画布之内,则多余的部分则自然为结束时的颜色。


2:径向渐变
RadialGradient


var grd = context.createRadialGradient(x0,y0,r0,x1,y1,r1)
grd.addColorStop(stop,color)


3:图片填充样式
createPattern


createPattern(img,repeat-style)
其中repeat-style:no-repeat
repeat-x
repeat-y
repeat 
eg:
var backgroundImage = new Image();
backgroundImage.src = "testBeauty.jpg"
backgroundImage.onload = function()
{
var pattern = context.createPattern(
backgroundImage,"repeat");
context.fillStyle = pattern;
context.fillRect(0,0,800,800);
}
当然也可以将画布作为样式 
createPattern(canvas,repeat-style)
甚至是video作为背景样式


总结:
1.fillStyle = color
 gradient
 image
 canvas
 video
2.对于:fillStyle = gradient
var grd = context.createLinearGradient(xstart,ystart,xend,yend)
var grd = context.createRadialGradient(x0,y0,r0,x1,y1,r1)


grd.addColorStop(stop,color)


3.fillStyle = image || canvas || video
createPattern(img,repeat-style)
createPattern(canvas,repeat-style)
createPattern(video,repeat-style)
repeat-style: no-repeat
 repeat-x
 repeat-y
 repeat


              十   canvas中的文字渲染
0. 预览
context.font = "bold 40px Arial"
context.fillText(string, x, y,[maxlen])  
context.strokeText(string, x, y,[maxlen]) 
其中(x,y)是文字开始绘制的参考点
第四个参数是可选参数,表示string文字的最长长度。
当然fillText前面应该加 fillStyle,fillStyle的任意填充仍旧试用与文字填充。


1.font      
默认值:"20px sans-serif"
context.font = font-style font-variant font-weight font-size font-family


1.1 font-style
font-style: normal italic(斜体字) oblique(倾斜的)


1.2  font-variant
font-variant: normal small-caps; small-caps是指小写字母显示时为大写字母变小,并不是真正显示小写字母。


1.3 font-weight  //描述文字粗细
font-weight: lighter normal bold bolder


1.4 font-size
font-size:20px 2em 150%


1.5 font-family
可以设置多个备选字体


2 文本对齐
2.1 水平对齐
context.textAlign = left
center
right
left:以参考点为左边界,即指定文本全部在参考点右边.


2.2 垂直对齐
textBaseline = top
  middle
  bottom
类似水平对齐,比如bottom:指定参考点的纵坐标恰好是文本的bottom,或是说文本在指定参考线的上面


3文本度量
context.measureText(string).width //根据font属性返回字符串的宽度属性.


               十一 高级特性
1.阴影


context.shadowColor
context.shadowOffsetX = 20 //阴影在右方
context.shadowOffsetY = -20 //阴影在上方
context.shadowBlur = 5




2 globalAlpha //全局透明度


globalAlpha = 1 (Default) 
在不透明绘制环境当中,后绘制的图形会遮盖住先前绘制的图形,设置全局透明度可以使重叠处也能隐约看见先前绘制的图形


3 globalCompositeOperation


globalCompositeOperation = "source-over"(Default) //先绘制的图形在上面
"destination-over" //后绘制的在上面
记忆方法:source-over destination-overlighter
 source-atop destination-atop copy
 source-in destination-in xor
 source-out    destination-out  


4 剪辑区域
context.clip()  //将规划的路径变成当前绘制环境,也就说只会渲染指定区域


5  非零环绕原则,一般用来做剪纸效果
6 context.isPointInPath(x,y)  //看(x,y)是否为当前所规划的路径内


     十二  canvas中使用html标签
<div id = "canvas-wrapper">
<canvas id="canvas">
你的浏览器不支持canvas
</canvas>
<div id="controller">
<h1>canvas 绘图之旅</h1>
<a href="#" id="canvas-btn">停止运动</a>
<a href="#" id="color-btn" id="white-color-btn">&nbsp;</a>
<a href="#" id="color-btn" id="black-white-btn">&nbsp;</a>


</div>

</div>
可知,要先用一个大的div包裹住canvas和其他div。并且其他div要放在canvas标签后面,已防canvas的背景白色覆盖原有的div。
0 0
原创粉丝点击