当前位置: 首页 > news >正文

十八、动画与canvas

在这里插入图片描述

1.RequestAnimationFrame

早期定时动画

setTimeout和setInterval不能保证时间精度,第二个参数只能保证何时将代码添加到浏览器的任务队列
requestAnimationFrame(cb)的cb在浏览器重绘屏幕前调用

function updateProgress(){const div = document.getElementById('div');div.style.width = (parseInt(div.style.width, 10) + 5) + '%';if (div.style.width !== '100%'){requestAnimationFrame(updateProgress);}
}
requestAnimationFrame(updateProgress);

requestAnimationFrame()的函数实际上可以接受一个参数,该参数为DOMHighResTimeStamp的实例,表示下次重绘的时间点。

cancelAnimationFrame(id); // 对应clearTimeout clearInterval

requestAnimationFrame()可以用作节流

let enabled = true;
function expensiveOperation(){console.log('scroll', Date.now());
}
window.addEventListener('scroll', () => {if (enabled) {enabled = false;window.requestAnimationFrame(expensiveOperation);setTimeout(() => enabled = true, 50)}
}

2.基本的画布功能

<canvas>元素必须要指定width和height两个属性,标签之间的内容是在浏览器不支持的情况下展示的内容

getContext();// 获取绘制上下文,参数为‘2d’或者‘webgl’
toDataURL(); // 导出canvas元素上的图像,接受一个MIME类型参数

3、2D绘图上下文

原点(0,0)在左上角,width和height分别为x轴和y轴的最大值

填充和描边

fillStyle和strokeStyle两个属性,属性值可以是字符串、渐变对象和图案对象

const myCanvas = document.getElementById('myCanvas');
const ctx = myCanvas.getContext('2d');
ctx.strokeStyle = 'red';
ctx.fillStyle = '#0000ff';

绘制矩形

fillRect(x,y, width, height);
strokeRect(x, y, width, height);
clearRect(x, y, width, height);

绘制路径

必须beginPath()开始绘制新路径,closePath()绘制一条返回起点的路径。而后可以指定fillStyle属性后,使用fill()填充区域,或者指定strokeStyle属性后,使用stroke()填充路径,或者使用clip()创建一个新的剪切区域。

方法说明
arc(x, y, startAngle, endAngle, counterclockwise)以(x,y)为圆心,从起始角度到结束角度绘制弧线,最后一个参数为是否顺时针,默认为true
arcTo(x1, y1, x2, y2, radius)给定半径,经过(x1, y1)从上一个点绘制到(x2,y2)的弧线
bezierCurveTo(c1x, c1y, c2x, c2y, x, y)以(c1x, c1y)(c2x, c2y)为控制点,绘制从上一点到(x,y)的三次贝塞尔曲线
lineTo(x,y)上一点到(x,y)的直线
moveTo(x,y)移动光标到(x,y)
quadraticCurveTo(cx, cy)以(cx, cy)为控制点,绘制从上一点到(x,y)的二次贝塞尔曲线
rect(x, y, width, height)绘制一个矩形路径,而非图形
isPointInPath(x, y)判断(x, y)是否在当前路径

绘制文本

fillText(contentStr, x, y, maxWidth);
strokeText(contentStr, x, y, maxWidth);
// 相关设置属性
ctx.font; // 以css样式指定字体样式、大小、字体簇
ctx.textAlign; // 文本对齐方式 start/end/left/right/center
ctx.textBaseLine; // 文本基线, top/hanging/middle/alphabetic/ideographic/bottom

辅助确定文本大小的方法measureText(str),返回一个TextMetrics对象

变换

方法
rotate(angle)围绕原点将图像旋转angle
scale(scaleX, scaleY)在x轴和y轴上分别缩放相应倍数
translate(x, y)将坐标原点移动到(x, y)
transform(m1_1, m1_2, m2_1, m2_2, dx, dy)通过矩阵乘法直接修改上下文矩阵
m1_1m2_1dx
m1_2m2_2dy
001
setTransform(m1_1, m1_2, m2_1, m2_2, dx, dy)先将上下文变换矩阵重置,然后以传入的参数调用transform

save()可以将所有设置放入一个暂存栈,需要恢复时调用restore()

绘制图像

drawImage()可以接受三组不同的参数

//1.传入一个HTML的<img>元素
let img = document.images[0];
ctx.drawImage(img, x, y);
ctx.drawImage(img, x, y, width, height); // width和height默认为<img>的宽高
// 2.将图像的部分绘制到指定区域
ctx.drawImage(img, srcX, srcY, srcWidth, srcHeight, targetX, targetY, targetWidth, targetHeight);
// 3.第一个参数可以是另外一个canvas元素
// 操作的结果可以通过toDataURL() 获取

阴影

属性值设置

属性说明
shadowColorCSS颜色值,默认黑色
shadowOffsetXx坐标偏移量
shadowOffsetYy坐标偏移量
shadowBlur阴影模糊量

渐变

线性渐变通过CanvasGradient的实例表示,createLinearGradient()创建一个CanvasGradient实例,接受起点和终点的坐标作为参数;
addColorStop()方法为gradient对象添加色标,接受两个参数(位置0-1,颜色)

const gradient = ctx.createLinearGradient(30,30,70,70);
gradient.addColorStop(0, 'white');
gradient.addColorStop(1, 'black');
// 绘制红色矩形
ctx.fillStyle = '#FF0000';
ctx.fillRect(10,10,50,50);
// 绘制渐变矩形
ctx.fillStyle = gradient;
ctx.fillRect(30,30,50,50);

径向渐变通过createRadialGradient()创建,接受六个参数,分别为起点和终点的圆心坐标、半径、

ctx.createRadialGradient(startX, startY, startR, endX, endY, endR);

图案

用于填充和描画重复图案,调用createPattern(),接受两个参数,第一个参数为<img>或者<video> 和<canvas>,第二个参数为重复模式(repeat-x, repeat-y, repeat, no-repeat)

图像数据

getImageData(startX, startY, width, height)返回一个ImageData对象,每个ImageData包含三个属性width, height, data,其中data中每四个值分别表示第i个像素点的红、绿、蓝和透明度值,取值范围为0-255

合成

属性值说明
globalAlpha全局透明度,0-1, 用于指定绘制内容的透明度
globalCompositionOperation新绘制的形状如何与已有的上下文形状融合
source-over新图形在原图形上面,默认值
source-in只画出新图形与原图形重叠的部分,画布上其他部分全部透明
source-out只画出新图形不重叠的部分,画布上其他部分全部透明
source-atop只画出新图形重叠部分,其他部分不受影响
destination-over新图形在原图形下面,重叠部分只有原图形透明像素下可见
destination-in新图形在原图形下面,画布上只留下两者重叠部分,其他部分全部透明
destination-out新图形与原图形重叠部分透明,不重叠部分不画,画布其他部分不受影响
destination-atop新图形在原图形下面,原图形不重叠部分全部透明
lighter新图形与原图形重叠部分像素值相加,让该部分变亮
copy新图形将擦除并完全取代原图形
xor新图形与原图形在重叠部分取“异或”操作

4.WebGL

webgl上下文

getContext(‘webgl’);

webgl基础

可以在调用getContext()时传入配置项,指定创建的上下文的一些选项

配置项说明默认值
alpha是否为上下文创建透明通道缓冲区true
depth是否使用16位深缓冲区true
stencil是否使用8位模板缓冲区false
antialias是否使用默认机制执行抗锯齿操作true
premultipliedAlpha绘图缓冲区是否预乘透明度true
preserveDrawingBuffer绘图完成后是否保留绘图缓冲区false
let drawing = document.getElementById("drawing");
// 确保浏览器支持<canvas>
if (drawing.getContext) {let gl = drawing.getContext("webgl", { alpha: false });if (gl) {// 使用 WebGL}
} 
1.常量

OpenGL中以GL_开头的常量大部分都被webGL支持,但不需要这个前缀

gl.COLOR_BUFFER_BIT // GL_COLOR_BUFFER_BIT
2.方法命名

参数数量(1-4)+数据类型(‘f’, ‘i’)如, gl.uniform4f()

3.准备绘图

绘图之前,需要使用clearColor(r, g, b, a) 使用一种颜色清除<canvas>元素, rgba参数值都在0-1;
也可以使用gl.clear(gl.COLOR_BUFFER_BIT)使用之前定义的颜色填充画图

4.视口与坐标

默认情况下,视口为整个canvas区域,也可以使用viewport()方法改变视口

gl.viewport(x, y, width, height)

定义视口的坐标系统是canvas像素坐标系统,而视口中,中心点是原点(0,0),左下角是(-1,-1),右上角是(1,1)。

5.缓冲区
const buffer = gl.createBuffer(); // 创建缓冲区
gl.bindBuffer(gl.ARRAY_BUFFER, buffer); // 将缓冲区绑定到上下文中,此处是将buffer与ARRAY_BUFFER绑定,将buffer设置为当前上下文的缓冲区
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([0,0.5,1]), gl.STATIC_DRAW); // 将数据写入缓冲区第三个参数可以有3个选择
/**
gl.STATIC_DRAW  数据加载一次,可以在多次绘制中使用
gl.STREAM_DRAW 数据加载一次,只能在几次绘制中使用
gl.DYNAMIC_DRAW  数据可以重复修改,在多次绘制中使用
**/
// 不再需要缓冲区
gl.deleteBuffer(buffer);
6.错误

webGL操作中通常不会抛出错误,gl.getError()方法会返回一个常量,表示发生的错误类型

gl.NO_ERROR没有发生错误
gl.INVALID_ENUM上一次操作没有传入webgl预定的常量
gl.INVALID_VALUE上一次操作需要无符号数值,但是传入了负数
gl.INVALID_OPERATION上一次操作在当前状态下无法完成
gl.OUT_OF_MEMORY上次操作因内存不足无法完成
gl.CONTEXT_LOST_WEBGL上次操作因外部事件而丢失了上下文
7.着色器

定点着色器将3D顶点绘制为2D的点;
片元着色器将计算每个像素的颜色值;
使用GLSL编程

编写着色器

每个着色器有一个main()方法,绘制期间反复执行,
给着色器传递数据的方式有两种attributeuniform
attribute将定点传入定点着色器,uniform将任意常量值传入任意着色器

创建着色器程序
gl.createShader(shaderType); // shaderType: gl.VERTEX_SHADER, gl.FRAGMENT_SHADER 创建着色器
gl.shaderSource(shader, shaderSource);// 将glsl代码应用于着色器
gl.compileShader(shader); // 编译着色器const program = gl.createProgram(); // 创建着色器程序
gl.attachShader(program, shader); // 将着色器添加到着色器程序,需要调用两次分别传入定点着色器和片元着色器
gl.linkProgram(program); // 将两个着色器链接到变量program
gl.useProgram(program); // 让webgl上下文使用该程序
给着色器传值
// 1.找到接受值的变量位置
let uColorLocation = gl.getUniformLocation(program, 'uColor'); // 针对uniform变量uColor
let aVertextPosLocation = gl.getAttribLocation(program, 'aVertextPosition'); //  针对attribute变量aVertexPosition
// 2.传值
// 针对uniform变量
gl.uniform4fv(uColorLocation, [0,0,0,1]);
// 针对attribte变量
gl.enableVertexAttribArray(aVertexPosLocation); 
gl.vertexAttribPointer(aVertexPosLocation, itemSize, gl.FLOAT, false, 0, 0) ; // 创建一个指向bindBuffer()指定的缓冲区指针,并保存在aVertexPosLocation中,
8.绘图

webGL只能绘制3中基本图形:点、线、三角形
绘图方法有两种:
drawArrays()使用数组缓冲区
drawElements()操作元素数组缓冲区
drawArrays()接受三个参数,第一个参数表示形状,第二个参数是数组缓冲区的起点索引,第三个参数是数组缓冲区顶点集合的数量
形状参数列表:

参数意义
gl.POINTS将每个顶点当做一个点
gl.LINES将数组作为一系列点,每两个点依次绘制直线,顶点数必须是偶数
gl.LINE_LOOP将数组作为一系列顶点,依次依次绘制直线连接成封闭形状
gl.LINE_STRIP类似于gl.LINE_LOOP,区别在于最后不会连接终点和起点
gl.TRIANGLES将数组作为一系列顶点,在这些顶点间绘制三角形,每个三角形都不会共享顶点
gl.TRIANGLES_STRIP类似于gl.TRIANGLES,区别在于共享点,如果有ABCD四个点,则会绘制两个三角形ABC和BCD
gl.TRIANGLES_FAN如果有ABCD四个点,则会绘制ABC, ACD三角形
/****** 绘制一个三角形 ******/const canvas = document.querySelector('#canvas');const gl = canvas.getContext('webgl') || canvas.getContext('experimental-webgl');const vSource = `attribute vec4 a_position;void main(){gl_Position = a_position;}`;const fSource = `precision highp float;uniform vec4 uColor;void main(){gl_FragColor = uColor;}`;const program = gl.createProgram();const vShader = gl.createShader(gl.VERTEX_SHADER);gl.shaderSource(vShader, vSource);gl.compileShader(vShader);const fShader = gl.createShader(gl.FRAGMENT_SHADER);gl.shaderSource(fShader, fSource);gl.compileShader(fShader);gl.attachShader(program, vShader);gl.attachShader(program, fShader);gl.linkProgram(program);gl.useProgram(program);const uColorLocation = gl.getUniformLocation(program, 'uColor');gl.uniform4f(uColorLocation, 1, 0, 0, 0.5);const positionData = [0.5, 0, 0,  0, 0.5, 0, -0.5, -0.5, 0.5];const positionBuffer = gl.createBuffer();gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(positionData), gl.STATIC_DRAW);const positionLocation = gl.getAttribLocation(program, 'a_position');gl.vertexAttribPointer(positionLocation, 3, gl.FLOAT, false, 0, 0);gl.enableVertexAttribArray(positionLocation);gl.clearColor(0,1,1,1);gl.clear(gl.COLOR_BUFFER_BIT)gl.drawArrays(gl.TRIANGLES, 0, 3);
纹理

