JavaScript的p5.js库使用详解(下)

JavaScript的p5.js库使用详解(下)

JavaScript的p5.js库使用详解(上)https://blog.csdn.net/cnds123/article/details/156979525

JavaScript的p5.js库使用详解(中)https://blog.csdn.net/cnds123/article/details/156981287

本文续接上篇 JavaScript的p5.js库使用详细介绍(中)

五、变换、投影和相机

变换(Transform)、投影(Projection)、相机(Camera) 是 p5.js (WEBGL 模式) 实现 2D/3D 视觉呈现与交互 的三大核心核心功能,三者分工明确、相辅相成、层层递进,共同决定了"最终在画布上能看到什么样的画面"。

✔ 变换 → 改变"物体本身的形态 / 位置";

✔ 投影 → 改变"3D 空间映射到 2D 画布的视觉规则";

✔ 相机 → 改变"观察者看这个 3D 空间的视角"。

三者组合,构成了 p5.js 中所有 2D 动画、3D 立体效果、视角交互的底层逻辑。

(一)变换

p5.js 中的 translate()/rotate()/scale()/shearX()/shearY() 所有变换函数,不是直接变换"图形本身",而是变换"整个坐标系"!

注意,变换顺序影响结果。

可以用push()、pop()隔离变换,避免相互干扰。

平移 → 把坐标系的原点挪到新位置;

旋转 → 把坐标系绕原点转一个角度;

缩放 → 把坐标系的单位像素放大 / 缩小;

坐标系变了,后续绘制的所有图形 / 文字,会"跟着坐标系一起变",看起来就像图形自己动了、转了、变大了。

一旦执行了translate()/rotate(),后续所有绘制的图形都会沿用这个"变换后的坐标系",除非用push()/pop()隔离,或手动重置坐标系。

1. 平移变换 translate()

完整语法(2 种写法,分模式)

2D 模式(无 WEBGL)

translate(x, y)

3D 模式(开启 WEBGL)

translate(x, y, z)

参数详解(严格匹配你掌握的坐标系规则,无偏差)

• x :X 轴平移距离 → 正 = 右移,负 = 左移(2D/3D 完全一致)

• y :Y 轴平移距离 → 正 = 下移,负 = 上移(2D/3D 完全一致,都是下 + 上 -)

• z :3D 专属,Z 轴平移距离 → 正 = 前移(出屏幕 / 朝向你),负 = 后移(入屏幕 / 远离你)

核心作用

修改坐标系的原点位置,比如 translate(100,200) 就是把画布的原点 (0,0) 从默认位置移动到 (100,200),后续所有图形都以这个新原点为基准绘制。

示例

translate(50, 80); // 2D:原点移到画布右下50,80

translate(50, 80, -30); //3D:右移50、下移80、前移30(出屏)

2. 旋转变换

2D 模式 旋转:只有一个函数 rotate(angle)

rotate(angle)

• 参数 angle :旋转弧度值,正数值 = 顺时针旋转,负数值 = 逆时针旋转(和你之前学的 2D 坐标系旋转规则一致)

• 旋转轴:固定绕「垂直于画布的虚拟 Z 轴」旋转,无需手动指定

3D 模式(开启 WEBGL) 旋转:三个专属函数,分轴旋转。

3D 模式下没有单独的rotate(),必须指定旋转轴,三个函数独立使用,可组合旋转,旋转方向匹配你的 3D 坐标系规则,是 3D 开发的核心:

rotateX(angle) // 绕 X 轴旋转(上下翻转,仰头/低头视角)

rotateY(angle) // 绕 Y 轴旋转(左右转圈,水平旋转,最常用!)

rotateZ(angle) // 绕 Z 轴旋转(平面旋转,和2D的rotate()完全等价)

• 参数 angle :弧度值,正负控制旋转方向,rotateY() 是 3D 中最常用的旋转函数(比如立方体水平转圈)

核心作用

修改坐标系的旋转角度,画布整体跟着旋转,后续绘制的图形也跟着旋转。

示例

rotate(PI/4); // 2D:顺时针旋转45度

rotateY(PI/6); // 3D:绕Y轴旋转30度,立方体水平转圈

rotateX(-PI/3); // 3D:绕X轴逆时针旋转60度,立方体上翻

3. 缩放变换 scale()

