feat: 全站20个模板添加国际化(i18n)支持 - 简体中文/繁体中文/英文三语切换
- 所有18套前端模板 + 管理后台共20个HTML文件添加i18n引擎 - 前端JavaScript方案:I18N_LOCALES翻译字典 + data-i18n属性 + t()函数调用 - 语言切换器UI:下拉菜单选择,匹配各模板主题风格 - 语言持久化:localStorage存储 + URL参数覆盖 + 浏览器语言自动检测 - onLangChange回调:语言切换时动态重新渲染所有内容 - 支持语言:zh-CN(简体中文) / zh-TW(繁体中文) / en(English)
This commit is contained in:
364
web/dist/shop4/index.html
vendored
364
web/dist/shop4/index.html
vendored
@@ -43,6 +43,19 @@ a{color:inherit;text-decoration:none}
|
||||
[data-theme="dark"] .moon-icon{transform:translateY(40px) rotate(180deg);opacity:0}
|
||||
[data-theme="light"] .moon-icon{transform:translateY(0) rotate(0);opacity:1}
|
||||
|
||||
/* ========== 语言切换器 ========== */
|
||||
.lang-switcher{position:relative}
|
||||
.lang-btn{display:flex;align-items:center;gap:6px;padding:8px 14px;border-radius:10px;font-size:13px;font-weight:600;color:var(--text-muted);cursor:pointer;background:var(--surface);border:1px solid var(--border);transition:all .25s}
|
||||
.lang-btn:hover{color:var(--text);background:var(--card);border-color:var(--primary)}
|
||||
.lang-btn svg{width:16px;height:16px}
|
||||
.lang-dropdown{position:absolute;top:calc(100% + 8px);right:0;min-width:160px;background:var(--bg2);backdrop-filter:blur(20px);-webkit-backdrop-filter:blur(20px);border:1px solid var(--border);border-radius:var(--radius);box-shadow:0 12px 40px rgba(0,0,0,.5);overflow:hidden;opacity:0;transform:translateY(-8px);pointer-events:none;transition:all .25s;z-index:1001}
|
||||
.lang-dropdown.open{opacity:1;transform:none;pointer-events:auto}
|
||||
.lang-option{display:flex;align-items:center;gap:10px;padding:12px 16px;font-size:14px;color:var(--text-muted);cursor:pointer;transition:all .2s}
|
||||
.lang-option:hover{background:var(--surface);color:var(--text)}
|
||||
.lang-option.active{color:var(--primary);font-weight:600}
|
||||
.lang-option .check{width:16px;height:16px;opacity:0;transition:opacity .2s}
|
||||
.lang-option.active .check{opacity:1}
|
||||
|
||||
/* ========== Hero 横向动态 ========== */
|
||||
.hero{position:relative;width:100%;height:100vh;min-height:640px;overflow:hidden;background:#060a06}
|
||||
#treeCanvas{position:absolute;inset:0;width:100%;height:100%;z-index:1}
|
||||
@@ -209,12 +222,33 @@ a{color:inherit;text-decoration:none}
|
||||
<nav class="navbar">
|
||||
<div class="nav-brand"><span class="tree-icon">🌳</span> TreeShop</div>
|
||||
<div class="nav-links">
|
||||
<a onclick="scrollToProducts()">全部商品</a>
|
||||
<a onclick="scrollToProducts()">分类</a>
|
||||
<a onclick="showToast('关于我们')">关于</a>
|
||||
<a onclick="showToast('联系方式')">联系</a>
|
||||
<a onclick="scrollToProducts()" data-i18n="nav_all">全部商品</a>
|
||||
<a onclick="scrollToProducts()" data-i18n="nav_cat">分类</a>
|
||||
<a onclick="showToast(t('toast_about'))" data-i18n="nav_about">关于</a>
|
||||
<a onclick="showToast(t('toast_contact'))" data-i18n="nav_contact">联系</a>
|
||||
</div>
|
||||
<div class="nav-actions">
|
||||
<div class="lang-switcher" id="langSwitcher">
|
||||
<button class="lang-btn" onclick="toggleLangDropdown()">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="12" r="10"/><path d="M2 12h20M12 2a15 15 0 0 1 0 20 15 15 0 0 1 0-20z"/></svg>
|
||||
<span id="langLabel">中文</span>
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" style="width:12px;height:12px"><path d="m6 9 6 6 6-6"/></svg>
|
||||
</button>
|
||||
<div class="lang-dropdown" id="langDropdown">
|
||||
<div class="lang-option active" data-lang="zh-CN" onclick="switchLang('zh-CN')">
|
||||
<svg class="check" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3"><polyline points="20 6 9 17 4 12"/></svg>
|
||||
中文
|
||||
</div>
|
||||
<div class="lang-option" data-lang="zh-TW" onclick="switchLang('zh-TW')">
|
||||
<svg class="check" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3"><polyline points="20 6 9 17 4 12"/></svg>
|
||||
繁體中文
|
||||
</div>
|
||||
<div class="lang-option" data-lang="en" onclick="switchLang('en')">
|
||||
<svg class="check" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3"><polyline points="20 6 9 17 4 12"/></svg>
|
||||
English
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<button class="theme-toggle" onclick="toggleTheme()" title="切换黑白模式">
|
||||
<span class="sun-icon">☀️</span>
|
||||
<span class="moon-icon">🌙</span>
|
||||
@@ -233,48 +267,48 @@ a{color:inherit;text-decoration:none}
|
||||
<!-- 面板1 -->
|
||||
<div class="hero-panel">
|
||||
<div class="hero-panel-content">
|
||||
<div class="hero-badge"><span class="dot"></span> 古树商城 · 2026 新季</div>
|
||||
<h1>扎根全球<br><span class="accent">枝连万物</span></h1>
|
||||
<p>如古树般扎根品质,如枝叶般连接全球好物。精选电子工具品类,从榨汁机到搅拌机,每一件产品都经过严选,为您带来高效纯粹的厨房体验。</p>
|
||||
<div class="hero-badge"><span class="dot"></span> <span data-i18n="hero_badge1">古树商城 · 2026 新季</span></div>
|
||||
<h1><span data-i18n="hero_title1_line1">扎根全球</span><br><span class="accent" data-i18n="hero_title1_line2">枝连万物</span></h1>
|
||||
<p data-i18n="hero_desc1">如古树般扎根品质,如枝叶般连接全球好物。精选电子工具品类,从榨汁机到搅拌机,每一件产品都经过严选,为您带来高效纯粹的厨房体验。</p>
|
||||
<div class="hero-panel-actions">
|
||||
<button class="btn-primary" onclick="scrollToProducts()">
|
||||
探索商品
|
||||
<span data-i18n="hero_cta1">探索商品</span>
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" style="width:18px;height:18px"><path d="M5 12h14M12 5l7 7-7 7"/></svg>
|
||||
</button>
|
||||
<button class="btn-ghost" onclick="scrollToPanel(1)">了解更多 →</button>
|
||||
<button class="btn-ghost" onclick="scrollToPanel(1)"><span data-i18n="hero_more">了解更多</span> →</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 面板2 -->
|
||||
<div class="hero-panel">
|
||||
<div class="hero-panel-content">
|
||||
<div class="hero-badge"><span class="dot"></span> 品质承诺</div>
|
||||
<h1>四大根基<br><span class="accent">品质如树</span></h1>
|
||||
<div class="hero-badge"><span class="dot"></span> <span data-i18n="hero_badge2">品质承诺</span></div>
|
||||
<h1><span data-i18n="hero_title2_line1">四大根基</span><br><span class="accent" data-i18n="hero_title2_line2">品质如树</span></h1>
|
||||
<div class="hero-features">
|
||||
<div class="hero-feature"><div class="icon">🌍</div><h3>全球直邮</h3><p>满 $99 免运费,覆盖全球 200+ 国家和地区</p></div>
|
||||
<div class="hero-feature"><div class="icon">✅</div><h3>正品保障</h3><p>品牌授权直供,假一赔十承诺</p></div>
|
||||
<div class="hero-feature"><div class="icon">🔄</div><h3>7天退换</h3><p>无理由退货,购物零风险</p></div>
|
||||
<div class="hero-feature"><div class="icon">🔒</div><h3>安全支付</h3><p>多渠道加密,保障支付安全</p></div>
|
||||
<div class="hero-feature"><div class="icon">🌍</div><h3 data-i18n="feat1_title">全球直邮</h3><p data-i18n="feat1_desc">满 $99 免运费,覆盖全球 200+ 国家和地区</p></div>
|
||||
<div class="hero-feature"><div class="icon">✅</div><h3 data-i18n="feat2_title">正品保障</h3><p data-i18n="feat2_desc">品牌授权直供,假一赔十承诺</p></div>
|
||||
<div class="hero-feature"><div class="icon">🔄</div><h3 data-i18n="feat3_title">7天退换</h3><p data-i18n="feat3_desc">无理由退货,购物零风险</p></div>
|
||||
<div class="hero-feature"><div class="icon">🔒</div><h3 data-i18n="feat4_title">安全支付</h3><p data-i18n="feat4_desc">多渠道加密,保障支付安全</p></div>
|
||||
</div>
|
||||
<div class="hero-panel-actions" style="margin-top:32px">
|
||||
<button class="btn-primary" onclick="scrollToProducts()">浏览商品</button>
|
||||
<button class="btn-ghost" onclick="scrollToPanel(0)">← 返回</button>
|
||||
<button class="btn-primary" onclick="scrollToProducts()"><span data-i18n="hero_browse">浏览商品</span></button>
|
||||
<button class="btn-ghost" onclick="scrollToPanel(0)">← <span data-i18n="hero_back">返回</span></button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 面板3 -->
|
||||
<div class="hero-panel">
|
||||
<div class="hero-panel-content" style="text-align:center">
|
||||
<div class="hero-badge" style="margin:0 auto 24px"><span class="dot"></span> 数据一览</div>
|
||||
<h1 style="text-align:center">数字见证<br><span class="accent">用户信赖</span></h1>
|
||||
<div class="hero-badge" style="margin:0 auto 24px"><span class="dot"></span> <span data-i18n="hero_badge3">数据一览</span></div>
|
||||
<h1 style="text-align:center"><span data-i18n="hero_title3_line1">数字见证</span><br><span class="accent" data-i18n="hero_title3_line2">用户信赖</span></h1>
|
||||
<div class="hero-features" style="grid-template-columns:repeat(4,1fr);margin-top:40px">
|
||||
<div class="hero-feature" style="text-align:center"><div class="icon">📦</div><h3 style="font-size:28px;color:var(--primary)">18+</h3><p>品类好物</p></div>
|
||||
<div class="hero-feature" style="text-align:center"><div class="icon">👥</div><h3 style="font-size:28px;color:var(--primary)">50万</h3><p>全球用户</p></div>
|
||||
<div class="hero-feature" style="text-align:center"><div class="icon">⭐</div><h3 style="font-size:28px;color:var(--primary)">99%</h3><p>好评率</p></div>
|
||||
<div class="hero-feature" style="text-align:center"><div class="icon">🌿</div><h3 style="font-size:28px;color:var(--primary)">7天</h3><p>无理由退换</p></div>
|
||||
<div class="hero-feature" style="text-align:center"><div class="icon">📦</div><h3 style="font-size:28px;color:var(--primary)">18+</h3><p data-i18n="stat1">品类好物</p></div>
|
||||
<div class="hero-feature" style="text-align:center"><div class="icon">👥</div><h3 style="font-size:28px;color:var(--primary)">50万</h3><p data-i18n="stat2">全球用户</p></div>
|
||||
<div class="hero-feature" style="text-align:center"><div class="icon">⭐</div><h3 style="font-size:28px;color:var(--primary)">99%</h3><p data-i18n="stat3">好评率</p></div>
|
||||
<div class="hero-feature" style="text-align:center"><div class="icon">🌿</div><h3 style="font-size:28px;color:var(--primary)">7天</h3><p data-i18n="stat4">无理由退换</p></div>
|
||||
</div>
|
||||
<div class="hero-panel-actions" style="margin-top:32px;justify-content:center">
|
||||
<button class="btn-primary" onclick="scrollToProducts()">立即选购</button>
|
||||
<button class="btn-primary" onclick="scrollToProducts()"><span data-i18n="hero_buy">立即选购</span></button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -284,7 +318,7 @@ a{color:inherit;text-decoration:none}
|
||||
<div class="hero-dot" onclick="scrollToPanel(1)"></div>
|
||||
<div class="hero-dot" onclick="scrollToPanel(2)"></div>
|
||||
</div>
|
||||
<div class="hero-arrow">横向滚动 →</div>
|
||||
<div class="hero-arrow"><span data-i18n="hero_scroll">横向滚动</span> →</div>
|
||||
</div>
|
||||
|
||||
<!-- 商品表格区域 -->
|
||||
@@ -292,30 +326,30 @@ a{color:inherit;text-decoration:none}
|
||||
<div class="products-bg" id="productsBg"></div>
|
||||
<div class="products-content">
|
||||
<div class="section-header">
|
||||
<h2>电子工具<span class="accent">精选</span></h2>
|
||||
<p>高效厨房好物,品质如树,扎根全球</p>
|
||||
<h2><span data-i18n="section_title1">电子工具</span><span class="accent" data-i18n="section_title2">精选</span></h2>
|
||||
<p data-i18n="section_desc">高效厨房好物,品质如树,扎根全球</p>
|
||||
</div>
|
||||
<div class="filter-bar" id="filterBar">
|
||||
<button class="filter-chip active" data-cat="0" onclick="filterCategory(0,this)">全部分类</button>
|
||||
<button class="filter-chip" data-cat="1" onclick="filterCategory(1,this)">榨汁搅拌</button>
|
||||
<button class="filter-chip" data-cat="2" onclick="filterCategory(2,this)">烹饪烘焙</button>
|
||||
<button class="filter-chip" data-cat="3" onclick="filterCategory(3,this)">生活电器</button>
|
||||
<button class="filter-chip active" data-cat="0" onclick="filterCategory(0,this)" data-i18n="cat_all">全部分类</button>
|
||||
<button class="filter-chip" data-cat="1" onclick="filterCategory(1,this)" data-i18n="cat_juice">榨汁搅拌</button>
|
||||
<button class="filter-chip" data-cat="2" onclick="filterCategory(2,this)" data-i18n="cat_cook">烹饪烘焙</button>
|
||||
<button class="filter-chip" data-cat="3" onclick="filterCategory(3,this)" data-i18n="cat_life">生活电器</button>
|
||||
<div class="search-box">
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="11" cy="11" r="8"/><path d="m21 21-4.3-4.3"/></svg>
|
||||
<input type="text" id="searchInput" placeholder="搜索商品..." oninput="onSearch()">
|
||||
<input type="text" id="searchInput" data-i18n-placeholder="search_placeholder" placeholder="搜索商品..." oninput="onSearch()">
|
||||
</div>
|
||||
</div>
|
||||
<div class="table-wrap">
|
||||
<table class="product-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>图片</th>
|
||||
<th>商品名称</th>
|
||||
<th>分类</th>
|
||||
<th>价格</th>
|
||||
<th>评分</th>
|
||||
<th>销量</th>
|
||||
<th>操作</th>
|
||||
<th data-i18n="th_img">图片</th>
|
||||
<th data-i18n="th_name">商品名称</th>
|
||||
<th data-i18n="th_cat">分类</th>
|
||||
<th data-i18n="th_price">价格</th>
|
||||
<th data-i18n="th_rating">评分</th>
|
||||
<th data-i18n="th_sales">销量</th>
|
||||
<th data-i18n="th_actions">操作</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="productTbody"></tbody>
|
||||
@@ -330,35 +364,35 @@ a{color:inherit;text-decoration:none}
|
||||
<div class="footer-content">
|
||||
<div class="footer-brand">
|
||||
<h3>🌳 TreeShop</h3>
|
||||
<p>如古树般扎根品质,如枝叶般连接全球。精选电子工具好物,为您带来高效纯粹的跨境购物体验。</p>
|
||||
<p data-i18n="footer_desc">如古树般扎根品质,如枝叶般连接全球。精选电子工具好物,为您带来高效纯粹的跨境购物体验。</p>
|
||||
</div>
|
||||
<div class="footer-col">
|
||||
<h4>购物指南</h4>
|
||||
<a>购物流程</a><a>会员介绍</a><a>常见问题</a><a>联系客服</a>
|
||||
<h4 data-i18n="footer_guide">购物指南</h4>
|
||||
<a data-i18n="guide_flow">购物流程</a><a data-i18n="guide_member">会员介绍</a><a data-i18n="guide_faq">常见问题</a><a data-i18n="guide_service">联系客服</a>
|
||||
</div>
|
||||
<div class="footer-col">
|
||||
<h4>配送退换</h4>
|
||||
<a>配送方式</a><a>运费规则</a><a>退换货政策</a><a>退款说明</a>
|
||||
<h4 data-i18n="footer_shipping">配送退换</h4>
|
||||
<a data-i18n="ship_method">配送方式</a><a data-i18n="ship_fee">运费规则</a><a data-i18n="ship_return">退换货政策</a><a data-i18n="ship_refund">退款说明</a>
|
||||
</div>
|
||||
<div class="footer-col">
|
||||
<h4>关于我们</h4>
|
||||
<a>公司简介</a><a>加入我们</a><a>隐私政策</a><a>用户协议</a>
|
||||
<h4 data-i18n="footer_about">关于我们</h4>
|
||||
<a data-i18n="about_intro">公司简介</a><a data-i18n="about_join">加入我们</a><a data-i18n="about_privacy">隐私政策</a><a data-i18n="about_terms">用户协议</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="footer-bottom">© 2026 TreeShop · 古树商城 · 电子工具精选</div>
|
||||
<div class="footer-bottom">© 2026 TreeShop · <span data-i18n="footer_copy">古树商城 · 电子工具精选</span></div>
|
||||
</footer>
|
||||
|
||||
<!-- Cart -->
|
||||
<div class="cart-overlay" id="cartOverlay" onclick="toggleCart()"></div>
|
||||
<div class="cart-drawer" id="cartDrawer">
|
||||
<div class="cart-drawer-header">
|
||||
<h3>购物车</h3>
|
||||
<h3 data-i18n="cart_title">购物车</h3>
|
||||
<button class="modal-close" onclick="toggleCart()">×</button>
|
||||
</div>
|
||||
<div class="cart-items" id="cartItems"></div>
|
||||
<div class="cart-drawer-footer">
|
||||
<div class="cart-total"><span>合计</span><span class="price" id="cartTotal">$0</span></div>
|
||||
<button class="checkout-btn" id="checkoutBtn" disabled onclick="showToast('结算功能开发中')">去结算</button>
|
||||
<div class="cart-total"><span data-i18n="cart_total">合计</span><span class="price" id="cartTotal">$0</span></div>
|
||||
<button class="checkout-btn" id="checkoutBtn" disabled onclick="showToast(t('toast_checkout'))"><span data-i18n="cart_checkout">去结算</span></button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -371,6 +405,156 @@ a{color:inherit;text-decoration:none}
|
||||
<div class="toast" id="toast"><span id="toastMsg"></span></div>
|
||||
|
||||
<script>
|
||||
// ========== I18N ==========
|
||||
var I18N_LOCALES = {
|
||||
'zh-CN': {
|
||||
nav_all: '全部商品', nav_cat: '分类', nav_about: '关于', nav_contact: '联系',
|
||||
hero_badge1: '古树商城 · 2026 新季', hero_title1_line1: '扎根全球', hero_title1_line2: '枝连万物',
|
||||
hero_desc1: '如古树般扎根品质,如枝叶般连接全球好物。精选电子工具品类,从榨汁机到搅拌机,每一件产品都经过严选,为您带来高效纯粹的厨房体验。',
|
||||
hero_cta1: '探索商品', hero_more: '了解更多',
|
||||
hero_badge2: '品质承诺', hero_title2_line1: '四大根基', hero_title2_line2: '品质如树',
|
||||
feat1_title: '全球直邮', feat1_desc: '满 $99 免运费,覆盖全球 200+ 国家和地区',
|
||||
feat2_title: '正品保障', feat2_desc: '品牌授权直供,假一赔十承诺',
|
||||
feat3_title: '7天退换', feat3_desc: '无理由退货,购物零风险',
|
||||
feat4_title: '安全支付', feat4_desc: '多渠道加密,保障支付安全',
|
||||
hero_browse: '浏览商品', hero_back: '返回',
|
||||
hero_badge3: '数据一览', hero_title3_line1: '数字见证', hero_title3_line2: '用户信赖',
|
||||
stat1: '品类好物', stat2: '全球用户', stat3: '好评率', stat4: '无理由退换',
|
||||
hero_buy: '立即选购', hero_scroll: '横向滚动',
|
||||
section_title1: '电子工具', section_title2: '精选', section_desc: '高效厨房好物,品质如树,扎根全球',
|
||||
cat_all: '全部分类', cat_juice: '榨汁搅拌', cat_cook: '烹饪烘焙', cat_life: '生活电器',
|
||||
search_placeholder: '搜索商品...',
|
||||
th_img: '图片', th_name: '商品名称', th_cat: '分类', th_price: '价格', th_rating: '评分', th_sales: '销量', th_actions: '操作',
|
||||
btn_add_cart: '加购', btn_detail: '详情', btn_empty: '暂无商品',
|
||||
footer_desc: '如古树般扎根品质,如枝叶般连接全球。精选电子工具好物,为您带来高效纯粹的跨境购物体验。',
|
||||
footer_guide: '购物指南', guide_flow: '购物流程', guide_member: '会员介绍', guide_faq: '常见问题', guide_service: '联系客服',
|
||||
footer_shipping: '配送退换', ship_method: '配送方式', ship_fee: '运费规则', ship_return: '退换货政策', ship_refund: '退款说明',
|
||||
footer_about: '关于我们', about_intro: '公司简介', about_join: '加入我们', about_privacy: '隐私政策', about_terms: '用户协议',
|
||||
footer_copy: '古树商城 · 电子工具精选',
|
||||
cart_title: '购物车', cart_total: '合计', cart_checkout: '去结算',
|
||||
cart_empty_line1: '购物车是空的', cart_empty_line2: '快去挑选心仪的商品吧',
|
||||
modal_cat: '分类', modal_price: '价格', modal_rating: '评分', modal_sales: '销量', modal_unit: '件',
|
||||
modal_add_cart: '加入购物车', modal_close: '关闭',
|
||||
toast_theme_light: '已切换至明亮模式', toast_theme_dark: '已切换至暗黑模式',
|
||||
toast_added: '已加入购物车', toast_about: '关于我们', toast_contact: '联系方式', toast_checkout: '结算功能开发中',
|
||||
catName_juice: '榨汁搅拌', catName_cook: '烹饪烘焙', catName_life: '生活电器'
|
||||
},
|
||||
'en': {
|
||||
nav_all: 'All Products', nav_cat: 'Categories', nav_about: 'About', nav_contact: 'Contact',
|
||||
hero_badge1: 'TreeShop · 2026 New Season', hero_title1_line1: 'Rooted Globally', hero_title1_line2: 'Connected to All',
|
||||
hero_desc1: 'Rooted in quality like an ancient tree, connected to global goods like its branches. Curated electronics from juicers to blenders — every product selected for a pure, efficient kitchen experience.',
|
||||
hero_cta1: 'Explore Products', hero_more: 'Learn More',
|
||||
hero_badge2: 'Quality Promise', hero_title2_line1: 'Four Pillars', hero_title2_line2: 'Quality Like a Tree',
|
||||
feat1_title: 'Global Shipping', feat1_desc: 'Free shipping on orders over $99, covering 200+ countries',
|
||||
feat2_title: 'Authentic Guarantee', feat2_desc: 'Authorized brand supply, 10x compensation promise',
|
||||
feat3_title: '7-Day Returns', feat3_desc: 'No-reason returns, zero-risk shopping',
|
||||
feat4_title: 'Secure Payment', feat4_desc: 'Multi-channel encryption for payment security',
|
||||
hero_browse: 'Browse Products', hero_back: 'Back',
|
||||
hero_badge3: 'Data Overview', hero_title3_line1: 'Numbers Speak', hero_title3_line2: 'User Trust',
|
||||
stat1: 'Categories', stat2: 'Global Users', stat3: 'Satisfaction', stat4: 'Free Returns',
|
||||
hero_buy: 'Shop Now', hero_scroll: 'Scroll Horizontally',
|
||||
section_title1: 'Kitchen Electronics', section_title2: ' Selection', section_desc: 'Quality kitchen essentials, rooted like a tree, connected to the world',
|
||||
cat_all: 'All Categories', cat_juice: 'Juicers & Blenders', cat_cook: 'Cooking & Baking', cat_life: 'Home Appliances',
|
||||
search_placeholder: 'Search products...',
|
||||
th_img: 'Image', th_name: 'Product Name', th_cat: 'Category', th_price: 'Price', th_rating: 'Rating', th_sales: 'Sales', th_actions: 'Actions',
|
||||
btn_add_cart: 'Add', btn_detail: 'Details', btn_empty: 'No products found',
|
||||
footer_desc: 'Rooted in quality like an ancient tree, connected to global goods. Curated electronics for an efficient, pure cross-border shopping experience.',
|
||||
footer_guide: 'Shopping Guide', guide_flow: 'How to Buy', guide_member: 'Membership', guide_faq: 'FAQ', guide_service: 'Customer Service',
|
||||
footer_shipping: 'Shipping & Returns', ship_method: 'Shipping Methods', ship_fee: 'Shipping Fees', ship_return: 'Return Policy', ship_refund: 'Refund Info',
|
||||
footer_about: 'About Us', about_intro: 'Company Info', about_join: 'Join Us', about_privacy: 'Privacy Policy', about_terms: 'Terms of Use',
|
||||
footer_copy: 'TreeShop · Curated Kitchen Electronics',
|
||||
cart_title: 'Shopping Cart', cart_total: 'Total', cart_checkout: 'Checkout',
|
||||
cart_empty_line1: 'Your cart is empty', cart_empty_line2: 'Find something you love!',
|
||||
modal_cat: 'Category', modal_price: 'Price', modal_rating: 'Rating', modal_sales: 'Sales', modal_unit: 'pcs',
|
||||
modal_add_cart: 'Add to Cart', modal_close: 'Close',
|
||||
toast_theme_light: 'Switched to light mode', toast_theme_dark: 'Switched to dark mode',
|
||||
toast_added: 'Added to cart', toast_about: 'About Us', toast_contact: 'Contact Us', toast_checkout: 'Checkout coming soon',
|
||||
catName_juice: 'Juicers & Blenders', catName_cook: 'Cooking & Baking', catName_life: 'Home Appliances'
|
||||
},
|
||||
'zh-TW': {
|
||||
nav_all: '全部商品', nav_cat: '分類', nav_about: '關於', nav_contact: '聯絡',
|
||||
hero_badge1: '古樹商城 · 2026 新季', hero_title1_line1: '扎根全球', hero_title1_line2: '枝連萬物',
|
||||
hero_desc1: '如古樹般扎根品質,如枝葉般連接全球好物。精選電子工具品類,從榨汁機到攪拌機,每一件產品都經過嚴選,為您帶來高效純粹的廚房體驗。',
|
||||
hero_cta1: '探索商品', hero_more: '了解更多',
|
||||
hero_badge2: '品質承諾', hero_title2_line1: '四大根基', hero_title2_line2: '品質如樹',
|
||||
feat1_title: '全球直郵', feat1_desc: '滿 $99 免運費,覆蓋全球 200+ 國家和地區',
|
||||
feat2_title: '正品保障', feat2_desc: '品牌授權直供,假一賠十承諾',
|
||||
feat3_title: '7天退換', feat3_desc: '無理由退貨,購物零風險',
|
||||
feat4_title: '安全支付', feat4_desc: '多渠道加密,保障支付安全',
|
||||
hero_browse: '瀏覽商品', hero_back: '返回',
|
||||
hero_badge3: '數據一覽', hero_title3_line1: '數字見證', hero_title3_line2: '用戶信賴',
|
||||
stat1: '品類好物', stat2: '全球用戶', stat3: '好評率', stat4: '無理由退換',
|
||||
hero_buy: '立即選購', hero_scroll: '橫向滾動',
|
||||
section_title1: '電子工具', section_title2: '精選', section_desc: '高效廚房好物,品質如樹,扎根全球',
|
||||
cat_all: '全部分類', cat_juice: '榨汁攪拌', cat_cook: '烹飪烘焙', cat_life: '生活電器',
|
||||
search_placeholder: '搜尋商品...',
|
||||
th_img: '圖片', th_name: '商品名稱', th_cat: '分類', th_price: '價格', th_rating: '評分', th_sales: '銷量', th_actions: '操作',
|
||||
btn_add_cart: '加購', btn_detail: '詳情', btn_empty: '暫無商品',
|
||||
footer_desc: '如古樹般扎根品質,如枝葉般連接全球。精選電子工具好物,為您帶來高效純粹的跨境購物體驗。',
|
||||
footer_guide: '購物指南', guide_flow: '購物流程', guide_member: '會員介紹', guide_faq: '常見問題', guide_service: '聯絡客服',
|
||||
footer_shipping: '配送退換', ship_method: '配送方式', ship_fee: '運費規則', ship_return: '退換貨政策', ship_refund: '退款說明',
|
||||
footer_about: '關於我們', about_intro: '公司簡介', about_join: '加入我們', about_privacy: '隱私政策', about_terms: '用戶協議',
|
||||
footer_copy: '古樹商城 · 電子工具精選',
|
||||
cart_title: '購物車', cart_total: '合計', cart_checkout: '去結算',
|
||||
cart_empty_line1: '購物車是空的', cart_empty_line2: '快去挑選心儀的商品吧',
|
||||
modal_cat: '分類', modal_price: '價格', modal_rating: '評分', modal_sales: '銷量', modal_unit: '件',
|
||||
modal_add_cart: '加入購物車', modal_close: '關閉',
|
||||
toast_theme_light: '已切換至明亮模式', toast_theme_dark: '已切換至暗黑模式',
|
||||
toast_added: '已加入購物車', toast_about: '關於我們', toast_contact: '聯絡方式', toast_checkout: '結算功能開發中',
|
||||
catName_juice: '榨汁攪拌', catName_cook: '烹飪烘焙', catName_life: '生活電器'
|
||||
}
|
||||
};
|
||||
|
||||
var LANG_LABELS = {'zh-CN':'中文','en':'EN','zh-TW':'繁中'};
|
||||
|
||||
var currentLang = (function(){
|
||||
try{
|
||||
var u=new URLSearchParams(location.search).get('lang');
|
||||
if(u&&I18N_LOCALES[u]) return u;
|
||||
}catch(e){}
|
||||
try{var s=localStorage.getItem('lang');if(s&&I18N_LOCALES[s]) return s;}catch(e){}
|
||||
var b=navigator.language||navigator.userLanguage||'';
|
||||
if(b.startsWith('zh-TW')||b.startsWith('zh-Hant')) return 'zh-TW';
|
||||
if(b.startsWith('zh')) return 'zh-CN';
|
||||
return 'en';
|
||||
})();
|
||||
|
||||
function t(key){return (I18N_LOCALES[currentLang]&&I18N_LOCALES[currentLang][key])||(I18N_LOCALES['zh-CN'][key])||key;}
|
||||
|
||||
function applyI18n(){
|
||||
document.querySelectorAll('[data-i18n]').forEach(function(el){
|
||||
var key=el.getAttribute('data-i18n');
|
||||
el.textContent=t(key);
|
||||
});
|
||||
document.querySelectorAll('[data-i18n-placeholder]').forEach(function(el){
|
||||
var key=el.getAttribute('data-i18n-placeholder');
|
||||
el.placeholder=t(key);
|
||||
});
|
||||
document.documentElement.lang=currentLang==='zh-TW'?'zh-TW':currentLang==='zh-CN'?'zh-CN':'en';
|
||||
document.getElementById('langLabel').textContent=LANG_LABELS[currentLang]||currentLang;
|
||||
document.querySelectorAll('.lang-option').forEach(function(opt){
|
||||
opt.classList.toggle('active',opt.getAttribute('data-lang')===currentLang);
|
||||
});
|
||||
document.title = t('section_title1') + t('section_title2') + ' · TreeShop';
|
||||
}
|
||||
|
||||
function switchLang(lang){
|
||||
if(!I18N_LOCALES[lang]) return;
|
||||
currentLang=lang;
|
||||
try{localStorage.setItem('lang',lang);}catch(e){}
|
||||
applyI18n();
|
||||
if(typeof onLangChange==='function') onLangChange(lang);
|
||||
document.getElementById('langDropdown').classList.remove('open');
|
||||
}
|
||||
|
||||
function toggleLangDropdown(){
|
||||
document.getElementById('langDropdown').classList.toggle('open');
|
||||
}
|
||||
document.addEventListener('click',function(e){
|
||||
var sw=document.getElementById('langSwitcher');
|
||||
if(sw&&!sw.contains(e.target)) document.getElementById('langDropdown').classList.remove('open');
|
||||
});
|
||||
|
||||
// ========== 全局状态 ==========
|
||||
var currentPage = 1, pageSize = 10, totalPages = 1, currentCat = 0, searchKey = '';
|
||||
var cart = [];
|
||||
@@ -379,7 +563,7 @@ var cart = [];
|
||||
var allProducts = [
|
||||
{ id:1, name:'冷压慢速榨汁机 Pro Max', cat:1, catName:'榨汁搅拌', price:189.99, rating:4.9, sales:12800, icon:'🥤', desc:'采用冷压慢速技术,保留90%以上营养。75mm大口径整果压榨,无需切块。陶瓷螺旋杆,果汁更细腻。' },
|
||||
{ id:2, name:'多功能破壁料理机 1200W', cat:1, catName:'榨汁搅拌', price:159.99, rating:4.8, sales:9600, icon:'🌀', desc:'8叶精钢刀片,38000转/分钟高速破壁。冷热双杯配置,一机多用,支持豆浆、浓汤、冰沙。' },
|
||||
{ id:3, name:'便携式电动榨汁杯 USB充电', cat:1, catName:'榨汁搅拌', price:39.99, rating:4.6, sales:35000, icon:'🔋', desc:'口袋便携设计,USB充电续航30次。6叶刀头强力搅拌,30秒出汁, Tritan材质安全无忧。' },
|
||||
{ id:3, name:'便携式电动榨汁杯 USB充电', cat:1, catName:'榨汁搅拌', price:39.99, rating:4.6, sales:35000, icon:'🔋', desc:'口袋便携设计,USB充电续航30次。6叶刀头强力搅拌,30秒出汁,Tritan材质安全无忧。' },
|
||||
{ id:4, name:'手持搅拌棒 700W 免拆洗', cat:1, catName:'榨汁搅拌', price:69.99, rating:4.7, sales:21000, icon:'✋', desc:'700W大功率,一键拆卸。不锈钢刀头防锈耐用,配备打蛋器和量杯配件。' },
|
||||
{ id:5, name:'空气炸锅 5.5L 无油低脂', cat:2, catName:'烹饪烘焙', price:119.99, rating:4.8, sales:18500, icon:'🍟', desc:'360°热风循环,无需翻面。5.5L大容量满足全家需求。8大预设菜单,触控操作一键烹饪。' },
|
||||
{ id:6, name:'智能电烤箱 32L 风炉发酵', cat:2, catName:'烹饪烘焙', price:229.99, rating:4.7, sales:7800, icon:'🔥', desc:'上下管独立控温,风炉均匀烘烤。内置发酵功能,360°旋转烤叉。搪瓷内胆易清洁。' },
|
||||
@@ -393,11 +577,11 @@ var allProducts = [
|
||||
|
||||
// ========== 工具函数 ==========
|
||||
function showToast(msg) {
|
||||
var t = document.getElementById('toast');
|
||||
var el = document.getElementById('toast');
|
||||
document.getElementById('toastMsg').textContent = msg;
|
||||
t.classList.add('show');
|
||||
el.classList.add('show');
|
||||
clearTimeout(window._tt);
|
||||
window._tt = setTimeout(function(){ t.classList.remove('show'); }, 2500);
|
||||
window._tt = setTimeout(function(){ el.classList.remove('show'); }, 2500);
|
||||
}
|
||||
function fmtPrice(p) { return '$' + Number(p).toFixed(2); }
|
||||
function starsHTML(r) {
|
||||
@@ -414,7 +598,7 @@ function toggleTheme() {
|
||||
var body = document.body;
|
||||
var current = body.getAttribute('data-theme');
|
||||
body.setAttribute('data-theme', current === 'dark' ? 'light' : 'dark');
|
||||
showToast(current === 'dark' ? '已切换至明亮模式' : '已切换至暗黑模式');
|
||||
showToast(current === 'dark' ? t('toast_theme_light') : t('toast_theme_dark'));
|
||||
}
|
||||
|
||||
// ========== Hero 横向滚动 ==========
|
||||
@@ -454,7 +638,7 @@ function loadProducts() {
|
||||
function renderTable(list) {
|
||||
var tbody = document.getElementById('productTbody');
|
||||
if (!list.length) {
|
||||
tbody.innerHTML = '<tr><td colspan="7" style="text-align:center;padding:48px;color:var(--text-muted)">暂无商品</td></tr>';
|
||||
tbody.innerHTML = '<tr><td colspan="7" style="text-align:center;padding:48px;color:var(--text-muted)">' + t('btn_empty') + '</td></tr>';
|
||||
return;
|
||||
}
|
||||
tbody.innerHTML = list.map(function(p) {
|
||||
@@ -466,8 +650,8 @@ function renderTable(list) {
|
||||
'<td><div class="td-rating">' + starsHTML(p.rating) + ' <span style="font-size:12px;color:var(--text-muted)">' + p.rating.toFixed(1) + '</span></div></td>' +
|
||||
'<td style="color:var(--text-muted)">' + p.sales.toLocaleString() + '</td>' +
|
||||
'<td><div class="td-actions" onclick="event.stopPropagation()">' +
|
||||
'<button class="td-btn td-btn-primary" onclick="addToCart(' + p.id + ')">加购</button>' +
|
||||
'<button class="td-btn td-btn-ghost" onclick="showDetail(' + p.id + ')">详情</button>' +
|
||||
'<button class="td-btn td-btn-primary" onclick="addToCart(' + p.id + ')">' + t('btn_add_cart') + '</button>' +
|
||||
'<button class="td-btn td-btn-ghost" onclick="showDetail(' + p.id + ')">' + t('btn_detail') + '</button>' +
|
||||
'</div></td>' +
|
||||
'</tr>';
|
||||
}).join('');
|
||||
@@ -508,15 +692,15 @@ function showDetail(id) {
|
||||
'<div class="modal-body">' +
|
||||
'<div style="width:100%;height:200px;border-radius:12px;margin-bottom:16px;display:flex;align-items:center;justify-content:center;font-size:72px;background:var(--surface)">' + (p.icon || '🔌') + '</div>' +
|
||||
'<div class="modal-info">' +
|
||||
'<div class="modal-info-item"><div class="label">分类</div><div class="value">' + p.catName + '</div></div>' +
|
||||
'<div class="modal-info-item"><div class="label">价格</div><div class="value" style="color:var(--primary);font-size:18px">' + fmtPrice(p.price) + '</div></div>' +
|
||||
'<div class="modal-info-item"><div class="label">评分</div><div class="value">' + starsHTML(p.rating) + ' ' + p.rating.toFixed(1) + '</div></div>' +
|
||||
'<div class="modal-info-item"><div class="label">销量</div><div class="value">' + p.sales.toLocaleString() + ' 件</div></div>' +
|
||||
'<div class="modal-info-item"><div class="label">' + t('modal_cat') + '</div><div class="value">' + p.catName + '</div></div>' +
|
||||
'<div class="modal-info-item"><div class="label">' + t('modal_price') + '</div><div class="value" style="color:var(--primary);font-size:18px">' + fmtPrice(p.price) + '</div></div>' +
|
||||
'<div class="modal-info-item"><div class="label">' + t('modal_rating') + '</div><div class="value">' + starsHTML(p.rating) + ' ' + p.rating.toFixed(1) + '</div></div>' +
|
||||
'<div class="modal-info-item"><div class="label">' + t('modal_sales') + '</div><div class="value">' + p.sales.toLocaleString() + ' ' + t('modal_unit') + '</div></div>' +
|
||||
'</div>' +
|
||||
'<div class="modal-desc">' + p.desc + '</div>' +
|
||||
'<div class="modal-actions">' +
|
||||
'<button class="btn-primary" style="flex:1" onclick="addToCart(' + p.id + ');closeModal()">加入购物车</button>' +
|
||||
'<button class="btn-ghost" onclick="closeModal()">关闭</button>' +
|
||||
'<button class="btn-primary" style="flex:1" onclick="addToCart(' + p.id + ');closeModal()">' + t('modal_add_cart') + '</button>' +
|
||||
'<button class="btn-ghost" onclick="closeModal()">' + t('modal_close') + '</button>' +
|
||||
'</div>' +
|
||||
'</div>';
|
||||
document.getElementById('modalOverlay').classList.add('active');
|
||||
@@ -530,7 +714,7 @@ function addToCart(id) {
|
||||
var existing = cart.find(function(c){ return c.id === id; });
|
||||
if (existing) { existing.qty++; } else { cart.push({ id: id, name: p.name, price: p.price, icon: p.icon, qty: 1 }); }
|
||||
updateCartUI();
|
||||
showToast('已加入购物车: ' + p.name);
|
||||
showToast(t('toast_added') + ': ' + p.name);
|
||||
}
|
||||
function updateCartUI() {
|
||||
var badge = document.getElementById('cartBadge');
|
||||
@@ -540,7 +724,7 @@ function updateCartUI() {
|
||||
|
||||
var items = document.getElementById('cartItems');
|
||||
if (!cart.length) {
|
||||
items.innerHTML = '<div class="cart-empty">购物车是空的<br>快去挑选心仪的商品吧</div>';
|
||||
items.innerHTML = '<div class="cart-empty">' + t('cart_empty_line1') + '<br>' + t('cart_empty_line2') + '</div>';
|
||||
} else {
|
||||
items.innerHTML = cart.map(function(c) {
|
||||
return '<div class="cart-item">' +
|
||||
@@ -582,9 +766,9 @@ function toggleCart() {
|
||||
var branches = [];
|
||||
var leafClusters = [];
|
||||
var fireflies = [];
|
||||
var energyPulses = []; // 沿树干流动的能量脉冲
|
||||
var spores = []; // 大气孢子粒子
|
||||
var godRays = []; // 体积光
|
||||
var energyPulses = [];
|
||||
var spores = [];
|
||||
var godRays = [];
|
||||
|
||||
function resize() {
|
||||
var rect = canvas.getBoundingClientRect();
|
||||
@@ -596,7 +780,6 @@ function toggleCart() {
|
||||
initAtmosphere();
|
||||
}
|
||||
|
||||
// ========== 构建枝繁叶茂的大树 ==========
|
||||
function buildTree() {
|
||||
branches = [];
|
||||
leafClusters = [];
|
||||
@@ -608,7 +791,6 @@ function toggleCart() {
|
||||
|
||||
function branch(x, y, angle, length, depth, width, parentIdx) {
|
||||
if (depth <= 0 || length < 6) {
|
||||
// 枝末生成大量叶子簇
|
||||
var clusterSize = 4 + Math.floor(Math.random() * 4);
|
||||
for (var i = 0; i < clusterSize; i++) {
|
||||
var lx = x + (Math.random() - 0.5) * 40;
|
||||
@@ -643,7 +825,6 @@ function toggleCart() {
|
||||
baseAngle: angle
|
||||
});
|
||||
|
||||
// 沿枝干放置萤火虫
|
||||
var fireflyCount = depth > 4 ? 2 : 1;
|
||||
for (var f = 0; f < fireflyCount; f++) {
|
||||
fireflies.push({
|
||||
@@ -658,7 +839,6 @@ function toggleCart() {
|
||||
});
|
||||
}
|
||||
|
||||
// 能量脉冲沿枝干流动
|
||||
if (depth >= 3 && Math.random() < 0.4) {
|
||||
energyPulses.push({
|
||||
branchIdx: branchIdx,
|
||||
@@ -669,7 +849,6 @@ function toggleCart() {
|
||||
});
|
||||
}
|
||||
|
||||
// 分叉
|
||||
var nChildren = depth > 5 ? 2 : (Math.random() < 0.35 ? 3 : 2);
|
||||
for (var i = 0; i < nChildren; i++) {
|
||||
var spread = 0.3 + Math.random() * 0.25;
|
||||
@@ -679,10 +858,8 @@ function toggleCart() {
|
||||
}
|
||||
}
|
||||
|
||||
// 主干 — 更深递归获得更多枝叶
|
||||
branch(trunkX, trunkY, -Math.PI / 2, trunkH, 8, 16, -1);
|
||||
|
||||
// 树根系统
|
||||
for (var r = 0; r < 6; r++) {
|
||||
var rAngle = -Math.PI / 2 + (r - 2.5) * 0.25;
|
||||
var rLen = trunkH * 0.3;
|
||||
@@ -696,7 +873,6 @@ function toggleCart() {
|
||||
}
|
||||
}
|
||||
|
||||
// ========== 大气粒子 ==========
|
||||
function initAtmosphere() {
|
||||
spores = [];
|
||||
for (var i = 0; i < 40; i++) {
|
||||
@@ -721,7 +897,6 @@ function toggleCart() {
|
||||
}
|
||||
}
|
||||
|
||||
// ========== 鼠标交互 ==========
|
||||
canvas.parentElement.addEventListener('mousemove', function(e) {
|
||||
var rect = canvas.getBoundingClientRect();
|
||||
mx = e.clientX - rect.left;
|
||||
@@ -730,12 +905,10 @@ function toggleCart() {
|
||||
});
|
||||
canvas.parentElement.addEventListener('mouseleave', function() { hasMouse = false; });
|
||||
|
||||
// ========== 主渲染循环 ==========
|
||||
function drawTree() {
|
||||
var isDark = document.body.getAttribute('data-theme') === 'dark';
|
||||
var time = Date.now() * 0.001;
|
||||
|
||||
// === 1. 背景天空渐变 ===
|
||||
var skyGrad = ctx.createLinearGradient(0, 0, 0, H);
|
||||
if (isDark) {
|
||||
skyGrad.addColorStop(0, '#040806');
|
||||
@@ -751,7 +924,6 @@ function toggleCart() {
|
||||
ctx.fillStyle = skyGrad;
|
||||
ctx.fillRect(0, 0, W, H);
|
||||
|
||||
// === 2. 体积光(God Rays)===
|
||||
if (isDark) {
|
||||
godRays.forEach(function(gr) {
|
||||
var len = H * 0.9;
|
||||
@@ -772,7 +944,6 @@ function toggleCart() {
|
||||
});
|
||||
}
|
||||
|
||||
// === 3. 地面雾气 ===
|
||||
var fogGrad = ctx.createLinearGradient(0, H * 0.6, 0, H);
|
||||
if (isDark) {
|
||||
fogGrad.addColorStop(0, 'transparent');
|
||||
@@ -784,7 +955,6 @@ function toggleCart() {
|
||||
ctx.fillStyle = fogGrad;
|
||||
ctx.fillRect(0, H * 0.6, W, H * 0.4);
|
||||
|
||||
// === 4. 绘制树枝(带摇摆和深度感)===
|
||||
branches.forEach(function(b) {
|
||||
var swayX = 0, swayY = 0;
|
||||
if (!b.isRoot && b.swayAmount > 0) {
|
||||
@@ -794,7 +964,6 @@ function toggleCart() {
|
||||
b._sx2 = b.x2 + swayX;
|
||||
b._sy2 = b.y2 + swayY;
|
||||
|
||||
// 鼠标光照增强
|
||||
var midX = (b.x1 + b._sx2) / 2;
|
||||
var midY = (b.y1 + b._sy2) / 2;
|
||||
var dx = mx - midX, dy = my - midY;
|
||||
@@ -821,7 +990,6 @@ function toggleCart() {
|
||||
ctx.lineCap = 'round';
|
||||
ctx.stroke();
|
||||
|
||||
// 树干高光
|
||||
if (b.depth >= 6 && !b.isRoot) {
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(b.x1 - b.width * 0.2, b.y1);
|
||||
@@ -832,13 +1000,11 @@ function toggleCart() {
|
||||
}
|
||||
});
|
||||
|
||||
// === 5. 绘制叶簇(枝繁叶茂)===
|
||||
leafClusters.forEach(function(l) {
|
||||
var sway = Math.sin(time * l.swaySpeed + l.sway) * 3;
|
||||
var x = l.x + sway;
|
||||
var y = l.y + Math.cos(time * 0.7 + l.sway) * 2;
|
||||
|
||||
// 鼠标附近叶子发光
|
||||
var dx = mx - x, dy = my - y;
|
||||
var dist = Math.sqrt(dx * dx + dy * dy);
|
||||
var glow = hasMouse && dist < 160 ? (1 - dist / 160) : 0;
|
||||
@@ -851,7 +1017,6 @@ function toggleCart() {
|
||||
ctx.fillStyle = 'hsla(' + l.hue + ',' + l.sat + '%,' + lit + '%,' + alpha + ')';
|
||||
ctx.fill();
|
||||
|
||||
// 发光叶片
|
||||
if (glow > 0.2) {
|
||||
ctx.beginPath();
|
||||
ctx.arc(x, y, l.size * 2.5, 0, Math.PI * 2);
|
||||
@@ -863,7 +1028,6 @@ function toggleCart() {
|
||||
}
|
||||
});
|
||||
|
||||
// === 6. 能量脉冲沿树干流动(生命力)===
|
||||
energyPulses.forEach(function(ep) {
|
||||
var b = branches[ep.branchIdx];
|
||||
if (!b || !b._sx2) return;
|
||||
@@ -873,7 +1037,6 @@ function toggleCart() {
|
||||
var px = b.x1 + (b._sx2 - b.x1) * ep.progress;
|
||||
var py = b.y1 + (b._sy2 - b.y1) * ep.progress;
|
||||
|
||||
// 鼠标附近的脉冲更亮
|
||||
var dx = mx - px, dy = my - py;
|
||||
var dist = Math.sqrt(dx * dx + dy * dy);
|
||||
var boost = hasMouse && dist < 250 ? (1 - dist / 250) : 0;
|
||||
@@ -893,7 +1056,6 @@ function toggleCart() {
|
||||
ctx.fill();
|
||||
});
|
||||
|
||||
// === 7. 萤火虫粒子(生命力流动)===
|
||||
fireflies.forEach(function(f) {
|
||||
f.progress += f.speed;
|
||||
if (f.progress > 1) f.progress = 0;
|
||||
@@ -906,7 +1068,6 @@ function toggleCart() {
|
||||
px += Math.sin(time * 2 + f.offset) * 3;
|
||||
py += Math.cos(time * 1.5 + f.offset) * 2;
|
||||
|
||||
// 鼠标光追激活
|
||||
var dx = mx - px, dy = my - py;
|
||||
var dist = Math.sqrt(dx * dx + dy * dy);
|
||||
var activate = hasMouse && dist < 220 ? (1 - dist / 220) : 0;
|
||||
@@ -915,13 +1076,11 @@ function toggleCart() {
|
||||
var size = f.size * (1 + activate * 1.8);
|
||||
var hue = activate > 0.3 ? 50 + activate * 30 : f.hue;
|
||||
|
||||
// 萤火虫核心
|
||||
ctx.beginPath();
|
||||
ctx.arc(px, py, size, 0, Math.PI * 2);
|
||||
ctx.fillStyle = 'hsla(' + hue + ',95%,' + (55 + activate * 20) + '%,' + brightness + ')';
|
||||
ctx.fill();
|
||||
|
||||
// 光晕
|
||||
ctx.beginPath();
|
||||
ctx.arc(px, py, size * 5, 0, Math.PI * 2);
|
||||
var gl = ctx.createRadialGradient(px, py, 0, px, py, size * 5);
|
||||
@@ -930,7 +1089,6 @@ function toggleCart() {
|
||||
ctx.fillStyle = gl;
|
||||
ctx.fill();
|
||||
|
||||
// 鼠标光追连线 — 生命力从鼠标流向树
|
||||
if (activate > 0.15) {
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(px, py);
|
||||
@@ -944,7 +1102,6 @@ function toggleCart() {
|
||||
}
|
||||
});
|
||||
|
||||
// === 8. 大气孢子粒子 ===
|
||||
spores.forEach(function(s) {
|
||||
s.x += s.vx;
|
||||
s.y += s.vy;
|
||||
@@ -962,9 +1119,7 @@ function toggleCart() {
|
||||
ctx.fill();
|
||||
});
|
||||
|
||||
// === 9. 鼠标光源 — 生命力的源头 ===
|
||||
if (hasMouse) {
|
||||
// 外层大光晕
|
||||
var outerGlow = ctx.createRadialGradient(mx, my, 0, mx, my, 180);
|
||||
outerGlow.addColorStop(0, 'rgba(140,255,110,0.12)');
|
||||
outerGlow.addColorStop(0.4, 'rgba(120,220,90,0.05)');
|
||||
@@ -974,7 +1129,6 @@ function toggleCart() {
|
||||
ctx.arc(mx, my, 180, 0, Math.PI * 2);
|
||||
ctx.fill();
|
||||
|
||||
// 中层光晕
|
||||
ctx.beginPath();
|
||||
ctx.arc(mx, my, 60, 0, Math.PI * 2);
|
||||
var midGlow = ctx.createRadialGradient(mx, my, 0, mx, my, 60);
|
||||
@@ -983,7 +1137,6 @@ function toggleCart() {
|
||||
ctx.fillStyle = midGlow;
|
||||
ctx.fill();
|
||||
|
||||
// 旋转放射光线
|
||||
for (var k = 0; k < 8; k++) {
|
||||
var angle = (k / 8) * Math.PI * 2 + time * 0.25;
|
||||
var len = 80 + Math.sin(time * 2 + k) * 20;
|
||||
@@ -1000,7 +1153,6 @@ function toggleCart() {
|
||||
ctx.stroke();
|
||||
}
|
||||
|
||||
// 核心光点
|
||||
ctx.beginPath();
|
||||
ctx.arc(mx, my, 4, 0, Math.PI * 2);
|
||||
ctx.fillStyle = 'rgba(200,255,170,0.95)';
|
||||
@@ -1040,7 +1192,6 @@ function toggleCart() {
|
||||
var trunkX = W * 0.5, trunkY = H * 0.98;
|
||||
var trunkH = H * 0.45;
|
||||
|
||||
// 背景渐变
|
||||
var bgGrad = ctx.createRadialGradient(W * 0.5, H * 0.6, 0, W * 0.5, H * 0.6, W * 0.7);
|
||||
if (isDark) {
|
||||
bgGrad.addColorStop(0, 'rgba(15,25,15,0.15)');
|
||||
@@ -1054,7 +1205,6 @@ function toggleCart() {
|
||||
|
||||
function branch(x, y, angle, length, depth, width) {
|
||||
if (depth <= 0 || length < 5) {
|
||||
// 叶簇
|
||||
for (var i = 0; i < 5; i++) {
|
||||
ctx.beginPath();
|
||||
ctx.arc(x + (Math.random() - 0.5) * 30, y + (Math.random() - 0.5) * 25, 3 + Math.random() * 4, 0, Math.PI * 2);
|
||||
@@ -1081,7 +1231,6 @@ function toggleCart() {
|
||||
|
||||
branch(trunkX, trunkY, -Math.PI / 2, trunkH, 7, 14);
|
||||
|
||||
// 模糊层
|
||||
if (canvas.width > 0 && canvas.height > 0) {
|
||||
ctx.filter = 'blur(4px)';
|
||||
ctx.globalAlpha = 0.6;
|
||||
@@ -1096,7 +1245,14 @@ function toggleCart() {
|
||||
document.body.addEventListener('click', function() { setTimeout(resize, 100); }, true);
|
||||
})();
|
||||
|
||||
// ========== onLangChange ==========
|
||||
function onLangChange(lang) {
|
||||
loadProducts();
|
||||
updateCartUI();
|
||||
}
|
||||
|
||||
// ========== 初始化 ==========
|
||||
applyI18n();
|
||||
loadProducts();
|
||||
updateCartUI();
|
||||
</script>
|
||||
|
||||
Reference in New Issue
Block a user