纹理的来源可以是图片、<video>或者<canvas>

let image = new Image(),texture;
image.src = "smile.gif";
image.onload = function() {texture = gl.createTexture(); // 创建纹理gl.bindTexture(gl.TEXTURE_2D, texture); // 绑定缓冲区gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true); // 设置存储格式gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, image);gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);// 除当前纹理gl.bindTexture(gl.TEXTURE_2D, null);
} 
读取像素
// 读取(0,0)到(25,25)区域的像素,并写入pixels数组,rgba四值,0-255
let pixels = new Uint8Array(25*25);
gl.readPixels(0, 0, 25, 25, gl.RGBA, gl.UNSIGNED_BYTE, pixels); 

相关文章:

十八、动画与canvas

1.RequestAnimationFrame 早期定时动画 setTimeout和setInterval不能保证时间精度&#xff0c;第二个参数只能保证何时将代码添加到浏览器的任务队列 requestAnimationFrame(cb)的cb在浏览器重绘屏幕前调用 function updateProgress(){const div document.getElementById(d…...

自动化测试学习-Day4-selenium的安装和8种定位方法

哈喽&#xff0c;大家好&#xff01; 本人21年毕业&#xff0c;软件工程专业&#xff0c;毕业后一直从事金融行业的软件测试。 希望大家一起见证一名卑微测试的成长之路。 目录 一、环境准备 1.浏览器下载 2.浏览器驱动下载 3.下载selenium 二、Selenium定位元素的8种方法…...

