渐变

线性渐变

在一条直线上进行渐变

  1. 调用createLinearGradient()方法创建一个linearGradient对象
var gnt = cxt.createLinearGradient(x1, y1, x2, y2);
  • x1、y1表示渐变色开始点的坐标
  • x2、y2表示渐变色结束点的坐标
  1. 添加渐变(开始)
gnt.addColorStop(value1,color1);
  • value1 渐变开始的位置,取值 0~1
  • color1 渐变开始的颜色
  1. 添加渐变(结束)
gnt.addColorStop(value2,color2);
  • value2 渐变结束的位置,取值 0~1
  • color2 渐变结束的颜色

第2和第3步可以反复多次添加多个渐变,每次渐变都以上一个渐变的结束位置为开始位置

  1. 填充渐变
cxt.fillStyle = gnt;
cxt.fill();

fill()可以改为fillRect()或fillText()。其中fillRect()表示矩形渐变,fillText()表示文字渐变。

             var gnt = cxt.createLinearGradient(0,150, 200, 150);gnt.addColorStop(0, "HotPink");gnt.addColorStop(1, "white");cxt.fillStyle = gnt;cxt.fillRect(0, 0, 200, 150);

             var text = "绿叶学习网";cxt.font = "bold 50px 微软雅黑";var gnt = cxt.createLinearGradient(0, 75, 200, 75);gnt.addColorStop(0, "HotPink");gnt.addColorStop(1, "LightSkyBlue");cxt.fillStyle = gnt;cxt.fillText(text, 10, 90);

径向渐变(用得少)

径向渐变,是一种从起点到终点、颜色从内到外进行的圆形渐变(从中间向外拉,像圆一样)。径向渐变是圆形渐变或椭圆形渐变,颜色不再沿着一条直线渐变,而是从一个起点向所有方向渐变。

  1. 调用createLinearGradient()方法创建一个radialGradient对象
var gnt = cxt.createRadialGradient(x1,y1,r1,x2,y2,r2);
  • (x1,y1)表示渐变开始圆心的坐标,r1表示渐变开始圆心的半径。
  • (x2,y2)表示渐变结束圆心的坐标,r2表示渐变结束圆的半径。

    当起点圆与终点圆的圆心坐标相同时,会有一种圆形渐变的效果
  1. 添加渐变(开始)
gnt.addColorStop(value1,color1);
  • value1 渐变开始的位置,取值 0~1
  • color1 渐变开始的颜色
  1. 添加渐变(结束)
gnt.addColorStop(value2,color2);
  • value2 渐变结束的位置,取值 0~1
  • color2 渐变结束的颜色

第2和第3步可以反复多次添加多个渐变,每次渐变都以上一个渐变的结束位置为开始位置

  1. 填充渐变
cxt.fillStyle = gnt;
cxt.fill();

