Canvas学习笔记

<canvas id='canvas'></canvas>

获取canvas对象上下文

var convas=document.getElementById('canvas');

var context=canvas.getContext('2d');

canvas是基于状态的绘图环境


画直线

context.moveTo(x,y); 挪到笔头  

context.lineTo(x,y);按着画笔移动 (可以结合使用moveTo画不相连的线段)moveTo lineTo +moveTo lineTo

context.lineWith=10;    canvas是基于状态的,它不会创建一个直线对象。我们是对canvas上下文进行其他设置。读完所以设置后再绘图

context.strokeStyle='red';   这里还有其他的样式,不仅仅只有颜色。

context.stroke();


context.beginPath();  开始一个全新的canvas状态。之前对context的设置不会因为beginPath()而改变。新的设置会覆盖之前的设置

context.closePath();  使用线段绘制封闭的图形。可以去掉最后一个lineTo。closePath()会完成封闭这个动作。

context.fillStyle='green';

context.fill();  建议在进行完所有的设置之后再fill和stroke。不然fill会覆盖一部分的线段宽度,会由10变成5;


可以通过以上方法进行封装各种图形的函数。当然canvas也提供了很多图形api

context.rect(x,y,width,height);绘制矩形的路径

context.fillRect(x,y,width,height);使用当前fillStyle绘制矩形 ( 颜色值可以使用css认同的所有颜色值包括rgb、rgba、hsl、hsla)

context.strokeRect(x,y,width,height);使用当前的strokeStyle绘制矩形


后面绘制的图形如果与之前的图形有重叠,则后者会覆盖前者。

但是如果fillStyle 或者strokeStyle的颜色值有一定的透明度,则被覆盖的部分还是有一部分显示的。当然也有其他对重叠部分的设置


线条属性:

lineWidth=10;

lineCap=''; 线段的2段的样式。butt(default)、round圆头、square方头。round和squqre比默认的长线条宽度的一半(5)的的长度。


lineJoin; 线段与线段之间连接的样式。miter(default)、bevel(斜截)、round(圆头)  


图形变换

context.translate(x,y);移动坐标系

context.rotate(deg);旋转坐标系弧度制

context.scale(x,y);缩放坐标系--->需要注意的是,它也会对坐标数值,边框宽度属性等进行缩放,使用时需要谨慎选择。

提示:在进行一次变换之后,坐标系已经发生变化,如果在使用变换,就会与之前预期不同。那么我们就需要将之前的变换再逆向执行一次,如context.translate(100,200)之后,如果还需要进行rotate变换,就需要再进行一次context.translate(-100,-200)操作。这样操作就会很麻烦,canvas提供了一个简单的方法来保存变换之前的canvas状态。如下

context.save();

context.translate(x,y);

context.restore();

在变换之前进行save操作,变换完成之后再restore操作,就可以还原到之前的canvas状态,避免第一的变换影响到第二次的变换。


变换矩阵---canvas为变换提供了一个更高级的方法。

contex.transform(a,b,c,d,e,f);   a、d-水平垂直缩放;b、c水平垂直倾斜;e、f水平垂直位移。

context.transform(1,0,0,1,0,0);基本矩阵,图形不发生任何变化。

当我们进行多次transform矩阵之后,标准系以及很混乱了,就需要下面这个方法了。

context.setTransform(a,b,e,d,e,f)。覆盖之前的transform设置,使用当前的transform设置,这样我们就很清楚当前具体transform变换。


context.fillStyle   ---填充样式  之  渐变

linearGradient:

var grd=context.creatLinearGradient(xStart,yStrart,xEnd,yEnd);   定义渐变色。在(xEnd,yEnd)点之后,填充的是最后的颜色值。

grd.addColorStop(stop,color);(stop的值,0-1的浮点数)   一般多个颜色断点配合使用,从而实现多颜色的渐变

context.fillStyle=grd;

context.fill();


radialGradient;

var grd=context.createRadialGradient(x0,y0,r0,x1,y1,r1); 定义2个同心圆,(x0,y0)位置的半径r0

gra.addColorStop(stop,color);

context.fillStyle=grd;

context.fill();


createPattern

var pattern=context.createPattern(img || canvas || video , repeat-style);

Img的值可以使一张图片,也可以使一个canvas画布,甚至是一段video

repeat-style的值:no-repeat、repeat-x、repeat-y、repeat

context.fillStyle=pattern;

context.fill();


注:以上说明了fillStyle的值:color、gradient、img、canvas、video。当然,以上的style值也是适用strokeStyle。


绘制一段弧---arc

context.arc(centerX , centerY , radius , startAngle , endAngle , anticlockwise=false),

