canvas样式和颜色

本文详细探讨了canvas的颜色、透明度、线型、渐变、图案样式、阴影及其填充规则。介绍了如何设置线条宽度、端点样式、连接样式、渐变应用、虚线绘制以及阴影效果。此外,还讲解了canvas的透明度属性,以及如何利用fillRule控制图形的填充行为。
摘要由CSDN通过智能技术生成

color(颜色)

fillStyle = color;	// 设置图形的填充颜色
stokeStyle = color;	// 设置图形的轮廓颜色

注:

  • color表示css颜色字符串,可以是字符串,渐变对象或者图像,默认情况下填充和线条的颜色是黑色(#000000);
  • 如果设置了fillStyle或者strokeStyle的值,设置的新值将会是后面绘制图形的默认值。

例如:

ctx.fillStyle = "green";
ctx.fillStyle = "#ff3300";
ctx.fillStyle = "rgb(0,0,200)";
ctx.fillStyle = "rgba(0,0,200,0.8)";

例如:

let cvs = document.getElementById("cvs");
	if (cvs.getContext) {
		let ctx = cvs.getContext("2d");
		for (let i=0; i<6; i++) {
			for (let j=0; j<6; j++) {
				ctx.fillStyle = "rgb("+Math.floor(255-42.5*i)+","+Math.floor(255-42.5*j)+","+ 0 + ")";
				ctx.fillRect(2.5+24*j,2.5+24*i,24,24);
				ctx.strokeStyle = "rgb("+Math.floor(255-42.5*i)+","+Math.floor(255-42.5*j)+","+ 0 + ")";
				ctx.beginPath();
				ctx.arc(162.5+j*25,12.5+i*25,10,0,Math.PI*2,true);
				ctx.stroke();
			}
		}
	}

在这里插入图片描述

transparency(透明度)

canvas中可以绘制半透明的图形,可以使用globalAlpha属性或者设置半透明的颜色(rgba(0,0,0,0.3))作为填充或者轮廓描边。

globalAlpha = transparencyValue;

注:

  • 此属性影响到canvas中所有图形的透明度,有效范围(0.0~1.0),默认为1.0(完全不透明)。
  • globalAlpha属性需要绘制大量拥有相同透明度的图形时是相当高效的。
  • 设置了ctx.globalAlpha = 0.2;,只对设置以后的图形透明度有影响,对设置此值之前的图形无影响。
  • rgba(0,0,0,0.3)使用更方便

globalAlpha示例:

let cvs = document.getElementById("cvs");
if (cvs.getContext) {
	let ctx = cvs.getContext("2d");
	// 画背景
	ctx.fillStyle = '#FD0';
	ctx.fillRect(0,0,75,75);
	ctx.fillStyle = '#6C0';
	ctx.fillRect(75,0,75,75);
	ctx.fillStyle = '#09F';
	ctx.fillRect(0,75,75,75);
	ctx.fillStyle = '#F30';
	ctx.fillRect(75,75,75,75);
	ctx.fillStyle = '#FFF';
	
	// 设置透明度值
	ctx.globalAlpha = 0.2;
	
	// 画半透明圆
	for (var i=0;i<7;i++){
	    ctx.beginPath();
	    ctx.arc(75,75,10+10*i,0,Math.PI*2,true);
	    ctx.fill();
	}
}

效果如图:
在这里插入图片描述

line styles(线型)

lineWidth = value;	// 设置线条的宽度
lineCap = value;	// 设置线条末端样式
lineJoin = value;	// 设置线条与线条接合处的样式
miterLimit = value;	// 限制两条线相交接处最大长度,所谓交接处长度(斜接长度)是指线条交接处内角顶点到外角顶点的长度
getLineDash();	// 返回包含当前虚线样式,长度为非负偶数的数组
setLineDash();		// 设置当前虚线样式
lineDashOffset = value;	// 设置虚线样式的起始偏移量
lineWidth示例
let cvs = document.getElementById("cvs");
if (cvs.getContext) {
	let ctx = cvs.getContext("2d");
	ctx.strokeStyle = "#ff3300";
	ctx.beginPath();
	ctx.moveTo(80,5);
    ctx.lineTo(80,200);
    ctx.moveTo(100.5,5);
    ctx.lineTo(100.5,200);
    ctx.stroke();
}

如下图,同样都是1px宽度的线条,但是看起来第一条模糊,第二条清晰,怎么回事呢?
在这里插入图片描述

要想知道其中的原因,必须对线条如何描绘理解。如下图,每个网格代表1px点。
在这里插入图片描述
第一张图中,绘制了从(2,1)(5,5)的矩形,整个区域的边界好像落在像素边缘上,这样得到的矩形有着清晰的边缘;
第二张图中,绘制了从(3,1)(3,5),宽度为1px的线条,实际填充区域仅仅延伸至路径两边的一半像素处,而这半个像素又以近似的方式进行渲染,结果就是以实际笔触颜色的一半色调的颜色来填充整个区域(浅蓝和深蓝部分)。这就是上述示例1px线条不准确的原因。
要解决上述问题,必须要对路径进行精确的控制。第三张图中,绘制了从(3.5,1)(3.5,5)的线条,其边缘正好落在像素边界,这样就填充出来就是准确的1px宽度的线条。

注:

  • 在这个竖线的例子中,其Y坐标刚好落在网格线上,否则端点上同样会出现半渲染的像素点(但还要注意,这种行为的表现取决于当前的lineCap风格,它默认为butt;您可能希望通过将lineCap样式设置为square正方形,来得到与奇数宽度线的半像素坐标相一致的笔画,这样,端点轮廓的外边框将被自动扩展以完全覆盖整个像素格)。
  • 只有路径的起点和终点受此影响:如果一个路径是通过closePath()来封闭的,它是没有起点和终点的;相反的情况下,路径上的所有端点都与上一个点相连,下一段路径使用当前的lineJoin设置(默认为miter),如果相连路径是水平和/或垂直的话,会导致相连路径的外轮廓根据相交点自动延伸,因此渲染出的路径轮廓会覆盖整个像素格。接下来的两个小节将展示这些额外的行样式。

对于那些宽度为偶数的线条,每一边的像素数都是整数,那么你想要其路径是落在像素点之间 (如那从 (3,1) 到 (3,5)) 而不是在像素点的中间。同样,注意到那个例子的垂直线条,其 Y 坐标刚好落在网格线上,如果不是的话,端点上同样会出现半渲染的像素点。

虽然开始处理可缩放的 2D 图形时会有点小痛苦,但是及早注意到像素网格与路径位置之间的关系,可以确保图形在经过缩放或者其它任何变形后都可以保持看上去蛮好:线宽为 1.0 的垂线在放大 2 倍后,会变成清晰的线宽为 2.0,并且出现在它应该出现的位置上。

lineCap示例

属性 lineCap 的值决定了线段端点显示的样子。它可以为下面的三种的其中之一:buttroundsquare。默认是 butt
在这里插入图片描述

最左边的线用了默认的 butt 。可以注意到它是与辅助线齐平的。中间的是 round 的效果,端点处加上了半径为一半线宽的半圆。右边的是 square 的效果,端点处加上了等宽且高度为一半线宽的方块。

lineJoin示例

lineJoin 的属性值决定了图形中两线段连接处所显示的样子。它可以是这三种之一:round, bevelmiter。默认是 miter
在这里插入图片描述
最上面一条是 round 的效果,边角处被磨圆了,圆的半径等于线宽。中间和最下面一条分别是 bevelmiter 的效果。当值是 miter 的时候,线段会在连接处外侧延伸直至交于一点,延伸效果受到下面将要介绍的 miterLimit 属性的制约。

miterLimit示例

就如上一个例子所见的应用 miter 的效果,线段的外侧边缘会延伸交汇于一点上。线段直接夹角比较大的,交点不会太远,但当夹角减少时,交点距离会呈指数级增大。

miterLimit 属性就是用来设定外延交点与连接点的最大距离,如果交点距离大于此值,连接效果会变成了 bevel。

使用虚线

setLineDash 方法和 lineDashOffset 属性来制定虚线样式. setLineDash 方法接受一个数组,来指定线段与间隙的交替;lineDashOffset 属性设置起始偏移量.

gradient(渐变)

可以用线性渐变或者径向渐变来填充或者描边。用下面的方法来新建一个canvasGradient对象,并赋值给fillStylestrokeStyle属性。

let lineargradient = ctx.createLinearGradient(x1,y1,x2,y2);		// 线性渐变,渐变的起点 (x1,y1) 与终点 (x2,y2)
let radialgradient = ctx.createRadialGradient(x1,y1,r1,x2,y2,r2);	// 径向渐变,渐变的起点 (x1,y1),半径为r1, 与终点 (x2,y2),半径为r2

创建出 canvasGradient 对象后,我们就可以用 addColorStop 方法给它上色了。

addColorStop(position,color); // position表示渐变中颜色所在的相对位置,有效值为0.0~1.0,0.5表示颜色出现在正中间;color必须是一个有效的颜色值。

createLinearGradient()示例

	let ctx = cvs.getContext("2d");
	let linearGradient = ctx.createLinearGradient(0,0,200,0);
	
	linearGradient.addColorStop(0,"red");
	linearGradient.addColorStop(0.16,"orange");
	linearGradient.addColorStop(0.32,"yellow");
	linearGradient.addColorStop(0.5,"green");
	linearGradient.addColorStop(0.66,"gray");
	linearGradient.addColorStop(0.82,"blue");
	linearGradient.addColorStop(1,"purple");
	
	ctx.fillStyle = linearGradient;
	ctx.fillRect(0,0,200,80);

效果:
在这里插入图片描述

createRadialGradient()示例

	let ctx = cvs.getContext("2d");
	let radgrad = ctx.createRadialGradient(45,45,10,52,50,30);
	radgrad.addColorStop(0, '#A7D30C');
	radgrad.addColorStop(0.9, '#019F62');
	radgrad.addColorStop(1, 'rgba(1,159,98,0)');
	
	ctx.fillStyle = radgrad;
	ctx.fillRect(0,0,150,150);

效果如图:
在这里插入图片描述

patterns(图案样式)

createPattern(image,type);	// image可以是Image对象的一个引用,type值有:repeat、repeat-x、repeat-y、no-repeat

应用如下:

let img = new Image();
img.src = "xx.png";
img.onload = function() {
	let ptrn = ctx.createPattern(img,"repeat");
	ctx.fillStyle = ptrn;
	ctx.fillRect(0,0,150,150);
}

注:

  • 创建的ptrn可以赋值给fillStylestrokeStyle
  • 使用Image对象的onload handler来确保设置图案之前图像已经加载完毕

shadows(阴影)

shadowColor = color	// 设置或返回阴影的颜色,默认为全透明的黑色
shadowBlur = float		// 设置或返回阴影的模糊程度,默认为0
shadowOffsetX = float	// 设置或返回阴影距形状的水平距离,负值表示向左,正值表示向右,默认为0
shadowOffsetY = float	// 设置或返回阴影距形状的垂直距离,负值表示向上,正值表示向下,默认为0

canvas填充规则

当我们用到 fill(或者 clipisPointinPath ),你可以选择一个填充规则,该填充规则根据某处在路径的外面或者里面来决定该处是否被填充,这对于自己与自己路径相交或者路径被嵌套的时候是有用的。

两个可能的值:

  • nonzero”: non-zero winding rule, 默认值.
  • evenodd”: even-odd winding rule.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值