<rss xmlns:atom="http://www.w3.org/2005/Atom" version="2.0">
    <channel>
        <title>Three.js - 标签 - lihuu — 系统工程、AI 工具链与 Rust 开发博客</title>
        <link>https://silentstormic.top/tags/Three.js/</link>
        <description>Three.js - 标签 - lihuu — 系统工程、AI 工具链与 Rust 开发博客</description>
        <generator>Hugo -- gohugo.io</generator><language>zh-CN</language><lastBuildDate>Sun, 13 Sep 2026 00:00:00 &#43;0800</lastBuildDate><atom:link href="https://silentstormic.top/tags/Three.js/" rel="self" type="application/rss+xml" /><item>
    <title>涂鸦俄罗斯方块</title>
    <link>https://silentstormic.top/research/doodle-tetris/</link>
    <pubDate>Sun, 13 Sep 2026 00:00:00 &#43;0800</pubDate>
    <author>lihuu</author>
    <guid>https://silentstormic.top/research/doodle-tetris/</guid>
    <description><![CDATA[<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>涂鸦俄罗斯方块 · Doodle Tetris</title>
<style>
  html, body { margin: 0; height: 100%; overflow: hidden; background: #faf3e4; }
  #scene { display: block; width: 100%; height: 100%; touch-action: none; cursor: grab; }
  #scene:active { cursor: grabbing; }
  .hud {
    position: fixed;
    font-family: 'Comic Sans MS', 'Chalkboard SE', 'Marker Felt', 'Segoe Print', 'PingFang SC', sans-serif;
    color: #4a443c;
    pointer-events: none;
    user-select: none;
    z-index: 10;
  }
  #title { top: 18px; left: 24px; font-size: 26px; font-weight: bold; transform: rotate(-2deg); letter-spacing: 2px; }
  #title small { display: block; font-size: 12px; font-weight: normal; opacity: .6; letter-spacing: 4px; margin-top: 4px; }
  #hint { bottom: 16px; left: 24px; font-size: 13px; opacity: .6; line-height: 1.7; }
  #keys {
    bottom: 16px; left: 24px; font-size: 13px; line-height: 2.1;
    transform: rotate(-1deg); opacity: .85;
  }
  #keys b { display: block; letter-spacing: 4px; font-size: 15px; margin-bottom: 3px; }
  #keys .k {
    display: inline-block; border: 1.5px solid #6b6357; border-radius: 5px;
    padding: 0 6px; margin: 0 2px; font-size: 11px; line-height: 1.7;
    background: rgba(255, 253, 244, .75); box-shadow: 1.5px 1.5px 0 rgba(58, 53, 46, .22);
  }
  #keys .k:nth-of-type(odd) { transform: rotate(-1.5deg); }
  #keys .k:nth-of-type(even) { transform: rotate(1.2deg); }
  #panel {
    top: 20px; right: 26px; font-size: 16px; line-height: 1.9;
    transform: rotate(2deg); text-align: right;
  }
  #panel b { font-size: 22px; margin-left: 8px; }
  #panel .lvl { color: #e8734a; }
  #overlay {
    top: 0; left: 0; right: 0; bottom: 0;
    display: none; flex-direction: column; align-items: center; justify-content: center;
    background: rgba(250, 243, 228, .55);
  }
  #ovTitle { font-size: 52px; font-weight: bold; transform: rotate(-3deg); letter-spacing: 6px; color: #3a352e; }
  #ovSub { margin-top: 18px; font-size: 16px; opacity: .7; transform: rotate(1deg); }
</style>
</head>
<body>
<canvas id="scene"></canvas>
<div class="hud" id="title">涂鸦俄罗斯方块<small>DOODLE TETRIS · THREE.JS</small></div>
<div class="hud" id="panel">
  分数<b id="score">0</b><br>
  行数<b id="lines">0</b><br>
  等级<b id="level" class="lvl">1</b>