2D 模式(无 WEBGL)

scale(x, y) // 分别缩放X轴、Y轴

scale(s) // 简写:等比缩放,x=y=s,最常用

3D 模式(开启 WEBGL)

scale(x, y, z) // 分别缩放X/Y/Z三轴

scale(s) // 简写:等比缩放,x=y=z=s

参数详解

• x :X 轴缩放倍数,y:Y 轴缩放倍数,z:3D 专属 Z 轴缩放倍数

• 缩放规则(通用):

① 参数>1 → 放大,例:scale(2) 图形放大 2 倍;

② 0<参数<1 → 缩小,例:scale(0.5) 图形缩小到一半;

③ 参数=1 → 无缩放,默认值;

④ 参数为负数 → 缩放 + 镜像翻转,例:scale(-1) 图形左右翻转;

核心作用

修改坐标系的缩放比例,坐标系被拉伸 / 压缩后,图形的宽高 / 体积也会同步缩放,缩放中心是「当前坐标系原点」。

示例

scale(0.8); // 2D/3D通用:整体等比缩小到0.8倍

scale(2, 1); // 2D:X轴放大2倍,Y轴不变,图形变宽

scale(1,1,0.5); // 3D:Z轴缩小到0.5倍,图形变薄/变远

4. 错切变换 shearX(angle) / shearY(angle)

注意, shearX(angle) / shearY(angle)仅 2D 模式有效!3D 模式无效果。

☆ shearX() 和 shearY() 是纯 2D 变换函数,在开启 WEBGL 的 3D 模式下,这两个函数完全无效,写了也不会有任何效果!

语法(只有 2D 写法)

shearX(angle) // 沿X轴方向错切/倾斜

shearY(angle) // 沿Y轴方向错切/倾斜

参数详解

• angle :错切的角度,单位是弧度,正负控制倾斜方向;

核心作用 & 视觉效果

错切 = "倾斜变形",只改变图形的形状,不改变图形的面积,本质是让坐标系的 X/Y 轴发生"平行倾斜",图形跟着倾斜:

• shearX(angle) :图形的垂直边(Y 轴方向) 向左右倾斜,水平边保持水平;正数值→向右倾斜,负数值→向左倾斜;

• shearY(angle) :图形的水平边(X 轴方向) 向上下倾斜,垂直边保持垂直;正数值→向下倾斜,负数值→向上倾斜;

示例

shearX(PI/6); // 2D:图形垂直边向右倾斜30度,变成平行四边形

shearY(-PI/4); // 2D:图形水平边向上倾斜45度,变成平行四边形

变换函数的5 个通用黄金规则

规则 1:变换是"累加叠加"的,会持续生效

所有变换函数的效果会叠加到上一次的坐标系上,不会重置,例:

translate(50,50); // 原点右移50、下移50

translate(30,20); // 在上一次基础上,再右移30、下移20 → 总位移(80,70)

规则 2:push() + pop() 是"隔离变换"的手段

push() → 保存"当前的坐标系状态"(无变换的原始状态 / 上一次变换后的状态)

pop() → 恢复到 push() 保存的状态,隔断变换的累加效应

这是最核心的用法,也是你绘制多图形时必须用的,例:画两个独立旋转的方块,互不影响

push(); translate(100,100); rotate(PI/4); rect(0,0,50,50); pop();

push(); translate(200,200); rotate(PI/2); rect(0,0,50,50); pop();

规则 3:变换的"执行顺序"会影响最终效果,顺序不同,结果不同

translate() → rotate() → scale() ≠ rotate() → translate() → scale()

2D 旋转黄金公式(永远不变):先平移到图形中心 再旋转 → 最后绘制图形

规则 4:所有变换都基于"当前坐标系原点",不是画布的固定原点

比如 2D 默认原点在左上角,translate 后原点变了,后续的 rotate/scale 都是绕「新原点」执行。

规则 5:3D 模式下,变换函数和相机 / 投影兼容

3D 中,translate(x,y,z)/rotateX/Y/Z() 可以和 camera()/perspective()/orbitControl() 混用,变换的是「3D 坐标系」,相机看的是「变换后的坐标系和图形」,无冲突;唯一例外是 shearX/Y 无效。

下面给出综合示例。

示例 1:2D 模式 所有变换函数综合使用