这些参数分别代表是中心坐标,半径,开始结束弧度,及是否逆时针(默认false)

可以封装一些方法来画圆形,圆线,圆角矩形等。


contex.arcTo(x1 , y1 ,  x2 , y2 , radius);

当前点(x0,y0)与(x1,y1)和(x2,y2)这三点组合成一个角,分别切于2边的弧就是arcTo绘制的效果。起点是当前点,结束点(x2,y2),当然这是一段直线+圆弧的效果,radius为圆弧的半径。如下图所示。



适用情景:一般画圆弧是需要圆心坐标的。使用arcTo我们可以在不清楚圆心坐标的情况下绘制一段弧。


插入一段:

我们在使用canvas封装一些画图形的函数时,一般步骤为先使用ctx.save()和ctx.restore()包裹函数的开始和结束。在其中做一些style的设置、变换的设置、及一个绘制图形路径的函数。在这个路径函数中以ctx.beginPath()和ctx.closePath()开始和结束,在其中使用一些moveTo,lineTo,arc,arcTo等方法。


二次贝塞尔曲线quadraticCurveTo(x1,y1,x2,y2);------http://tinyurl.com/html5quadratic

ctx.moveTo(x0,y0);

ctx.quadraticCurveTo(x1,y1,x2,y2);

这样就绘制一段以(x0,y0)为起点,(x2,y2)为终点的一段弧。  那么这样的一段弧,不一定是一段圆弧。


三次贝塞尔曲线bezierCurveTo(x1,y1,x2,y2,x3,y3)-----http://tinyurl.com/html5bezier

ctx.moveTo(x0,y0);

ctx.bezierCurveTo(x1,y1,x2,y2,x3,y3)  

这样就绘制一段以(x0,y0)为起点,(x3,y3)为终点的一段弧。 这么一段弧度可以绘制二次曲线不能完成的波浪弧线。


canvas中文字的绘制

ctx.font = "bold 40px Arial";

ctx.fillStyle=;

ctx.fillText(string ,x ,y,[maxlen]);在(x,y)位置绘制string 这个字符串

ctx.strokeStyle=;

ctx.strokeText(string,x,y,[maxlen]);在(x,y)位置绘制string 这个字符串,这个文字只有文字的边框,并没有填充

string 这个字符串如果设置了maxlen这个可选参数,那么这段文字就会强制压缩在maxlen这个宽度中。

当然,我们也可以设置fillStyle为一段纹理背景,在绘制文字,那么就会一段带纹理背景的文字。


文字细节部分

ctx.font="20px sans-serif"(默认),如果需要设置,只是这2个值

font:font-style、font-varient、font-weight、font-size、font-family(一个5个属性,和css基本相似)

font-style:normal、italic(斜体)、oblique(倾斜字体)。一般的web页面中italic和oblique是一样的,除非使用自己导入的倾斜字体。

font-varient:normal、small-caps(使用小型大写字母 替代 小写字母,大小和小写一样,只是他是大写的)

font-weight:lighter、normal、 bold、bolder。一般浏览器,前2者一样,后2者一样。

font-size:px、em、%、large等

font-family:支持设置多种字体备用、支持@font-face、支持web安全字体


ctx.textAlign=left、center、right。

分别是以fillText(string,x,y);中x坐标为左边界、中间线、右边界绘制文字。(注意:left、right分别是指的边界)

ctx.textBaseLine=top、middle、bottom;

分别是以fillText(string,x,y);中x坐标为上边界、中间线、下边界绘制文字。同样也是边界。

另外还有alphabetic(默认,英文等)、ideographic(汉字,日语)、hanging(印度)三种值分别对应三类语言设置基准线


ctx.measureText(string).width-------根据对font设置之后,返回一个一段文字渲染的宽度

暂时不支持其他的属性如height等


阴影

ctx.shadowColor     --->CSS接受的颜色值均可

ctx.shadowOffsetX   --->x、y方向上的偏移    可为负值

ctx.shadowOffsetY

ctx.shadowBlur   --->模糊  0--> 越大越模糊

只需要设置shadowColor 和下面的任何一个属性,阴影就会出现,一般需要全部设置。

canvas绘制 均可设置shadow阴影


global属性  对全局设置

ctx.globalAlpha=1(default)   对全局设置透明度


ctx.globalCompositeOperation=   前后绘制图形重叠部分的样式     共有11种样式

"source-over"(default)  : 后绘制的图形覆盖前绘制的图形(默认)

"destination-over":前绘制的图形覆盖后绘制的图形

11种样式如下:

source-oversource-atopsource-insource-out

destination-over destination-atopdestination-indestination-out 