【Kubernetes】第二十五篇 - 布署 nodejs 后端项目(下)

一&#xff0c;前言 上一篇&#xff0c;介绍了部署后端项目之前&#xff0c;需要的准备的相关配置信息&#xff1b; 本篇&#xff0c;创建 Deployment、Service 完成后端项目布署&#xff1b; 二&#xff0c;解决 jenkins 安全问题 构建 docker 镜像之后&#xff0c;登录 do…...

贪心算法之区间问题总结

一、跳跃游戏跳跃游戏类的问题&#xff0c;不关心每一步怎么跳&#xff0c;只需要关心最大覆盖范围这里注意i是在当前最大可覆盖范围内遍历&#xff0c;如{2,1,0,1}&#xff0c;就是在0~2范围内遍历&#xff0c;千万不能0~numsSize-1范围内遍历&#xff01;&#xff01;&#x…...

无线WiFi安全渗透与攻防(七)之WIFI07-WEP-wifite自动化渗透WEP加密

WIFI07-WEP-wifite自动化渗透WEP加密 1.wifite介绍 wifite是一款自动化wep、wpa以及wps破解工具&#xff0c;不支持windows和osx。wifite的特点是可以同时攻击多个采用wep和wpa加密的网络。wifite只需简单的配置即可自动化运行&#xff0c;期间无需人工干预。 目前支持任何li…...