html 复制代码
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.7.0/p5.js"></script>
<script>
function setup() { createCanvas(400,400); }
function draw() {
  background(240);
  // 平移+旋转+缩放+错切 组合
  push();
  translate(200,200);  // 原点移到画布中心
  rotate(PI/6);        // 顺时针旋转30度
  scale(1.2);          // 放大1.2倍
  shearX(PI/12);       // 轻微右倾斜15度
  fill(255,0,0);
  rect(-50,-50,100,100); // 以新原点为中心画正方形
  pop();
}
</script>

运行截图:

示例 2:3D 模式 核心变换函数 + orbitControl

运行截图:

(二)投影和相机

1.orbitControl() 这个函数的本质是p5.js 内置的"自动相机控制器"。简单说:没有orbitControl(),你的 3D 视角是"固定死的";有了它,你可以用鼠标自由控制相机视角。

• 它会自动帮你创建一个"虚拟相机",放在画布后方;

• 你鼠标左键拖拽 → 相机绕着 3D 物体旋转视角;

• 你鼠标滚轮缩放 → 相机靠近 / 远离 3D 物体;

• 你鼠标右键平移 → 相机平行移动视角;

• 它还会自动启用"透视投影",让 3D 物体有"近大远小"的真实立体感。

2.perspective() 透视投影(默认模式,最常用)语法:

perspective([fovy], [aspect], [near], [far])

所有参数都是"调整透视的细节",不写这个函数,p5.js 会用默认值,完全够用,新手 99% 的场景不用手动设置:

• fovy:视野角度(单位:弧度),默认值≈PI/3 → 简单说:数值越大,「相机的视野越广」,能看到更多东西,画面里的物体越小;数值越小,「视野越窄」,像望远镜,画面里的物体越大。

• aspect:画布的宽高比 → 一般写 width/height,和你的画布尺寸匹配,避免图形被拉伸变形。

• near:近裁剪面 → 相机能看到的最近距离,比这个距离更近的物体,会被「裁剪掉」(看不见)。

• far:远裁剪面 → 相机能看到的最远距离,比这个距离更远的物体,会被「裁剪掉」(看不见)。

3.ortho() 正交投影(平行投影,无透视感)语法:

ortho([left], [right], [bottom], [top], [near], [far])

参数是"相机能看到的画面边界",不写的话 p5.js 会用默认值,覆盖整个画布:

• left/right/bottom/top:相机能看到的"左右上下边界";

• near/far:相机能看到的"最近 / 最远距离"。

4.camera() 相机位置设置语法:

camera(eyeX, eyeY, eyeZ, centerX, centerY, centerZ, upX, upY, upZ)

camera()函数在 3D 空间中精准设置:观察者的位置、视线的目标点、相机的正立方向,但不会改变任何物体的位置、形态、大小,也不会改变投影规则,只改变"观察者的视角"。

其中有 9 个参数被逗号分成了3 个核心部分,每部分 3 个值,对应 X/Y/Z 轴,逻辑清晰,不用死记顺序:

第一组:eyeX, eyeY, eyeZ → 【相机在哪?】(你的眼睛的位置)

核心含义:设置"相机"这个点,在 3D 坐标系中的绝对坐标,所有值都遵循 3D 坐标系规则:

• eyeX:相机的左右位置 → 正 = 右,负 = 左;

• eyeY:相机的上下位置 → 正 = 下,负 = 上;

• eyeZ:相机的里外位置 → 正 = 内(远离屏幕),负 = 外(靠近屏幕);

第二组:centerX, centerY, centerZ → 【相机看哪?】(视线的目标点)

核心含义:设置相机"镜头对准的那个点",也是 3D 坐标系中的一个点,相机永远朝向这个点看。

• 默认值是 0,0,0 → 画布正中心,也就是所有 3D 物体的默认位置;

• 比如你把目标点设为100,0,0,相机就会一直看向画布右侧的那个点;

第三组:upX, upY, upZ → 【相机的头顶朝向?】(相机的正立方向)

核心含义:设置相机的"头顶"朝向哪个方向,决定相机是"正立""倒立"还是"倾斜"。

• 默认值是 0, -1, 0 → Y 轴负方向(向上),也就是相机"正立",这是最符合人类视角的状态;

