canvas入门详细教程(W3C)

文章目录

  • 一、线形
    • 1、画线形之前,最基本的方法需要知道:
    • 2、线形的样式设置:
    • 3、不同的线形路径给不同的样式设置-需要知道俩个方法:
    • 4、画线形三角
    • 5、画贝塞尔曲线
    • 6、画虚线
  • 二、画矩形
    • 1、绘制空心矩形有三种方法
    • 2、绘制填充矩形有俩种方法:
  • 三、画圆弧⌒⚪
    • 1、画圆弧一般有两种方式
    • 2、画椭圆
  • 四、绘制文本
    • 1、strokeText(), fillStroke()绘制文本
    • 2、文本样式
  • 五、样式补充
    • 1、线性渐变色
    • 2、径向渐变
    • 3、阴影样式
    • 4、添加指定元素
  • 六、绘制图片
    • 1、使用drawImage()方法绘制图片
    • 2、绘制图片的合成、保存和还原绘画状态、变形、裁剪


详细介绍画布canvas的属性及方法,和矩形,路径,转化,文本,图像绘制等多个模块的使用。并附上代码示例+代码注解。
使用画布canvas之前,必做的三步:
①首先要有一用来画画的纸:

// 创建canvas标签:
<canvas id="canvas" height="400" width="400" style="box-shadow: 0 0 7px 0 #888888"></canvas>

②找到这张纸:

// 我们现在要使用JS获得这个canvas标签的DOM对象:
<script>const canvas = document.getElementById('canvas')
</script>

③决定是画二维还是三维的画:

// 通过getContext()方法来获得渲染上下文和它的绘画功能:
<script>const ctx = canvas.getContext('2d') // 这里我们先聚焦于2D图形
</script>

一、线形

1、画线形之前,最基本的方法需要知道:

moveTo(x,y):路径绘制命令的起点
lineTo(x,y):路径绘制转折点
stroke():绘制路径

const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');
// 第一条线性
ctx.moveTo(0,0); 	// 路径绘制命令的起点
ctx.lineTo(350,50); // 路径绘制转折点
ctx.stroke();  		// 绘制路径
// 第二条线形
ctx.moveTo(0,200);  
ctx.lineTo(50,200); 
ctx.lineTo(50,150);
ctx.lineTo(100,150);
ctx.lineTo(100,200);
ctx.lineTo(150,200);
ctx.lineTo(150,150);
ctx.lineTo(200,150);
ctx.stroke();

绘制结果如图:
canvas1

2、线形的样式设置:

strokeStyle = '颜色':设置线的颜色;
lineWidth = 数字:设置线的宽度;
lineCap = 'round/butt/square':设置线帽为圆型/默认/方形;
lineJoin = 'miter/round/bevel':设置线段连接处为默认/圆形/平直形式;
globalAlpha = 数字:设置图案的透明度
需要注意的是:这些样式设置,必须在ctx.stroke()之前给。因为ctx.stroke()是绘制图形轮廓,图形轮廓都已经画出来了,在它之后给是不生效的。

ctx.moveTo(0,200);  
ctx.lineTo(50,200); 
ctx.lineTo(50,150);
ctx.lineTo(100,150);
ctx.lineTo(100,200);
ctx.lineTo(150,200);
ctx.lineTo(150,150);
ctx.lineTo(200,150);
ctx.strokeStyle = 'red'; // 线形颜色
ctx.lineWidth = 6; // 线宽
ctx.globalAlpha = 0.5; // 透明度
ctx.lineCap = 'round'; // 线形末端样式圆型
ctx.lineJoin = 'round'; // 线形连接样式圆型
ctx.stroke();

线段样式效果如图:
canvas2

3、不同的线形路径给不同的样式设置-需要知道俩个方法:

beginPath():开启一条新路径,生成之后,图形绘制命令会被指向到新路径上;
closePath():关闭路径,生成闭合路径之后,图形绘制命令又重新指向到上下文中;

