前端 | (十四)canvas基本用法 | 尚硅谷前端HTML5教程(html5入门经典)

文章目录

  • 📚canvas基本用法
    • 🐇什么是canvas(画布)
    • 🐇替换内容
    • 🐇canvas标签的两个属性
    • 🐇渲染上下文
  • 📚绘制矩形
    • 🐇绘制矩形
    • 🐇strokeRect时,边框像素渲染问题
    • 🐇添加样式和颜色
    • 🐇lineJoin
  • 📚绘制路径
    • 🐇canvas绘制路径
    • 🐇lineCap
    • 🐇save
    • 🐇restore
    • 🔥电子签名实例
  • 📚绘制曲线
    • 🐇canvas绘制圆形
    • 🐇arcTo
    • 🐇二次贝塞尔
    • 🐇三次贝塞尔
  • 📚canvas中的变换
    • 🐇translate(x, y)
    • 🐇rotate(angle)
    • 🐇scale(x, y)
    • 🔥放缩变换实例
    • 🔥画一个电子钟表
  • 📚图片
    • 🐇插入图片(需要image对象)
    • 🐇设置背景(需要image对象)
    • 🐇渐变
    • 🔥图片变动画
  • 📚文本
    • 🐇绘制文本
    • 🐇文本样式
    • 🐇阴影(文本阴影&盒模型阴影)
  • 📚像素操作
    • 🐇得到像素数据
    • 🔥马赛克实例
  • 📚合成
    • 🐇全局透明度的设置
    • 🐇合成
    • 🔥刮刮卡实例

  • 前端 | ( 十)HTML5简介及相关新增属性
  • 尚硅谷前端HTML5教程(html5入门经典)

📚canvas基本用法

🐇什么是canvas(画布)

  • <canvas> 是 HTML5 新增的元素,可用于通过使用JavaScript中的脚本来绘制图形。例如,它可以用于绘制图形,创建动画。<canvas> 最早由Apple引入WebKit。
  • 我们可以使用<canvas>标签来定义一个canvas元素
  • 使用<canvas>标签时,建议要成对出现,不要使用闭合的形式。
  • canvas元素默认具有高宽:width: 300pxheight:150px

🐇替换内容

  • <canvas>很容易定义一些替代内容。由于某些较老的浏览器(尤其是IE9之前的IE浏览器)不支持HTML元素"canvas",但在这些浏览器上你应该要给用户展示些替代内容。
  • 我们只需要在<canvas>标签中提供替换内容就可以。
  • 支持<canvas>的浏览器将会忽略在容器中包含的内容,并且只是正常渲染canvas。不支持<canvas>的浏览器会显示代替内容。
    <!-- 如果浏览器不支持​<canvas>元素,那么它会显示"您的浏览器不支持画布元素 请您换成萌萌的谷歌"。 -->
    <canvas id="test" width="300" height="300"><span>您的浏览器不支持画布元素 请您换成可爱的谷歌</span>
    </canvas>
    

🐇canvas标签的两个属性

  • <canvas> 看起来和 元素很相像,唯一的不同就是它并没有 src 和 alt 属性。
  • 实际上,<canvas> 标签只有两个属性—— width和height。这些都是可选的。
  • 当没有设置宽度和高度的时候,canvas会初始化宽度为300像素和高度为150像素。
  • 画布的高宽
    • html属性设置width height时只影响画布本身不影画布内容。
    • css属性设置width height时不但会影响画布本身的高宽,还会使画布中的内容等比例缩放(缩放参照于画布默认的尺寸)。

🐇渲染上下文

  • <canvas> 元素只是创造了一个固定大小的画布,要想在它上面去绘制内容,我们需要找到它的渲染上下文。
  • <canvas> 元素有一个叫做 getContext() 的方法,这个方法是用来获得渲染上下文和它的绘画功能。getContext()只有一个参数:上下文的格式
  • 获取方式
    var canvas = document.getElementById('box');
    var ctx = canvas.getContext('2d');
    
  • 检查支持性
    var canvas = document.getElementById('tutorial');
    if (canvas.getContext){var ctx = canvas.getContext('2d');
    } 
    

📚绘制矩形

🐇绘制矩形

  • canvas提供了三种方法绘制矩形:
    • 绘制一个填充的矩形(填充色默认为黑色):fillRect(x, y, width, height)
    • 绘制一个矩形的边框(默认边框为:一像素实心黑色):strokeRect(x, y, width, height)
    • 清除指定矩形区域,让清除部分完全透明:clearRect(x, y, width, height)
  • x与y指定了在canvas画布上所绘制的矩形的左上角(相对于原点)的坐标。
  • width和height设置矩形的尺寸(存在边框的话,边框会在width上占据一个边框的宽度,height同理)。
<!DOCTYPE html>
<html><head><meta charset="UTF-8"><title></title><style type="text/css">*{margin: 0;padding: 0;}html,body{height: 100%;overflow: hidden;}body{background: pink;}#test{background: gray;position: absolute;left: 0;top: 0;right: 0;bottom: 0;margin: auto;}</style></head><body><canvas id="test" width="300" height="300"><span>您的浏览器不支持画布元素 请您换成可爱的谷歌</span></canvas></body><script type="text/javascript">window.onload=function(){//拿到画布var canvas = document.querySelector("#test");if(canvas.getContext){var ctx = canvas.getContext("2d");//注意不加单位,填充的矩形ctx.fillRect(0,0,100,100)//带边框的矩形  ctx.strokeRect(100.5,100.5,100,100)// 清除指定矩形区域,让清除部分完全透明// ctx.clearRect(0,0,100,100)}}</script>
</html>

在这里插入图片描述

🐇strokeRect时,边框像素渲染问题

  • 按理渲染出的边框应该是1px的,canvas在渲染矩形边框时,边框宽度是平均分在偏移位置的两侧。
  • context.strokeRect(10,10,50,50):边框会渲染在10.5 和 9.5之间,浏览器是不会让一个像素只用自己的一半的,相当于边框会渲染在9到11之间。
  • context.strokeRect(10.5,10.5,50,50):边框会渲染在10到11之间。

