knowledge-vault/sources/references/AI学习笔记/效果/demo2 copy.html

265 lines
11 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<html lang="zh-cn">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>多画布 JS 动画演示</title>
<script src="https://wantsong.life/p5-demo/p5.js"></script>
<style>
body {
margin: 0;
padding: 20px;
display: flex;
flex-direction: column; /* Stack title and canvases */
align-items: center;
min-height: 100vh;
background-color: #1e1e1e; /* 深色背景 */
font-family: sans-serif;
color: #e0e0e0;
}
h1 {
margin-bottom: 20px;
}
#canvas-container-wrapper {
display: flex;
flex-wrap: wrap; /* 允许换行 */
gap: 20px; /* 画布之间的间距 */
justify-content: center; /* 水平居中 */
}
.canvas-container {
border: 1px solid #444; /* 给每个画布容器添加边框 */
box-shadow: 0 0 10px rgba(0,0,0,0.5);
}
</style>
</head>
<body>
<div id="canvas-container-wrapper">
<div id="canvas-container-1" class="canvas-container"></div>
<div id="canvas-container-2" class="canvas-container"></div>
<div id="canvas-container-3" class="canvas-container"></div>
<div id="canvas-container-4" class="canvas-container"></div>
<div id="canvas-container-5" class="canvas-container"></div>
</div>
<script>
// 工厂函数,用于创建 p5.js sketch
const drawPatternPoint_original = (p, x, y_in, t_current, canvasWidth, canvasHeight) => {
// 参数来自原始公式 (有些是隐式的)
let k_p1 = 4, k_p2 = 2, k_p3 = 3, k_p4 = 29;
let e_p1 = 8, e_p2 = 13;
let q_p1 = 3, q_p2 = 2, q_p3 = 0.3;
let q_s_p1 = 25;
let q_k_mult_c1 = 9, q_k_mult_c2 = 4;
let q_k_mult_sine_e = 9, q_k_mult_sine_d = 3, q_k_mult_sine_t = 2;
let pt_p1 = 30, pt_p2 = 39;
const k_val = (k_p1 + p.sin(y_in * k_p2 - t_current) * k_p3) * p.cos(x / k_p4);
const e_val = y_in / e_p1 - e_p2;
const d_val = p.mag(k_val, e_val);
const c_val = d_val - t_current;
let k_for_division = k_val;
const min_k_magnitude = 0.1; // 防止除以非常小的数
if (Math.abs(k_for_division) < min_k_magnitude) {
k_for_division = min_k_magnitude * (Math.sign(k_for_division) || 1);
}
const q_val_calc = q_p1 * p.sin(k_val * q_p2) +
q_p3 / k_for_division +
p.sin(y_in / q_s_p1) * k_val *
(q_k_mult_c1 + q_k_mult_c2 * p.sin(e_val * q_k_mult_sine_e - d_val * q_k_mult_sine_d + t_current * q_k_mult_sine_t));
// 图案在“原始400x400画布”上的坐标应用了原始偏移
let pattern_x_component = q_val_calc + pt_p1 * p.cos(c_val);
let pattern_y_component = q_val_calc * p.sin(c_val) + d_val * pt_p2;
const original_global_x_offset = 200;
const original_global_y_offset = -220; // 原始公式的Y偏移
const original_canvas_width = 400;
const original_canvas_height = 400;
let x_on_original_canvas = pattern_x_component + original_global_x_offset;
let y_on_original_canvas = pattern_y_component + original_global_y_offset;
// 缩放到当前画布尺寸
const finalX = (x_on_original_canvas / original_canvas_width) * canvasWidth;
const finalY = (y_on_original_canvas / original_canvas_height) * canvasHeight;
p.point(finalX, finalY);
};
// --- 2. 新算法变体 1: "宇宙风车" ---
const drawPatternPoint_variant1 = (p, x_input, y_input, t_current, canvasWidth, canvasHeight) => {
const k_amp = 1.5 + p.sin(t_current * 0.15) * 0.5;
const k_freq1 = 0.025 + p.cos(t_current * 0.06) * 0.01;
const d_scale = 0.035 + p.sin(t_current * 0.08) * 0.01;
const q_amp = 1.8;
let k = k_amp * p.sin(x_input * k_freq1 - t_current * 1.2) * p.cos(y_input * k_freq1 * 0.8 + t_current * 0.6);
let e = p.atan2(y_input / 12 - 8, x_input / 22 - 6) + t_current * 0.25;
let d = p.mag(p.cos(x_input * d_scale + t_current*0.1), p.sin(y_input * d_scale - t_current*0.1)) * 60 + k * 25;
let c = d * 0.12 + e + t_current * 0.9;
let q_base = p.sin(k * q_amp + t_current * 2.2) + p.cos(d * 0.06 - t_current * 1.1);
let q = q_base * (70 + p.sin(e * 2.5 + t_current * 1.5) * 35);
q += p.tan((k + e * 0.5) * 0.1 + t_current * 0.33) * 8;
let pattern_x_component = q * p.cos(c) + d * p.sin(e * 1.2);
let pattern_y_component = q * p.sin(c) - d * p.cos(e * 1.2);
const original_global_x_offset = 200;
const original_global_y_offset = 200; // 调整Y偏移以适应新公式的视觉中心
const original_canvas_width = 400;
const original_canvas_height = 400;
let x_on_original_canvas = pattern_x_component + original_global_x_offset;
let y_on_original_canvas = pattern_y_component + original_global_y_offset;
const finalX = (x_on_original_canvas / original_canvas_width) * canvasWidth;
const finalY = (y_on_original_canvas / original_canvas_height) * canvasHeight;
p.point(finalX, finalY);
};
// --- 3. 新算法变体 2: "电光网格" ---
const drawPatternPoint_variant2 = (p, x_input, y_input, t_current, canvasWidth, canvasHeight) => {
const grid_scale = 0.12 + p.sin(t_current * 0.22) * 0.04;
const ripple_amp = 18 + p.cos(t_current * 0.35) * 6;
const d_factor = 1.8;
const q_mod = 35;
let gx = x_input * grid_scale;
let gy = y_input * grid_scale;
let k = p.sin(gx + t_current * 1.1) * ripple_amp + p.cos(gy - t_current * 0.9) * ripple_amp;
k += p.floor(gx * 0.5) * 8;
let e = p.cos(gy + t_current * 1.3) * ripple_amp - p.sin(gx - t_current * 0.7) * ripple_amp;
e += p.floor(gy * 0.5) * 8;
let d = p.mag(k, e) * d_factor;
d = (d % 180) + p.sin(t_current + gx*0.1)*20;
let c = p.atan2(e, k) + t_current * 0.55 + p.sin(gy*0.2)*0.5;
let q = (p.sin(d * 0.08 + t_current * 1.4) * q_mod) + (p.cos( (k/(Math.abs(k)>0.1?k:0.1)) * 0.06 - t_current) * q_mod);
q += (x_input % 60 - 30) * p.cos(t_current * 0.8 + gy * 0.3);
let pattern_x_component = q * p.cos(c + d*0.01) + k * 0.7;
let pattern_y_component = q * p.sin(c - d*0.01) + e * 0.7;
const original_global_x_offset = 200;
const original_global_y_offset = 200;
const original_canvas_width = 400;
const original_canvas_height = 400;
let x_on_original_canvas = pattern_x_component + original_global_x_offset;
let y_on_original_canvas = pattern_y_component + original_global_y_offset;
const finalX = (x_on_original_canvas / original_canvas_width) * canvasWidth;
const finalY = (y_on_original_canvas / original_canvas_height) * canvasHeight;
p.point(finalX, finalY);
};
// --- 4. 新算法变体 3: "流动丝线" ---
const drawPatternPoint_variant3 = (p, x_input, y_input, t_current, canvasWidth, canvasHeight) => {
const scale1 = 0.025 + p.sin(t_current * 0.06) * 0.01;
const scale2 = 0.035 + p.cos(t_current * 0.09) * 0.01;
const time_factor_k = 0.55 + p.sin(t_current * 0.11) * 0.2;
const time_factor_e = 0.35 + p.cos(t_current * 0.13) * 0.1;
let k_base = p.sin(x_input * scale1 + y_input * scale2 * 0.7 + t_current * time_factor_k);
let e_base = p.cos(x_input * scale2 * 0.7 - y_input * scale1 + t_current * time_factor_e);
let k = k_base * (90 + p.sin(t_current * 0.22 + x_input * 0.015) * 35);
let e = e_base * (90 + p.cos(t_current * 0.27 + y_input * 0.015) * 35);
let d = p.sqrt(k*k + e*e) * 0.35;
d = p.abs(p.tan(d * 0.06 + t_current * 0.33)) * 22;
d = p.constrain(d, 0, 160);
let angle_offset = p.sin(t_current * 0.45 + (x_input - y_input) * 0.006) * p.PI * 0.8;
let c = p.atan2(e_base, k_base) + angle_offset + t_current*0.2;
let q_val = p.sin(d * 0.11 - t_current * 1.3) * 55;
q_val += p.cos((k_base - e_base) * 5.5 + t_current * 2.1) * (35 + p.sin(t_current*0.55)*12);
let pattern_x_component = q_val * p.cos(c) + d * p.sin(c + p.PI / 1.8);
let pattern_y_component = q_val * p.sin(c) - d * p.cos(c + p.PI / 1.8);
const original_global_x_offset = 200;
const original_global_y_offset = 200;
const original_canvas_width = 400;
const original_canvas_height = 400;
let x_on_original_canvas = pattern_x_component + original_global_x_offset;
let y_on_original_canvas = pattern_y_component + original_global_y_offset;
const finalX = (x_on_original_canvas / original_canvas_width) * canvasWidth;
const finalY = (y_on_original_canvas / original_canvas_height) * canvasHeight;
p.point(finalX, finalY);
};
const sketchFactory = (config) => {
return (p) => {
p.t = 0; // 每个 sketch 独立的时间变量
const canvasWidth = config.canvasSize;
const canvasHeight = config.canvasSize;
const numPoints = config.points;
const type = config.type; // 这个 'type' 将用来选择绘图函数
let currentDrawingFunction; // 用于存储选定的绘图函数
// 根据 type 选择绘图函数
switch (type) {
case 1:
currentDrawingFunction = drawPatternPoint_variant1;
break;
case 2:
currentDrawingFunction = drawPatternPoint_variant2;
break;
case 3:
currentDrawingFunction = drawPatternPoint_variant3;
break;
// 您可以添加 case 4, case 5 等来对应更多的变体
default: // type 0 或其他未指定的值将使用原始算法
currentDrawingFunction = drawPatternPoint_original;
}
p.setup = () => {
p.createCanvas(canvasWidth, canvasHeight);
};
p.draw = () => {
p.background(9);
p.stroke(255, 96);
p.t += p.PI / 240; // 更新当前 sketch 的时间
for (let i = 0; i < numPoints; i++) {
// 调用选定的绘图函数
// 参数: p5实例, x输入, y输入, 当前时间, 画布宽, 画布高
currentDrawingFunction(p, i, i / 235, p.t, canvasWidth, canvasHeight);
}
};
};
};
// --- 6. 更新 canvasConfigs 以使用新的类型 ---
const canvasConfigs = [
{ type: 0, canvasSize: 400, points: 8000 }, // 使用原始算法
{ type: 1, canvasSize: 400, points: 2000 }, // 使用变体1
{ type: 2, canvasSize: 400, points: 8000 }, // 使用变体2
{ type: 3, canvasSize: 400, points: 8000 }, // 使用变体3
{ type: 1, canvasSize: 400, points: 8500 } // 再次使用变体1 (或选择其他类型,可以增加点数)
];
// --- 7. 创建 p5 实例 (这部分代码保持不变) ---
canvasConfigs.forEach((config, index) => {
const containerId = `canvas-container-${index + 1}`;
new p5(sketchFactory(config), containerId);
});
</script>
</body>
</html>