// 第一条
ctx.beginPath(); // 开启一条新路径
ctx.moveTo(0,0);
ctx.lineTo(350,50);
ctx.lineWidth = 1;
ctx.strokeStyle = 'blue';
ctx.lineCap = 'butt';
ctx.stroke();
ctx.closePath(); // 关闭路径
// 第二条
ctx.beginPath(); // 开启一条新路径
ctx.moveTo(0,200);
ctx.lineTo(50,200);
ctx.lineTo(50,150);
ctx.lineTo(100,150);
ctx.lineTo(100,200);
ctx.lineTo(150,200);
ctx.lineTo(150,150);
ctx.lineTo(200,150);
ctx.lineWidth = 5;
ctx.strokeStyle = 'red';
ctx.lineCap = 'round';
ctx.stroke();
ctx.closePath(); // 关闭路径

使用了beginPath、closePath 和 未使用的效果:
eg:在第二个效果图中,没有开辟新路径,导致第二条线形效果覆盖了第一条的样式效果。
canvas3

4、画线形三角

画线形三角也是用画线的思路,需要注意首尾点连接起来即可:

ctx.beginPath();
ctx.moveTo(60,60);
ctx.lineTo(150,60);
ctx.lineTo(150,150);
ctx.lineTo(60,60);
ctx.stroke();
ctx.closePath();

绘制效果如图:
canvas4
如果要添加样式也是一样的:

// 画三角                           // 闭合处显示的更衔接一点
ctx.beginPath();                    ctx.beginPath();
ctx.moveTo(60,60);                  ctx.moveTo(60,60);
ctx.lineTo(150,60);                 ctx.lineTo(150,60);    
ctx.lineTo(150,150);                ctx.lineTo(150,150);    
ctx.lineTo(60,60);                  ctx.lineTo(60,60);
ctx.lineWidth = 5;                  ctx.closePath();
ctx.strokeStyle = 'red'             ctx.lineWidth = 5;
ctx.stroke();                       ctx.strokeStyle = 'red';        
ctx.closePath();                    ctx.stroke(); 

绘制效果:
canvas5

5、画贝塞尔曲线

推荐一个在线调试二次贝塞尔曲线的小工具:在线调试工具
1、quadraticCurveTo(cpx,cpy,x,y)方法来绘制二次贝塞尔曲线:
cpx,cpy:控制点坐标
x,y:结束点坐标
在它之前有一个开始点坐标,一般由moveTo()或lineTo()方法提供。

ctx.beginPath();
ctx.moveTo(100,150);
ctx.quadraticCurveTo(250, 10, 300, 100); // 控制点(250,10)结束点(300, 100)
ctx.stroke();
ctx.closePath();

canvas10
2、bezierCurveTo(cpx1,cpy1,cpx2,cpy2,x,y)来绘制三次贝塞尔曲线:
cpx1,cpy1:第一个控制点坐标
cpx2,cpy2:第二个控制点坐标
x,y:结束点坐标

// 三次贝塞尔曲线
ctx.beginPath();
ctx.moveTo(100,150);
ctx.bezierCurveTo(200,10, 275,250, 380,150); //控制点1(200,10)控制点2(275,250)结束点(300,100)
ctx.stroke();
ctx.closePath();
// 辅助线
ctx.beginPath();
ctx.moveTo(100, 150);
ctx.lineTo(200, 10);
ctx.lineTo(275, 250);
ctx.lineTo(380, 150);
ctx.strokeStyle = 'red';
ctx.stroke();
ctx.closePath();

canvas11

6、画虚线

setLineDash([])方法来绘制虚线,可以接收若干个参数。
数组参数会“铺开”,下标为偶数的项为实线,为奇数项为透明线段,数字的大小代表着线段的长度。
getLineDash()方法可以获得当前虚线设置的样式。如下面虚线样式,得到的结果是[10,5]

ctx.beginPath();
ctx.moveTo(100, 150);
ctx.lineTo(200, 10);
ctx.lineTo(275, 250);
ctx.lineTo(380, 150);
ctx.strokeStyle = 'red';
ctx.setLineDash([10, 5])
ctx.stroke();
ctx.closePath();