fill()可以改为fillRect()或fillText()。其中fillRect()表示矩形渐变,fillText()表示文字渐变。

             //画圆cxt.beginPath();cxt.arc(80, 80, 50, 0, Math.PI * 2, true);cxt.closePath();//渐变var gnt = cxt.createRadialGradient(100, 60, 10, 80, 80, 50);gnt.addColorStop(0, "white");gnt.addColorStop(0.9, "orange");gnt.addColorStop(1, "rgba(0,0,0,0)");//填充cxt.fillStyle = gnt;cxt.fill();

             gradient = cxt.createRadialGradient(60, 60, 0, 60, 60, 60);gradient.addColorStop("0", "magenta");gradient.addColorStop("0.25", "blue");gradient.addColorStop("0.50", "green");gradient.addColorStop("0.75", "yellow");gradient.addColorStop("1.0", "HotPink");cxt.fillStyle = gradient;cxt.fillRect(0, 0, 120, 120);

             var i = 0;setInterval(function () {gradient = cxt.createRadialGradient(60, 60, 0, 60, 60, 60);gradient.addColorStop(i * 0, "magenta");gradient.addColorStop(i * 0.25, "blue");gradient.addColorStop(i * 0.50, "green");gradient.addColorStop(i * 0.75, "yellow");gradient.addColorStop(i * 1.0, "HotPink");cxt.fillStyle = gradient;i = i + 0.1;if (i >= 1) { //超过颜色点值后,自动归0i = 0;}cxt.fillRect(0, 0, 120, 120);}, 50);

阴影

属性

说明

shadowOffsetX

阴影与图形的水平距离,默认值为0。大于0时向右偏移,小于0时向左偏移

shadowOffsetY

阴影与图形的垂直距离,默认值为0。大于0时向下偏移,小于0时向上偏移

shadowColor

阴影的颜色,默认值为黑色

shadowBlur

阴影的模糊值,默认值为0。该值越大,模糊度越强;该值越小,模糊度越弱

Canvas阴影属性使用的也是W3C坐标系,y 轴向下

             //设置左上方向的阴影cxt.shadowOffsetX = -5;cxt.shadowOffsetY = -5;cxt.shadowColor = "LightSkyBlue ";cxt.shadowBlur = 1;cxt.fillStyle = "HotPink";cxt.fillRect(30, 30, 50, 50);//设置右下方向的阴影cxt.shadowOffsetX = 5;cxt.shadowOffsetY = 5;cxt.shadowColor = "LightSkyBlue ";cxt.shadowBlur = 10;cxt.fillStyle = "HotPink";cxt.fillRect(100, 30, 50, 50);

             //定义文字var text = "绿叶学习网";cxt.font = "bold 60px 微软雅黑";//定义阴影cxt.shadowOffsetX = 5;cxt.shadowOffsetY = 5;cxt.shadowColor = "LightSkyBlue ";cxt.shadowBlur = 10;//填充文字cxt.fillStyle = "HotPink";cxt.fillText(text, 10, 90);

             //创建image对象var image = new Image();image.src = "images/princess.png";image.onload = function () {//定义阴影cxt.shadowOffsetX = 5;cxt.shadowOffsetY = 5;cxt.shadowColor = "HotPink";cxt.shadowBlur = 10;cxt.fillRect(40, 15, 120, 120);cxt.drawImage(image, 40, 15);}


四个方向的阴影效果,只需要shadowOffsetX和shadowOffsetY这两个属性的值都定义为0就可以了。

             //创建image对象var image = new Image();image.src = "images/princess.png";image.onload = function () {//定义阴影cxt.shadowOffsetX = 0;cxt.shadowOffsetY = 0;cxt.shadowColor = "HotPink";cxt.shadowBlur = 10;cxt.fillRect(40, 15, 120, 120);cxt.drawImage(image, 40, 15);}

路径

方法

说明

beginPath()

开始一条新的路径

closePath()

关闭当前路径

isPointInPath()

判断某一个点是否存在于当前路径内

beginPath()

 cxt.beginPath();

用于开始一个新路径(同时也是结束上一个路径),刚开始绘图时,其实都默认执行了一次 beginPath() 开始了一个新路径,直到再次遇到 beginPath() 才会结束默认创建的路径,而开始一段新路径。

Canvas基于“状态”绘制图形。每一次绘制(stroke()或fill()),Canvas会检测整个程序定义的所有状态,这些状态包括strokeStyle、fillStyle、lineWidth等。当一个状态值没有被改变时,Canvas就一直使用最初的值,当一个状态值被改变时,需要分两种情况考虑。

(1)如果使用beginPath()开始一个新的路径,则不同路径使用不同的值。

(2)如果没有使用beginPath()开始一个新的路径,则后面的值会覆盖前面的值(后来者居上原则)。

             cxt.lineWidth = 5;//第1条直线cxt.moveTo(50, 40);cxt.lineTo(150, 40);cxt.strokeStyle = "red";cxt.stroke();//第2条直线cxt.moveTo(50, 80);cxt.lineTo(150, 80);cxt.strokeStyle = "green";cxt.stroke();//第3条直线cxt.moveTo(50, 120);cxt.lineTo(150, 120);cxt.strokeStyle = "blue";cxt.stroke();


三条直线都属于同一个路径,所以cxt.strokeStyle=‘green’;会覆盖cxt.strokeStyle=‘red’;,然后cxt.strokeStyle=‘blue’;会覆盖cxt.strokeStyle=‘green’;。因此strokeStyle属性最终取值为blue,即三条直线都是blue。

             cxt.lineWidth = 5;//第1条直线cxt.beginPath();cxt.moveTo(50, 40);cxt.lineTo(150, 40);cxt.strokeStyle = "red";cxt.stroke();//第2条直线cxt.beginPath();cxt.moveTo(50, 80);cxt.lineTo(150, 80);cxt.strokeStyle = "green";cxt.stroke();//第3条直线cxt.beginPath();cxt.moveTo(50, 120);cxt.lineTo(150, 120);cxt.strokeStyle = "blue";cxt.stroke();


使用beginPath()后,三条直线将位于不同的路径中。因此,不同路径中定义的状态不会像上一个例子那样发生覆盖。

判断是否属于同一路径的标准是:是否使用了beginPath(),而不是视觉上是否有首尾连线。

Canvas中的绘制方法如stroke()、fill()等,都是以“之前最近的beginPath()”后面所有定义的状态为基础进行绘制的。

closePath()

cxt.closePath();

用于关闭路径,即将同一个路径的起点与终点连接起来,使其成为一个封闭的图形。
常用于绘制多边形的最后一步。

如果Canvas只有一条线段的话,那么closePath()方法就什么都不做。

             cxt.arc(70, 70, 50, 0, -90 * Math.PI / 180, true);cxt.stroke();cxt.closePath();

             cxt.lineWidth = 10;cxt.strokeStyle = "HotPink";cxt.moveTo(40, 60);cxt.lineTo(100, 60);cxt.lineTo(100, 30);cxt.lineTo(150, 75);cxt.lineTo(100, 120);cxt.lineTo(100, 90);cxt.lineTo(40, 90);cxt.lineTo(40, 60);cxt.stroke();


将lineWidth定义得足够大(10px)时,如果使用lineTo()方法来关闭图形,会有一个如图所示的“缺口”小问题。有两种方法可以解决:

  1. 定义lineCap属性值为square。
  2. 在stroke()方法之前使用closePath()关闭图形(推荐)

isPointInPath()

cxt.isPointInPath(x , y);

用于判断点 x,y 是否在当前路径中,若在返回true,否则返回false,仅对 rect()方法有效,对 strokeRect() 和 fillRect() 无效。

             cxt.strokeStyle = "HotPink";cxt.rect(50, 50, 80, 80);cxt.stroke();if (cxt.isPointInPath(100, 50)) {alert("点(100,100)存在于当前路径中");}

             cxt.moveTo(50, 50);cxt.lineTo(150, 50);cxt.stroke();if (cxt.isPointInPath(100, 50)) {alert("点(50,100)存在于当前路径中");}

上面代码只在IE浏览器中运行中有效果,但是在Google浏览器和Firefox中不会弹出对话框。实际上,当我们想要使用isPointInPath()方法判断某个点是否位于一条直线上时,在Goole和Firefox浏览器中都是无法实现的。不过可以使用isPointInPath()方法判断某个点是否位于一个图形(如矩形、圆形等)上面。

状态

Canvas基于“状态”来绘制图形。每一次绘制(stroke()或fill()),Canvas会检测整个程序定义的所有状态,这些状态包括strokeStyle、fillStyle、lineWidth等。当一个状态值没有被改变时,Canvas就会一直使用最初的值。当一个状态值被改变时,分两种情况考虑:

(1)如果使用beginPath()开始一个新的路径,则不同路径使用不同的值。

(2)如果没有使用beginPath()开始一个新的路径,则后面的值会覆盖前面的值(后来者居上原则)。

状态的保存和恢复

Canvas提供了两个操作状态的方法:

  • save() 保存“当前状态”,如剪切状态、变换状态和绘图状态(各种绘图样式属性),不能保存路径状态(开始新的路径,只有beginPath()一个方法),也不能保存图形(Canvas只有当前一个上下文环境,如果想要恢复图形,就只能清空画布再重绘。)。
  • restore() 恢复“之前保存的状态”。

save()和restore()一般情况下都是成对配合使用,使用场景如下:

(1)图形或图片裁切。
(2)图形或图片变换。
(3)以下属性改变的时候:fillStyle、font、globalAlpha、globalCompositeOperation、lineCap、lineJoin、lineWidth、miterLimit、shadowBlur、shadowColor、shadowOffsetX、shadowOffsetY、strokeStyle、textAlign、textBaseline。

应用一:清除剪切区域

创建剪切区域 clip()

创建剪切区域后,绘制的图形都只限于这个剪切区域之内,超出剪切区域的部分不会显示(被剪切掉了)。

把整个画布(Canvas)看成一个房子,clip()方法的剪切区域则可以看成一扇窗户。即使房子再大,最终透过窗户所能看到的空间也就只有窗户这么大。

cxt.clip();
  1. 绘制一个基本图形
  2. 调用 clip() 创建一个剪切区域

clip()方法也不支持Canvas自带的两个方法:strokeRect()、fillRect()。如果要使用strokeRect()和fillRect(),请使用rect()方法来代替。

             //绘制一个"描边圆",圆心为(50,50),半径为40cxt.beginPath();cxt.arc(50, 50, 40, 0, 360 * Math.PI / 180, true);cxt.closePath();cxt.strokeStyle = "HotPink";cxt.stroke();//使用clip(),使得"描边圆"成为一个剪切区域cxt.clip();//绘制一个"填充矩形"cxt.beginPath();cxt.fillStyle = "#66CCFF";cxt.fillRect(50, 50, 100, 80);


若注释掉 cxt.clip();

清除剪切区域

在图形或者图片剪切(clip())之前使用save()方法来保持当前状态,然后在剪切(clip())之后使用restore()方法恢复之前保存的状态。

如果不使用save()和restore(),即便使用clearRect()方法清空画布,后面绘制的所有图形或图片也都会限制在这个剪切区域内。

             //save()保存状态cxt.save();//使用clip()方法指定一个圆形的剪切区域cxt.beginPath();cxt.arc(70, 70, 50, 0, 360 * Math.PI / 180, true);cxt.closePath();cxt.stroke();cxt.clip();//绘制一张图片var image = new Image();image.src = "images/princess.png";image.onload = function () {cxt.drawImage(image, 10, 20);}$$("btn").onclick = function () {//restore()恢复状态cxt.restore();//清空画布cxt.clearRect(0, 0, cnv.width, cnv.height);//绘制一张新图片var image = new Image();image.src = "images/Judy.png";image.onload = function () {cxt.drawImage(image, 10, 20);}}


删除 cxt.save()和cxt.restore() 后效果为:

应用二:图片/图形的变换

             cxt.fillStyle = "HotPink";cxt.translate(30, 30);cxt.fillRect(0, 0, 100, 50);cxt.fillStyle = "LightSkyBlue ";cxt.translate(60, 60);cxt.fillRect(0, 0, 100, 50);


蓝色矩形预期坐标为 (60,60),最终效果却是 (90,90),因为之前 translate(30, 30),整个坐标系的原点已经发生了位移变化 !

解决方案是使用 save()和restore()来实现

             cxt.save();cxt.fillStyle = "HotPink";cxt.translate(30, 30);cxt.fillRect(0, 0, 100, 50);cxt.restore();cxt.fillStyle = "LightSkyBlue ";cxt.translate(60, 60);cxt.fillRect(0, 0, 100, 50);


在变换操作(平移、缩放、旋转)中,一般都是在操作之前使用save()方法保存当前状态,其中当前状态包括参考坐标、图形大小等。然后再使用restore()方法来恢复之前保存的状态。

Canvas对象

属性

  • globalAlpha 透明度
    默认值为1.0(完全不透明),取值范围为:0.0~1.0。其中0.0表示完全透明,1.0表示完全不透明。globalAlpha属性必须在图形绘制之前定义才有效。
  • width 宽度
  • height 高度

常用于文字水平居中对齐和清空画布

cxt.clearRect(0, 0, cnv.width, cnv.height);

方法

  • getContext(“2d”) 获取Canvas 2D上下文环境对象
  • toDataURL() 获取Canvas对象产生的位图的字符串,即将Canvas画布转换为图片的base64格式的字符串。
cnv.toDataURL(type);
  • type 可选,默认值为image/png类型

直接在Canvas画布上点击鼠标右键,在弹出的快捷菜单中也能“另存为”图片为本地图片,为什么还要那么麻烦地使用toDataURL()呢?

事实上,很多旧版本的浏览器并不具备这个功能。因此为了兼容性,建议使用toDataURL()方法进行处理。

  • canvas保存图片时,谷歌浏览器Chrome报错【解决方案】Not allowed to navigate top frame to data URL
    https://blog.csdn.net/weixin_41192489/article/details/124386704

图形的重叠模式

默认情况下,后绘制的图形会覆盖之前绘制的图形。

通过 globalCompositeOperation 可以修改重叠模式

cxt.globalCompositeOperation = 属性值;

不同属性值,效果如下图:

属性值

说明

source-over

默认值,新图形覆盖旧图形

copy

只显示新图形,旧图形作透明处理

darker

两种图形都显示,在重叠部分,颜色由两个图形的颜色值相减后形成

destination-atop

只显示新图形与旧图形重叠部分以及新图形的其余部分,其他部分作透明处理

destination-in

只显示旧图形中与新图形重叠部分,其他部分作透明处理

destination-out

只显示旧图形中与新图形不重叠部分,其他部分作透明处理

destination-over

与source-over属性相反,旧图形覆盖新图形

lighter

两种图形都显示,在图形重叠部分,颜色由两个图形的颜色值相加后形成

source-atop

只显示旧与新图形重叠部分及旧图形的其余部分,其他部分作透明处理

source-in

只显示新图形中与旧图形重叠部分,其他部分作透明处理

source-out

只显示新图形中与旧图形不重叠部分,其余部分作透明处理

xor

两种图形都绘制,其中重叠部分透明处理

             cxt.globalCompositeOperation = "xor";//绘制矩形cxt.fillStyle = "HotPink";cxt.fillRect(30, 30, 60, 60);//绘制圆形cxt.beginPath();cxt.arc(100, 100, 40, 0, Math.PI * 2, true);cxt.closePath();cxt.fillStyle = "LightSkyBlue";cxt.fill();

             cxt.globalCompositeOperation = "xor";//绘制第1个矩形cxt.fillStyle = "HotPink";cxt.fillRect(30, 30, 60, 60);//绘制圆形cxt.beginPath();cxt.arc(100, 100, 40, 0, Math.PI * 2, true);cxt.closePath();cxt.fillStyle = "LightSkyBlue";cxt.fill();//绘制第2个矩形cxt.fillStyle = "HotPink";cxt.fillRect(110, 30, 60, 60);

canvas系列教程04 —— 渐变、阴影、路径、状态、Canvas对象、图形重叠模式相关推荐

  1. 前端画圆弧html弧线的像素,[js高手之路] html5 canvas系列教程 - arc绘制曲线图形(曲线,弧线,圆形)...

    arc:画弧度 cxt.arc( x, y, 半径, 开始角度,结束角度,是否逆时针 ); x, y: 为弧度的中心横坐标和纵坐标,如果这是画一个圆.那么x,y就是圆的圆心. 开始角度与结束角度都是以 ...

  2. HTML弧度文本,[js高手之路] html5 canvas系列教程 - 文本样式(strokeText,fillText,measureText,textAlign,textBaseline)...

    canvas提供两种输出文本的方式: strokeText:描边文本 fillText:填充文本 fillStyle配合fillText使用,strokeStyle配合strokeText使用 str ...

  3. 【微信小程序-原生开发】实用教程20 - 生成海报(实战范例为生成活动海报,内含生成指定页面的小程序二维码,保存图片到手机,canvas 系列教程)

    可在系列教程的基础上继续开发,也可以单独使用 [微信小程序-原生开发]系列教程 效果预览 代码实现 点击触发生成海报 在活动详情页,指定点击某图标/按钮,触发跳转到生成海报的页面 pages\comp ...

  4. [js高手之路] html5 canvas系列教程 - 线条样式(lineWidth,lineCap,lineJoin,setLineDash)

    上文,写完弧度与贝塞尔曲线[js高手之路] html5 canvas系列教程 - arcTo(弧度与二次,三次贝塞尔曲线以及在线工具),本文主要是关于线条的样式设置 lineWidth: 设置线条的宽 ...

  5. [js高手之路] html5 canvas系列教程 - 掌握画直线图形的常用API

    我们接着上文[js高手之路] html5 canvas系列教程 - 认识canvas以及基本使用方法继续. 一.直线的绘制 cxt.moveTo( x1, y1 ): 将画笔移动到x1, y1这个点 ...

  6. PVE系列教程(九)、openWRT设置主路由与旁路由模式

    PVE系列教程(九).openWRT设置主路由与旁路由模式 为了更好的浏览体验,欢迎光顾勤奋的凯尔森同学个人博客http://nas.hepcloud.top:7000 Hello,小伙伴们,这是凯尔 ...

  7. State(状态)--对象行为型模式

    State(状态)–对象行为型模式 一.意图 允许一个对象在其内部状态改变时改变它的行为.对象看起来似乎修改了它的类. 二.动机 1.在软件构建过程中,某些对象的状态如果改变,其行为也会随之而发生变化 ...

  8. canvas系列教程01——直线、三角形、多边形、矩形、调色板

    绘图步骤 html中添加 canvas 标签,通常需指定 id width(默认 300px) height(默认 150px) <canvas id="canvas" wi ...

  9. canvas系列教程07 ——捕获、拖拽、抛掷、缓动动画、弹性动画

    捕获物体 多边形以及不规则图形的捕获非常复杂,采用的方法是分离轴定理(SAT)和最小平移向量(MTV).这里不展开介绍,有兴趣的小伙伴可以自行搜索了解一下.下面来介绍一下矩形和圆的捕获. 矩形的捕获 ...

最新文章

  1. 使用docker-compose进行多节点部署
  2. 如何让ie 7 支持box-shadow
  3. 一个NSObject对象占多少内存?
  4. 鼠标右键添加项目 注册表 注意
  5. 安装Oracle数据库操作步骤
  6. java enummap_Java EnumMap size()方法与示例
  7. c java http通讯,c语言经过http请求javaee项目
  8. diabetes影响因子2017_2017年SCI影响因子发布,几家欢喜几家愁
  9. 或非门sr锁存器_问:或非门构成的基本SR锁存器当SR=10时,锁存器输出什么状态?...
  10. 3.6计算机网络(网络层概述 电路交换 报文交换 分组交换)
  11. Android 更改头像(图片)并上传服务器功能Demo详解
  12. 第二届“梧桐杯”复赛开战在即,邀您观赛!
  13. Postman团队协作开发
  14. 第八十三章 Caché 函数大全 $ZDATE 函数
  15. modis 通道简介
  16. 共模电压你了解多少?陈老师带你搞清楚
  17. 由一位坛友的布局想到的定位问题:absolute和relative
  18. python函数的用法字帖_Python 3 爬虫之批量下载字帖图片
  19. 我的世界正版服务器开服,MC服务器开服方法
  20. 华为5c_华为5c参数详细参数解析 这款手机好不好【图文】

热门文章

  1. 计算机系统基础实验——拆除二进制炸弹
  2. 用于单眼深度估计的结构化注意力导向卷积神经场(论文2018)
  3. 16 .net core http请求
  4. html的圆形字体,css字体加载和圆形加载.html
  5. jdbc、jdbcTemplate、hibernate、jpa、spring之间的关系
  6. 论文清单:SIGIR 2021推荐系统相关论文分类整理
  7. 使用IPV6+DDNS连接内网主机
  8. 2020低压电工模拟考试及低压电工模拟考试题库
  9. 推荐一本Python数据分析必备工具书
  10. 开源游戏区块链项目分享:Unity开发的独立区块链