lighter(颜色计算)copy(只保留后者)xor(清除重叠部分)


剪辑区域clip-----》使用刚刚规划的路径  为剪辑区域,那么我们看到,也只是这个剪辑区域的图形

ctx.beginPath();

ctx.arc(400,400,200,0,Math.PI*2);

ctx.clip();    --->有绘制了一个圆形的剪辑区域




<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>canvas之globalCompositeOperation</title>
	<style type="text/css">
	body{
		background-color: #ccc;
	}
	</style>
</head>
<body>
	<canvas id="canvas" style="display: block;margin: 50px auto;border:1px solid #ccc; background-color: #FFF"></canvas>
</body>
<script type="text/javascript">
	var canvas=document.getElementById('canvas');
	var WIDTH=1500;
	var HEIGHT=800;
	canvas.width=WIDTH;
	canvas.height=HEIGHT;
	var CIRCLES=[];
	var COLORS=["0","1","2","3","4","5","6","7","8","9","a","b","c","d","e","f"];
	var NUMS=220;
	var SPEEDX=16;
	var SPEEDY=8;
	var RADIUS=25;

	window.οnlοad=function(){
		if(canvas){
			var context=canvas.getContext('2d');
			gloablCompositeOperation(context);
		}else{
			console.log('浏览器不支持canvas,请更新浏览器!')
		}
	}

	function gloablCompositeOperation(context){
		context.clearRect(0, 0, WIDTH, HEIGHT);
		context.globalCompositeOperation="xor";
		context.globalAlpha=1;
		addCircles(CIRCLES,NUMS);
		paintCircles(context,CIRCLES);

		//setInterval(run(context),90);	  //setInterval、setTimeout不能直接传入带参数的方法调用。 一般有2中方法,1、使用匿名方法包装下。
		var interval=setInterval(function(){
			go(context);
		},90);	
	}

	/*function run(context){	//2、定义一个带参数,返回一个无参方法,在返回的无参方法中调用之前带参方法。
		return function(){
			go(context);
		}
	}*/

	function go(context){
		updateCirCles(CIRCLES);
		paintCircles(context,CIRCLES);
	}

	/*绘制一个圆对象*/
	function paintCircles(ctx ,CIRCLES){
		ctx.clearRect(0, 0, WIDTH, HEIGHT);
		for(var i=0 ; i<CIRCLES.length ; i++){
			ctx.beginPath();
			ctx.arc(CIRCLES[i].x,CIRCLES[i].y,CIRCLES[i].r,0,Math.PI*2);
			ctx.closePath();
			ctx.fillStyle=CIRCLES[i].color;
			ctx.fill();
		}
	}

	/*随机生成新的圆对象,加入到数组*/
	function addCircles(CIRCLES,num){		
		for(var i=0 ; i<num ;i++){
			var circle={};
			var radius=(1+Math.random())*RADIUS;
			var	cX=Math.random()*WIDTH;
			var	cY=Math.random()*HEIGHT;
			cX=cX<radius?radius:cX;
			cY=cY<radius?radius:cY;
			cX=cX>(WIDTH-radius)?(WIDTH-radius):cX;
			cY=cY>(HEIGHT-radius)?(HEIGHT-radius):cY;
			circle.x=cX;
			circle.y=cY;
			circle.r=radius;
			circle.color=createRandomRGBColor(); 
			circle.vX=(Math.floor(Math.random()*10)%2)==0?SPEEDX:(-1)*SPEEDX;
			circle.vY=(Math.floor(Math.random()*10)%2)==0?SPEEDY:(-1)*SPEEDY;
			circle.vX=circle.vX+Math.random()*6;
			circle.vY=circle.vY+Math.random()*3;
			CIRCLES[i]=circle;
		}
	}

	function updateCirCles(CIRCLES){
		for(var i=0 ; i<CIRCLES.length ; i++){
			var width=WIDTH-CIRCLES[i].r;
			var height=HEIGHT-CIRCLES[i].r;
			
			if(CIRCLES[i].x + CIRCLES[i].vX>width){
				CIRCLES[i].x=CIRCLES[i].x;
				CIRCLES[i].vX=CIRCLES[i].vX*(-1); 
			}else	if(CIRCLES[i].y + CIRCLES[i].vY>height){
				CIRCLES[i].y=CIRCLES[i].y; 
				CIRCLES[i].vY=CIRCLES[i].vY*(-1); 
			}else	if(CIRCLES[i].x + CIRCLES[i].vX<CIRCLES[i].r){
				CIRCLES[i].x=CIRCLES[i].x;
				CIRCLES[i].vX=CIRCLES[i].vX*(-1); 
			}else	if(CIRCLES[i].y + CIRCLES[i].vY<CIRCLES[i].r){
				CIRCLES[i].y=CIRCLES[i].y;
				CIRCLES[i].vY=CIRCLES[i].vY*(-1); 
			}else{
				CIRCLES[i].x=CIRCLES[i].x + CIRCLES[i].vX;
				CIRCLES[i].y=CIRCLES[i].y + CIRCLES[i].vY;
			}
		}
	}

	//随机生成rgb颜色值"#123abc"
	function createRandomRGBColor(){
		var color="";
		for(var i=0 ; i<6 ; i++){
			color+=COLORS[Math.floor(Math.random()*COLORS.length)];
		}
		return "#"+color;
	}

	//随机生成rgba颜色值"#123abc"
	function createRandomRGBAColor(){
		var color="";
		for(var i=0 ; i<3 ; i++){
			color+=Math.floor(Math.random()*255)+",";
		}
		return "rgba("+color+Math.random()+")";  //"rgba("+color+Math.random()+")"
	}