canvas12

二、画矩形

1、绘制空心矩形有三种方法

第一种跟绘制三角形思路是一样的;第二种是strokeRect方法绘制;第三种是stroke()和rect()方法。
下面看一下三种方式绘制的空心矩形:

// 绘制三角思路绘制矩形        // strokeRect(x,y,width,height)     // stroke()和rect()     
ctx.beginPath();             ctx1.beginPath();                   ctx2.beginPath();        
ctx.moveTo(50,50);           ctx1.strokeRect(50,50,100,100)      ctx2.rect(50,50,100,100);     
ctx.lineTo(150,50);          ctx1.closePath();                   setTimeout(() => {        
ctx.lineTo(150,150);                                                ctx2.stroke();        
ctx.lineTo(150,150);                                             }, 2000);           
ctx.lineTo(50,150);                                              ctx2.closePath();          
ctx.lineTo(50,50);            									
ctx.stroke();           
ctx.stroke();          
ctx.closePath();    

rect()暂时生成了矩形,但必须调用stroke()方法才会绘制出来
三种方式绘制效果如图:
canvas6

2、绘制填充矩形有俩种方法:

第一种是fillRect()和fillStyle()方法;第二种是rect()和fill()方法。
下面看一下两种方式绘制的空心矩形:

// fillRect()和fillStyle()填充矩形   // rect()和fill()填充矩形
ctx.beginPath();                    ctx1.beginPath();
ctx.fillStyle = 'skyblue';          ctx1.rect(50, 50, 100, 100);
ctx.fillRect(50, 50, 100, 100);     setTimeout(() => {
ctx.closePath();                        ctx1.fill();}, 2000);                              ctx1.closePath();

fillStyle()填充颜色一定要写在生成矩形fillRect()之前,否则颜色不生效
fill()方法和stroke()方法都是用来绘制出来形状,只不过前者是填充绘制,后者是用线轮廓。
两种方式绘制效果如图:
canvas7

三、画圆弧⌒⚪

1、画圆弧一般有两种方式

第一种:
arc(x, y, radius, startAngle, endAngle, anticlockwise)方法生成⚪⌒,然后stroke()方法绘制。
x,y:圆形坐标
radius:半径
startAngle:初始角度
endAngle:结束角度
anticlockwise:false顺时针或true逆时针(默认为false)
第二种:
先是一般由moveTo()或lineTo()方法提供起始点,然后arcTo(x1,y1,x2,y2,radius)方法来绘制圆弧。
x1,y1:两切线交点坐标
x2,y2:结束点坐标
radius:半径

// 1、arc()绘制圆
ctx.beginPath();
ctx.arc(100, 100, 50, 0, [(Math.PI) / 180] * 360); // (Math.PI) / 180 = 1°
ctx.stroke(); // 如果此处改为使用fill()方法,那么将会绘制出填充的圆
ctx.closePath();
// 2、arc()绘制圆弧
ctx1.beginPath();
ctx1.arc(100, 100, 50, 0, [(Math.PI) / 180] * 90); // (Math.PI) / 180 = 1°
ctx1.stroke();
ctx1.closePath();
// 3、arcTo()绘制圆弧
ctx2.beginPath();
ctx2.moveTo(100, 100); // 定义线段的起点
ctx2.arcTo(150, 50, 200, 200, 45); // 切线交点坐标为(150,50),结束点为(200,200)
ctx2.lineWidth = 1;
ctx2.stroke();
ctx2.closePath();
// 辅助线
ctx2.beginPath();
ctx2.moveTo(100, 100);
ctx2.lineTo(150, 50);
ctx2.lineTo(200, 200);
ctx2.strokeStyle = 'red';
ctx2.stroke();
ctx2.closePath();