震撼,支持多模态模型的ChatGPT 4.0发布了

最近几个月&#xff0c;互联网和科技圈几乎ChatGPT刷屏了&#xff0c;各种关于ChatGPT的概念和应用的帖子也是围绕在周围。当去年年底ChatGPT发布的那几天&#xff0c;ChatGPT确实震撼到了所有人&#xff0c;原来AI还可以这么玩&#xff0c;并且对国内的那些所谓的人工智能公司…...

IDEA常用插件列表

一 背景 IDEA常用插件列表&#xff0c;用来提供工作效率。你都安装了吗 IntelliJ IDEA 默认安装并提供了非常多的工具&#xff0c;比如 Maven Integration、Markdown support、SSH Remote Run 等。其中有很多好用&#xff0c;但是不为人知的工具。 二 插件列表 阿里代码规约…...

比df更好用的命令!

大家好&#xff0c;我是良许。 对于分析磁盘使用情况&#xff0c;有两个非常好用的命令&#xff1a;du 和 df 。简单来说&#xff0c;这两个命令的作用是这样的&#xff1a; du 命令&#xff1a;它是英文单词 disk usage 的简写&#xff0c;主要用于查看文件与目录占用多少磁…...

【Git使用学习】记录学习过程(1)

安装就省略了&#xff0c;安装结果如下。 Git Bash&#xff1a;这是一个模拟Linux环境的命令行工具&#xff0c;可以使用Git的所有功能。Git GUI&#xff1a;这是一个图形化界面的工具&#xff0c;可以方便地执行Git的常用操作。Git CMD&#xff1a;这是一个Windows命令行工具&…...