</div>
<div class="hud" id="keys">
  <b>键位</b>
  <div><span class="k">A</span><span class="k">D</span> 左右 · <span class="k">W</span><span class="k">空格</span> 旋转 · <span class="k">S</span><span class="k">↓</span> 秒落 · <span class="k">P</span> 暂停 · <span class="k">R</span> 重来</div>
  <div>鼠标 移动瞄准列 · <span class="k">左键</span> 旋转 · <span class="k">右键</span> 秒落</div>
  <div>视角固定正面 · 滚轮缩放 · 双击复位</div>
</div>
<div class="hud" id="overlay"><div id="ovTitle"></div><div id="ovSub"></div></div>
<script type="module" src="./tetris.js?v=7"></script>
</body>
</html>]]></description>
</item>
<item>
    <title>涂鸦贪吃蛇 · Doodle Snake</title>
    <link>https://silentstormic.top/research/doodle-snake/</link>
    <pubDate>Sun, 13 Sep 2026 00:00:00 &#43;0800</pubDate>
    <author>lihuu</author>
    <guid>https://silentstormic.top/research/doodle-snake/</guid>
    <description><![CDATA[<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>涂鸦贪吃蛇 · Doodle Snake</title>
<style>
  html, body { margin: 0; height: 100%; overflow: hidden; background: #faf3e4; }
  #scene { display: block; width: 100%; height: 100%; touch-action: none; cursor: grab; }
  #scene:active { cursor: grabbing; }
  .hud {
    position: fixed;
    font-family: 'Comic Sans MS', 'Chalkboard SE', 'Marker Felt', 'Segoe Print', 'PingFang SC', sans-serif;
    color: #4a443c;
    pointer-events: none;
    user-select: none;
    z-index: 10;
  }
  #title { top: 18px; left: 24px; font-size: 26px; font-weight: bold; transform: rotate(-2deg); letter-spacing: 2px; }
  #title small { display: block; font-size: 12px; font-weight: normal; opacity: .6; letter-spacing: 4px; margin-top: 4px; }
  #keys {
    bottom: 16px; left: 24px; font-size: 13px; line-height: 2.1;
    transform: rotate(-1deg); opacity: .85;
  }
  #keys b { display: block; letter-spacing: 4px; font-size: 15px; margin-bottom: 3px; }
  #keys .k {
    display: inline-block; border: 1.5px solid #6b6357; border-radius: 5px;
    padding: 0 6px; margin: 0 2px; font-size: 11px; line-height: 1.7;
    background: rgba(255, 253, 244, .75); box-shadow: 1.5px 1.5px 0 rgba(58, 53, 46, .22);
  }
  #keys .k:nth-of-type(odd) { transform: rotate(-1.5deg); }
  #keys .k:nth-of-type(even) { transform: rotate(1.2deg); }
  #panel {
    top: 20px; right: 26px; font-size: 16px; line-height: 1.9;
    transform: rotate(2deg); text-align: right;
  }
  #panel b { font-size: 22px; margin-left: 8px; }
  #panel .lvl { color: #e8734a; }
  #overlay {
    top: 0; left: 0; right: 0; bottom: 0;
    display: none; flex-direction: column; align-items: center; justify-content: center;
    background: rgba(250, 243, 228, .55);
  }
  #ovTitle { font-size: 52px; font-weight: bold; transform: rotate(-3deg); letter-spacing: 6px; color: #3a352e; }
  #ovSub { margin-top: 18px; font-size: 16px; opacity: .7; transform: rotate(1deg); }
</style>
</head>
<body>
<canvas id="scene"></canvas>
<div class="hud" id="title">涂鸦贪吃蛇<small>DOODLE SNAKE · THREE.JS</small></div>
<div class="hud" id="panel">
  分数<b id="score">0</b><br>
  长度<b id="length">3</b><br>
  速度<b id="level" class="lvl">1</b>
</div>
<div class="hud" id="keys">
  <b>键位</b>
  <div><span class="k">↑</span><span class="k">↓</span><span class="k">←</span><span class="k">→</span> 或 <span class="k">W</span><span class="k">A</span><span class="k">S</span><span class="k">D</span> 转向 · <span class="k">Esc</span>/<span class="k">P</span> 暂停 · <span class="k">R</span> 重来</div>
  <div>鼠标 点击蛇头四周转向 · 手机 滑动转向</div>
  <div>吃苹果 +10 · 金宝石 +50 · 撞墙或咬到自己就完啦</div>
  <div>视角固定 · 滚轮缩放 · 双击复位</div>