• 如果改成0,1,0,相机就会"倒立",画面里的 3D 物体会上下翻转;

//p5.js WEBGL 3D 模式 官方默认相机位置(不用手写,自动生效)

camera(0, 0, (height/2) / tan(PI/6), 0, 0, 0, 0, -1, 0);

下面给出几个示例源码。

示例1:透视投影(默认)→ 近大远小,有立体感

html 复制代码
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.7.0/p5.js"></script>
<script>
function setup() {
  createCanvas(800, 600, WEBGL);
  // 默认是perspective()透视投影,不用写
}
function draw() {
  background(240);
  ambientLight(220);
  stroke(0); strokeWeight(1);
  
  // 核心修改1:Z轴位置调换,让红色更靠近相机(z=-100)、蓝色更远(z=200)
  // 近处的红色立方体 → 大
  push(); 
  translate(0, 0, -100); // z=-100:靠近相机
  ambientMaterial(255,0,0); 
  box(80); 
  pop();

  // 远处的蓝色立方体 → 小
  push(); 
  translate(0, 0, 200); // z=200:远离相机
  ambientMaterial(0,100,220); 
  box(80); 
  pop();

  // 核心修改2:添加鼠标视角控制,能旋转看立体效果
  orbitControl(); 
}
</script>

效果:红色立方体大,蓝色立方体小,明显的透视感。开始有遮挡现象,按住鼠标左键拖拽 → 旋转视角,能看到立方体的 3D 立体形态,近大远小的透视感更明显。

示例2:正交投影 → 等大不变形,无立体感

html 复制代码
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.7.0/p5.js"></script>
<script>
function setup() {
  createCanvas(800, 600, WEBGL);
  ortho(); // 开启正交投影
}
function draw() {
  background(240);
  ambientLight(220);
  stroke(0); strokeWeight(1);
  
  // 左+远 → 红色立方体 (Z=-200, X=-100)
  push(); translate(-100, 0, -200); ambientMaterial(255,0,0); box(80); pop();
  // 右+近 → 蓝色立方体 (Z=200, X=100)
  push(); translate(100, 0, 200); ambientMaterial(0,100,220); box(80); pop();

  orbitControl();
}
</script>

效果:两个立方体大小完全一样。

示例3:手动设置 camera () → 自定义视角看 3D 物体(无 orbitControl)

html 复制代码
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.7.0/p5.js"></script>
<script>
function setup() {
  createCanvas(800, 600, WEBGL);
  // 手动设置相机:站在画布右侧+上方+远处,看向画布中心
  camera(300, -200, 500,  0, 0, 0,  0, -1, 0);
}
function draw() {
  background(240);
  ambientLight(220);
  stroke(0); strokeWeight(1);
  ambientMaterial(255,120,0);
  //rotateY(frameCount*0.01); // 注意这句:立方体绕Y轴缓慢自转
  box(100);
}
</script>

效果:固定视角,看到立方体的"右上角斜视图",不用鼠标控制,完全是你手动设置的视角。不改其他代码,只改 camera () 里的数值,就能看到完全不同的固定视角,帮你快速掌握手动相机的精髓,都是实用视角:

✔ 视角 1:左侧 + 下方 + 近处 → 左下角斜视图(常用)

camera(-300, 200, 300, 0,0,0, 0,-1,0);

✔ 视角 2:正上方俯视 → 只能看到立方体的顶面

camera(0, -500, 500, 0,0,0, 0,-1,0);

✔ 视角 3:正前方平视 → 只能看到立方体的正面(平面正方形)

camera(0, 0, 500, 0,0,0, 0,-1,0);

✔ 视角 4:右侧 + 正前方 → 只能看到立方体的右侧面

camera(500, 0, 500, 0,0,0, 0,-1,0);

你可以试试,帮助你直观感受理解。

如果想让画面的代码视角固定,但立方体能自转,只需将 "box(100); "一句前的一句:

rotateY(frameCount*0.01);的注释去掉。

这样,立方体在固定视角下缓慢旋转,能看到更多面,立体感更强。

特别提示两点:

1.camera() 手动相机 和 orbitControl() 自动相机,是互斥关系,两者不能同时生效!

  • 如果代码里同时写了 camera() 和 orbitControl() → 你的手动相机设置会被完全覆盖失效,画面依然会被鼠标控制;
  • 想手动固定视角 → 只写 camera(),删掉 orbitControl();
  • 想鼠标自由控制视角 → 只写 orbitControl(),删掉 camera();

