首页 web前端 H5教程 H5+Canvas使用案例详解

H5+Canvas使用案例详解

Jun 04, 2018 am 11:33 AM
html5 详解

这次给大家带来H5+Canvas使用案例详解,H5+Canvas使用的注意事项有哪些,下面就是实战案例,一起来看一下。

<canvas id=&#39;canvas&#39;></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.onload=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>
登录后复制

相信看了本文案例你已经掌握了方法,更多精彩请关注php中文网其它相关文章!

推荐阅读:

通俗易懂解析JS原型与原型链

如何访问JS的对象属性与方法

以上是H5+Canvas使用案例详解的详细内容。更多信息请关注PHP中文网其他相关文章!

本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

Video Face Swap

Video Face Swap

使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热工具

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

HTML 中的表格边框 HTML 中的表格边框 Sep 04, 2024 pm 04:49 PM

HTML 表格边框指南。在这里,我们以 HTML 中的表格边框为例,讨论定义表格边框的多种方法。

HTML 中的嵌套表 HTML 中的嵌套表 Sep 04, 2024 pm 04:49 PM

这是 HTML 中嵌套表的指南。这里我们讨论如何在表中创建表以及相应的示例。

HTML 左边距 HTML 左边距 Sep 04, 2024 pm 04:48 PM

HTML 左边距指南。在这里,我们讨论 HTML margin-left 的简要概述及其示例及其代码实现。

HTML 表格布局 HTML 表格布局 Sep 04, 2024 pm 04:54 PM

HTML 表格布局指南。在这里,我们详细讨论 HTML 表格布局的值以及示例和输出。

HTML 输入占位符 HTML 输入占位符 Sep 04, 2024 pm 04:54 PM

HTML 输入占位符指南。在这里,我们讨论 HTML 输入占位符的示例以及代码和输出。

HTML 有序列表 HTML 有序列表 Sep 04, 2024 pm 04:43 PM

HTML 有序列表指南。在这里我们还分别讨论了 HTML 有序列表和类型的介绍以及它们的示例

在 HTML 中移动文本 在 HTML 中移动文本 Sep 04, 2024 pm 04:45 PM

HTML 中的文本移动指南。在这里我们讨论一下marquee标签如何使用语法和实现示例。

HTML onclick 按钮 HTML onclick 按钮 Sep 04, 2024 pm 04:49 PM

HTML onclick 按钮指南。这里我们分别讨论它们的介绍、工作原理、示例以及各个事件中的onclick事件。

See all articles