K_A18_001 基于STM32等单片机采集MQ2传感参数串口与OLED0.96双显示

K_A18_001 基于STM32等单片机采集MQ2传感参数串口与OLED0.96双显示一、资源说明二、基本参数参数引脚说明三、驱动说明IIC地址/采集通道选择/时序对应程序:四、部分代码说明1、接线引脚定义1.1、STC89C52RCMQ2传感参模块1.2、STM32F103C8T6MQ2传感参模块五、基础知识学习与相关…...

【云原生·Docker】常用命令

目录 &#x1f341;1、管理命令 &#x1f341;2、帮助命令 &#x1f341;3、镜像命令 &#x1f341;4、容器命令 &#x1f342;4.1.查看容器 &#x1f342;4.2.创建容器 &#x1f342;4.3.删除容器 &#x1f342;4.4.拷贝文件 &#x1f342;4.5.查看容器IP &#x1f341;5、部署…...

户外露营储能电源芯片CSU3AF10

户外露营的项目有很多&#xff0c;随着户外储能电源的发展&#xff0c;越来越多的电子产品可以在户外使用&#xff0c;也不用担心因为在户外时间过长而手机或者其他电子产品电量耗尽。户外储能电源可保证人们随时随地的用电需求&#xff0c;同时也可以满足家电炊具的供电需求&a…...