原因:orbitControl() 本质是"自动帮你动态刷新 camera () 的参数",会覆盖手动设置的相机位置。

2.perspective()/ortho() (投影模式) + camera() (相机位置),必须写在 draw() 函数的最开头,或 setup() 里!

执行顺序:先设置投影模式 → 再设置相机位置 → 最后绘制 3D 物体(translate/rotate/box/sphere)

原因:投影和相机是"全局视角设置",必须先定义视角,再画物体,否则物体的显示效果会错乱。

六、交互功能

交互功能,本质是:通过"鼠标、键盘、触摸"等用户操作,实时修改 3D 场景的视角、 物体状态、动画参数,让静态的2D、3D 画面变成可操控、可互动的动态场景。

1. 鼠标交互

通过 p5.js 原生的鼠标事件函数,监听鼠标的"点击、松开、悬停"操作,实现"点击物体触发动作、鼠标移到物体上变色"等交互效果,2D/3D 通用,无任何兼容性问题。核心鼠标事件函数(全部写在draw()外面,独立定义):

(1). mousePressed() → 鼠标按下时触发一次(点击);

(2). mouseReleased() → 鼠标松开时触发一次;

(3). mouseIsPressed → 全局变量,判断鼠标是否处于按下状态(长按持续触发)。

示例源码:

html 复制代码
<p>移动鼠标试试看</p>
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.7.0/p5.js"></script>
<script>
function setup() {
    createCanvas(400, 400);
}

function draw() {
    // 根据鼠标位置设置背景色
    let r = map(mouseX, 0, width, 0, 255);
    let g = map(mouseY, 0, height, 0, 255);
    background(r, g, 150);
    
    // 绘制随鼠标移动的形状
    fill(255, 255, 0);
    ellipse(mouseX, mouseY, 50, 50);
    
    // 显示鼠标坐标
    fill(0);
    //text(`X: ${mouseX}, Y: ${mouseY}`, 20, 20);
    text(`X: ${round(mouseX)}, Y: ${round(mouseY)}`, 20, 20); //用round()取整,完美消除小数位
}
</script>

运行截图

2. 键盘交互

通过 p5.js 原生的键盘事件 / 键盘变量,监听键盘的「按键按下 / 松开」操作,实现 「按键控制 3D 物体移动 / 旋转 / 缩放、切换投影模式、暂停动画」 等核心交互,2D/3D 通用,是「操控物体行为」的最佳方式,没有之一。

(1). keyIsPressed → 全局变量,判断「是否有任意按键按下」(长按持续触发);

(2). key → 全局变量,获取「当前按下的具体按键」(比如 key === 'w'、key === 'ArrowUp')。

示例源码:

html 复制代码
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.7.0/p5.js"></script>
<script>
let x = 200;
let y = 200;

function setup() {
    createCanvas(400, 400);
}

function draw() {
    background(220);
    fill(0, 100, 200);
    ellipse(x, y, 50, 50);
    
    fill(0);
    text("使用方向键移动", 150, 380);
}

function keyPressed() {
    // 方向键控制移动
    if (keyCode === LEFT_ARROW) {
        x -= 10;
    } else if (keyCode === RIGHT_ARROW) {
        x += 10;
    } else if (keyCode === UP_ARROW) {
        y -= 10;
    } else if (keyCode === DOWN_ARROW) {
        y += 10;
    }
    
    // 限制在画布内
    x = constrain(x, 25, width - 25);
    y = constrain(y, 25, height - 25);
}

</script>

运行截图

七、动画和粒子系统简介

1. 动画基础

p5.js 实现动画的核心原理:动画 = draw() 函数的"自动循环重绘" + "变量的逐帧增量修改"。p5.js 实现动画前面有些例子已经展示过了,没有任何高深奥秘,是已经介绍过的基础知识的运用,现在概括总结。要点:

• 静态图形,只要逐帧修改变量,就能变成动画。

• 动画本质是"帧循环 + 变量增量",2D 控 X/Y,3D 控 X/Y/Z;

• 变换是动画载体,交互是动画灵魂,投影 / 相机是 3D 动画的视角补充。