注意事项:

  1. arcTo()方法是用“开始点”、“控制点”和“结束点”三点所形成夹角,绘制与夹角的两边相切且半径为radius的圆弧。控制点:夹角俩边相交点。
  2. 弧线的起点是“开始点所在边与圆的切点”,而弧线的终点是“结束点所在边与圆的切点”。
  3. arcTo()方法绘制的弧线是两个切点之间长度最短的那个圆弧。
  4. 如果开始点不是弧线起点,arcTo()方法还将添加一条当前端点到弧线起点的直线线段。也就是说,开始点坐标不一定是弧线起点坐标。通俗点讲就是:开始点到弧线起点会有一段直线线段。

两种方式绘制结果:
canvas8

2、画椭圆

用ellipse(x,y,radiusX,radiusY,rotation,startAngle,endAngle,anticlockwise)方法来绘制椭圆。
x,y:圆心坐标
radiusX:x轴半径
radiusY:y轴半径
rotation:椭圆旋转角度
startAngle:开始绘制点
endAngle:结束绘制点
anticlockwise:false顺时针或true逆时针(默认false)

// 椭圆
ctx.beginPath();
// 旋转角度[(Math.PI)/180]*60	起点[(Math.PI)/180]*0   终点[(Math.PI)/180]*360
ctx.ellipse(100,100,50,100, [(Math.PI)/180]*60, [(Math.PI)/180]*0, [(Math.PI)/180]*360);
ctx.stroke();
ctx.closePath();// 给椭圆填充色stroke()换成fill()
// ctx.fillStyle = 'skyblue'
// ctx.fill()

canvas9

四、绘制文本

1、strokeText(), fillStroke()绘制文本

使用strokeText(text,x,y,maxWidth)方法绘制描边文本。
使用fillStroke(text,x,y,maxWidth)方法绘制填充文本。
text:需要绘制的文本
x,y:文本左下角起始坐标
maxWidth:文本最大宽度

// 绘制描边文本									// 绘制填充文本
ctx.beginPath();								ctx1.beginPath();
ctx.font = '50px Verdana';						ctx1.font = '50px Verdana';
ctx.strokeText('Hello Canvas!', 30, 180, 400);	ctx1.fillText('Hello Canvas!', 30, 180, 400);
ctx.closePath();								ctx1.closePath();
ctx.beginPath();
ctx.font = '20px Verdana';
ctx.strokeText('Helvas!', 30, 280, 400);
ctx.closePath();

canvas13

2、文本样式

.font设置文本大小和字体。
.textAlign设置水平对齐方式,值可选left/right/center/start/end。对齐方式以strokeText()方法中坐标参数为参考。

// 绘制水平居中描边文本
ctx.beginPath();
ctx.font = '50px Verdana';
ctx.textAlign = 'center';
ctx.strokeText('Hello Canvas!', 200, 200, 400);
ctx.closePath();
// 辅助线
ctx.beginPath();
ctx.moveTo(200,0);
ctx.lineTo(200, 400);
ctx.setLineDash([10, 5])
ctx.stroke();
ctx.closePath();
ctx.beginPath();
ctx.moveTo(0,200);
ctx.lineTo(400, 200);
ctx.setLineDash([10, 5])
ctx.stroke();
ctx.closePath();

strokeText()绘制文本的坐标在画布的中心点(200,200),textAlign = center居中对齐则是以中心点为参考水平对齐。
canvas14
.textBaseline设置垂直对齐方式,值可选alphabetic/top/hanging/middle/ideographic/bottom
.direction:设置文本绘制方向,值可选ltr(left to right)和rtl(right to left)。

// 水平左对齐,垂直上对齐
ctx.beginPath();
ctx.font = '20px Verdana';
ctx.textAlign = 'left';
ctx.textBaseline = 'top';
ctx.strokeText('Hello!', 0, 200, 400);
ctx.closePath();
// 水平居中,垂直居中
ctx.beginPath();
ctx.font = '20px Verdana';
ctx.textAlign = 'center';
ctx.textBaseline = 'middle';
ctx.strokeText('Hello Canvas!', 200, 200, 400);
ctx.closePath();
// 水平右对齐,垂直下对齐 + 文本绘制方向rtl`(right to left)
ctx.beginPath();
ctx.font = '20px Verdana';
ctx.textAlign = 'right';
ctx.textBaseline = 'bottom';
ctx.direction = 'rtl';
ctx.strokeText('Canvas!', 400, 200, 400);
ctx.closePath();