无线WiFi安全渗透与攻防(八)之WEP-Hirte渗透WEP加密

WEP-渗透WEP新思路–Hirte 1.Hirte介绍 Hirte是破解无线网络WEP Key的一种攻击类型 只要客户端设备&#xff08;笔记本电脑&#xff0c;手机等&#xff09;连接过的无线网络&#xff0c;那些WIFI即使是不在攻击者范围内也都能被破解&#xff0c;因为该wifi的WEP密钥和配置文…...

前端常考面试题整理

display:none与visibility:hidden的区别 这两个属性都是让元素隐藏&#xff0c;不可见。两者区别如下&#xff1a; &#xff08;1&#xff09;在渲染树中 display:none会让元素完全从渲染树中消失&#xff0c;渲染时不会占据任何空间&#xff1b;visibility:hidden不会让元素…...

二十二、身份验证与权限

一、 准备工作 为了讲清楚身份验证与权限&#xff0c;我们再创建一个应用projects,设计模型如下&#xff1a; class Project(models.Model):name models.CharField(项目名称, max_length20, help_text项目名称)desc models.CharField(项目描述, max_length200, help_text项目…...

k8s pod 升级与回滚

当集群中的某个服务需要升级时&#xff0c;我们需要停止目前与该服务相关的所有pod&#xff0c;然后下载新版本镜像并创建新的pod。如果集群规模比较大&#xff0c;则这个工作变成了一个挑战&#xff0c;而且先全部停止然后逐步升级的方式会导致较长时间的服务不可用。kubernet…...

【Go】Go语言开发环境安装

【Go】Go语言开发环境安装 导入 安装环境&#xff1a;Winowds 我现在是win7安装的&#xff0c;与win10整体步骤是一样的&#xff0c;只是部分显示的时候有点差异不影响&#xff1b; 【名词】 编译器&#xff1a;先将代码编译成可执行文件&#xff0c;再执行&#xff1b; —…...

el-switch使用

效果图&#xff1a; 1.表格代码&#xff0c;给el-waitch加上change事件 <el-table-column prop"status" label"状态" align"center" width"150"> <template slot-sc…...

【算法入门】字符串基础

目录 一.字符串引言1.字符串基础二.洛谷P5734详解1.字符串相关库函数&#x1f4ab;&#xff08;1&#xff09; strcpy函数 &#x1f4ab;&#x1f4ab;&#xff08;2&#xff09; strcat函数 &#x1f4ab;&#x1f4ab;&#xff08;3&#xff09;strstr函数 &#x1f4ab;2.题…...

前端面试题 —— 浏览器原理(二)

目录 一、有哪些可能引起前端安全的问题? 二、网络劫持有哪几种&#xff0c;如何防范&#xff1f; 三、浏览器渲染进程的线程有哪些 四、僵尸进程和孤儿进程是什么&#xff1f; 五、为什么需要浏览器缓存&#xff1f; 六、对浏览器的理解 七、CSS 如何阻塞文档解析&…...

51c自动驾驶~合集58