</script>
</html>


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Canvas红包雨是一种基于HTML5 Canvas技术开发的节日效果,通过JavaScript控制红包的下落和动画效果,实现一个红包雨的动态效果。 下面是Canvas红包雨的开发流程: 1. HTML页面中添加Canvas画布,并设置画布的宽高和样式。 ```html <canvas id="canvas"></canvas> ``` ```css #canvas { width: 100%; height: 100%; position: absolute; top: 0; left: 0; z-index: 999; } ``` 2. 在JavaScript中获取Canvas画布对象,并设置画布的宽高。 ```javascript var canvas = document.getElementById('canvas'); var ctx = canvas.getContext('2d'); canvas.width = window.innerWidth; canvas.height = window.innerHeight; ``` 3. 定义红包对象,包括红包的位置、速度、大小和颜色等属性。 ```javascript function RedPacket(x, y, vx, vy, size, color) { this.x = x; this.y = y; this.vx = vx; this.vy = vy; this.size = size; this.color = color; } ``` 4. 在Canvas画布上绘制红包,并实现红包的下落和动画效果。 ```javascript var redPackets = []; // 存储红包对象的数组 function drawRedPacket(redPacket) { ctx.beginPath(); ctx.arc(redPacket.x, redPacket.y, redPacket.size, 0, 2 * Math.PI); ctx.fillStyle = redPacket.color; ctx.fill(); } function updateRedPacket(redPacket) { redPacket.x += redPacket.vx; redPacket.y += redPacket.vy; redPacket.vy += gravity; } function animate() { ctx.clearRect(0, 0, canvas.width, canvas.height); for (var i = 0; i < redPackets.length; i++) { drawRedPacket(redPackets[i]); updateRedPacket(redPackets[i]); } requestAnimationFrame(animate); } requestAnimationFrame(animate); ``` 5. 实现红包的自动生成和动态效果,可以通过setInterval或setTimeout定时调用生成红包的函数。 ```javascript function createRedPacket() { var x = Math.random() * canvas.width; var y = -20; var vx = Math.random() * 6 - 3; var vy = Math.random() * 2 + 2; var size = Math.random() * 10 + 10; var color = '#' + Math.floor(Math.random() * 16777215).toString(16); // 随机生成颜色 var redPacket = new RedPacket(x, y, vx, vy, size, color); redPackets.push(redPacket); } setInterval(createRedPacket, 500); // 每500ms生成一个红包 ``` 6. 实现红包的点击事件,当用户点击红包时,可以实现红包爆炸效果,并显示红包金额或祝福语。 ```javascript function explodeRedPacket(redPacket) { var particles = []; // 存储爆炸粒子的数组 for (var i = 0; i < 20; i++) { var particle = { x: redPacket.x, y: redPacket.y, vx: Math.random() * 6 - 3, vy: Math.random() * 6 - 3, size: Math.random() * 3 + 1, color: redPacket.color }; particles.push(particle); } for (var i = 0; i < particles.length; i++) { drawRedPacket(particles[i]); } } canvas.addEventListener('click', function(event) { var x = event.clientX; var y = event.clientY; for (var i = 0; i < redPackets.length; i++) { var redPacket = redPackets[i]; if (x > redPacket.x - redPacket.size && x < redPacket.x + redPacket.size && y > redPacket.y - redPacket.size && y < redPacket.y + redPacket.size) { explodeRedPacket(redPacket); redPackets.splice(i, 1); break; } } }); ``` 上述就是Canvas红包雨的开发流程,通过Canvas技术和JavaScript实现红包的下落、动画、自动生成和点击事件等效果,可以增加网站的趣味性和用户互动性。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值