简单示例

html 复制代码
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.7.0/p5.js"></script>
<script>
let angle = 0;
let size = 50;

function setup() {
    createCanvas(400, 400);
    angleMode(DEGREES); // 使用角度制
}

function draw() {
    background(220);
    
    // 平移坐标系
    push();
    translate(width/2, height/2);
    
    // 旋转
    rotate(angle);
    
    // 缩放
    let scaleFactor = map(sin(frameCount * 2), -1, 1, 0.5, 1.5);
    scale(scaleFactor);
    
    // 绘制
    fill(100, 200, 255);
    rect(-50, -50, 100, 100);
    pop();
    
    // 更新角度
    angle += 2;
}
</script>

运行截图

2. 粒子系统基础

粒子系统本质是"大量微小独立粒子的群体动画集合",用简单的规则控制无数粒子的行为,形成极具视觉效果的动态场景。本质是"数组 + 循环 + 基础动画"。

粒子系统是游戏、创意编程、可视化的核心技术,几乎所有炫酷的动态效果,都是粒子系统实现的:

√ 2D 场景:雨滴、雪花、火焰、爆炸、烟雾、流水、画笔轨迹、星空、烟花;

√ 3D 场景:3D 星云、行星轨迹、立体爆炸、粒子流、3D 烟雾、光影特效。

粒子系统的"2D/3D 通用优化规则"(避坑)

• 必须清理"死亡粒子":用splice()删除生命周期结束的粒子,否则数组会越来越大,导致动画卡顿;

• 控制粒子数量:一次生成的粒子数不要太多(比如不超过 1000),否则会影响性能;

• 3D 粒子可以用sphere()/box()做粒子,也可以用point()做光点,后者性能更好。

示例

html 复制代码
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.7.0/p5.js"></script>
<script>
let particles = [];

function setup() {
    createCanvas(600, 400);
    
    // 初始化粒子
    for (let i = 0; i < 100; i++) {
        particles.push({
            x: random(width),
            y: random(height),
            vx: random(-1, 1),
            vy: random(-1, 1),
            size: random(5, 15),
            color: [random(255), random(255), random(255)]
        });
    }
}

function draw() {
    background(0, 20); // 半透明背景创建拖尾效果
    
    // 更新和绘制所有粒子
    for (let p of particles) {
        // 更新位置
        p.x += p.vx;
        p.y += p.vy;
        
        // 边界检查
        if (p.x < 0 || p.x > width) p.vx *= -1;
        if (p.y < 0 || p.y > height) p.vy *= -1;
        
        // 鼠标吸引
        let dx = mouseX - p.x;
        let dy = mouseY - p.y;
        let distance = sqrt(dx*dx + dy*dy);
        
        if (distance < 100) {
            p.vx += dx * 0.001;
            p.vy += dy * 0.001;
        }
        
        // 绘制粒子
        fill(p.color[0], p.color[1], p.color[2]);
        noStroke();
        ellipse(p.x, p.y, p.size, p.size);
    }
}

</script>

运行截图

相关推荐
aini_lovee2 小时前
基于MATLAB Simulink的定轴齿轮与行星齿轮仿真模型
开发语言·matlab
沛沛老爹2 小时前
从Web到AI:金融/医疗/教育行业专属Skills生态系统设计实战
java·前端·人工智能·git·金融·架构
w***76552 小时前
PHP vs Python:如何选择?
开发语言·python·php
e***98572 小时前
PHP8.4重磅更新:性能飙升新特性
开发语言
艾莉丝努力练剑2 小时前
【QT】Qt 从零上手:Hello World、项目文件与实战避坑指南
linux·运维·开发语言·c++·qt·继承·qt5
Remember_9932 小时前
Java 入门指南:从零开始掌握核心语法与编程思想
java·c语言·开发语言·ide·python·leetcode·eclipse
sheji34162 小时前
【开题答辩全过程】以 基于Python的街区医院管理系统的设计与实现为例,包含答辩的问题和答案
开发语言·python
C_心欲无痕2 小时前
Next.js 的哲学思想
开发语言·前端·javascript·ecmascript·nextjs
hxjhnct2 小时前
Vue-Router 哈希路由 vs 历史路由详解
javascript·vue.js·哈希算法