Skip to content

Commit 428ae17

Browse files
momoclaude
authored andcommitted
Optimize performance and fix timer leak
- Fix closeTimer not cleared on unmount in LicenseSelector - Replace Math.sqrt with squared distance in collision/proximity checks - Skip triggerRef for empty/inactive arrays in animation loop - Extract i18n translations to dedicated license-i18n.ts Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 4909f8e commit 428ae17

3 files changed

Lines changed: 194 additions & 187 deletions

File tree

docs/.vitepress/components/LicenseSelector.vue

Lines changed: 6 additions & 176 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
<script setup lang="ts">
2-
import { ref, computed } from 'vue'
2+
import { ref, computed, onUnmounted } from 'vue'
33
import { useData } from 'vitepress'
4+
import { i18n } from './license-i18n'
45
56
const { lang } = useData()
67
@@ -13,181 +14,6 @@ interface FeatureBadge {
1314
color: string
1415
}
1516
16-
const i18n: Record<string, {
17-
pickYourLicense: string
18-
downloading: string
19-
downloadLicense: string
20-
licenseDeclaration: string
21-
addToReadme: string
22-
modelSheetOptional: string
23-
copy: string
24-
copied: string
25-
badges: Record<string, { fullName: string; desc: string }>
26-
}> = {
27-
en: {
28-
pickYourLicense: 'Pick Your License',
29-
downloading: 'Downloading...',
30-
downloadLicense: 'Download {name} License',
31-
licenseDeclaration: 'License Declaration',
32-
addToReadme: 'Add to your README',
33-
modelSheetOptional: 'Model Sheet (Optional)',
34-
copy: 'Copy',
35-
copied: '✓ Copied!',
36-
badges: {
37-
BY: { fullName: 'Attribution', desc: 'Must give credit, retain attribution and license in copies and derivatives.' },
38-
NC: { fullName: 'NonCommercial', desc: 'Must use and distribute for non-commercial purposes only.' },
39-
ND: { fullName: 'NoDerivatives', desc: 'May not distribute any modified works based on the model.' },
40-
RAI: { fullName: 'ResponsibleAI', desc: 'Must comply with responsible use of AI terms.' },
41-
SA: { fullName: 'ShareAlike', desc: 'Must keep derivatives open source and apply the same license.' },
42-
MG0: { fullName: '0 Conditions', desc: 'Almost no restrictions. Maximum sharing and freedom.' },
43-
}
44-
},
45-
'zh-CN': {
46-
pickYourLicense: '选择您的许可证',
47-
downloading: '下载中...',
48-
downloadLicense: '下载 {name} 许可证',
49-
licenseDeclaration: '许可证声明',
50-
addToReadme: '添加到您的 README',
51-
modelSheetOptional: 'Model Sheet(可选)',
52-
copy: '复制',
53-
copied: '✓ 已复制!',
54-
badges: {
55-
BY: { fullName: '署名', desc: '必须注明出处,在副本和衍生品中保留署名和许可证。' },
56-
NC: { fullName: '非商业', desc: '仅限非商业目的使用和分发。' },
57-
ND: { fullName: '禁止衍生', desc: '不得分发基于该模型的任何修改作品。' },
58-
RAI: { fullName: '负责任AI', desc: '必须遵守负责任使用 AI 的条款。' },
59-
SA: { fullName: '相同方式共享', desc: '衍生品必须保持开源并适用相同许可证。' },
60-
MG0: { fullName: '零条件', desc: '几乎没有限制。最大程度的共享和自由。' },
61-
}
62-
},
63-
'zh-TW': {
64-
pickYourLicense: '選擇您的授權條款',
65-
downloading: '下載中...',
66-
downloadLicense: '下載 {name} 授權條款',
67-
licenseDeclaration: '授權條款聲明',
68-
addToReadme: '新增至您的 README',
69-
modelSheetOptional: 'Model Sheet(選填)',
70-
copy: '複製',
71-
copied: '✓ 已複製!',
72-
badges: {
73-
BY: { fullName: '署名', desc: '必須註明出處,在副本和衍生品中保留署名和授權條款。' },
74-
NC: { fullName: '非商業', desc: '僅限非商業目的使用和分發。' },
75-
ND: { fullName: '禁止衍生', desc: '不得分發基於該模型的任何修改作品。' },
76-
RAI: { fullName: '負責任AI', desc: '必須遵守負責任使用 AI 的條款。' },
77-
SA: { fullName: '相同方式共享', desc: '衍生品必須保持開源並適用相同授權條款。' },
78-
MG0: { fullName: '零條件', desc: '幾乎沒有限制。最大程度的共享和自由。' },
79-
}
80-
},
81-
ja: {
82-
pickYourLicense: 'ライセンスを選択',
83-
downloading: 'ダウンロード中...',
84-
downloadLicense: '{name} ライセンスをダウンロード',
85-
licenseDeclaration: 'ライセンス宣言',
86-
addToReadme: 'README に追加',
87-
modelSheetOptional: 'Model Sheet(任意)',
88-
copy: 'コピー',
89-
copied: '✓ コピーしました!',
90-
badges: {
91-
BY: { fullName: '表示', desc: 'クレジットを表示し、コピーおよび派生物に帰属表示とライセンスを保持する必要があります。' },
92-
NC: { fullName: '非営利', desc: '非営利目的でのみ使用および配布する必要があります。' },
93-
ND: { fullName: '改変禁止', desc: 'モデルに基づく改変作品を配布することはできません。' },
94-
RAI: { fullName: '責任あるAI', desc: '責任あるAI使用条件に準拠する必要があります。' },
95-
SA: { fullName: '継承', desc: '派生物をオープンソースで維持し、同じライセンスを適用する必要があります。' },
96-
MG0: { fullName: '条件なし', desc: 'ほぼ制限なし。最大限の共有と自由。' },
97-
}
98-
},
99-
ko: {
100-
pickYourLicense: '라이선스 선택',
101-
downloading: '다운로드 중...',
102-
downloadLicense: '{name} 라이선스 다운로드',
103-
licenseDeclaration: '라이선스 선언',
104-
addToReadme: 'README에 추가',
105-
modelSheetOptional: 'Model Sheet (선택사항)',
106-
copy: '복사',
107-
copied: '✓ 복사됨!',
108-
badges: {
109-
BY: { fullName: '저작자표시', desc: '출처를 밝히고, 사본 및 파생물에 저작자 표시와 라이선스를 유지해야 합니다.' },
110-
NC: { fullName: '비영리', desc: '비상업적 목적으로만 사용 및 배포해야 합니다.' },
111-
ND: { fullName: '변경금지', desc: '모델을 기반으로 한 수정된 작품을 배포할 수 없습니다.' },
112-
RAI: { fullName: '책임있는AI', desc: '책임 있는 AI 사용 조건을 준수해야 합니다.' },
113-
SA: { fullName: '동일조건변경허락', desc: '파생물을 오픈 소스로 유지하고 동일한 라이선스를 적용해야 합니다.' },
114-
MG0: { fullName: '조건 없음', desc: '거의 제한 없음. 최대한의 공유와 자유.' },
115-
}
116-
},
117-
ru: {
118-
pickYourLicense: 'Выберите лицензию',
119-
downloading: 'Загрузка...',
120-
downloadLicense: 'Скачать лицензию {name}',
121-
licenseDeclaration: 'Декларация лицензии',
122-
addToReadme: 'Добавить в README',
123-
modelSheetOptional: 'Model Sheet (необязательно)',
124-
copy: 'Копировать',
125-
copied: '✓ Скопировано!',
126-
badges: {
127-
BY: { fullName: 'Атрибуция', desc: 'Необходимо указать авторство, сохранить атрибуцию и лицензию в копиях и производных.' },
128-
NC: { fullName: 'Некоммерческая', desc: 'Использование и распространение только в некоммерческих целях.' },
129-
ND: { fullName: 'Без производных', desc: 'Запрещено распространять модифицированные работы на основе модели.' },
130-
RAI: { fullName: 'Ответственный ИИ', desc: 'Необходимо соблюдать условия ответственного использования ИИ.' },
131-
SA: { fullName: 'С сохранением условий', desc: 'Производные должны оставаться открытыми и использовать ту же лицензию.' },
132-
MG0: { fullName: 'Без условий', desc: 'Почти без ограничений. Максимальная свобода обмена.' },
133-
}
134-
},
135-
es: {
136-
pickYourLicense: 'Elige tu licencia',
137-
downloading: 'Descargando...',
138-
downloadLicense: 'Descargar licencia {name}',
139-
licenseDeclaration: 'Declaración de licencia',
140-
addToReadme: 'Agregar a tu README',
141-
modelSheetOptional: 'Model Sheet (Opcional)',
142-
copy: 'Copiar',
143-
copied: '✓ Copiado!',
144-
badges: {
145-
BY: { fullName: 'Atribución', desc: 'Debe dar crédito, conservar la atribución y la licencia en copias y derivados.' },
146-
NC: { fullName: 'NoComercial', desc: 'Solo para uso y distribución con fines no comerciales.' },
147-
ND: { fullName: 'SinDerivadas', desc: 'No se pueden distribuir obras modificadas basadas en el modelo.' },
148-
RAI: { fullName: 'IA Responsable', desc: 'Debe cumplir con los términos de uso responsable de IA.' },
149-
SA: { fullName: 'CompartirIgual', desc: 'Los derivados deben mantenerse de código abierto y aplicar la misma licencia.' },
150-
MG0: { fullName: 'Sin condiciones', desc: 'Casi sin restricciones. Máxima libertad para compartir.' },
151-
}
152-
},
153-
fr: {
154-
pickYourLicense: 'Choisissez votre licence',
155-
downloading: 'Téléchargement...',
156-
downloadLicense: 'Télécharger la licence {name}',
157-
licenseDeclaration: 'Déclaration de licence',
158-
addToReadme: 'Ajouter à votre README',
159-
modelSheetOptional: 'Model Sheet (Facultatif)',
160-
copy: 'Copier',
161-
copied: '✓ Copié !',
162-
badges: {
163-
BY: { fullName: 'Attribution', desc: 'Doit créditer, conserver l\'attribution et la licence dans les copies et dérivés.' },
164-
NC: { fullName: 'NonCommercial', desc: 'Utilisation et distribution à des fins non commerciales uniquement.' },
165-
ND: { fullName: 'PasDeDérivés', desc: 'Interdiction de distribuer des œuvres modifiées basées sur le modèle.' },
166-
RAI: { fullName: 'IA Responsable', desc: 'Doit respecter les conditions d\'utilisation responsable de l\'IA.' },
167-
SA: { fullName: 'PartageIdentique', desc: 'Les dérivés doivent rester open source et appliquer la même licence.' },
168-
MG0: { fullName: 'Sans conditions', desc: 'Presque aucune restriction. Partage et liberté maximaux.' },
169-
}
170-
},
171-
ar: {
172-
pickYourLicense: 'اختر ترخيصك',
173-
downloading: 'جارٍ التحميل...',
174-
downloadLicense: 'تحميل ترخيص {name}',
175-
licenseDeclaration: 'إعلان الترخيص',
176-
addToReadme: 'أضف إلى README',
177-
modelSheetOptional: 'Model Sheet (اختياري)',
178-
copy: 'نسخ',
179-
copied: '✓ تم النسخ!',
180-
badges: {
181-
BY: { fullName: 'نسب المصنف', desc: 'يجب ذكر المصدر والاحتفاظ بالإسناد والترخيص في النسخ والمشتقات.' },
182-
NC: { fullName: 'غير تجاري', desc: 'يجب الاستخدام والتوزيع لأغراض غير تجارية فقط.' },
183-
ND: { fullName: 'بلا مشتقات', desc: 'لا يجوز توزيع أي أعمال معدلة بناءً على النموذج.' },
184-
RAI: { fullName: 'ذكاء اصطناعي مسؤول', desc: 'يجب الامتثال لشروط الاستخدام المسؤول للذكاء الاصطناعي.' },
185-
SA: { fullName: 'الترخيص بالمثل', desc: 'يجب أن تبقى المشتقات مفتوحة المصدر وتطبق نفس الترخيص.' },
186-
MG0: { fullName: 'بدون شروط', desc: 'بدون قيود تقريبًا. أقصى درجات المشاركة والحرية.' },
187-
}
188-
},
189-
}
190-
19117
function t(key: string): string {
19218
const locale = i18n[lang.value] || i18n['en']
19319
return (locale as any)[key] || (i18n['en'] as any)[key] || key
@@ -705,6 +531,10 @@ async function copyText(text: string, type: 'readme' | 'sheet') {
705531
copied.value = type
706532
setTimeout(() => { copied.value = null }, 1500)
707533
}
534+
535+
onUnmounted(() => {
536+
clearTimeout(closeTimer)
537+
})
708538
</script>
709539

710540
<template>

docs/.vitepress/components/PixelRobots.vue

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -538,8 +538,9 @@ function tick(time) {
538538
const a = rabbits.value[i], b = rabbits.value[j]
539539
if (a.grabbed || b.grabbed) continue
540540
const dx = b.x - a.x, dy = b.y - a.y
541-
const dist = Math.sqrt(dx * dx + dy * dy)
542-
if (dist < COLLISION_DIST && dist > 0) {
541+
const distSq = dx * dx + dy * dy
542+
if (distSq < COLLISION_DIST * COLLISION_DIST && distSq > 0) {
543+
const dist = Math.sqrt(distSq)
543544
const nx = dx / dist, ny = dy / dist
544545
const ov = (COLLISION_DIST - dist) / 2
545546
a.x -= nx * ov; a.y -= ny * ov
@@ -611,8 +612,8 @@ function tick(time) {
611612
rabbits.value.forEach(r => {
612613
if (r.y < -5) {
613614
const bfY = b.baseY + Math.sin(b.phase) * b.bobAmp + b.driftY, rY = -r.y
614-
const d = Math.sqrt((b.x - r.x) ** 2 + (bfY - rY) ** 2)
615-
if (d < 40 && !b.fleeing) { b.fleeing = true; b.fleeTimer = 30; b.dir = b.x > r.x ? 1 : -1 }
615+
const bdx = b.x - r.x, bdy = bfY - rY
616+
if (bdx * bdx + bdy * bdy < 1600 && !b.fleeing) { b.fleeing = true; b.fleeTimer = 30; b.dir = b.x > r.x ? 1 : -1 }
616617
}
617618
})
618619
})
@@ -627,8 +628,8 @@ function tick(time) {
627628
const s = rb.phase
628629
const eRx = 136 * s, eRy = 88 * s
629630
if (eRx < 1 || eRy < 1) return
630-
const norm = Math.sqrt((dx / eRx) ** 2 + (bfY / eRy) ** 2)
631-
if (norm > 0.55 && norm < 0.99) bf.rainbowHue = 100
631+
const normSq = (dx / eRx) * (dx / eRx) + (bfY / eRy) * (bfY / eRy)
632+
if (normSq > 0.3025 && normSq < 0.9801) bf.rainbowHue = 100
632633
})
633634
})
634635
@@ -705,8 +706,8 @@ function tick(time) {
705706
const s = rb.phase
706707
const eRx = 136 * s, eRy = 88 * s
707708
if (eRx < 1 || eRy < 1) return
708-
const norm = Math.sqrt((dx / eRx) ** 2 + (dy / eRy) ** 2)
709-
if (norm > 0.3 && norm < 1.15) cl.rainbowHue = 100
709+
const normSq = (dx / eRx) * (dx / eRx) + (dy / eRy) * (dy / eRy)
710+
if (normSq > 0.09 && normSq < 1.3225) cl.rainbowHue = 100
710711
})
711712
})
712713
@@ -741,10 +742,10 @@ function tick(time) {
741742
triggerRef(clouds)
742743
triggerRef(butterflies)
743744
triggerRef(snails)
744-
triggerRef(rainbows)
745-
triggerRef(spores)
746745
triggerRef(grasses)
747-
triggerRef(wxParticles)
746+
if (rainbows.value.length) triggerRef(rainbows)
747+
if (spores.value.length) triggerRef(spores)
748+
if (wxParticles.value.length && weather.value.type !== 'clear') triggerRef(wxParticles)
748749
749750
animFrame = requestAnimationFrame(tick)
750751
}

0 commit comments

Comments
 (0)