mirror of
https://github.com/aculix/huashu-design.git
synced 2026-10-27 07:15:54 +00:00
launch huashu-design v1.0: 9 demos + marketing-first README
- 新增 9 个能力 demo(workflow + capability),每个 MP4 + GIF + 60fps - README 重写:营销 hook 开头 · 功能优先结构 · 自然嵌入 GIF - 修复 render-video.js Google Fonts networkidle 超时 - 修复 c1-ios-prototype 刘海/Home Indicator 背景色 - 补充 references/editable-pptx.md 和 scripts/export_deck_stage_pdf.mjs Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
f3692aac10
commit
b127f8baa3
24 files changed
+8206
-281
No files matched your search
+11
-2
@@ -162,6 +162,12 @@
|
||||
const startTimeRef = useRef(performance.now());
|
||||
const canvasRef = useRef(null);
|
||||
|
||||
// Recording mode: render-video.js injects window.__recording = true before goto.
|
||||
// When set, force loop=false so the export ends on the final frame instead of
|
||||
// wrapping back to t=0 and capturing the start of the next cycle.
|
||||
// (Browsers viewing manually still loop because __recording is undefined there.)
|
||||
const effectiveLoop = (typeof window !== 'undefined' && window.__recording) ? false : loop;
|
||||
|
||||
useEffect(() => {
|
||||
function updateScale() {
|
||||
const vw = window.innerWidth;
|
||||
@@ -195,7 +201,10 @@
|
||||
setTime(prev => {
|
||||
const next = prev + delta;
|
||||
if (next >= duration) {
|
||||
return loop ? 0 : duration;
|
||||
// effectiveLoop honors window.__recording (forced non-loop during export).
|
||||
// Stop just shy of duration so the final-frame state stays rendered
|
||||
// (avoids exiting all Sprites that end exactly at `duration`).
|
||||
return effectiveLoop ? 0 : duration - 0.001;
|
||||
}
|
||||
return next;
|
||||
});
|
||||
@@ -218,7 +227,7 @@
|
||||
cancelled = true;
|
||||
cancelAnimationFrame(rafRef.current);
|
||||
};
|
||||
}, [playing, duration, loop]);
|
||||
}, [playing, duration, effectiveLoop]);
|
||||
|
||||
const handleScrub = useCallback((e) => {
|
||||
const rect = e.currentTarget.getBoundingClientRect();
|
||||
|
||||
+20
-5
@@ -43,12 +43,27 @@
|
||||
this._width = parseInt(this.getAttribute('width')) || 1920;
|
||||
this._height = parseInt(this.getAttribute('height')) || 1080;
|
||||
|
||||
// Shadow DOM 先渲染(独立于子节点,不受 parser 时机影响)
|
||||
this._render();
|
||||
this._collectSlides();
|
||||
this._setupEventListeners();
|
||||
this._restoreSlide();
|
||||
this._updateDisplay();
|
||||
this._setupPrintStyles();
|
||||
|
||||
// 防御:若 script 放在 <head> 里(而非 </deck-stage> 之后),
|
||||
// parser 此刻可能还没处理完子 <section>,querySelectorAll 会返回空。
|
||||
// 延迟到下一个事件循环,确保子节点都已 parse 完毕。
|
||||
const init = () => {
|
||||
this._collectSlides();
|
||||
this._setupEventListeners();
|
||||
this._restoreSlide();
|
||||
this._updateDisplay();
|
||||
this._setupPrintStyles();
|
||||
};
|
||||
|
||||
if (this.ownerDocument.readyState === 'loading') {
|
||||
// 文档还在 parse,等 DOMContentLoaded 一次搞定所有 section
|
||||
this.ownerDocument.addEventListener('DOMContentLoaded', init, { once: true });
|
||||
} else {
|
||||
// 文档已 parse 完(script 在 body 底部或 defer),下一帧收集即可
|
||||
requestAnimationFrame(init);
|
||||
}
|
||||
}
|
||||
|
||||
_render() {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"_meta": {
|
||||
"description": "个人素材索引模板 — 复制此文件并填入你的真实数据",
|
||||
"how_to_use": "1. 复制此文件到你的 agent 私有 memory 目录(Claude Code: ~/.claude/memory/personal-asset-index.json;其他 agent 按其约定) 2. 填入你的真实信息 3. huashu-design skill 在需要个人素材/锚定当前品牌时会自动读取",
|
||||
"how_to_use": "1. 复制此文件到 ~/.claude/memory/personal-asset-index.json 2. 填入你的真实信息 3. design-philosophy skill 会自动读取",
|
||||
"note": "真实数据文件不要放在 skill 目录内,避免随 skill 分发泄露隐私"
|
||||
},
|
||||
|
||||
|
||||
Reference in new issue
Block a user