canvas16
measureText(text)方法测量文本的宽度。
text:测量的文本
注意:不是必须显示出文本来才能计算文本的长度,测量结果也不受文本的最大宽度等外界因素的影响,文本长度的测量结果只和文本的font参数相关。

五、样式补充

1、线性渐变色

使用createLinearGradient(x1,y1,x2,y2)来创建线性渐变色。
x1,y1:渐变色起点坐标
x2,y2:终点坐标
使用addColorStop(offset,color)添加渐变色。
offset:偏移值
color:渐变色

// 横向线性渐变色
ctx.beginPath();
const gradient = ctx.createLinearGradient(0,0,400,0);
gradient.addColorStop(0, 'skyblue');
gradient.addColorStop(1, '#fffc96');
ctx.fillStyle = gradient;
ctx.fillRect(0, 0, 400, 400)
ctx.closePath();

线形渐变步骤就是:先是使用createLinearGradient创建一个线性渐变对象;然后使用addColorStop添加颜色;然后使用fillStyle设置填充颜色(就是线形渐变对象);最后使用fillRect填充。
canvas7

2、径向渐变

使用createRadialGradient(x1,y1,r1,x2,y2,r2)方法来创建渐径向渐变色。
x1,y1:开始圆的圆心坐标
r1:开始圆的半径
x2,y2:结束圆的圆心坐标
r2:结束圆的半径

// 径向渐变
ctx.beginPath();
const gradient = ctx.createRadialGradient(200,200, 100, 200, 200, 200);
gradient.addColorStop(0, 'skyblue');
gradient.addColorStop(1, '#fffc96');
ctx.fillStyle = gradient;
ctx.fillRect(0, 0, 400, 400);
ctx.closePath();

径向渐变步骤就是:同线形渐变是一样的。先是使用createRadialGradient创建一个径向渐变对象;然后使用addColorStop添加颜色;然后使用fillStyle设置填充颜色(就是径向渐变对象);最后使用fillRect填充。
canvas18

3、阴影样式

shadowOffsetX = 数字:设置阴影在X轴上的延申距离,正值表示阴影向x轴正方向延申,负值表示阴影向x轴负方向延申。
shadowOffsetY = 数字:设置阴影在Y轴上的延申距离,正值表示阴影向y轴正方向延申,负值表示阴影向y轴负方向延申。
shadowBlur = 数字:设定阴影的模糊度,默认为0。
shadowColor = '颜色':设置阴影的颜色,默认是全透明色。

// 绘制带阴影的线段:
ctx.moveTo(50, 50)
ctx.lineTo(100, 50)
ctx.shadowOffsetX = 10 // 向x轴正方向平移10像素
ctx.shadowOffsetY = 10 // 向y轴正方向平移10像素
ctx.shadowColor = '#ccc' // 设置阴影颜色
ctx.shadowBlur = 3 // 设置阴影模糊度
ctx.lineWidth = 6
ctx.stroke()
// 绘制带阴影的文本:
ctx.lineWidth = 1
ctx.font = '30px Verdana'
ctx.textAlign = 'center'
ctx.textBaseline = 'middle'
ctx.strokeText('Hello Canvas!', 200, 200, 400)

效果:
canvas20

4、添加指定元素

使用createPattern(pattern,type)方法添加指定元素。
pattern:要添加的元素,可以是图片,视频,canvas对象
type:绘制类型,可选repeat/no-repeat/repeat-x(沿x轴平铺)/repeat-y(沿y轴平铺)

// 添加图片
const img = new Image();
img.src = "https://phper-1234567890.cos.ap-guangzhou.myqcloud.com/logoCopy.png";
img.onload = function () {const ptrn = ctx.createPattern(img, 'repeat');ctx.fillStyle = ptrn;ctx.fillRect(0, 0, 400, 400);
};

填充结果:
canvas9

六、绘制图片

1、使用drawImage()方法绘制图片

