一个上帝类程序作画

<!DOCTYPE html>

<html lang="zh-CN">

<head>

<meta charset="UTF-8">

<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">

<title>上帝类 · 算法创世绘 | 自动生成艺术</title>

<style>

* {

box-sizing: border-box;

user-select: none;

}

body {

background: radial-gradient(circle at 20% 30%, #0f111f, #010207);

font-family: 'Segoe UI', 'Inter', system-ui, monospace;

min-height: 100vh;

padding: 1.5rem;

display: flex;

justify-content: center;

align-items: center;

}

.god-panel {

max-width: 1300px;

width: 100%;

background: rgba(14, 17, 30, 0.9);

backdrop-filter: blur(6px);

border-radius: 2rem;

box-shadow: 0 25px 45px rgba(0,0,0,0.6), 0 0 0 1px rgba(255,215,130,0.2);

padding: 1.5rem;

}

h1 {

font-size: 1.9rem;

font-weight: 800;

background: linear-gradient(120deg, #FFE6B0, #B7C9FF);

-webkit-background-clip: text;

background-clip: text;

color: transparent;

}

.sub {

color: #a4afdf;

font-size: 0.8rem;

margin-bottom: 1.5rem;

border-left: 3px solid #ffb347;

padding-left: 14px;

}

.canvas-area {

background: #0a0c16;

border-radius: 1.5rem;

padding: 1rem;

box-shadow: inset 0 0 6px #00000040, 0 8px 20px black;

margin-bottom: 1.5rem;

}

canvas {

width: 100%;

height: auto;

background: white;

border-radius: 1rem;

box-shadow: 0 4px 12px rgba(0,0,0,0.5);

display: block;

}

.controls {

background: #0b0d19cc;

border-radius: 1.2rem;

padding: 1rem;

backdrop-filter: blur(4px);

}

.title-sm {

font-size: 0.9rem;

font-weight: 600;

color: #ffcd94;

margin-bottom: 10px;

display: flex;

align-items: center;

gap: 8px;

}

.algo-selector {

display: flex;

flex-wrap: wrap;

gap: 10px;

margin-bottom: 15px;

}

button {

background: #2a2f50;

border: none;

padding: 6px 16px;

border-radius: 40px;

font-weight: 600;

color: white;

font-size: 0.8rem;

cursor: pointer;

transition: 0.2s;

}

button.primary {

background: #ffa62e;

color: #1e1f2c;

}

button.primary:hover {

background: #ffbc62;

transform: scale(0.96);

}

button:hover {

background: #404871;

transform: translateY(-1px);

}

.param-slider {

margin: 12px 0;

}

.param-slider label {

font-size: 0.75rem;

color: #bfc8ff;

display: flex;

justify-content: space-between;

}

inputtype="range" {

width: 100%;

background: #2f3557;

height: 3px;

border-radius: 3px;

}

.status {

background: #00000066;

border-radius: 1rem;

padding: 6px 12px;

font-size: 0.7rem;

color: #ccd6ff;

margin-top: 12px;

text-align: center;

}

footer {

font-size: 0.7rem;

color: #6b729b;

text-align: center;

margin-top: 1rem;

}

</style>

</head>

<body>

<div class="god-panel">

<h1>🌀 上帝类 · 算法创世绘 🌀</h1>

<div class="sub">≡ 从白纸生成 · 分形/噪声/递归艺术 ≡</div>

<div class="canvas-area">

<canvas id="artCanvas" width="800" height="600" style="width:100%; height:auto; aspect-ratio:800/600;"></canvas>

</div>

<div class="controls">

<div class="title-sm">⚙️ 算法圣所</div>

<div class="algo-selector">

<button data-algo="fractalTree" class="primary">🌳 递归分形树</button>

<button data-algo="mandelbrot">🐚 曼德博集合</button>

<button data-algo="noiseWave">🌊 噪声波纹</button>

<button data-algo="sierpinski">🔺 谢尔宾斯基地毯</button>

<button data-algo="circlePacking">🔘 圆填充</button>

</div>

<div id="paramPanel" class="param-slider">

<label><span>🌿 递归深度 / 迭代次数</span><span id="depthValue">5</span></label>

<input type="range" id="depthSlider" min="1" max="12" step="1" value="5">

</div>

<div class="status" id="statusMsg">⚡ 上帝算法待命 | 选择一种创世法则</div>

</div>

<footer>🎨 全知全能生成 | 每个算法自动在白纸上绘制神迹 | 无需手动画一笔</footer>

</div>

<script>

// ======================== 上帝类:算法自动绘图核心 ========================

class ArtGenesisGod {

constructor() {

this.canvas = document.getElementById('artCanvas');

this.ctx = this.canvas.getContext('2d');

this.width = 800;

this.height = 600;

this.canvas.width = this.width;

this.canvas.height = this.height;

// 当前选中的算法

this.currentAlgo = 'fractalTree';

// 参数

this.depth = 5; // 递归深度 / 迭代次数

this.maxDepth = 12;

// DOM 元素

this.algoBtns = document.querySelectorAll('data-algo');

this.depthSlider = document.getElementById('depthSlider');

this.depthValueSpan = document.getElementById('depthValue');

this.statusDiv = document.getElementById('statusMsg');

this.initEvents();

// 初始绘制默认算法

this.draw();

}

initEvents() {

// 算法切换

this.algoBtns.forEach(btn => {

btn.addEventListener('click', (e) => {

this.currentAlgo = btn.dataset.algo;

// 更新按钮高亮

this.algoBtns.forEach(b => b.classList.remove('primary'));

btn.classList.add('primary');

this.draw();

});

});

// 深度/迭代滑动条

this.depthSlider.addEventListener('input', (e) => {

this.depth = parseInt(e.target.value);

this.depthValueSpan.innerText = this.depth;

this.draw();

});

}

updateStatus(msg) {

this.statusDiv.innerHTML = `✨ ${msg}`;

setTimeout(() => {

if (this.statusDiv.innerHTML === `✨ ${msg}`) {

// 保持静默

}

}, 2000);

}

// 清空白纸(填充白色)

clearCanvas() {

this.ctx.fillStyle = '#FFFFFF';

this.ctx.fillRect(0, 0, this.width, this.height);

}

// 核心:根据算法调用对应绘制函数

draw() {

this.clearCanvas();

switch (this.currentAlgo) {

case 'fractalTree':

this.drawFractalTree();

break;

case 'mandelbrot':

this.drawMandelbrot();

break;

case 'noiseWave':

this.drawNoiseWave();

break;

case 'sierpinski':

this.drawSierpinskiCarpet();

break;

case 'circlePacking':

this.drawCirclePacking();

break;

default:

this.drawFractalTree();

}

this.updateStatus(`已显圣 · {this.getAlgoName(this.currentAlgo)} \| 深度/迭代: {this.depth}`);

}

getAlgoName(algo) {

const map = {

fractalTree: '递归分形树',

mandelbrot: '曼德博集合',

noiseWave: '噪声波纹',

sierpinski: '谢尔宾斯基地毯',

circlePacking: '圆填充'

};

return mapalgo || algo;

}

// ---------- 算法 1: 递归分形树 (彩色渐变) ----------

drawFractalTree() {

const startX = this.width / 2;

const startY = this.height - 50;

const startLen = 100;

const angle = -Math.PI / 2; // 向上

const branchAngle = Math.PI / 6; // 分支角度30度

const shrink = 0.67; // 长度缩减比例

this.ctx.save();

this.ctx.translate(startX, startY);

this.drawBranch(this.depth, startLen, angle, branchAngle, shrink);

this.ctx.restore();

}

drawBranch(depth, length, angle, branchAngle, shrink) {

if (depth === 0 || length < 2) return;

const x2 = Math.cos(angle) * length;

const y2 = Math.sin(angle) * length;

// 绘制树干/分支

this.ctx.beginPath();

this.ctx.moveTo(0, 0);

this.ctx.lineTo(x2, y2);

// 颜色:根据深度渐变 (棕色 -> 绿色)

const greenIntensity = 0.3 + (depth / this.maxDepth) * 0.6;

const r = 100 + (this.maxDepth - depth) * 12;

const g = 70 + depth * 15;

const b = 40;

this.ctx.strokeStyle = `rgb({r}, {g}, ${b})`;

this.ctx.lineWidth = Math.max(1, depth * 1.2);

this.ctx.stroke();

// 递归左分支 & 右分支

this.ctx.save();

this.ctx.translate(x2, y2);

this.drawBranch(depth - 1, length * shrink, angle - branchAngle, branchAngle, shrink);

this.drawBranch(depth - 1, length * shrink, angle + branchAngle, branchAngle, shrink);

this.ctx.restore();

// 叶子效果: 最后一级绘制小圆点

if (depth === 1) {

this.ctx.beginPath();

this.ctx.arc(x2, y2, 3, 0, Math.PI * 2);

this.ctx.fillStyle = `rgb(255, ${120 + depth * 30}, 80)`;

this.ctx.fill();

}

}

// ---------- 算法 2: 曼德博集合 (经典分形) ----------

drawMandelbrot() {

const maxIter = Math.min(200, Math.max(20, this.depth * 15));

const xMin = -2.5, xMax = 1;

const yMin = -1.2, yMax = 1.2;

const imageData = this.ctx.createImageData(this.width, this.height);

for (let py = 0; py < this.height; py++) {

for (let px = 0; px < this.width; px++) {

const x0 = xMin + (px / this.width) * (xMax - xMin);

const y0 = yMin + (py / this.height) * (yMax - yMin);

let x = 0, y = 0;

let iter = 0;

while (x*x + y*y <= 4 && iter < maxIter) {

const xt = x*x - y*y + x0;

y = 2*x*y + y0;

x = xt;

iter++;

}

const color = iter === maxIter ? 0 : 255 - (iter / maxIter) * 255;

const hue = (iter / maxIter) * 360;

const sat = 0.8;

const light = iter === maxIter ? 0 : 0.6;

const rgb = this.hslToRgb(hue, sat, light);

const idx = (py * this.width + px) * 4;

if (iter === maxIter) {

imageData.dataidx = 0;

imageData.dataidx+1 = 0;

imageData.dataidx+2 = 0;

} else {

imageData.dataidx = rgb0;

imageData.dataidx+1 = rgb1;

imageData.dataidx+2 = rgb2;

}

imageData.dataidx+3 = 255;

}

}

this.ctx.putImageData(imageData, 0, 0);

}

hslToRgb(h, s, l) {

let r, g, b;

if (s === 0) {

r = g = b = l;

} else {

const hue2rgb = (p, q, t) => {

if (t < 0) t += 1;

if (t > 1) t -= 1;

if (t < 1/6) return p + (q - p) * 6 * t;

if (t < 1/2) return q;

if (t < 2/3) return p + (q - p) * (2/3 - t) * 6;

return p;

};

const q = l < 0.5 ? l * (1 + s) : l + s - l * s;

const p = 2 * l - q;

r = hue2rgb(p, q, h / 360 + 1/3);

g = hue2rgb(p, q, h / 360);

b = hue2rgb(p, q, h / 360 - 1/3);

}

return Math.round(r \* 255), Math.round(g \* 255), Math.round(b \* 255);

}

// ---------- 算法 3: 噪声波纹 (基于正弦+余弦的抽象图案) ----------

drawNoiseWave() {

const freq = 0.02 + this.depth * 0.005;

const time = 0; // 静态图案

for (let y = 0; y < this.height; y++) {

for (let x = 0; x < this.width; x++) {

const nx = x / this.width;

const ny = y / this.height;

// 多组波形叠加

const val1 = Math.sin(nx * Math.PI * 8 * (this.depth/3)) * Math.cos(ny * Math.PI * 8);

const val2 = Math.sin((nx * 15 + ny * 10) * freq * 20);

const val3 = Math.sin(ny * 20 * freq * 10) * Math.cos(nx * 15);

let intensity = (val1 + val2 + val3) / 2.2;

intensity = (intensity + 1) / 2; // 0-1

const hue = (intensity * 360 + (nx * 180)) % 360;

const sat = 0.7;

const light = 0.5 + intensity * 0.3;

const rgb = this.hslToRgb(hue, sat, light);

const idx = (y * this.width + x) * 4;

this.ctx.fillStyle = `rgb({rgb\[0\]}, {rgb1}, ${rgb2})`;

this.ctx.fillRect(x, y, 1, 1);

}

}

}

// ---------- 算法 4: 谢尔宾斯基地毯 (递归方块) ----------

drawSierpinskiCarpet() {

const size = Math.min(this.width, this.height) * 0.8;

const startX = (this.width - size) / 2;

const startY = (this.height - size) / 2;

this.ctx.fillStyle = '#000000';

this.ctx.fillRect(startX, startY, size, size);

this.drawCarpet(startX, startY, size, this.depth);

}

drawCarpet(x, y, size, depth) {

if (depth === 0) return;

const newSize = size / 3;

// 中间挖空 (白色)

this.ctx.fillStyle = '#FFFFFF';

this.ctx.fillRect(x + newSize, y + newSize, newSize, newSize);

// 递归周围8个格子

for (let i = 0; i < 3; i++) {

for (let j = 0; j < 3; j++) {

if (i === 1 && j === 1) continue;

this.drawCarpet(x + i * newSize, y + j * newSize, newSize, depth - 1);

}

}

}

// ---------- 算法 5: 圆填充 (随机生成不重叠的圆,用颜色渐变) ----------

drawCirclePacking() {

const circles = \[\];

const minRadius = 5;

const maxRadius = 50;

const targetCount = 180 + this.depth * 20;

const maxAttempts = 5000;

let attempts = 0;

while (circles.length < targetCount && attempts < maxAttempts) {

const radius = minRadius + Math.random() * (maxRadius - minRadius) * (1 - circles.length / targetCount * 0.5);

const x = radius + Math.random() * (this.width - 2 * radius);

const y = radius + Math.random() * (this.height - 2 * radius);

let overlapping = false;

for (let c of circles) {

const dx = c.x - x;

const dy = c.y - y;

const dist = Math.sqrt(dx*dx + dy*dy);

if (dist < c.radius + radius) {

overlapping = true;

break;

}

}

if (!overlapping) {

circles.push({ x, y, radius });

}

attempts++;

}

// 绘制圆形,颜色基于位置和半径

for (let c of circles) {

const hue = (c.x / this.width * 360 + c.y / this.height * 180) % 360;

const sat = 0.6 + (c.radius / maxRadius) * 0.4;

const light = 0.5 + (c.radius / maxRadius) * 0.3;

const rgb = this.hslToRgb(hue, sat, light);

this.ctx.beginPath();

this.ctx.arc(c.x, c.y, c.radius, 0, Math.PI * 2);

this.ctx.fillStyle = `rgb({rgb\[0\]}, {rgb1}, ${rgb2})`;

this.ctx.fill();

this.ctx.strokeStyle = '#ffffff';

this.ctx.lineWidth = 1;

this.ctx.stroke();

}

}

}

// 启动上帝类

window.addEventListener('DOMContentLoaded', () => {

window.artGod = new ArtGenesisGod();

});

</script>

</body>

</html>

相关推荐
如意IT3 小时前
浏览器CDP自动化检测技术-Error和Worker
前端·javascript·自动化·chromium·指纹浏览器
IT_陈寒3 小时前
Python列表的+=操作符坑了我一整天
前端·人工智能·后端
右耳朵猫AI3 小时前
React周刊2026W22 | React 13周年、React Router 7.16.0、Spoiled 0.5
前端·react.js·前端框架
恋猫de小郭3 小时前
flutter_agent_lens 用 MCP 服务,将 Flutter DevTools 暴露给 AI
android·前端·flutter
广州灵眸科技有限公司3 小时前
3Tops NPU + 4核高性能架构:灵眸科技EASY-EAI-PI2开发板,为边缘AI开启“easy模式”
服务器·前端·人工智能·python·科技·深度学习·架构
李白的天不白3 小时前
服务器地址在哪里 pwd
运维·前端·nginx
晓13133 小时前
【Cocos Creator 3.x】篇——第三章 脚本编程
前端·javascript·游戏引擎
雨翼轻尘3 小时前
01_HTML基本结构
前端·html·基本结构
右耳朵猫AI3 小时前
前端周刊2026W22 | React 13周年、TanStack Router、Deno 2.8、Node.js 26、npm 分阶段发布
前端·react.js·node.js