🐇添加样式和颜色

  • fillStyle:设置图形的填充颜色。
  • strokeStyle:设置图形轮廓的颜色。
    • 默认情况下,线条和填充颜色都是黑色(CSS 颜色值 #000000)
  • lineWidth:这个属性设置当前绘线的粗细。属性值必须为正数。描述线段宽度的数字。 0、 负数、 Infinity 和 NaN 会被忽略。默认值是1.0。

🐇lineJoin

  • 设定线条与线条间接合处的样式(默认是 miter)

    • round : 圆角
    • bevel : 斜角
    • miter : 直角
    <!DOCTYPE html>
    <html><head><meta charset="UTF-8"><title></title><style type="text/css">*{margin: 0;padding: 0;}html,body{height: 100%;overflow: hidden;}body{background: pink;}#test{background: gray;position: absolute;left: 0;top: 0;right: 0;bottom: 0;margin: auto;}</style></head><body><canvas id="test" width="300" height="300"><span>您的浏览器不支持画布元素 请您换成可爱的谷歌</span></canvas></body><script type="text/javascript">window.onload=function(){//拿到画布var canvas = document.querySelector("#test");if(canvas.getContext){var ctx = canvas.getContext("2d");// 设置图形的填充颜色ctx.fillStyle="deeppink";// 设置图形轮廓的颜色ctx.strokeStyle="pink";// 当前绘线的粗细ctx.lineWidth=25;// 设定线条与线条间接合处的样式ctx.lineJoin="round";ctx.strokeRect(100,100,100,100)ctx.fillRect(0,0,100,100)//ctx.clearRect(100,100,100,100)}}</script>
    </html>
    

在这里插入图片描述


  • rect画矩形
    var canvas = document.querySelector("#test");
    if(canvas.getContext){var ctx = canvas.getContext("2d");ctx.rect(50,50,100,100);ctx.fillStyle="skyblue";ctx.strokeStyle="black";ctx.fill();ctx.stroke();
    }
    

在这里插入图片描述

📚绘制路径

🐇canvas绘制路径

图形的基本元素是路径。路径是通过不同颜色和宽度的线段或曲线相连形成的不同形状的点的集合。

  • 首先,创建路径起始点

    • beginPath():新建一条路径,生成之后,图形绘制命令被指向到路径上准备生成路径。
      • 本质上,路径是由很多子路径构成,这些子路径都是在一个列表中,所有的子路径(线、弧形、等等)构成图形。
      • 而每次这个方法调用之后,列表清空重置,然后我们就可以重新绘制新的图形。
  • 使用画图命令去画出路径

    • moveTo(x, y)
      • 将笔触移动到指定的坐标x以及y上
      • 当canvas初始化或者beginPath()调用后,你通常会使用moveTo()函数设置起点
    • lineTo(x, y)
      • 将笔触移动到指定的坐标x以及y上
      • 绘制一条从当前位置到指定x以及y位置的直线。
  • 之后你把路径封闭

    • closePath()
      • 闭合路径之后图形绘制命令又重新指向到上下文中。
      • 闭合路径closePath(),不是必需的。这个方法会通过绘制一条从当前点到开始点的直线来闭合图形。
      • 如果图形是已经闭合了的,即当前点为开始点,该函数什么也不做。当你调用fill()函数时,所有没有闭合的形状都会自动闭合,所以你不需要调用closePath()函数。但是调用stroke()时不会自动闭合。
      • stroke():通过线条来绘制图形轮廓。不会自动调用closePath()。
      • fill():通过填充路径的内容区域生成实心的图形。自动调用closePath()。
  • 一旦路径生成,你就能通过描边或填充路径区域来渲染图形。

    <!DOCTYPE html>
    <html><head><meta charset="UTF-8"><title></title><style type="text/css">*{margin: 0;padding: 0;}html,body{height: 100%;overflow: hidden;}body{background: pink;}#test{background: gray;position: absolute;left: 0;top: 0;right: 0;bottom: 0;margin: auto;}</style></head><body><canvas id="test" width="300" height="300"><span>您的浏览器不支持画布元素 请您换成可爱的谷歌</span></canvas></body><script type="text/javascript">window.onload=function(){var canvas = document.querySelector("#test");if(canvas.getContext){var ctx = canvas.getContext("2d");ctx.strokeStyle="deeppink";ctx.lineWidth=10;ctx.moveTo(100,100);ctx.lineTo(100,200);ctx.lineTo(200,200);ctx.closePath();ctx.stroke();//fill方法会自动合并路径ctx.fill();}}</script>
    </html>
    

在这里插入图片描述

🐇lineCap

  • lineCap 是 Canvas 2D API 指定如何绘制每一条线段末端的属性。有3个可能的值,分别是:
    • butt:线段末端以方形结束。
    • round:线段末端以圆形结束
    • square:线段末端以方形结束,但是增加了一个宽度和线段相同,高度是线段厚度一半的矩形区域
    • 默认值是 butt。
    var canvas = document.querySelector("#test");
    if(canvas.getContext){var ctx = canvas.getContext("2d");ctx.strokeStyle="pink";ctx.lineWidth=10;ctx.lineCap="round";	ctx.moveTo(100,100);ctx.lineTo(100,200);ctx.stroke();
    }
    

在这里插入图片描述

🐇save

  • save() 是 Canvas 2D API 通过将当前状态放入栈中,保存 canvas 全部状态的方法。保存到栈中的绘制状态有下面部分组成:
    • 当前的变换矩阵。
    • 当前的剪切区域。
    • 当前的虚线列表。
    • 以下属性当前的值: strokeStyle, fillStyle, lineWidth, lineCap, lineJoin…

🐇restore

  • restore() 是 Canvas 2D API 通过在绘图状态栈中弹出顶端的状态,将 canvas 恢复到最近的保存状态的方法。

  • 如果没有保存状态,此方法不做任何改变。

    var canvas = document.querySelector("#test");
    if(canvas.getContext){var ctx = canvas.getContext("2d");ctx.save();ctx.fillStyle="pink";ctx.save();// 没保存的不入栈ctx.fillStyle="deeppink";ctx.fillStyle="blue";ctx.save();ctx.fillStyle="red";ctx.save();ctx.fillStyle="green";ctx.save();ctx.beginPath();// 弹出,restore四个是pink,三个是blue,二个是red,一个是greenctx.restore();ctx.restore();ctx.restore();ctx.restore();ctx.fillRect(50,50,100,100);
    }
    

在这里插入图片描述


🔥电子签名实例

<!DOCTYPE html>
<html><head><meta charset="UTF-8"><title></title><style type="text/css">*{margin: 0;padding: 0;}body{background: #dbd0ff;}#test{position: absolute;left: 0;right: 0;top: 0;bottom: 0;margin: auto;background:white;}</style></head><body><canvas id="test" width="500" height="500"></canvas></body><script type="text/javascript">window.onload=function(){var canvas =document.getElementById("test");if(canvas.getContext){var ctx = canvas.getContext("2d");}// 在鼠标按下时触发事件canvas.onmousedown=function(ev){// 获取事件对象ev = ev || window.event;if(canvas.setCapture){// 设置鼠标捕获,确保鼠标事件在元素上持续触发canvas.setCapture();}ctx.beginPath();// ev.clientX表示鼠标相对于文档可视区域的水平坐标,canvas.offsetLeft表示画布相对于文档可视区域的水平偏移量ctx.moveTo(ev.clientX -canvas.offsetLeft,ev.clientY -canvas.offsetTop);document.onmousemove=function(ev){// 在整个文档区域内移动鼠标时触发事件// 保存画布当前的状态ctx.save();ctx.strokeStyle="black";ev = ev || event;// 创建从当前点到指定点的线段,即绘制直线ctx.lineTo(ev.clientX -canvas.offsetLeft,ev.clientY -canvas.offsetTop);// 绘制已定义的路径ctx.stroke();ctx.restore();}// 释放鼠标捕获document.onmouseup=function(){document.onmousemove=document.onmouseup=null;if(document.releaseCapture){document.releaseCapture();}}return false;}}</script>
</html>

在这里插入图片描述

📚绘制曲线

  • 角度与弧度的js表达式:radians=(Math.PI/180)*degrees

🐇canvas绘制圆形

  • arc(x, y, radius, startAngle, endAngle, anticlockwise)
    • 画一个以(x,y)为圆心的以radius为半径的圆弧(圆),从startAngle开始到endAngle结束,按照anticlockwise给定的方向(默认为顺时针)来生成。ture:逆时针,false:顺时针
    • x,y为绘制圆弧所在圆上的圆心坐标,radius为半径
    • startAngle以及endAngle参数用弧度定义了开始以及结束的弧度。这些都是以x轴为基准参数anticlockwise 为一个布尔值。为true时,是逆时针方向,否则顺时针方向。
    var canvas = document.querySelector("#test");
    if(canvas.getContext){var ctx = canvas.getContext("2d");ctx.beginPath();ctx.moveTo(100,100);ctx.arc(100,100,50,0,90*Math.PI/180,true);ctx.closePath();ctx.stroke();
    }
    

在这里插入图片描述

🐇arcTo

  • arcTo(x1, y1, x2, y2, radius),根据给定的控制点和半径画一段圆弧。

  • 相当于指定了起点和终点的切线(就是下边示例中,画出的直线就是在画弧线时的切线)

    var canvas = document.querySelector("#test");
    if(canvas.getContext){var ctx = canvas.getContext("2d");ctx.strokeStyle="purple";ctx.beginPath();ctx.moveTo(50,50);ctx.lineTo(300,0);ctx.lineTo(200,200);ctx.stroke();ctx.beginPath();ctx.moveTo(50,50)ctx.arcTo(300,0,200,200,50);ctx.stroke();
    }
    

在这里插入图片描述

🐇二次贝塞尔

  • quadraticCurveTo(cp1x, cp1y, x, y)
    • 绘制二次贝塞尔曲线,cp1x,cp1y为一个控制点,x,y为结束点。
    • 起始点为moveto时指定的点。
    var ctx = canvas.getContext("2d");
    ctx.strokeStyle="purple";
    ctx.beginPath();
    ctx.moveTo(50,50);
    ctx.lineTo(300,0);
    ctx.lineTo(200,200);
    ctx.stroke();ctx.beginPath();
    ctx.moveTo(50,50)
    ctx.quadraticCurveTo(300,0,200,200);
    ctx.stroke();
    

在这里插入图片描述

🐇三次贝塞尔

  • bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y)
    • 绘制三次贝塞尔曲线,cp1x,cp1y为控制点一,cp2x,cp2y为控制点二,x,y为结束点。
    • 起始点为moveto时指定的点。
    var canvas = document.querySelector("#test");
    if(canvas.getContext){var ctx = canvas.getContext("2d");ctx.beginPath();ctx.moveTo(50,50);ctx.lineTo(300,0);ctx.lineTo(0,300);ctx.lineTo(300,300);ctx.stroke();ctx.strokeStyle="purple";ctx.beginPath();ctx.moveTo(50,50)ctx.bezierCurveTo(300,0,0,300,300,300);ctx.stroke();
    }
    

在这里插入图片描述

📚canvas中的变换

🐇translate(x, y)

  • 我们先介绍 translate 方法,它用来移动 canvas的原点到一个不同的位置。
  • translate 方法接受两个参数。x 是左右偏移量,y 是上下偏移量,在 canvas中translate是累加的。
    var canvas = document.querySelector("#test");
    if(canvas.getContext){var ctx = canvas.getContext("2d");ctx.translate(100,100)ctx.beginPath();ctx.fillStyle="skyblue";ctx.fillRect(0,0,100,100);
    }
    

在这里插入图片描述

🐇rotate(angle)

  • 这个方法只接受一个参数:旋转的角度(angle),它是顺时针方向的,以弧度为单位的值。
  • 旋转的中心点始终是 canvas 的原点,如果要改变它,我们需要用到 translate 方法,在canvas中rotate是累加的。
    var canvas = document.querySelector("#test");
    if(canvas.getContext){var ctx = canvas.getContext("2d");ctx.translate(70,70)ctx.rotate(22.1*Math.PI/180)ctx.rotate(22.9*Math.PI/180)ctx.beginPath();ctx.fillStyle="skyblue";ctx.fillRect(50,50,100,100);
    }
    

在这里插入图片描述

🐇scale(x, y)

  • scale 方法接受两个参数。x,y 分别是横轴和纵轴的缩放因子,它们都必须是正值。

  • 值比 1.0 小表示缩小,比 1.0 大则表示放大,值为 1.0 时什么效果都没有。

  • 缩放一般我们用它来增减图形在 canvas 中的像素数目,对形状,位图进行缩小或者放大。

  • 在canvas中scale是累积的。

    var ctx = canvas.getContext("2d");
    ctx.fillStyle="skyblue";
    ctx.beginPath();
    ctx.fillRect(50,50,100,100);
    ctx.beginPath();
    ctx.fillStyle="green";
    ctx.scale(0.5,0.5)
    ctx.fillRect(50,50,100,100);
    ctx.beginPath();
    ctx.fillStyle="yellow";
    // 因为累加,相当于两倍
    ctx.scale(4,4)
    ctx.fillRect(50,50,100,100);
    

在这里插入图片描述

🔥放缩变换实例

<!DOCTYPE html>
<html><head><meta charset="UTF-8"><title></title><style type="text/css">*{margin: 0;padding: 0;}html,body{height: 100%;background-color: #dbdbff;overflow: hidden;}#test{background: rgba(143, 143, 253, 0.785);position: absolute;left: 0;top: 0;right: 0;bottom: 0;margin: auto;}</style></head><body><canvas id="test" width="300" height="300"><span>您的浏览器不支持画布元素 请您换成可爱的谷歌</span></canvas></body><script type="text/javascript">window.onload=function(){var angle =0;//角度var scale = 0;//比例var angleScale = 0;//状态var canvas = document.querySelector("#test");if(canvas.getContext){var ctx = canvas.getContext("2d");ctx.fillStyle="rgba(10, 10, 79, 0.785)";ctx.save();// 将坐标原点平移到150,150ctx.translate(150,150);ctx.beginPath();ctx.fillRect(-50,-50,100,100);ctx.restore();// 设定定时器函数,每隔10毫秒执行一次setInterval(function(){// 每次执行时,将旋转角度标记加1angle++;ctx.clearRect(0,0,canvas.width,canvas.height);ctx.save();ctx.translate(150,150);// 旋转ctx.rotate(angle*Math.PI/180);// 0~100之间缩放if(scale==100){angleScale=-1;}else if(scale==0){angleScale=1;}scale+=angleScale;// 缩放ctx.scale(scale/50,scale/50);ctx.beginPath();ctx.fillRect(-50,-50,100,100);ctx.restore();},10)}}</script>
</html>

在这里插入图片描述

🔥画一个电子钟表

<!DOCTYPE html>
<html><head><meta charset="UTF-8"><title></title><style type="text/css">*{margin: 0;padding: 0;}html,body{height: 100%;overflow: hidden;background: rgb(197, 197, 255);}#clock{background: rgb(167, 208, 255);position: absolute;left: 50%;top: 50%;transform: translate3d(-50%,-50%,0);}</style></head><body><canvas id="clock" width="400" height="400"></canvas></body><script type="text/javascript">window.onload=function(){var clock = document.querySelector("#clock"); if(clock.getContext){ var ctx = clock.getContext("2d"); // 定时器函数,每隔1秒执行一次setInterval(function(){ // 清除整个画布的内容ctx.clearRect(0,0,clock.width,clock.height); // 调用move函数move(); },1000);move(); // move函数,用于绘制时钟function move(){ ctx.save(); ctx.lineWidth = 8; ctx.strokeStyle = "black"; // 设置线条末端的形状为圆形ctx.lineCap = "round"; // 将坐标原点平移到(200, 200)的位置ctx.translate(200,200); // 对画布进行旋转操作,旋转的角度为-90°,即将角度转换为弧度单位,并逆时针旋转ctx.rotate(-90*Math.PI/180); ctx.beginPath(); // 外层空心圆盘ctx.save(); ctx.strokeStyle="#325FA2"; ctx.lineWidth = 14;ctx.beginPath();// 绘制一个从0°到360°的弧线,即画一个圆ctx.arc(0,0,140,0,360*Math.PI/180); ctx.stroke(); // 绘制已定义的路径ctx.restore(); // 恢复之前保存的画布状态// 时针刻度ctx.save(); // 循环绘制12个时针刻度for(var i=0;i<12;i++){ // 逆时针旋转30°,即将角度转换为弧度单位ctx.rotate(30*Math.PI/180); ctx.beginPath(); ctx.moveTo(100,0) ctx.lineTo(120,0); ctx.stroke(); }ctx.restore(); // 分针刻度ctx.save(); ctx.lineWidth=4; // 循环绘制60个分针刻度for(var i=0;i<60;i++){ // 逆时针旋转6°,即将角度转换为弧度单位ctx.rotate(6*Math.PI/180); // 如果不是整点刻度,则绘制if((i+1)%5!=0){ ctx.beginPath();ctx.moveTo(117,0) ctx.lineTo(120,0); ctx.stroke(); }}ctx.restore(); // 时针、分针、秒针、表座// 创建一个Date对象,获取当前时间var date = new Date(); // 获取当前的秒数var s = date.getSeconds(); // 获取当前的分钟数,并加上秒数的部分var m = date.getMinutes()+s/60; // 获取当前的小时数,并加上分钟数的部分var h = date.getHours()+m/60; // 如果小时数大于12,则减去12h = h>12?h-12:h; // 时针ctx.save() ctx.lineWidth=14; // 逆时针旋转小时数乘以30°,即将角度转换为弧度单位ctx.rotate(h*30*Math.PI/180) ctx.beginPath() ctx.moveTo(-20,0); ctx.lineTo(80,0);ctx.stroke(); ctx.restore() // 分针ctx.save() ctx.lineWidth=10; // 逆时针旋转分钟数乘以6°,即将角度转换为弧度单位ctx.rotate(m*6*Math.PI/180) ctx.beginPath() ctx.moveTo(-28,0); ctx.lineTo(112,0); ctx.stroke(); ctx.restore() // 秒针ctx.save() ctx.lineWidth=6; ctx.strokeStyle="#D40000"; ctx.fillStyle="#D40000"; // 逆时针旋转秒数乘以6°,即将角度转换为弧度单位ctx.rotate(s*6*Math.PI/180) ctx.beginPath(); ctx.moveTo(-30,0); ctx.lineTo(83,0); ctx.stroke(); // 表座ctx.beginPath(); ctx.arc(0,0,10,0,360*Math.PI/180); ctx.fill(); // 秒针头ctx.beginPath(); ctx.arc(96,0,10,0,360*Math.PI/180);ctx.stroke(); ctx.restore() ctx.restore(); }}
}</script>
</html>

在这里插入图片描述

📚图片

🐇插入图片(需要image对象)

  • canvas操作图片时,必须要等图片加载完才能操作
  • drawImage(image, x, y, width, height):其中 image 是 image 或者 canvas 对象,x 和 y 是其在目标 canvas 里的起始坐标。这个方法多了2个参数:width 和 height,这两个参数用来控制 当像canvas画入时应该缩放的大小
    var ctx = canvas.getContext("2d");
    var img = new Image();
    img.src="tg.png";
    img.onload=function(){draw();
    }
    function draw(){ctx.drawImage(img,0,0,img.width,img.height)
    }
    

🐇设置背景(需要image对象)

  • createPattern(image, repetition)

  • image:图像源

  • epetition:“repeat” 、“repeat-x” 、“repeat-y” 、“no-repeat”

  • 一般情况下,我们都会将createPattern返回的对象作为fillstyle的值

    var canvas = document.querySelector("#test");
    if(canvas.getContext){var ctx = canvas.getContext("2d");var img = new Image();img.src="tg.png";img.onload=function(){draw();}function draw(){var pattern = ctx.createPattern(img,"no-repeat")ctx.fillStyle=pattern;ctx.fillRect(0,0,300,300);}	}
    

🐇渐变

  • 线性渐变:createLinearGradient(x1, y1, x2, y2),表示渐变的起点 (x1,y1) 与终点 (x2,y2)
  • gradient.addColorStop(position, color)
    • gradient :createLinearGradient的返回值
    • addColorStop 方法接受 2 个参数,position 参数必须是一个 0.0 与 1.0 之间的数值,表示渐变中颜色所在的相对位置。例如,0.5 表示颜色会出现在正中间。
    • color 参数必须是一个有效的 CSS 颜色值(如 #FFF, rgba(0,0,0,1),等等)。
    var canvas = document.querySelector("#test");
    if(canvas.getContext){var ctx = canvas.getContext("2d");var gradient =  ctx.createLinearGradient(0, 0, 200, 200);gradient.addColorStop(0,"red");gradient.addColorStop(0.5,"yellow");gradient.addColorStop(0.7,"pink");gradient.addColorStop(1,"green");ctx.fillStyle=gradient;ctx.fillRect(0,0,300,300);
    }
    

在这里插入图片描述


  • 径向渐变:createRadialGradient(x1, y1, r1, x2, y2, r2)

    • 前三个参数则定义另一个以(x1,y1) 为原点,半径为 r1 的圆
    • 后三个参数则定义另一个以 (x2,y2) 为原点,半径为 r2 的圆
    var canvas = document.querySelector("#test");
    if(canvas.getContext){var ctx = canvas.getContext("2d");var gradient = ctx.createRadialGradient(150, 150, 50, 150, 150, 100)gradient.addColorStop(0,"red");gradient.addColorStop(0.5,"yellow");gradient.addColorStop(0.7,"pink");gradient.addColorStop(1,"green");ctx.fillStyle=gradient;ctx.fillRect(0,0,300,300);	
    }
    

在这里插入图片描述

🔥图片变动画

<!DOCTYPE html>
<html><head><meta charset="UTF-8"><title></title><style type="text/css">*{margin: 0;padding: 0;}html,body{height: 100%;overflow: hidden;}#test{background: white;position: absolute;left: 0;top: 0;right: 0;bottom: 0;margin: auto;}</style></head><body><canvas id="test" width="300" height="300"></canvas></body><script type="text/javascript">window.onload=function(){var canvas = document.querySelector("#test");canvas.width = document.documentElement.clientWidth;canvas.height = document.documentElement.clientHeight;if(canvas.getContext){var ctx = canvas.getContext("2d");// 用于标记当前显示的图片序号var flag = 0;// 用于控制图片在x轴的偏移量var value=0;setInterval(function(){ctx.clearRect(0,0,canvas.width,canvas.height)value+=10;flag++;if(flag==9){// 当图片序号达到9时,重新设置为1flag=1;}var img = new Image();img.src="img/q_r"+(flag)+".jpg";img.onload=function(){draw(this);}	},100)function draw(img){ctx.drawImage(img,value,0)}}}	</script>
</html>

在这里插入图片描述

📚文本

🐇绘制文本

  • canvas 提供了两种方法来渲染文本:

    • fillText(text, x, y):在指定的(x,y)位置填充指定的文本
    • strokeText(text, x, y):在指定的(x,y)位置绘制文本边框
    var canvas = document.querySelector("#test");
    if(canvas.getContext){var ctx = canvas.getContext("2d");ctx.fillStyle="skyblue"ctx.font="40px sans-serif"ctx.fillText("lalayouyi",70,150);ctx.strokeText("lalayouyi",70,150);
    }
    

在这里插入图片描述

🐇文本样式

  • font = value

    • 当前我们用来绘制文本的样式,这个字符串使用和 CSS font 属性相同的语法。
    • 默认的字体是 10px sans-serif。
    • font属性在指定时,必须要有。大小和字体 缺一不可
  • textAlign = value:文本对齐选项。可选的值包括: left, right center.

  • textBaseline = value:描述绘制文本时,当前文本基线的属性。

  • measureText() 方法返回一个 TextMetrics 对象,包含关于文本尺寸的信息(例如文本的宽度)

  • canvas中文本水平垂直居中

    var oC =document.getElementById('c1');
    var oGC = oC.getContext('2d');
    oGC.font = '60px impact';
    oGC.textAlign = 'left';
    oGC.textBaseline = 'middle'; 
    var w = oGC.measureText('lalayouyi').width;
    oGC.fillText('lalayouyi',(oC.width - w)/2 , (oC.height - 60)/2);
    

在这里插入图片描述

🐇阴影(文本阴影&盒模型阴影)

  • shadowOffsetX = float:shadowOffsetX 和 shadowOffsetY 用来设定阴影在 X 和 Y 轴的延伸距离,它们默认都为 0。
  • shadowOffsetY = float:shadowOffsetX 和 shadowOffsetY 用来设定阴影在 X 和 Y 轴的延伸距离,它们默认都为 0。
  • shadowBlur = float:shadowBlur 用于设定阴影的模糊程度,其数值并不跟像素数量挂钩,也不受变换矩阵的影响,默认为 0。
  • shadowColor = color(必需项):shadowColor 是标准的 CSS 颜色值,用于设定阴影颜色效果,默认是全透明的黑色。
    var oC =document.getElementById('c1');
    var oGC = oC.getContext('2d');
    oGC.font = '60px impact';
    oGC.textAlign = 'left';
    oGC.textBaseline = 'middle'; 
    var w = oGC.measureText('lalayouyi').width;
    //文本阴影&盒阴影
    oGC.shadowOffsetX = 20;
    oGC.shadowOffsetY = 20;
    oGC.shadowBlur = 30;
    oGC.shadowColor = "yellow";
    oGC.fillText('lalayouyi',(oC.width - w)/2 , (oC.height - 60)/2);
    

在这里插入图片描述

📚像素操作

到目前为止,我们尚未深入了解Canvas画布真实像素的原理,事实上,你可以直接通过ImageData对象操纵像素数据,直接读取或将数据数组写入该对象中。

🐇得到像素数据

  • getImageData():获得一个包含画布场景像素数据的ImageData对像,它代表了画布区域的对象数据
  • ctx.getImageData(sx, sy, sw, sh)
    • sx:将要被提取的图像数据矩形区域的左上角 x 坐标。
    • sy:将要被提取的图像数据矩形区域的左上角 y 坐标。
    • sw:将要被提取的图像数据矩形区域的宽度。
    • sh:将要被提取的图像数据矩形区域的高度。
  • ImageData对象中存储着canvas对象真实的像素数据,它包含以下几个只读属性:
    • width:图片宽度,单位是像素
    • height:图片高度,单位是像素
    • data:Uint8ClampedArray类型的一维数组

  • putImageData()方法去对场景进行像素数据的写入。
  • putImageData(myImageData, dx, dy):dx和dy参数表示你希望在场景内左上角绘制的像素数据所得到的设备坐标。
  • ctx.createImageData(width, height):创建一个ImageData对象,默认创建出来的是透明的。
    var ctx = canvas.getContext("2d");
    // 设置填充样式为"rgba(255, 192, 203,1)"
    ctx.fillStyle="rgba(255, 192, 203,1)";
    ctx.fillRect(0,0,100,100);
    // 获取矩形区域(0, 0, 100, 100)内的图像数据
    var imageData = ctx.getImageData(0,0,100,100);
    // var imageData = ctx.createImageData(100,100);
    // 透明度即为数组 ​imageData.data​中下标为4i+3的值(其中i表示像素点的索引)。
    // 将每个像素点的透明度设置为100,即不完全透明状态。
    for(var i=0;i<imageData.data.length;i++){imageData.data[4*i+3]=100;
    }
    // 重新绘制
    ctx.putImageData(imageData,0,0)
    

在这里插入图片描述

🔥马赛克实例

  • 流程

    • 创建一个Image对象,并将其src属性设置为图片路径。
    • 在图片加载完成后,设置canvas的宽度为图片宽度的两倍,高度为图片高度。调用draw函数绘制原始图片。
    • 在draw函数中
      • 首先使用ctx.drawImage方法绘制原始图片。
      • 使用ctx.getImageData方法获取原始图片的图像数据,并保存在oldImgdata变量中。
      • 使用ctx.createImageData方法创建新的图像数据,并保存在newImgdata变量中。
      • 定义size变量为5,表示每个小方块的大小为5像素。
      • 使用嵌套的循环遍历每个小方块内的像素点,随机获取小方块内某个像素点的颜色信息,并将该颜色信息应用于整个小方块内的像素。
      • 清除画布内容。
      • 使用ctx.putImageData方法将修改后的新图像数据绘制到画布上。
  • 通过获取和设置图像数据的像素颜色信息,将原始图片划分为小块,并在每个小块中随机选择一个像素点的颜色信息,并应用于整个小块内的所有像素点,从而实现像素化的效果。

    <!DOCTYPE html>
    <html><head><meta charset="UTF-8"><title></title><style type="text/css">*{margin: 0;padding: 0;}html,body{height: 100%;overflow: hidden;}#msk{position: absolute;left: 50%;top: 50%;transform: translate3d(-50%,-50%,0);}</style></head><body><canvas id="msk" ></canvas></body><script type="text/javascript">var oc = document.querySelector("#msk");if(oc.getContext){var ctx = oc.getContext("2d");var img = new Image();img.src="2.png";img.onload=function(){oc.width=img.width*2;oc.height=img.height;draw();}function draw(){ctx.drawImage(img,0,0);var oldImgdata = ctx.getImageData(0,0,img.width,img.height);var newImgdata = ctx.createImageData(img.width,img.height);// 定义每个小方块的大小为5像素var size = 5;for(var i=0;i<oldImgdata.width/size;i++){for(var j=0;j<oldImgdata.height/size;j++){// 获取当前小方块内某个像素的颜色信息var color = getPxInfo(oldImgdata,i*size+Math.floor(Math.random()*size),j*size+Math.floor(Math.random()*size));for(var a=0;a<size;a++){for(var b=0;b<size;b++){// 设置新图像数据中的像素颜色信息setPxInfo(newImgdata,i*size+a,j*size+b,color)}}}}ctx.clearRect(0,0,oc.width,oc.height);ctx.putImageData(newImgdata,0,0);}// 获取指定位置像素的颜色信息function getPxInfo(imgdata,x,y){var color = [];var data = imgdata.data;var w = imgdata.width;var h = imgdata.height;// 获取像素点的红色值color[0]=data[(y*w+x)*4];// 获取像素点的绿色值color[1]=data[(y*w+x)*4+1];// 获取像素点的蓝色值color[2]=data[(y*w+x)*4+2];// 获取像素点的透明度值color[3]=data[(y*w+x)*4+3];// 返回颜色信息数组return color;}// 设置指定位置像素的颜色信息function setPxInfo(imgdata,x,y,color){var data = imgdata.data;var w = imgdata.width;var h = imgdata.height;data[(y*w+x)*4]=color[0];data[(y*w+x)*4+1]=color[1];data[(y*w+x)*4+2]=color[2];data[(y*w+x)*4+3]=color[3];}}</script>
    </html>
    

在这里插入图片描述

📚合成

🐇全局透明度的设置

globalAlpha = value。这个属性影响到 canvas 里所有图形的透明度,有效的值范围是 0.0 (完全透明)到 1.0(完全不透明),默认是 1.0。

var ctx = canvas.getContext("2d");
ctx.fillStyle="red";
ctx.globalAlpha=.4;
ctx.fillRect(0,0,100,100);
ctx.fillRect(100,100,100,100);

在这里插入图片描述

🐇合成

globalCompositeOperation属性用于设置绘制图形时的组合操作方式。组合操作可以理解为将已有的图形和新绘制的图形进行合并或者覆盖的方式。该属性的值可以是以下几种:

  • "source-over"(默认值):新绘制的图形覆盖在已有图形之上。这是最常用的组合操作方式。

  • "source-in":新绘制的图形只显示于已有图形的重叠部分,其他部分不可见。

  • "source-out":新绘制的图形只显示于已有图形之外的部分,与已有图形重叠的部分不可见。

  • "source-atop":新绘制的图形显示于已有图形上方的重叠部分,与已有图形下方的部分不可见。

  • "destination-over":已有的图形覆盖在新绘制的图形之上。

  • "destination-in":已有的图形只显示于新绘制图形的重叠部分,其他部分不可见。

  • "destination-out":已有的图形只显示于新绘制图形之外的部分,与新绘制图形重叠的部分不可见。

  • "destination-atop":已有的图形显示于新绘制图形上方的重叠部分,与新绘制图形下方的部分不可见。

  • "lighter":将已有的图形和新绘制的图形颜色混合,得到更亮的颜色。

  • "copy":新绘制的图形完全替换已有的图形。

  • "xor":新绘制的图形与已有的图形进行异或运算,产生一种类似于橡皮擦的效果。

var ctx = canvas.getContext("2d");
ctx.fillStyle="pink";
ctx.fillRect(50,50,100,100);
// 控制新绘制的图形如何与已有的图形进行组合。
// 源图形仅会在与目标图形重叠的区域内显示,并且会覆盖目标图形,而非重叠区域将保持目标图形原有的样式。
ctx.globalCompositeOperation="destination-atop";
ctx.fillStyle="green";
ctx.fillRect(100,100,100,100);

在这里插入图片描述

🔥刮刮卡实例

<!DOCTYPE html>
<html><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width,initial-scale=1.0,user-scalable=no"></meta><title></title><style type="text/css">*{margin: 0;padding: 0;}html,body{height: 100%;overflow: hidden;}#wrap,ul,ul>li{height: 100%;}ul>li{background: url(img/b.png);background-size:100% 100% ;}canvas{position: absolute;left: 0;top: 0;transition:1s;}</style></head><body><div id="wrap"><!-- 画布 --><canvas></canvas><ul><li></li></ul></div></body><script type="text/javascript">window.onload = function() {var canvas = document.querySelector("canvas"); canvas.width = document.documentElement.clientWidth;canvas.height = document.documentElement.clientHeight;if (canvas.getContext) {var ctx = canvas.getContext("2d"); var img = new Image();img.src = "img/a.png"; img.onload = function() { draw(); }//绘制画布function draw() {// 记录透明像素点的数量var flag = 0; // 将图片绘制到画布上ctx.drawImage(img, 0, 0, canvas.width, canvas.height); // 判断是否正在绘制路径(使得刮刮乐更平滑)var isDrawing = false; var lastX = 0; // 上一个绘制点的水平坐标var lastY = 0; // 上一个绘制点的垂直坐标canvas.addEventListener("mousedown", startDrawing); canvas.addEventListener("mousemove", drawPath); canvas.addEventListener("mouseup", stopDrawing); /*** 开始绘制路径* @param {MouseEvent} ev 鼠标按下事件*/function startDrawing(ev) {isDrawing = true; // 获取当前鼠标位置的水平坐标var x = ev.clientX - canvas.offsetLeft; // 获取当前鼠标位置的垂直坐标var y = ev.clientY - canvas.offsetTop; // 记录起始坐标[lastX, lastY] = [x, y]; }/*** 绘制路径* @param {MouseEvent} ev 鼠标移动事件*/function drawPath(ev) {if (!isDrawing) return; var x = ev.clientX - canvas.offsetLeft; var y = ev.clientY - canvas.offsetTop; // 设置绘制模式为“目标图像透明部分显示出来”ctx.globalCompositeOperation = "destination-out";ctx.lineWidth = 40; ctx.lineCap = "round"; ctx.lineJoin = "round"; ctx.save(); ctx.beginPath(); ctx.moveTo(lastX, lastY); ctx.lineTo(x, y); ctx.stroke(); ctx.restore(); [lastX, lastY] = [x, y]; }/*** 停止绘制路径*/function stopDrawing() {isDrawing = false; var imgData = ctx.getImageData(0, 0, canvas.width, canvas.height);// 计算像素总数var allPx = imgData.width * imgData.height; for (var i = 0; i < allPx; i++) {// 判断像素是否透明if (imgData.data[4 * i + 3] === 0) { flag++; }}// 如果透明像素点数量超过一半,则将画布透明度设置为0(就认为已经刮得差不多if (flag >= allPx / 2) { canvas.style.opacity = 0;}}// 监听CSS过渡效果结束事件canvas.addEventListener("transitionend", function() { this.remove(); // 移除画布元素})}}}</script>
</html>

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/132298.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

公开IP属地信息如何保护用户的隐私?

公开IP属地信息通常涉及与用户或组织的隐私有关&#xff0c;因此在公开此类信息时需要非常小心&#xff0c;以避免侵犯他人的隐私权。以下是触碰底线的几种情况以及如何保护网络安全和用户隐私&#xff1a; 个人隐私保护&#xff1a; 公开IP属地信息可能泄露用户的物理位置&…

最新版一媒体7.3、星媒体、皮皮剪辑,视频MD ,安卓手机剪辑去重神器+搬运脚本+去视频重软件工具

最新版一媒体app安卓版介绍&#xff1a; 这是一款功能强大的视频搬运工具&#xff0c;内置海量视频编辑工具&#xff0c;支持一键智能化处理、混剪、搬运、还能快速解析和去水印等等&#xff0c;超多实用功能等着您来体验&#xff01; 老牌手机剪辑去重神器&#xff0c;用过的…

uniapp 编译到模拟器(mumu)

一开始我是用逍遥模拟器&#xff0c;但这个玩意突然不好使了&#xff0c;一直加载卡在这页面 1、下载 官网下载&#xff1a;mumu模拟器12 2、打开mumu多开器&#xff0c;在右上角adb查看端口号 3、打开mumu模拟器 4、打开HBuiderX 工具—设置—运行配置 5、配置电脑的系统…

了解web3,什么是web3

Web3是指下一代互联网&#xff0c;它基于区块链技术&#xff0c;将各种在线活动更加安全、透明和去中心化。Web3是一个广义的概念&#xff0c;它包括了很多方面&#xff0c;如数字货币、去中心化应用、智能合约等等。听不懂且大多数人听到这个东西&#xff0c;直觉感觉就像骗子…

Python新手必读:容器类型使用的实用小贴士

更多资料获取 &#x1f4da; 个人网站&#xff1a;涛哥聊Python Python提供了多种容器类型&#xff0c;如列表&#xff08;List&#xff09;、元组&#xff08;Tuple&#xff09;、集合&#xff08;Set&#xff09;、字典&#xff08;Dictionary&#xff09;等&#xff0c;用于…

linux查看文件夹使用情况以及查看文件大小

查看文件夹的使用情况&#xff0c;包含已用和可用空间大小 df -h 文件夹路径然后再查看里面某一个文件夹占用大小 du -sh /data1、ls ls 命令是 Linux 中最常用的文件和目录列表命令之一。它可以显示文件的各种属性&#xff0c;包括文件大小。 ls -l <文件名>上述命令…

mybatis在springboot当中的使用

1.当使用Mybatis实现数据访问时&#xff0c;主要&#xff1a; - 编写数据访问的抽象方法 - 配置抽象方法对应的SQL语句 关于抽象方法&#xff1a; - 必须定义在某个接口中&#xff0c;这样的接口通常使用Mapper作为名称的后缀&#xff0c;例如AdminMapper - Mybatis框架底…

AI:57-基于机器学习的番茄叶部病害图像识别

🚀 本文选自专栏:AI领域专栏 从基础到实践,深入了解算法、案例和最新趋势。无论你是初学者还是经验丰富的数据科学家,通过案例和项目实践,掌握核心概念和实用技能。每篇案例都包含代码实例,详细讲解供大家学习。 📌📌📌在这个漫长的过程,中途遇到了不少问题,但是…

基于Pytorch框架的LSTM算法(一)——单维度单步滚动预测(2)

#项目说明&#xff1a; 说明&#xff1a;1time_steps滚动预测代码 y_norm scaler.fit_transform(y.reshape(-1, 1)) y_norm torch.FloatTensor(y_norm).view(-1)# 重新预测 window_size 12 future 12 L len(y)首先对模型进行训练&#xff1b; 然后选择所有数据的后wind…

汇编-字符串

字符串常量是用单引号或双引号括起来的一个字符序列 当以下面例子中的方式使用时&#xff0c;嵌入引号也是允许的&#xff1a; 正如字符常量以整数形式存放一样&#xff0c;字符串常量在内存中的存储形式为整数字节值的序列。例如&#xff0c; 字符串字面量“ABCD”包含四个字…

【代码】【5 二叉树】d3

关键字&#xff1a; 非叶子结点数、k层叶子结点数、层次遍历、找双亲结点、找度为1、叶子结点数

Eolink Apikit 版本更新:「数据字典」功能上线、支持 MongoDB 数据库操作、金融行业私有化协议、GitLab 生成 API 文档...

&#x1f389; 新增 搭建自定义接口协议架构&#xff0c;支持快速适配金融行业各类型私有协议的导入、编辑和展示。 数据字典功能上线&#xff0c;支持以数据字典的形式管理参数枚举值&#xff1b; 数据库连接支持 MongoDB 数据库操作&#xff1b; 基于 Apikit 类型导入 API…

如何设置没有采购申请不允许创建采购订单(TCODE:OMET)<转载>

原文链接 &#xff1a; https://mp.weixin.qq.com/s/0kcj9JWltlZoYhmzlwvT5g 在SAP/ERP项目实施中可能经常会遇到这样的业务需求&#xff0c;在系统中创建采购订单PO必须要有采购申请PR&#xff0c;否则不允许创建采购订单&#xff0c;通常这样业务需求一般通过采购订单增强去实…

携程AI布局:三重创新引领旅游行业智能化升级

2023年10月24日&#xff0c;携程全球合作伙伴峰会在新加坡召开&#xff0c;携程集团联合创始人、董事局主席梁建章做了名为《旅游业是独一无二的最好的行业》的演讲&#xff0c;梁建章在演讲中宣布了携程生成式 AI、内容榜单、ESG 低碳酒店标准三重创新的战略方向。这些创新将为…

206.反转链表

206.反转链表 力扣题目链接(opens new window) 题意&#xff1a;反转一个单链表。 示例: 输入: 1->2->3->4->5->NULL 输出: 5->4->3->2->1->NULL 双双指针法&#xff1a; 创建三个节点 pre(反转时的第一个节点)、cur(当前指向需要反转的节点…

利用shp文件构建mask【MATLAB和ARCGIS】两种方法

1 ARCGIS &#xff08;推荐&#xff01;&#xff01;&#xff01;-速度很快&#xff09; 利用Polygon to Raster 注意&#xff1a;由于我们想要的mask有效值是1&#xff0c;在进行转换的时候&#xff0c;注意设置转换字段【Value field】 【Value field】通过编辑shp文件属性表…

【CIO人物展】国家能源集团信息技术主管王爱军:中国企业数智化转型升级的内在驱动力...

王爱军 本文由国家能源集团信息技术主管王爱军投递并参与《2023中国数智化转型升级优秀CIO》榜单/奖项评选。丨推荐企业—锐捷网络 大数据产业创新服务媒体 ——聚焦数据 改变商业 随着全球信息化和网络化的进程日益加速&#xff0c;数字化转型已经成为当下各大企业追求的核心…

前端数据加解密:保护敏感信息的关键

前言 如今&#xff0c;数据安全和隐私保护变得至关重要。本文旨在引领大家探索前端数据加密与解密的基本概念&#xff0c;并介绍常用的加密算法&#xff0c;让大家深入了解数据加解密的世界&#xff0c;探究其背后的原理、最佳实践和常见应用场景。 前端主流加密方式 对称加密 …

企业通配符SSL证书的特点

企业通配符SSL证书是一种数字证书&#xff0c;其可以用于保护多个企业网站&#xff0c;对网站传输信息进行加密服务。这种证书通常适用于拥有多个子域名或二级域名的企事业单位。今天就随SSL盾小编了解企业通配符SSL证书的相关信息。 1. 保护所有域名和子域名&#xff1a;企业通…

Verilog刷题[hdlbits] :Alwaysblock2

题目&#xff1a;Alwaysblock2 For hardware synthesis, there are two types of always blocks that are relevant: 对于硬件综合&#xff0c;有两种相关的always块&#xff1a; Combinational: always () 组合型&#xff1a;always ()Clocked: always (posedge clk) 时钟型…