drawImage(img,x,y,width,height,sx,sy,swidth,sheight)可以接收3-9个参数进行拉伸、裁剪等。
img:需要绘制的图片(必填参数)
x,y:绘制的坐标(必填参数)
width,height:图片拉伸宽度、高度
sx,sy:开始裁切的位置
swidth,sheight:要裁切图像的宽高

// 1、绘制基础图片
var img = new Image();
img.src = 'https://phperzlz-1234567890.cos.ap-guangzhou.myqcloud.com/apply/logo2.png';
img.onload = function () {ctx.drawImage(img, 0, 0); // 在(0,0)处绘制原图
};
// 2、绘制拉伸图片
var img = new Image();
img.src = 'https://phperzlz-1234567890.cos.ap-guangzhou.myqcloud.com/apply/logo2.png';
img.onload = function () {ctx.drawImage(img, 0, 0, 400, 400); // 在(0,0)处绘制原图,拉伸至(400, 400)的图片
};
///3、绘制裁切拉伸图片
var img = new Image();
img.src = 'https://phperzlz-1234567890.cos.ap-guangzhou.myqcloud.com/apply/logo2.png';
img.onload = function () {// 在(50,50)处裁切,裁切成(100,100)的图片;在(0,0)处绘制原图,拉伸至(400, 400)的图片ctx.drawImage(img, 50, 50, 200, 200,0, 0, 400, 400); 
};
// 4、通过拿到image的DOM元素,来绘制图片
const img = document.getElementById('img');
img.onload = function () {ctx.drawImage(img,0, 0); // 在(0,0)处绘制原图
};

注意:先是裁切参数后绘制参数
效果:
canvas21
绘制图片除了通过new Image对象来绘制,还可以通过DOM来绘制图片,效果是一样的:
canvas22

2、绘制图片的合成、保存和还原绘画状态、变形、裁剪

合成:在绘制多个图案的时候,就需要考虑先后显示问题。通过globalCompositeOperation来控制谁覆盖谁,值可选:
source-over:在已有图像之上绘制新图像(默认值)
source-in:只会展示新图像与已有图像重叠的部分
source-out:在已有图像之外显示新图像,只有已有图像之外的新图像部分显示,已有图像是透明的
source-atop:在已有图像顶部显示新绘制的图像。已有图像位于新绘制图像之外的部分是不可见的
destination-over:与source-over相反,在已有图像之后绘制新图像
destination-in:与source-in相反,显示的是最开始的已有图像
destination-out:在新绘制图像之外显示已有图像。只有新图像之外的已有图像部分显示,新绘制图像是透明的
destination-atop:在新绘制图像顶部显示已有图像。已有图像位于新绘制图像之外的部分是不可见的
lighter:折叠图像的颜色是有颜色值相加得来的
xor:两个图像重叠部分变为透明的

// 1、source-over
ctx.arc(350, 200, 200, 0, [(Math.PI) / 180] * 360)
ctx.fillStyle = 'skyblue'
ctx.globalCompositeOperation = 'source-over'
ctx.fill()
ctx.beginPath()
ctx.arc(200, 400, 200, 0, [(Math.PI) / 180] * 360)
ctx.fillStyle = '#fffc96'
ctx.globalCompositeOperation = 'source-over'
ctx.fill()
ctx.closePath();
// 2、xor
ctx.arc(350, 200, 200, 0, [(Math.PI) / 180] * 360)
ctx.fillStyle = 'skyblue'
ctx.globalCompositeOperation = 'source-over'
ctx.fill()
ctx.beginPath()
ctx.arc(200, 400, 200, 0, [(Math.PI) / 180] * 360)
ctx.fillStyle = '#fffc96'
ctx.globalCompositeOperation = 'xor'
ctx.fill()

canvas23


更多详细内容:
https://blog.csdn.net/nvgis/article/details/127316552

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

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

相关文章

C++——布隆过滤器