</div>
<div class="hud" id="overlay"><div id="ovTitle"></div><div id="ovSub"></div></div>
<script type="module" src="./snake.js"></script>
</body>
</html>]]></description>
</item>
<item>
    <title>二维码工坊：Three.js 3D 石刻二维码（涂鸦风）</title>
    <link>https://silentstormic.top/research/doodle-qr/</link>
    <pubDate>Wed, 09 Sep 2026 08:56:00 &#43;0800</pubDate>
    <author>lihuu</author>
    <guid>https://silentstormic.top/research/doodle-qr/</guid>
    <description><![CDATA[<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>二维码工坊 · 3D 石刻 · Doodle QR</title>
<style>
  :root { --ink: #3a352e; --paper: #faf3e4; --accent: #f25c54; }
  * { box-sizing: border-box; }
  html, body { margin: 0; height: 100%; overflow: hidden; background: var(--paper); }
  #scene { display: block; width: 100%; height: 100%; touch-action: none; cursor: grab; }
  #scene:active { cursor: grabbing; }

  .hud {
    position: fixed;
    font-family: 'Comic Sans MS', 'Chalkboard SE', 'Marker Felt', 'Segoe Print', 'PingFang SC', sans-serif;
    color: var(--ink);
    pointer-events: none;
    user-select: none;
    z-index: 10;
  }
  #title { top: 18px; left: 24px; font-size: 30px; font-weight: bold; transform: rotate(-2deg); letter-spacing: 2px; }
  #title small { display: block; font-size: 12px; font-weight: normal; opacity: .6; letter-spacing: 4px; margin-top: 4px; }
  #hint { bottom: 16px; left: 24px; font-size: 13px; opacity: .55; }
  #status { bottom: 78px; left: 50%; transform: translateX(-50%) rotate(-.6deg); font-size: 15px; font-weight: bold; opacity: .8; letter-spacing: 1px; white-space: nowrap; }
  #status.done { color: var(--accent); }

  /* 底部操作条 */
  #bar {
    position: fixed; bottom: 22px; left: 50%; transform: translateX(-50%);
    display: flex; gap: 10px; align-items: stretch; z-index: 20;
    font-family: 'Comic Sans MS', 'Chalkboard SE', 'Marker Felt', 'Segoe Print', 'PingFang SC', sans-serif;
    max-width: calc(100vw - 32px);
  }
  input {
    font: inherit; color: var(--ink); background: #fffdf6; width: min(300px, 42vw);
    border: 2.5px solid var(--ink); border-radius: 15px 225px 15px 255px / 255px 15px 225px 15px;
    padding: 10px 14px; outline: none; min-width: 0;
  }
  input:focus { box-shadow: 2px 3px 0 rgba(58, 53, 46, .35); }
  .btn {
    font: inherit; font-weight: bold; cursor: pointer; color: var(--ink); background: #fff;
    border: 2.5px solid var(--ink); border-radius: 255px 15px 225px 15px / 15px 225px 15px 255px;
    padding: 10px 16px; box-shadow: 2px 3px 0 rgba(58, 53, 46, .85); transform: rotate(.6deg);
    white-space: nowrap;
  }
  .btn:active { transform: translateY(2px); box-shadow: 0 1px 0 rgba(58, 53, 46, .85); }
  .btn.primary { background: #ffd166; }
  @keyframes shake { 0%,100% { transform: translateX(0); } 25% { transform: translateX(-6px); } 75% { transform: translateX(6px); } }
  .shake { animation: shake .3s 2; }

  /* 右上角 2D 原图卡片 */
  #card {
    position: fixed; top: 18px; right: 20px; z-index: 20;
    background: #fff; border: 2.5px solid var(--ink);
    border-radius: 255px 15px 225px 15px / 15px 225px 15px 255px;
    box-shadow: 3px 4px 0 rgba(58, 53, 46, .8);
    padding: 14px 14px 10px; transform: rotate(1.6deg);
    display: flex; flex-direction: column; align-items: center; gap: 6px;
    font-family: 'Comic Sans MS', 'Chalkboard SE', 'Marker Felt', 'Segoe Print', 'PingFang SC', sans-serif;
  }
  #card .tape {
    position: absolute; width: 60px; height: 18px;
    background: rgba(255, 214, 102, .78); border: 1px solid rgba(58, 53, 46, .25);
    top: -10px; left: -20px; transform: rotate(-9deg);
  }
  #qr2d { width: 124px; height: auto; display: block; }
  #qr2dmeta { font-size: 10.5px; opacity: .6; letter-spacing: 1px; }
  .btn.mini { font-size: 12px; padding: 5px 12px; }

  @media (max-width: 720px) {
    #title { font-size: 22px; }
    #card { transform: rotate(1.6deg) scale(.82); transform-origin: top right; }
    #bar { flex-wrap: wrap; justify-content: center; }
    input { width: 60vw; }
    #status { bottom: 118px; }
  }
</style>
</head>
<body>
<canvas id="scene"></canvas>

<div class="hud" id="title">✏️ 二维码工坊<small>DOODLE QR · 3D 石刻 · THREE.JS</small></div>

<div id="card">
  <i class="tape"></i>
  <canvas id="qr2d" width="10" height="10"></canvas>
  <div id="qr2dmeta"></div>
  <button id="dl" class="btn mini">下载 PNG</button>
</div>

<div class="hud" id="status">素坯已就位 · 点「开刻」</div>

<div id="bar">
  <input id="input" type="text" value="https://www.google.com" spellcheck="false" placeholder="输入网址或文字…">
  <button id="gen" class="btn primary">开刻</button>
  <button id="replay" class="btn">重播</button>
  <button id="front" class="btn">摆正</button>
</div>

<div class="hud" id="hint">拖动旋转 · 滚轮缩放 · 双击复位 · 不动它就自己转</div>
<script type="module" src="./qr.js?v=2"></script>
</body>
</html>]]></description>
</item>
<item>
    <title>涂鸦小镇：Three.js 手绘涂鸦风 3D 场景</title>
    <link>https://silentstormic.top/research/doodle-town/</link>
    <pubDate>Wed, 09 Sep 2026 08:53:00 &#43;0800</pubDate>
    <author>lihuu</author>
    <guid>https://silentstormic.top/research/doodle-town/</guid>
    <description><![CDATA[<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>涂鸦小镇 · Doodle Town</title>
<style>
  html, body { margin: 0; height: 100%; overflow: hidden; background: #faf3e4; }
  #scene { display: block; width: 100%; height: 100%; touch-action: none; cursor: grab; }
  #scene:active { cursor: grabbing; }
  .hud {
    position: fixed;
    font-family: 'Comic Sans MS', 'Chalkboard SE', 'Marker Felt', 'Segoe Print', 'PingFang SC', sans-serif;
    color: #4a443c;
    pointer-events: none;
    user-select: none;
    z-index: 10;
  }
  #title { top: 18px; left: 24px; font-size: 30px; font-weight: bold; transform: rotate(-2deg); letter-spacing: 2px; }
  #title small { display: block; font-size: 13px; font-weight: normal; opacity: .6; letter-spacing: 4px; margin-top: 4px; }
  #hint { bottom: 16px; left: 24px; font-size: 14px; opacity: .6; }
  #badge { top: 20px; right: 24px; font-size: 14px; opacity: .75; transform: rotate(2deg); pointer-events: auto; cursor: pointer; touch-action: none; }
  #badge:hover { opacity: 1; }
  #badge:active { cursor: grabbing; }
</style>
</head>
<body>
<canvas id="scene"></canvas>
<div class="hud" id="title">涂鸦小镇<small>DOODLE TOWN · THREE.JS DEMO</small></div>
<div class="hud" id="badge">🌤 加载天气中…</div>
<div class="hud" id="hint">点徽章换天气 · 拖徽章拨时间 · 双击徽章回现实 · 拖动旋转 · 滚轮缩放</div>
<script type="module" src="./main.js?v=2"></script>
</body>
</html>]]></description>
</item>
</channel>
</rss>