我自己的原文哦~ https://blog.51cto.com/whaosoft/13967107 #CCA-Attention 全局池化局部保留&#xff0c;CCA-Attention为LLM长文本建模带来突破性进展 琶洲实验室、华南理工大学联合推出关键上下文感知注意力机制&#xff08;CCA-Attention&#xff09;&#xff0c;…...

循环冗余码校验CRC码 算法步骤+详细实例计算

通信过程&#xff1a;&#xff08;白话解释&#xff09; 我们将原始待发送的消息称为 M M M&#xff0c;依据发送接收消息双方约定的生成多项式 G ( x ) G(x) G(x)&#xff08;意思就是 G &#xff08; x ) G&#xff08;x) G&#xff08;x) 是已知的&#xff09;&#xff0…...

java调用dll出现unsatisfiedLinkError以及JNA和JNI的区别

UnsatisfiedLinkError 在对接硬件设备中&#xff0c;我们会遇到使用 java 调用 dll文件 的情况&#xff0c;此时大概率出现UnsatisfiedLinkError链接错误&#xff0c;原因可能有如下几种 类名错误包名错误方法名参数错误使用 JNI 协议调用&#xff0c;结果 dll 未实现 JNI 协…...

使用分级同态加密防御梯度泄漏

抽象 联邦学习 &#xff08;FL&#xff09; 支持跨分布式客户端进行协作模型训练&#xff0c;而无需共享原始数据&#xff0c;这使其成为在互联和自动驾驶汽车 &#xff08;CAV&#xff09; 等领域保护隐私的机器学习的一种很有前途的方法。然而&#xff0c;最近的研究表明&…...

UE5 学习系列(三)创建和移动物体

这篇博客是该系列的第三篇&#xff0c;是在之前两篇博客的基础上展开&#xff0c;主要介绍如何在操作界面中创建和拖动物体&#xff0c;这篇博客跟随的视频链接如下&#xff1a; B 站视频&#xff1a;s03-创建和移动物体 如果你不打算开之前的博客并且对UE5 比较熟的话按照以…...

Map相关知识

数据结构 二叉树 二叉树&#xff0c;顾名思义&#xff0c;每个节点最多有两个“叉”&#xff0c;也就是两个子节点&#xff0c;分别是左子 节点和右子节点。不过&#xff0c;二叉树并不要求每个节点都有两个子节点&#xff0c;有的节点只 有左子节点&#xff0c;有的节点只有…...

CMake控制VS2022项目文件分组

我们可以通过 CMake 控制源文件的组织结构,使它们在 VS 解决方案资源管理器中以“组”(Filter)的形式进行分类展示。 🎯 目标 通过 CMake 脚本将 .cpp、.h 等源文件分组显示在 Visual Studio 2022 的解决方案资源管理器中。 ✅ 支持的方法汇总(共4种) 方法描述是否推荐…...

Java求职者面试指南:计算机基础与源码原理深度解析

Java求职者面试指南&#xff1a;计算机基础与源码原理深度解析 第一轮提问&#xff1a;基础概念问题 1. 请解释什么是进程和线程的区别&#xff1f; 面试官&#xff1a;进程是程序的一次执行过程&#xff0c;是系统进行资源分配和调度的基本单位&#xff1b;而线程是进程中的…...

从物理机到云原生:全面解析计算虚拟化技术的演进与应用

前言&#xff1a;我的虚拟化技术探索之旅 我最早接触"虚拟机"的概念是从Java开始的——JVM&#xff08;Java Virtual Machine&#xff09;让"一次编写&#xff0c;到处运行"成为可能。这个软件层面的虚拟化让我着迷&#xff0c;但直到后来接触VMware和Doc…...

DAY 45 超大力王爱学Python

来自超大力王的友情提示&#xff1a;在用tensordoard的时候一定一定要用绝对位置&#xff0c;例如&#xff1a;tensorboard --logdir"D:\代码\archive (1)\runs\cifar10_mlp_experiment_2" 不然读取不了数据 知识点回顾&#xff1a; tensorboard的发展历史和原理tens…...