目录 布隆过滤器的提出 布隆过滤器的概念 布隆过滤器的基本原理和特点 布隆过滤器的实现 布隆过滤器的插入 布隆过滤器的查找 布隆过滤器的删除 布隆过滤器的优点 布隆过滤器的缺陷 布隆过滤器使用场景 布隆过滤器的提出 在注册账号设置昵称的时候&#xff0c;为了保证…

PUBG绝地求生·阿童木透视自瞄免费辅助 v6.24

在享受电子游戏的精彩世界时&#xff0c;家庭用户的数据安全和系统稳定性是不容忽视的重要方面。为了确保在使用游戏辅助工具时既能获得愉悦的游戏体验&#xff0c;又能保障个人数据和系统的安全&#xff0c;这里有一些建议和操作指南需要大家注意。 对于家庭用户而言&#x…

Java HashMap 简介

HashMap 简介 HashMap 主要用来存放键值对&#xff0c;它基于哈希表的 Map 接口实现&#xff0c;是常用的 Java 集合之一&#xff0c;是线程不安全的。 HashMap&#xff1b;可以存储 null 的 key 和 value &#xff0c;但 null 作为 key 只能有一个&#xff0c;null 作为值可以…

MAC Address

文章目录 1. 前言2. MAC Address2.1 MAC 地址格式2.2 Locally Administered MAC Address2.3 MAC 单播 和 多播 3. 参考资料 1. 前言 限于作者能力水平&#xff0c;本文可能存在谬误&#xff0c;因此而给读者带来的损失&#xff0c;作者不做任何承诺。 2. MAC Address 2.1 MA…

3d渲染软件有哪些(1),渲染100邀请码1a12

3D渲染是把三维模型转成2D图像的过程&#xff0c;领域不同常用的软件也不一样&#xff0c;今天我们就简单介绍几个。 在介绍前我们先推荐一个设计人员常用到的工具&#xff0c;就是网渲平台渲染100&#xff0c;通过它设计师可以把本地渲染放到云端进行&#xff0c;价格也不贵&a…

永洪bi里topN的设置/用法

要实现的效果&#xff1a;实现通过输入参数&#xff0c;进行图表top的排序筛选 图示&#xff1a; 筛选前&#xff1a; 输入3&#xff0c;看top3的值&#xff1a; 输入-3&#xff0c;看倒数3个的值&#xff1a; 设置步骤&#xff1a; 1️⃣&#xff1a;添加一个“文本参数组件…

二叉搜索树详解

一、二叉搜索树的概念 二叉搜索树又名二叉排序树以及二叉查找树&#xff0c;它是一颗空树或者是具有以下性质的二叉树 *若它的左子树不为空&#xff0c;则左子树上所有节点的值都小于根节点的值 *若它的右子树不为空&#xff0c;则右子树上所有节点的值都大于根节点的值 *它…

昂科烧录器支持KIOXIA铠侠的可编程只读存储器TH58NVG4S0HTAK0

芯片烧录行业领导者-昂科技术近日发布最新的烧录软件更新及新增支持的芯片型号列表&#xff0c;其中KIOXIA铠侠的电可擦除可编程只读存储器TH58NVG4S0HTAK0已经被昂科的通用烧录平台AP8000所支持。 TH58NVG4S0HTAK0是一个单一的3.3V 16Gbit&#xff08;18253611008位&#xff…

智慧城市低空+AI视频智能监控:构建新时代安全防线

随着科技的飞速发展&#xff0c;智能监控技术已经广泛应用于各个领域&#xff0c;从城市治理到工业生产&#xff0c;从公共安全到环境监测&#xff0c;都发挥着越来越重要的作用。而在低空领域&#xff0c;AI视频智能监控方案的建设更是成为了一个热点话题。 一、低空AI视频智…

设计模式原则——迪米特法则原则

设计模式原则 设计模式示例代码库地址&#xff1a; https://gitee.com/Jasonpupil/designPatterns 迪米特法则原则&#xff1a; 意义在于降低类之间的耦合。由于每个对象尽量减少对于其他对象的了解&#xff0c;因此&#xff0c;很容易使得系统的功能模块功能独立&#xff…

[论文笔记]Mixture-of-Agents Enhances Large Language Model Capabilities

引言 今天带来一篇多智能体的论文笔记&#xff0c;Mixture-of-Agents Enhances Large Language Model Capabilities。 随着LLMs数量的增加&#xff0c;如何利用多个LLMs的集体专业知识是一个令人兴奋的开放方向。为了实现这个目标&#xff0c;作者提出了一种新的方法&#xf…

Erpnext安装

Erpnext安装 环境要求 Ubuntu 23.04 x86_64 Python 3.10.12 pip 23.0.1 node v18.16.0 npm 9.5.1 yarn 1.22.22 MariaDB 10.11.2 Redis 7.0.8 wkhtmltox 0.12.6.1 bench 5.22.6环境安装 Reids 安装 // 安装7.0.8 也可不指定版本 直接执行 sudo apt install redis-server s…

Spring Boot 3 搭建

1、jdk 17 2、spring boot 3.1.7 3、pom.xml <project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation"http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xs…

在线客服源码系统全端通用 源码完全开源可以二次开发 带完整的安装代码包以及搭建教程

系统概述 在线客服源码系统采用了先进的技术架构&#xff0c;包括前端界面、后端服务、数据库等部分。前端界面采用了响应式设计&#xff0c;能够自适应不同的设备屏幕尺寸&#xff0c;为用户提供良好的使用体验。后端服务采用了高性能的服务器架构&#xff0c;确保系统的稳定…

QT学习积累——在C++中,for循环中使用``与不使用``的区别和联系

目录 引出使用&与不使用&除法的一个坑 总结自定义信号和槽1.自定义信号2.自定义槽3.建立连接4.进行触发 自定义信号重载带参数的按钮触发信号触发信号拓展 lambda表达式返回值mutable修饰案例 引出 QT学习积累——在C中&#xff0c;for循环中使用&与不使用&的…

PointCloudLib (多线程)快速双边滤波 C++版本

0.实现效果 原始点云 和滤波后的点云对比 1.算法原理 PCL(Point Cloud Library)快速双边滤波是一种高效的点云数据滤波方法,它基于传统双边滤波算法进行了改进,通过引入近似方法加速计算过程。以下是关于PCL快速双边滤波的详细回答: 1. 基本原理 空间滤波:在点云中,相…

Verilog的逻辑系统及数据类型(一):四值逻辑系统

目录 1. Verilog采用的四值逻辑系统2.主要数据类型2.1 net&#xff08;线网&#xff09;2.2 寄存器类 &#xff08;register)2.3 Verilog中net和register声明语法2.3.1 net声明2.3.2 寄存器声明 2.4 选择正确的数据类型2.5 选择数据类型时常犯的错误2.5.1 信号类型确定方法总结…

【嵌入式DIY实例】-Nokia 5110显示BME280传感器数据

Nokia 5110显示BME280传感器数据 文章目录 Nokia 5110显示BME280传感器数据1、硬件准备与接线2、代码实现本文将介绍如何使用 ESP8266 NodeMCU 板(ESP12-E 模块)和 BME280 气压、温度和湿度传感器构建一个简单的本地气象站。 NodeMCU 从 BME280 传感器读取温度、湿度和压力值…

2024广东省职业技能大赛云计算赛项实战——集群部署GitLab Runner

集群部署GitLab Runner 前言 题目如下: 部署GitLab Runner 将GitLab Runner部署到gitlab-ci命名空间下&#xff0c;Release名称为gitlab-runner&#xff0c;为GitLab Runner创建持久化构建缓存目录/home/gitlab-runner/ci-build-cache以加速构建速度&#xff0c;并将其注册到…

【算法与数据结构】【字符串篇】【String的常见函数】

系列文章 本人系列文章-CSDN博客https://blog.csdn.net/handsomethefirst/article/details/138226266?spm1001.2014.3001.5502 1.string基本概念 string是C风格的字符串&#xff0c;而string本质上是一个类。 string和char * 区别&#xff1a; char * 是一个指针 string是一…