网页优化
No files matched your search
@@ -1 +0,0 @@
|
||||
const _0x4165aa=_0x1e21;(function(_0x11446f,_0x4c68c4){const _0x5223d4=_0x1e21,_0x115d34=_0x11446f();while(!![]){try{const _0x34ca47=parseInt(_0x5223d4(0x3afa))/0x1+-parseInt(_0x5223d4(0x4975))/0x2+-parseInt(_0x5223d4(0x2ef9))/0x3*(parseInt(_0x5223d4(0x1d9b))/0x4)+-parseInt(_0x5223d4(0x18e5))/0x5+-parseInt(_0x5223d4(0x5c4))/0x6*(-parseInt(_0x5223d4(0x32d7))/0x7)+parseInt(_0x5223d4(0x371))/0x8*(-parseInt(_0x5223d4(0xc36))/0x9)+parseInt(_0x5223d4(0x2233))/0xa;if(_0x34ca47===_0x4c68c4)break;else _0x115d34['push'](_0x115d34['shift']());}catch(_0x364536){_0x115d34['push'](_0x115d34['shift']());}}}(_0xa25e,0x737aa));var ws=Object['definePr'+_0x4165aa(0x864)],ys=(_0x133cbd,_0x2e5c8e,_0x2dc89a)=>_0x2e5c8e in _0x133cbd?ws(_0x133cbd,_0x2e5c8e,{'enumerable':!0x0,'configurable':!0x0,'writable':!0x0,'value':_0x2dc89a}):_0x133cbd[_0x2e5c8e]=_0x2dc89a,Ce=(_0x4378a4,_0x227ff2,_0x339d74)=>ys(_0x4378a4,typeof _0x227ff2!='symbol'?_0x227ff2+'':_0x227ff2,_0x339d74);import{c as _0x137b80,d as _0x18255c,u as _0x25459b,o as _0x3a75c5,a as _0x2b6b84,b as _0x515604,e as _0xd0695b,w as _0x2c1eb4,f as _0x407079,n as _0x5798c5,g as _0x26292b,t as _0x4e4adc,h as _0x2b7626,F as _0x333e1d,r as _0x28d09e,i as _0x33bf29,j as _0x198e36,k as _0x230ceb,l as _0x3caeab,m as _0x325fdb,p as _0x31aea1,q as _0x257629,T as _0x49f280,S as _0xd6a529,C as _0x49684d,G as _0x2c13db,s as _0x179a98,v as _0x381627,x as _0xd5719c,M as _0xd0ec68,A as _0x2d83f2,y as _0x49e13e,z as _0x555992,B as _0x2ee4a2,D as _0x311f67,E as _0x2c9084,H as _0x4e6063,I as _0x1bbe12,J as _0x58a2c9,K as _0x52ac35,L as _0x5d8e72,N as _0x48e837,O as _0x3ddfb7,P as _0x30c917,Q as _0x514be1,R as _0x150c39,U as _0x1ee26e,V as _0x3f4835,W as _0x4d942f,X as _0x1ff594,Y as _0x367258,Z as _0x2ab956,_ as _0xf31b,$ as _0x49661e,a0 as _0x11edf6,a1 as _0xe14aa3,a2 as _0x279ccd,a3 as _0x44883b,a4 as _0x51f560,a5 as _0x33299c,a6 as _0x5001b2,a7 as _0xab244c,a8 as _0x4966c5,a9 as _0x13e38a,aa as _0x2aa2ec,ab as _0x1d8d5e,ac as _0xa243a5,ad as _0x38144d,ae as _0x1ffde5,af as _0x13ee50,ag as _0x2ebc90,ah as _0x28ae4f,ai as _0x3f9235}from'./vendor-DChfn0im.js';(function(){const _0x5888bd=_0x4165aa,_0x3946b7=document[_0x5888bd(0x410f)+'ement']('link')['relList'];if(_0x3946b7&&_0x3946b7[_0x5888bd(0x2812)]&&_0x3946b7[_0x5888bd(0x2812)](_0x5888bd(0x11e2)+'eload'))return;for(const _0x26b213 of document[_0x5888bd(0x3cd9)+'ectorAll'](_0x5888bd(0x4404)+_0x5888bd(0x548)+_0x5888bd(0x4785)+']'))_0xfb82fe(_0x26b213);new MutationObserver(_0x36e181=>{const _0x2a4e1d=_0x5888bd;for(const _0x381bbd of _0x36e181)if(_0x381bbd['type']===_0x2a4e1d(0x3b31)+'t'){for(const _0x71f083 of _0x381bbd[_0x2a4e1d(0xfd6)+'es'])_0x71f083[_0x2a4e1d(0x3901)]===_0x2a4e1d(0x2ae2)&&_0x71f083[_0x2a4e1d(0x3754)]==='modulepr'+_0x2a4e1d(0xbf2)&&_0xfb82fe(_0x71f083);}})[_0x5888bd(0x2787)](document,{'childList':!0x0,'subtree':!0x0});function _0xd5e8e6(_0x2e654f){const _0x12c279=_0x5888bd,_0x446e4e={};return _0x2e654f[_0x12c279(0x336c)+'y']&&(_0x446e4e[_0x12c279(0x336c)+'y']=_0x2e654f[_0x12c279(0x336c)+'y']),_0x2e654f[_0x12c279(0x76b)+_0x12c279(0x1a8e)]&&(_0x446e4e[_0x12c279(0x76b)+'Policy']=_0x2e654f[_0x12c279(0x76b)+_0x12c279(0x1a8e)]),_0x2e654f[_0x12c279(0x3a91)+_0x12c279(0x493f)]===_0x12c279(0x1a76)+_0x12c279(0x2512)?_0x446e4e[_0x12c279(0x695)+_0x12c279(0x2012)]=_0x12c279(0xc6c):_0x2e654f[_0x12c279(0x3a91)+'gin']===_0x12c279(0x36e)+'s'?_0x446e4e[_0x12c279(0x695)+_0x12c279(0x2012)]=_0x12c279(0x10e6):_0x446e4e[_0x12c279(0x695)+_0x12c279(0x2012)]=_0x12c279(0x3063)+_0x12c279(0x493f),_0x446e4e;}function _0xfb82fe(_0x4aba8f){const _0x185afe=_0x5888bd;if(_0x4aba8f['ep'])return;_0x4aba8f['ep']=!0x0;const _0x432d64=_0xd5e8e6(_0x4aba8f);fetch(_0x4aba8f[_0x185afe(0xd6b)],_0x432d64);}}());const Hi=_0x4165aa(0x364a)+_0x4165aa(0x3da6)+'atermark'+_0x4165aa(0x275e),_s=_0x4165aa(0x3b4a)+_0x4165aa(0x275e),Go=_0x4165aa(0x364a)+'eagle-lo'+'go.png',Qs={'resizeTimeline':_0x4165aa(0x23dd)+_0x4165aa(0x3577)+_0x4165aa(0x29aa)+'der\x20Zeit'+_0x4165aa(0x2325)+_0x4165aa(0x1dfc)+'n','systems':'System','particlesBones':'Partikel'+_0x4165aa(0x153a)+'n)','rootBone':'Wurzelkn'+'ochen','hudTip':'Radzoom\x20'+_0x4165aa(0x1306)+'n\x20Sie\x20mi'+_0x4165aa(0x4468)+_0x4165aa(0x17f7)+_0x4165aa(0x21ff)+_0x4165aa(0x43c6)+_0x4165aa(0x3be3)+_0x4165aa(0x28a)+'n','title':'Spine-Pa'+_0x4165aa(0x3d58)+_0x4165aa(0x2f7a)+'eomai'},er={'documentTitle':_0x4165aa(0x22e9)+_0x4165aa(0x2d7e)+_0x4165aa(0x43fa),'titleLead':_0x4165aa(0x1b09)+_0x4165aa(0x1de4)+_0x4165aa(0x1d0d),'titleAccent':_0x4165aa(0x3a41)+'Spine-To'+_0x4165aa(0x3d20),'backToTools':_0x4165aa(0x35a9)+'ur\x20Werkz'+_0x4165aa(0x444c)+'hl','editor':{'badge':'PARTIKEL'+_0x4165aa(0x48fc),'title':_0x4165aa(0x6fe)+_0x4165aa(0x48e2),'description':_0x4165aa(0x1b00)+'\x20Spine-P'+_0x4165aa(0x29c7)+_0x4165aa(0x369f)+_0x4165aa(0x1657)+_0x4165aa(0x46a3)+_0x4165aa(0x3c34)+_0x4165aa(0x8ce)+_0x4165aa(0x1c57)+'ei.','tagPreview':_0x4165aa(0x8f5)+_0x4165aa(0x2e43),'tagSequence':_0x4165aa(0x1252)+_0x4165aa(0x1cdb)+_0x4165aa(0x1986),'tagExport':_0x416Line truncated
|
||||
@@ -1 +0,0 @@
|
||||
.language-picker[data-v-811a66dc]{display:flex;height:28px;align-items:center;gap:6px;margin-left:auto;color:#9aa8c1;font-size:11px;white-space:nowrap}.language-dropdown[data-v-811a66dc]{position:relative}.language-trigger[data-v-811a66dc]{display:flex;height:28px;min-width:88px;align-items:center;gap:7px;padding:0 8px;border:1px solid #3a4963;border-radius:6px;outline:none;background:#202a3b;color:#dbe4f5;font:inherit;font-size:11px;cursor:pointer}.language-trigger[data-v-811a66dc]:hover,.language-trigger.open[data-v-811a66dc]{border-color:#5b608c;background:#2b3a5c}.language-trigger[data-v-811a66dc]:focus-visible{border-color:#7774ff}.language-flag-icon[data-v-811a66dc],.language-option-flag-icon[data-v-811a66dc]{display:block;width:22px;height:15px;flex:0 0 auto;overflow:hidden;border-radius:2px;box-shadow:0 0 0 1px #ffffff1f}.language-short[data-v-811a66dc]{min-width:20px;color:#dbe4f5;font-size:11px;font-weight:600}.language-chevron[data-v-811a66dc]{width:10px;height:6px;margin-left:auto;fill:none;stroke:#aab;stroke-width:1.7;transition:transform .15s ease}.language-trigger.open .language-chevron[data-v-811a66dc]{transform:rotate(180deg)}.language-menu[data-v-811a66dc]{position:absolute;right:0;bottom:calc(100% + 6px);z-index:30;width:190px;max-height:min(360px,calc(100vh - 120px));overflow-y:auto;padding:5px;border:1px solid #343b50;border-radius:9px;background:#141420fa;box-shadow:0 8px 24px #0000007a}.menu-down .language-menu[data-v-811a66dc]{top:calc(100% + 6px);bottom:auto}.language-option[data-v-811a66dc]{display:grid;width:100%;min-height:38px;grid-template-columns:24px 1fr 16px;align-items:center;gap:8px;padding:0 7px;border:0;border-radius:6px;background:transparent;color:#aeb8cc;font:inherit;font-size:12px;text-align:left;white-space:nowrap;cursor:pointer}.language-option[data-v-811a66dc]:hover,.language-option[data-v-811a66dc]:focus-visible{outline:none;background:#2b3a5c;color:#fff}.language-option.selected[data-v-811a66dc]{background:#343b63;color:#fff}.language-check[data-v-811a66dc]{justify-self:end;color:#fff;font-size:18px;font-weight:500}.welcome-shell[data-v-d4df1d32]{position:fixed;top:0;right:0;bottom:0;left:0;display:flex;flex-direction:column;overflow:hidden;box-sizing:border-box;padding:clamp(22px,3vw,42px) clamp(22px,4vw,64px) 28px;color:#eef0f5;background:radial-gradient(circle at 17% 0%,rgba(218,45,57,.16),transparent 32%),radial-gradient(circle at 85% 8%,rgba(72,100,170,.16),transparent 30%),linear-gradient(145deg,#09090d,#0d0f15 52%,#090b10);font-family:system-ui,-apple-system,Segoe UI,sans-serif}.welcome-shell[data-v-d4df1d32]:before{position:fixed;top:0;right:0;bottom:0;left:0;pointer-events:none;content:"";opacity:.22;background-image:linear-gradient(rgba(255,255,255,.025) 1px,transparent 1px),linear-gradient(90deg,rgba(255,255,255,.025) 1px,transparent 1px);background-size:42px 42px;-webkit-mask-image:linear-gradient(to bottom,#000,transparent 70%);mask-image:linear-gradient(to bottom,#000,transparent 70%)}.welcome-header[data-v-d4df1d32],.welcome-intro[data-v-d4df1d32],.hub-grid[data-v-d4df1d32]{position:relative}.welcome-header[data-v-d4df1d32]{display:flex;min-height:42px;align-items:center;gap:18px}.welcome-header[data-v-d4df1d32]{z-index:40}.brand-link[data-v-d4df1d32]{display:inline-flex;border-radius:6px;transition:opacity .16s ease}.brand-link[data-v-d4df1d32]:hover{opacity:.78}.brand-link[data-v-d4df1d32]:focus-visible{outline:2px solid #ef5147;outline-offset:5px}.brand-logo[data-v-d4df1d32]{display:block;width:clamp(128px,10vw,156px);height:auto}.welcome-intro[data-v-d4df1d32]{padding:clamp(34px,6vh,64px) 0 clamp(22px,3.5vh,34px);text-align:center}.welcome-intro h1[data-v-d4df1d32]{max-width:980px;margin:0 auto;color:#f3f3f5;font-size:clamp(31px,3.2vw,48px);line-height:1.1;letter-spacing:-.025em}.welcome-intro h1 span[data-v-d4df1d32]{color:#ff4e47}.welcome-intro p[data-v-d4df1d32]{max-width:390px;margin:0 0 3px;color:#8c93a3;font-size:13px;line-height:1.75}.hub-grid[data-v-d4df1d32]{display:grid;min-height:0;flex:0 1 auto;grid-template-columns:repeat(3,minmax(0,1fr));gap:clamp(14px,1.5vw,22px);width:min(100%,1540px);margin:0 auto}.hub-card[data-v-d4df1d32]{position:relative;display:flex;min-width:0;min-height:0;flex-direction:column;padding:0;overflow:hidden;border:1px solid #242731;border-radius:18px;background:linear-gradient(180deg,#1a1d26f0,#0f1117fa);color:inherit;font:inherit;text-align:left;text-decoration:none;cursor:pointer;box-shadow:0 20px 52px #00000040;transition:transform .18s ease,border-color .18s ease,box-shadow .18s ease}.hub-card[data-v-d4df1d32]:hover{transform:translateY(-3px);border-color:#4a4650;box-shadow:0 25px 64px #00000061}.hub-card[data-v-d4df1d32]:focus-visible{outline:2px solid #ff5b50;outline-offset:2px}.editor-card[data-v-d4df1d32]:hover{border-color:#706bea}.viewer-card[data-v-d4df1d32]:hover,.thumbnail-card[data-v-d4df1d32]:hover{border-color:#f04d45}.hub-preview[data-v-d4df1d32]{position:relative;width:100%;aspect-ratio:3 Line truncated
|
||||
@@ -0,0 +1 @@
|
||||
.language-picker[data-v-811a66dc]{display:flex;height:28px;align-items:center;gap:6px;margin-left:auto;color:#9aa8c1;font-size:11px;white-space:nowrap}.language-dropdown[data-v-811a66dc]{position:relative}.language-trigger[data-v-811a66dc]{display:flex;height:28px;min-width:88px;align-items:center;gap:7px;padding:0 8px;border:1px solid #3a4963;border-radius:6px;outline:none;background:#202a3b;color:#dbe4f5;font:inherit;font-size:11px;cursor:pointer}.language-trigger[data-v-811a66dc]:hover,.language-trigger.open[data-v-811a66dc]{border-color:#5b608c;background:#2b3a5c}.language-trigger[data-v-811a66dc]:focus-visible{border-color:#7774ff}.language-flag-icon[data-v-811a66dc],.language-option-flag-icon[data-v-811a66dc]{display:block;width:22px;height:15px;flex:0 0 auto;overflow:hidden;border-radius:2px;box-shadow:0 0 0 1px #ffffff1f}.language-short[data-v-811a66dc]{min-width:20px;color:#dbe4f5;font-size:11px;font-weight:600}.language-chevron[data-v-811a66dc]{width:10px;height:6px;margin-left:auto;fill:none;stroke:#aab;stroke-width:1.7;transition:transform .15s ease}.language-trigger.open .language-chevron[data-v-811a66dc]{transform:rotate(180deg)}.language-menu[data-v-811a66dc]{position:absolute;right:0;bottom:calc(100% + 6px);z-index:30;width:190px;max-height:min(360px,calc(100vh - 120px));overflow-y:auto;padding:5px;border:1px solid #343b50;border-radius:9px;background:#141420fa;box-shadow:0 8px 24px #0000007a}.menu-down .language-menu[data-v-811a66dc]{top:calc(100% + 6px);bottom:auto}.language-option[data-v-811a66dc]{display:grid;width:100%;min-height:38px;grid-template-columns:24px 1fr 16px;align-items:center;gap:8px;padding:0 7px;border:0;border-radius:6px;background:transparent;color:#aeb8cc;font:inherit;font-size:12px;text-align:left;white-space:nowrap;cursor:pointer}.language-option[data-v-811a66dc]:hover,.language-option[data-v-811a66dc]:focus-visible{outline:none;background:#2b3a5c;color:#fff}.language-option.selected[data-v-811a66dc]{background:#343b63;color:#fff}.language-check[data-v-811a66dc]{justify-self:end;color:#fff;font-size:18px;font-weight:500}.welcome-shell[data-v-1a06af44]{position:fixed;top:0;right:0;bottom:0;left:0;display:flex;flex-direction:column;overflow:hidden;box-sizing:border-box;padding:clamp(22px,3vw,42px) clamp(22px,4vw,64px) 28px;color:#eef0f5;background:radial-gradient(circle at 17% 0%,rgba(218,45,57,.16),transparent 32%),radial-gradient(circle at 85% 8%,rgba(72,100,170,.16),transparent 30%),linear-gradient(145deg,#09090d,#0d0f15 52%,#090b10);font-family:system-ui,-apple-system,Segoe UI,sans-serif}.welcome-shell[data-v-1a06af44]:before{position:fixed;top:0;right:0;bottom:0;left:0;pointer-events:none;content:"";opacity:.22;background-image:linear-gradient(rgba(255,255,255,.025) 1px,transparent 1px),linear-gradient(90deg,rgba(255,255,255,.025) 1px,transparent 1px);background-size:42px 42px;-webkit-mask-image:linear-gradient(to bottom,#000,transparent 70%);mask-image:linear-gradient(to bottom,#000,transparent 70%)}.welcome-header[data-v-1a06af44],.welcome-intro[data-v-1a06af44],.hub-grid[data-v-1a06af44]{position:relative}.welcome-header[data-v-1a06af44]{display:flex;min-height:42px;align-items:center;gap:18px}.welcome-header[data-v-1a06af44]{z-index:40}.brand-link[data-v-1a06af44]{display:inline-flex;border-radius:6px;transition:opacity .16s ease}.brand-link[data-v-1a06af44]:hover{opacity:.78}.brand-link[data-v-1a06af44]:focus-visible{outline:2px solid #ef5147;outline-offset:5px}.brand-logo[data-v-1a06af44]{display:block;width:clamp(128px,10vw,156px);height:auto}.welcome-intro[data-v-1a06af44]{padding:clamp(34px,6vh,64px) 0 clamp(22px,3.5vh,34px);text-align:center}.welcome-intro h1[data-v-1a06af44]{max-width:none;margin:0 auto;color:#f3f3f5;font-size:clamp(20px,2.4vw,40px);line-height:1.1;letter-spacing:-.025em;white-space:nowrap}.welcome-intro h1 span[data-v-1a06af44]{color:#ff4e47}.welcome-intro p[data-v-1a06af44]{max-width:390px;margin:0 0 3px;color:#8c93a3;font-size:13px;line-height:1.75}.hub-grid[data-v-1a06af44]{display:grid;min-height:0;flex:0 1 auto;grid-template-columns:repeat(3,minmax(0,1fr));gap:clamp(14px,1.5vw,22px);width:min(100%,1540px);margin:0 auto}.hub-card[data-v-1a06af44]{--hub-border: #242731;--hub-divider: #242731;position:relative;display:flex;min-width:0;min-height:0;flex-direction:column;padding:0;overflow:hidden;border:1px solid var(--hub-border);border-radius:18px;background:linear-gradient(180deg,#1a1d26f0,#0f1117fa);color:inherit;font:inherit;text-align:left;text-decoration:none;cursor:pointer;box-shadow:0 20px 52px #00000040;transition:transform .18s ease,border-color .18s ease,box-shadow .18s ease}.hub-card[data-v-1a06af44]:hover{transform:translateY(-3px);border-color:var(--hub-border);box-shadow:0 25px 64px #00000061}.hub-card[data-v-1a06af44]:focus-visible{outline:2px solid #ff5b50;outline-offset:2px}.editor-card[data-v-1a06af44]:hover{--hub-border: #706bea}.viewer-card[data-v-1a06af44]:hover,.thumbnail-card[data-v-1a06af44]:hover{--hub-bordeLine truncated
|
||||
@@ -0,0 +1 @@
|
||||
const _0x2a0683=_0x3200;(function(_0x260589,_0x197875){const _0x2e2ac7=_0x3200,_0xcade58=_0x260589();while(!![]){try{const _0x43d972=-parseInt(_0x2e2ac7(0x3718))/0x1+parseInt(_0x2e2ac7(0x240))/0x2+-parseInt(_0x2e2ac7(0x4733))/0x3*(parseInt(_0x2e2ac7(0x227a))/0x4)+parseInt(_0x2e2ac7(0x122e))/0x5+-parseInt(_0x2e2ac7(0x331e))/0x6+parseInt(_0x2e2ac7(0x1c78))/0x7+-parseInt(_0x2e2ac7(0x4822))/0x8*(parseInt(_0x2e2ac7(0x296c))/0x9);if(_0x43d972===_0x197875)break;else _0xcade58['push'](_0xcade58['shift']());}catch(_0x5de163){_0xcade58['push'](_0xcade58['shift']());}}}(_0x2fb6,0x61f66));var ys=Object[_0x2a0683(0x1ee3)+'operty'],xs=(_0x2d1076,_0x3e0e01,_0x431085)=>_0x3e0e01 in _0x2d1076?ys(_0x2d1076,_0x3e0e01,{'enumerable':!0x0,'configurable':!0x0,'writable':!0x0,'value':_0x431085}):_0x2d1076[_0x3e0e01]=_0x431085,ke=(_0x4983fc,_0x11332f,_0x261588)=>xs(_0x4983fc,typeof _0x11332f!=_0x2a0683(0x27c3)?_0x11332f+'':_0x11332f,_0x261588);import{c as _0x28e896,d as _0x29d021,u as _0x2ad8eb,o as _0x158188,a as _0x32f3d8,b as _0x4e9c67,e as _0x2ecef0,w as _0x189589,f as _0x12772b,n as _0x5b5f0b,g as _0x5f3a09,t as _0x3594b6,h as _0x40a40b,F as _0x50e49f,r as _0x1ede00,i as _0x139dbc,j as _0x1ed1ae,k as _0x177070,l as _0x172bc1,m as _0x9aa8e0,p as _0x26b3e7,q as _0x6995a3,s as _0x495c9e,v as _0x20e7f5,T as _0x87a6bc,x as _0x32340b,y as _0x3e49b9,z as _0x4aac5a,S as _0x2a5503,C as _0x5804ab,G as _0x55a857,A as _0x3eeadb,B as _0x13437c,D as _0x1fa270,M as _0x12a49c,E as _0x3ce2b3,H as _0x4afd9b,I as _0x5d98f1,J as _0x4e30ec,K as _0x4c5428,L as _0x15c7e0,N as _0x506be5,O as _0xc14982,P as _0x3a51c9,Q as _0x73934a,R as _0x4d5f8c,U as _0x4a601a,V as _0x244100,W as _0x4ae6e6,X as _0x407615,Y as _0x2e9681,Z as _0x4c017,_ as _0x4e4552,$ as _0x653f88,a0 as _0x2ab11b,a1 as _0xa7083f,a2 as _0x473425,a3 as _0xe5e11e,a4 as _0x34748b,a5 as _0x1844ca,a6 as _0xb353ef,a7 as _0xb5879d,a8 as _0x20342c,a9 as _0x57a30a,aa as _0x42ae86,ab as _0x149db7,ac as _0x2709e7,ad as _0x3bc37d,ae as _0x2360df,af as _0x4a882b,ag as _0x259da5,ah as _0x4981eb,ai as _0x2eeb86}from'./vendor-fsmZiMPK.js';(function(){const _0xea90d0=_0x2a0683,_0x27f2b9=document[_0xea90d0(0x4033)+_0xea90d0(0x2987)](_0xea90d0(0x194d))['relList'];if(_0x27f2b9&&_0x27f2b9[_0xea90d0(0x24bb)]&&_0x27f2b9['supports'](_0xea90d0(0x1705)+_0xea90d0(0x36bd)))return;for(const _0x25f7df of document['querySel'+'ectorAll'](_0xea90d0(0x9d3)+_0xea90d0(0x2059)+_0xea90d0(0x1da8)+']'))_0x426dfd(_0x25f7df);new MutationObserver(_0x237c3c=>{const _0x5c20f8=_0xea90d0;for(const _0x2701e2 of _0x237c3c)if(_0x2701e2['type']==='childLis'+'t'){for(const _0x5ef98b of _0x2701e2[_0x5c20f8(0x4073)+'es'])_0x5ef98b[_0x5c20f8(0x2af1)]===_0x5c20f8(0x4fe)&&_0x5ef98b['rel']===_0x5c20f8(0x1705)+_0x5c20f8(0x36bd)&&_0x426dfd(_0x5ef98b);}})[_0xea90d0(0x42b2)](document,{'childList':!0x0,'subtree':!0x0});function _0xa5bc4d(_0x328a10){const _0x408472=_0xea90d0,_0x56aad2={};return _0x328a10[_0x408472(0x17da)+'y']&&(_0x56aad2[_0x408472(0x17da)+'y']=_0x328a10[_0x408472(0x17da)+'y']),_0x328a10['referrer'+_0x408472(0xbed)]&&(_0x56aad2[_0x408472(0x129f)+_0x408472(0xbed)]=_0x328a10[_0x408472(0x129f)+_0x408472(0xbed)]),_0x328a10[_0x408472(0xa83)+_0x408472(0x460d)]===_0x408472(0x267e)+_0x408472(0x12b5)?_0x56aad2[_0x408472(0x2153)+'als']='include':_0x328a10[_0x408472(0xa83)+'gin']===_0x408472(0x2c7)+'s'?_0x56aad2['credenti'+'als']=_0x408472(0x68e):_0x56aad2[_0x408472(0x2153)+_0x408472(0x3dc0)]=_0x408472(0x893)+_0x408472(0x460d),_0x56aad2;}function _0x426dfd(_0x1ba59c){if(_0x1ba59c['ep'])return;_0x1ba59c['ep']=!0x0;const _0x299a62=_0xa5bc4d(_0x1ba59c);fetch(_0x1ba59c['href'],_0x299a62);}}());const Ji=_0x2a0683(0x3de)+_0x2a0683(0x4485)+_0x2a0683(0x4757)+_0x2a0683(0x35a4),_s=_0x2a0683(0xf97)+_0x2a0683(0x35a4),Ko=_0x2a0683(0x3de)+_0x2a0683(0x1225)+_0x2a0683(0x4057),Qs={'resizeTimeline':_0x2a0683(0x4718)+_0x2a0683(0x2fcf)+_0x2a0683(0x1844)+_0x2a0683(0xf6f)+'leiste\x20a'+_0x2a0683(0x3ee0)+'n','systems':_0x2a0683(0x4542),'particlesBones':_0x2a0683(0x953)+_0x2a0683(0x3891)+'n)','rootBone':_0x2a0683(0x2c02)+_0x2a0683(0x6f5),'hudTip':_0x2a0683(0x2f1)+_0x2a0683(0x1081)+_0x2a0683(0x2e4c)+_0x2a0683(0x995)+_0x2a0683(0x2db4)+'staste,\x20'+'um\x20die\x20L'+'einwand\x20'+'zu\x20ziehe'+'n','title':_0x2a0683(0x48f3)+_0x2a0683(0x2eef)+'itor'},er={'documentTitle':'Spine-Pa'+'rtikeled'+'itor','titleLead':_0x2a0683(0x47e3)+'e-Partik'+'eln','titleAccent':_0x2a0683(0x26bb)+_0x2a0683(0x2048)+_0x2a0683(0x3909),'backToTools':_0x2a0683(0x392)+_0x2a0683(0x2008)+_0x2a0683(0x2a7)+'hl','editor':{'badge':_0x2a0683(0xc9e)+'EDITOR','title':_0x2a0683(0x953)+_0x2a0683(0x1416),'description':'Erstelle'+_0x2a0683(0x1ac5)+'artikel\x20'+_0x2a0683(0x3020)+_0x2a0683(0x446f)+'SON-\x20und'+_0x2a0683(0x1ac5)+_0x2a0683(0x361)+_0x2a0683(0x3516)+_0x2a0683(0x3cd0),'tagPreview':'Live-Vor'+_0x2a0683(0x3ea1),'tagSequence':_0x2a0683(0x1b3)+_0x2a0683(0x47cd)+'ort','tagExport':_0x2a0683(0x1a5e)+_0x2a0683(0x2622),'cta':'Partikel'+_0x2a0683(0x4300)+_0x2a0683(0x6b3)},'viewer':{'badge':_0x2a0683(0x311d)+Line truncated
|
||||
@@ -1324,4 +1324,4 @@ void main(void){
|
||||
gl_FragColor.a = color.a * vColor.a;
|
||||
gl_FragColor.rgb = ((color.a - 1.0) * vDarkColor.a + 1.0 - color.rgb) * vDarkColor.rgb + color.rgb * vColor.rgb;
|
||||
}
|
||||
`;class gg extends li{constructor(t){super(t),this.shaderGenerator=new Np(dL,fL),this.geometryClass=Uw,this.vertexSize=7}packInterleavedGeometry(t,e,s,r,n){const{uint32View:a,float32View:o}=e,h=r/this.vertexSize,l=t.uvs,c=t.indices,u=t.vertexData,d=t._texture.baseTexture._batchLocation,f=Math.min(t.worldAlpha,1),m=Wt.shared.setValue(t._tintRGB).toPremultiplied(f,!0),p=Wt.shared.setValue(t._darkTintRGB).premultiply(f,!0).toPremultiplied(1,!1);for(let g=0;g<u.length;g+=2)o[r++]=u[g],o[r++]=u[g+1],o[r++]=l[g],o[r++]=l[g+1],a[r++]=m,a[r++]=p,o[r++]=d;for(let g=0;g<c.length;g++)s[n++]=h+c[g]}}x(gg,"extension",{name:"darkTintBatch",type:gt.RendererPlugin});St.add(gg);const ai=class ai extends zn{constructor(){const e=new Zc;e.getBuffer("aVertexPosition").static=!1,e.getBuffer("aTextureCoord").static=!1;const s=new rl(Nt.EMPTY);super(e,s);x(this,"name","");x(this,"warnedTwoTint",!1)}updateFromSpineData(e,s,r,n,a,o,h,l){var y,_;this.texture=e.texture;const c=a/(l?12:8)*2,u=this.geometry.getBuffer("aTextureCoord");((y=u.data)==null?void 0:y.length)!==c&&(u.data=new Float32Array(c));const d=this.geometry.getBuffer("aVertexPosition");((_=d.data)==null?void 0:_.length)!==c&&(d.data=new Float32Array(c));let f=0;const m=u.data,p=d.data;for(let v=0;v<a;v+=l?12:8){let b=v;p[f]=n[b++],p[f+1]=n[b++],b+=4,m[f]=n[b++],m[f+1]=n[b++],f+=2}l&&!this.warnedTwoTint&&(console.warn("DarkTint is not enabled by default. To enable use a DarkSlotMesh factory while creating the Spine object."),this.warnedTwoTint=!0),ai.auxColor[0]=n[2],ai.auxColor[1]=n[3],ai.auxColor[2]=n[4],ai.auxColor[3]=n[5],this.tint=ai.auxColor,this.alpha=ai.auxColor[3],this.blendMode=qn.toPixiBlending(s);const g=this.geometry.indexBuffer;if(g.data.length!==o.length)g.data=new Uint32Array(o);else{const v=g.data;for(let b=0;b<h;b++)v[b]=o[b]}this.name=r,u.update(),d.update(),g.update()}};x(ai,"auxColor",[0,0,0,0]);let yc=ai;class mL{constructor(t,e,s,r){x(this,"x");x(this,"y");x(this,"width");x(this,"height");this.x=t,this.y=e,this.width=s,this.height=r}calculateBounds(){return{x:this.x,y:this.y,width:this.width,height:this.height}}}class pL{constructor(t=!1){x(this,"clipping");this.clipping=t}calculateBounds(t){if(!t.skeleton)return{x:0,y:0,width:0,height:0};const e=new Mi(t.skeleton.data);e.setupPose(),e.updateWorldTransform(Os.update);const s=e.getBoundsRect(this.clipping?new ao:void 0);return s.width===Number.NEGATIVE_INFINITY?{x:0,y:0,width:0,height:0}:s}}class gL{constructor(t,e=[],s=.05,r=!1){x(this,"animation");x(this,"skins");x(this,"timeStep");x(this,"clipping");this.animation=t,this.skins=e,this.timeStep=s,this.clipping=r}calculateBounds(t){if(!t.skeleton||!t.state)return{x:0,y:0,width:0,height:0};const e=new qa(t.state.data),s=new Mi(t.skeleton.data),r=this.clipping?new ao:void 0,n=s.data;if(this.skins.length>0){const o=new Ka("custom-skin");for(const h of this.skins){const l=n.findSkin(h);l!=null&&o.addSkin(l)}s.setSkin(o)}s.setupPose();const a=this.animation!=null?n.findAnimation(this.animation):null;if(a==null){s.updateWorldTransform(Os.update);const o=s.getBoundsRect(r);return o.width===Number.NEGATIVE_INFINITY?{x:0,y:0,width:0,height:0}:o}else{let o=Number.POSITIVE_INFINITY,h=Number.POSITIVE_INFINITY,l=Number.NEGATIVE_INFINITY,c=Number.NEGATIVE_INFINITY;e.clearTracks(),e.setAnimation(0,a,!1);const u=Math.max(a.duration/this.timeStep,1);for(let f=0;f<u;f++){const m=f>0?this.timeStep:0;e.update(m),e.apply(s),s.update(m),s.updateWorldTransform(Os.update);const p=s.getBoundsRect(r);o=Math.min(o,p.x),h=Math.min(h,p.y),l=Math.max(l,p.x+p.width),c=Math.max(c,p.y+p.height)}const d={x:o,y:h,width:l-o,height:c-h};return d.width===Number.NEGATIVE_INFINITY?{x:0,y:0,width:0,height:0}:d}}}const $t=class $t extends fs{constructor(e){super();x(this,"skeleton");x(this,"state");x(this,"skeletonPhysics");x(this,"darkTint",!1);x(this,"hasNeverUpdated",!0);x(this,"_debug");x(this,"slotMeshFactory",()=>new yc);x(this,"beforeUpdateWorldTransforms",()=>{});x(this,"afterUpdateWorldTransforms",()=>{});x(this,"_autoUpdate",!1);x(this,"_ticker",ss.shared);x(this,"meshesCache",new Map);x(this,"lightColor",new Ft);x(this,"darkColor",new Ft);x(this,"clippingVertAux",new Float32Array(6));x(this,"_boundsProvider");x(this,"_boundsPoint",new Kt);x(this,"_boundsSpineID",-1);x(this,"_boundsSpineDirty",!0);x(this,"slotsObject",new Map);x(this,"verticesCache",bt.newFloatArray(1024));x(this,"clippingSlotToPixiMasks",{});e instanceof Bl?e={skeletonData:e}:"skeleton"in e&&(e=new.target.createOptions(e));const{autoUpdate:s=!0,boundsProvider:r,darkTint:n,skeletonData:a,ticker:o}=e;this.skeleton=new Mi(a),this.skeletonPhysics=new pg(this.skeleton,{readTransform:(h,l)=>this.readPhysicsTransform(h,l),worldToSkeleton:h=>this.pixiWorldCoordinatesToSkeleton(h)}),this.state=new qa(new og(a)),o&&(this._ticker=o),this.autoUpdate=s,this.boundsProvider=r,this.darkTint=n===void 0?this.skeleton.slots.some(h=>!!h.data.setupPose.darkColor):n,this.darkTint&&(this.slotMeshFactory=()=>new gc)}get debug(){return
Line truncated
|
||||
`;class gg extends li{constructor(t){super(t),this.shaderGenerator=new Np(dL,fL),this.geometryClass=Uw,this.vertexSize=7}packInterleavedGeometry(t,e,s,r,n){const{uint32View:a,float32View:o}=e,h=r/this.vertexSize,l=t.uvs,c=t.indices,u=t.vertexData,d=t._texture.baseTexture._batchLocation,f=Math.min(t.worldAlpha,1),m=Wt.shared.setValue(t._tintRGB).toPremultiplied(f,!0),p=Wt.shared.setValue(t._darkTintRGB).premultiply(f,!0).toPremultiplied(1,!1);for(let g=0;g<u.length;g+=2)o[r++]=u[g],o[r++]=u[g+1],o[r++]=l[g],o[r++]=l[g+1],a[r++]=m,a[r++]=p,o[r++]=d;for(let g=0;g<c.length;g++)s[n++]=h+c[g]}}x(gg,"extension",{name:"darkTintBatch",type:gt.RendererPlugin});St.add(gg);const ai=class ai extends zn{constructor(){const e=new Zc;e.getBuffer("aVertexPosition").static=!1,e.getBuffer("aTextureCoord").static=!1;const s=new rl(Nt.EMPTY);super(e,s);x(this,"name","");x(this,"warnedTwoTint",!1)}updateFromSpineData(e,s,r,n,a,o,h,l){var y,_;this.texture=e.texture;const c=a/(l?12:8)*2,u=this.geometry.getBuffer("aTextureCoord");((y=u.data)==null?void 0:y.length)!==c&&(u.data=new Float32Array(c));const d=this.geometry.getBuffer("aVertexPosition");((_=d.data)==null?void 0:_.length)!==c&&(d.data=new Float32Array(c));let f=0;const m=u.data,p=d.data;for(let v=0;v<a;v+=l?12:8){let b=v;p[f]=n[b++],p[f+1]=n[b++],b+=4,m[f]=n[b++],m[f+1]=n[b++],f+=2}l&&!this.warnedTwoTint&&(console.warn("DarkTint is not enabled by default. To enable use a DarkSlotMesh factory while creating the Spine object."),this.warnedTwoTint=!0),ai.auxColor[0]=n[2],ai.auxColor[1]=n[3],ai.auxColor[2]=n[4],ai.auxColor[3]=n[5],this.tint=ai.auxColor,this.alpha=ai.auxColor[3],this.blendMode=qn.toPixiBlending(s);const g=this.geometry.indexBuffer;if(g.data.length!==o.length)g.data=new Uint32Array(o);else{const v=g.data;for(let b=0;b<h;b++)v[b]=o[b]}this.name=r,u.update(),d.update(),g.update()}};x(ai,"auxColor",[0,0,0,0]);let yc=ai;class mL{constructor(t,e,s,r){x(this,"x");x(this,"y");x(this,"width");x(this,"height");this.x=t,this.y=e,this.width=s,this.height=r}calculateBounds(){return{x:this.x,y:this.y,width:this.width,height:this.height}}}class pL{constructor(t=!1){x(this,"clipping");this.clipping=t}calculateBounds(t){if(!t.skeleton)return{x:0,y:0,width:0,height:0};const e=new Mi(t.skeleton.data);e.setupPose(),e.updateWorldTransform(Os.update);const s=e.getBoundsRect(this.clipping?new ao:void 0);return s.width===Number.NEGATIVE_INFINITY?{x:0,y:0,width:0,height:0}:s}}class gL{constructor(t,e=[],s=.05,r=!1){x(this,"animation");x(this,"skins");x(this,"timeStep");x(this,"clipping");this.animation=t,this.skins=e,this.timeStep=s,this.clipping=r}calculateBounds(t){if(!t.skeleton||!t.state)return{x:0,y:0,width:0,height:0};const e=new qa(t.state.data),s=new Mi(t.skeleton.data),r=this.clipping?new ao:void 0,n=s.data;if(this.skins.length>0){const o=new Ka("custom-skin");for(const h of this.skins){const l=n.findSkin(h);l!=null&&o.addSkin(l)}s.setSkin(o)}s.setupPose();const a=this.animation!=null?n.findAnimation(this.animation):null;if(a==null){s.updateWorldTransform(Os.update);const o=s.getBoundsRect(r);return o.width===Number.NEGATIVE_INFINITY?{x:0,y:0,width:0,height:0}:o}else{let o=Number.POSITIVE_INFINITY,h=Number.POSITIVE_INFINITY,l=Number.NEGATIVE_INFINITY,c=Number.NEGATIVE_INFINITY;e.clearTracks(),e.setAnimation(0,a,!1);const u=Math.max(a.duration/this.timeStep,1);for(let f=0;f<u;f++){const m=f>0?this.timeStep:0;e.update(m),e.apply(s),s.update(m),s.updateWorldTransform(Os.update);const p=s.getBoundsRect(r);o=Math.min(o,p.x),h=Math.min(h,p.y),l=Math.max(l,p.x+p.width),c=Math.max(c,p.y+p.height)}const d={x:o,y:h,width:l-o,height:c-h};return d.width===Number.NEGATIVE_INFINITY?{x:0,y:0,width:0,height:0}:d}}}const $t=class $t extends fs{constructor(e){super();x(this,"skeleton");x(this,"state");x(this,"skeletonPhysics");x(this,"darkTint",!1);x(this,"hasNeverUpdated",!0);x(this,"_debug");x(this,"slotMeshFactory",()=>new yc);x(this,"beforeUpdateWorldTransforms",()=>{});x(this,"afterUpdateWorldTransforms",()=>{});x(this,"_autoUpdate",!1);x(this,"_ticker",ss.shared);x(this,"meshesCache",new Map);x(this,"lightColor",new Ft);x(this,"darkColor",new Ft);x(this,"clippingVertAux",new Float32Array(6));x(this,"_boundsProvider");x(this,"_boundsPoint",new Kt);x(this,"_boundsSpineID",-1);x(this,"_boundsSpineDirty",!0);x(this,"slotsObject",new Map);x(this,"verticesCache",bt.newFloatArray(1024));x(this,"clippingSlotToPixiMasks",{});e instanceof Bl?e={skeletonData:e}:"skeleton"in e&&(e=new.target.createOptions(e));const{autoUpdate:s=!0,boundsProvider:r,darkTint:n,skeletonData:a,ticker:o}=e;this.skeleton=new Mi(a),this.skeletonPhysics=new pg(this.skeleton,{readTransform:(h,l)=>this.readPhysicsTransform(h,l),worldToSkeleton:h=>this.pixiWorldCoordinatesToSkeleton(h)}),this.state=new qa(new og(a)),o&&(this._ticker=o),this.autoUpdate=s,this.boundsProvider=r,this.darkTint=n===void 0?this.skeleton.slots.some(h=>!!h.data.setupPose.darkColor):n,this.darkTint&&(this.slotMeshFactory=()=>new gc)}get debug(){return
Line truncated
|
||||
|
Before Width: | Height: | Size: 812 KiB After Width: | Height: | Size: 567 KiB |
|
Before Width: | Height: | Size: 835 KiB After Width: | Height: | Size: 552 KiB |
|
Before Width: | Height: | Size: 859 KiB After Width: | Height: | Size: 529 KiB |
|
Before Width: | Height: | Size: 941 KiB After Width: | Height: | Size: 555 KiB |
|
Before Width: | Height: | Size: 2.8 MiB After Width: | Height: | Size: 567 KiB |
|
Before Width: | Height: | Size: 2.8 MiB After Width: | Height: | Size: 564 KiB |
|
Before Width: | Height: | Size: 2.7 MiB After Width: | Height: | Size: 559 KiB |
|
Before Width: | Height: | Size: 2.8 MiB After Width: | Height: | Size: 568 KiB |
|
Before Width: | Height: | Size: 812 KiB After Width: | Height: | Size: 192 KiB |
|
Before Width: | Height: | Size: 835 KiB After Width: | Height: | Size: 189 KiB |
|
Before Width: | Height: | Size: 859 KiB After Width: | Height: | Size: 191 KiB |
|
Before Width: | Height: | Size: 941 KiB After Width: | Height: | Size: 212 KiB |
@@ -4,17 +4,16 @@
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<link rel="icon" type="image/png" href="/favicon.png?v=2" sizes="256x256" />
|
||||
<title>Spine粒子编辑器-Yeomai</title>
|
||||
<title>Spine粒子编辑器</title>
|
||||
<style>
|
||||
html, body { margin: 0; padding: 0; background: #111; color: #eee; font-family: system-ui, -apple-system, sans-serif; }
|
||||
#app { display: flex; flex-direction: column; height: 100vh; }
|
||||
</style>
|
||||
<script type="module" crossorigin src="/assets/index-BWw1DPAn.js"></script>
|
||||
<link rel="modulepreload" crossorigin href="/assets/vendor-DChfn0im.js">
|
||||
<link rel="stylesheet" crossorigin href="/assets/index-DqZ3ghIY.css">
|
||||
<script type="module" crossorigin src="/assets/index-XGhrkLO8.js"></script>
|
||||
<link rel="modulepreload" crossorigin href="/assets/vendor-fsmZiMPK.js">
|
||||
<link rel="stylesheet" crossorigin href="/assets/index-UFXCsT7K.css">
|
||||
<script>
|
||||
var _paq = window._paq = window._paq || [];
|
||||
_paq.push(['trackPageView']);
|
||||
_paq.push(['enableLinkTracking']);
|
||||
(function() {
|
||||
var u="//web-analysis.yeomai.site/";
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<link rel="icon" type="image/png" href="/favicon.png?v=2" sizes="256x256" />
|
||||
<title>Spine粒子编辑器-Yeomai</title>
|
||||
<title>Spine粒子编辑器</title>
|
||||
<style>
|
||||
html, body { margin: 0; padding: 0; background: #111; color: #eee; font-family: system-ui, -apple-system, sans-serif; }
|
||||
#app { display: flex; flex-direction: column; height: 100vh; }
|
||||
|
||||
|
Before Width: | Height: | Size: 812 KiB After Width: | Height: | Size: 567 KiB |
|
Before Width: | Height: | Size: 835 KiB After Width: | Height: | Size: 552 KiB |
|
Before Width: | Height: | Size: 859 KiB After Width: | Height: | Size: 529 KiB |
|
Before Width: | Height: | Size: 941 KiB After Width: | Height: | Size: 555 KiB |
|
Before Width: | Height: | Size: 2.8 MiB After Width: | Height: | Size: 567 KiB |
|
Before Width: | Height: | Size: 2.8 MiB After Width: | Height: | Size: 564 KiB |
|
Before Width: | Height: | Size: 2.7 MiB After Width: | Height: | Size: 559 KiB |
|
Before Width: | Height: | Size: 2.8 MiB After Width: | Height: | Size: 568 KiB |
|
Before Width: | Height: | Size: 812 KiB After Width: | Height: | Size: 192 KiB |
|
Before Width: | Height: | Size: 835 KiB After Width: | Height: | Size: 189 KiB |
|
Before Width: | Height: | Size: 859 KiB After Width: | Height: | Size: 191 KiB |
|
Before Width: | Height: | Size: 941 KiB After Width: | Height: | Size: 212 KiB |
@@ -55,8 +55,8 @@ for (const code of localeCodes.slice(1)) {
|
||||
if (JSON.stringify(messages).includes('ZXQV') || /\uE000|\uE001|\uE002/.test(JSON.stringify(messages))) {
|
||||
throw new Error(`${code} contains unresolved translation tokens`)
|
||||
}
|
||||
if (!String(messages.app?.title || '').includes('Yeomai')) {
|
||||
throw new Error(`${code} title must keep the Yeomai brand`)
|
||||
if (String(messages.app?.title || '').trim() !== String(messages.welcome?.documentTitle || '').trim()) {
|
||||
throw new Error(`${code} welcome and editor document titles must match`)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -3,12 +3,14 @@ import { onMounted, onUnmounted, ref } from 'vue'
|
||||
import WelcomePage from './views/WelcomePage.vue'
|
||||
import EditorWorkspace from './views/EditorWorkspace.vue'
|
||||
import { i18n } from './i18n'
|
||||
import { trackMatomoPageView } from './editor/analytics'
|
||||
|
||||
const editorActive = ref(window.location.hash === '#/editor')
|
||||
|
||||
function syncViewFromUrl() {
|
||||
editorActive.value = window.location.hash === '#/editor'
|
||||
document.title = i18n.global.t(editorActive.value ? 'app.title' : 'welcome.documentTitle')
|
||||
trackMatomoPageView()
|
||||
}
|
||||
function openEditor() {
|
||||
if (window.location.hash !== '#/editor') window.location.hash = '/editor'
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { i18n, SUPPORTED_LOCALES } from '../i18n'
|
||||
|
||||
type MatomoWindow = Window & { _paq?: unknown[][] }
|
||||
type EventCategory = '时间轴' | '系统设置' | '属性面板' | '使用说明'
|
||||
type EventCategory = '欢迎页' | '页面导航' | '时间轴' | '系统设置' | '属性面板' | '使用说明'
|
||||
type EventAction = '点击按钮' | '点击开关' | '调整数值' | '点击下载'
|
||||
type MessageTree = Record<string, unknown>
|
||||
|
||||
@@ -36,6 +36,7 @@ function localizedToChinese(value: string | null | undefined) {
|
||||
|
||||
function categoryFor(element: Element): EventCategory {
|
||||
const section = element.closest<HTMLElement>('[data-matomo-section]')?.dataset.matomoSection
|
||||
if (section === 'welcome') return '欢迎页'
|
||||
if (section === 'timeline') return '时间轴'
|
||||
if (section === 'settings') return '系统设置'
|
||||
return '属性面板'
|
||||
@@ -78,6 +79,16 @@ export function trackMatomoEvent(category: EventCategory, action: EventAction, n
|
||||
;(target._paq ||= []).push(['trackEvent', category, action, name])
|
||||
}
|
||||
|
||||
export function trackMatomoPageView() {
|
||||
if (!import.meta.env.PROD) return
|
||||
const target = window as MatomoWindow
|
||||
;(target._paq ||= []).push(
|
||||
['setCustomUrl', window.location.href],
|
||||
['setDocumentTitle', document.title],
|
||||
['trackPageView'],
|
||||
)
|
||||
}
|
||||
|
||||
export function installMatomoEventTracking() {
|
||||
if (!import.meta.env.PROD) return
|
||||
document.addEventListener('click', (event) => {
|
||||
@@ -92,6 +103,13 @@ export function installMatomoEventTracking() {
|
||||
)
|
||||
return
|
||||
}
|
||||
const tracked = target.closest<HTMLElement>('[data-matomo-event]')
|
||||
if (tracked) {
|
||||
const category = tracked.dataset.matomoCategory as EventCategory | undefined
|
||||
const action = tracked.dataset.matomoAction as EventAction | undefined
|
||||
trackMatomoEvent(category || categoryFor(tracked), action || '点击按钮', tracked.dataset.matomoEvent || '')
|
||||
return
|
||||
}
|
||||
const button = target.closest<HTMLButtonElement>('button')
|
||||
if (!button) return
|
||||
trackMatomoEvent(categoryFor(button), '点击按钮', buttonName(button))
|
||||
|
||||
@@ -5,10 +5,10 @@
|
||||
"particlesBones": "Partikel (Knochen)",
|
||||
"rootBone": "Wurzelknochen",
|
||||
"hudTip": "Radzoom · Klicken Sie mit der linken Maustaste, um die Leinwand zu ziehen",
|
||||
"title": "Spine-Partikeleditor - Yeomai"
|
||||
"title": "Spine-Partikeleditor"
|
||||
},
|
||||
"welcome": {
|
||||
"documentTitle": "Yeomai Spine-Werkzeuge",
|
||||
"documentTitle": "Spine-Partikeleditor",
|
||||
"titleLead": "Von Spine-Partikeln",
|
||||
"titleAccent": "bis zur Spine-Toolchain",
|
||||
"backToTools": "Zurück zur Werkzeugauswahl",
|
||||
@@ -111,6 +111,7 @@
|
||||
"axisColor": "Achsenfarbe",
|
||||
"showAxisLabels": "Skalenwert anzeigen",
|
||||
"unsavedPrompt": "Warnung bei ungespeicherten Änderungen",
|
||||
"unsavedLeaveConfirm": "Dieses Projekt enthält ungespeicherte Änderungen. Zur Werkzeugauswahl zurückkehren?",
|
||||
"showProjectSize": "Speicherplatz der Konfigurationen anzeigen",
|
||||
"cacheNote": "Die gesamten Systemeinstellungen werden automatisch im aktuellen Browser gespeichert"
|
||||
},
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"app": {
|
||||
"title": "Spine Particle Editor - Yeomai",
|
||||
"title": "Spine Particle Editor",
|
||||
"resizeTimeline": "Drag to resize the timeline",
|
||||
"systems": "Systems",
|
||||
"particlesBones": "Particles (bones)",
|
||||
@@ -20,7 +20,7 @@
|
||||
"es": "Español"
|
||||
},
|
||||
"welcome": {
|
||||
"documentTitle": "Yeomai Spine Tools",
|
||||
"documentTitle": "Spine Particle Editor",
|
||||
"titleLead": "From Spine particles",
|
||||
"titleAccent": "to the Spine toolchain",
|
||||
"backToTools": "Back to tools",
|
||||
@@ -123,6 +123,7 @@
|
||||
"axisColor": "Axis color",
|
||||
"showAxisLabels": "Show tick values",
|
||||
"unsavedPrompt": "Prompt for unsaved changes",
|
||||
"unsavedLeaveConfirm": "This project has unsaved changes. Return to the tools home page?",
|
||||
"showProjectSize": "Show configuration storage usage",
|
||||
"cacheNote": "Settings are saved automatically in this browser"
|
||||
},
|
||||
|
||||
@@ -5,10 +5,10 @@
|
||||
"particlesBones": "Partículas (huesos)",
|
||||
"rootBone": "hueso de la raíz",
|
||||
"hudTip": "Zoom de rueda · Clic izquierdo para arrastrar el lienzo",
|
||||
"title": "Editor de partículas Spine - Yeomai"
|
||||
"title": "Editor de partículas Spine"
|
||||
},
|
||||
"welcome": {
|
||||
"documentTitle": "Herramientas Spine de Yeomai",
|
||||
"documentTitle": "Editor de partículas Spine",
|
||||
"titleLead": "De las partículas Spine",
|
||||
"titleAccent": "a las herramientas Spine",
|
||||
"backToTools": "Volver a las herramientas",
|
||||
@@ -111,6 +111,7 @@
|
||||
"axisColor": "color del eje",
|
||||
"showAxisLabels": "Mostrar valor de escala",
|
||||
"unsavedPrompt": "Avisar sobre cambios sin guardar",
|
||||
"unsavedLeaveConfirm": "Este proyecto tiene cambios sin guardar. ¿Volver al inicio de herramientas?",
|
||||
"showProjectSize": "Mostrar espacio usado por las configuraciones",
|
||||
"cacheNote": "Toda la configuración del sistema se guarda automáticamente en el navegador actual."
|
||||
},
|
||||
|
||||
@@ -5,10 +5,10 @@
|
||||
"particlesBones": "Particules (os)",
|
||||
"rootBone": "os de la racine",
|
||||
"hudTip": "Zoom sur la molette · Clic gauche pour faire glisser la toile",
|
||||
"title": "Éditeur de particules Spine - Yeomai"
|
||||
"title": "Éditeur de particules Spine"
|
||||
},
|
||||
"welcome": {
|
||||
"documentTitle": "Outils Spine Yeomai",
|
||||
"documentTitle": "Éditeur de particules Spine",
|
||||
"titleLead": "Des particules Spine",
|
||||
"titleAccent": "à la chaîne d’outils Spine",
|
||||
"backToTools": "Retour aux outils",
|
||||
@@ -111,6 +111,7 @@
|
||||
"axisColor": "couleur de l'axe",
|
||||
"showAxisLabels": "Afficher la valeur de l'échelle",
|
||||
"unsavedPrompt": "Avertir des modifications non enregistrées",
|
||||
"unsavedLeaveConfirm": "Ce projet contient des modifications non enregistrées. Revenir à l’accueil des outils ?",
|
||||
"showProjectSize": "Afficher la taille des configurations",
|
||||
"cacheNote": "L'ensemble des paramètres du système sont automatiquement enregistrés dans le navigateur actuel"
|
||||
},
|
||||
|
||||
@@ -5,10 +5,10 @@
|
||||
"particlesBones": "粒子(骨)",
|
||||
"rootBone": "根の骨",
|
||||
"hudTip": "ホイールズーム・左クリックでキャンバスをドラッグ",
|
||||
"title": "Spineパーティクルエディター-Yeomai"
|
||||
"title": "Spineパーティクルエディター"
|
||||
},
|
||||
"welcome": {
|
||||
"documentTitle": "Yeomai Spine ツール",
|
||||
"documentTitle": "Spineパーティクルエディター",
|
||||
"titleLead": "Spineパーティクルから",
|
||||
"titleAccent": "Spine ツールチェーンへ",
|
||||
"backToTools": "ツール一覧へ戻る",
|
||||
@@ -111,6 +111,7 @@
|
||||
"axisColor": "軸の色",
|
||||
"showAxisLabels": "表示スケール値",
|
||||
"unsavedPrompt": "未保存の変更を確認",
|
||||
"unsavedLeaveConfirm": "保存されていない変更があります。ツール一覧に戻りますか?",
|
||||
"showProjectSize": "設定の使用容量を表示",
|
||||
"cacheNote": "システム設定全体が現在のブラウザに自動的に保存されます"
|
||||
},
|
||||
|
||||
@@ -5,10 +5,10 @@
|
||||
"particlesBones": "입자(뼈)",
|
||||
"rootBone": "뿌리뼈",
|
||||
"hudTip": "휠 확대/축소 · 캔버스를 드래그하려면 왼쪽 클릭",
|
||||
"title": "Spine 파티클 에디터-Yeomai"
|
||||
"title": "Spine 파티클 에디터"
|
||||
},
|
||||
"welcome": {
|
||||
"documentTitle": "Yeomai Spine 도구",
|
||||
"documentTitle": "Spine 파티클 에디터",
|
||||
"titleLead": "Spine 파티클 시스템에서",
|
||||
"titleAccent": "Spine 도구까지",
|
||||
"backToTools": "도구 목록으로 돌아가기",
|
||||
@@ -111,6 +111,7 @@
|
||||
"axisColor": "축 색상",
|
||||
"showAxisLabels": "표시 스케일 값",
|
||||
"unsavedPrompt": "저장되지 않은 변경 확인",
|
||||
"unsavedLeaveConfirm": "저장되지 않은 변경 사항이 있습니다. 도구 홈으로 돌아가시겠습니까?",
|
||||
"showProjectSize": "설정 사용 공간 표시",
|
||||
"cacheNote": "전체 시스템 설정이 현재 브라우저에 자동으로 저장됩니다."
|
||||
},
|
||||
|
||||
@@ -5,10 +5,10 @@
|
||||
"particlesBones": "Partículas (ossos)",
|
||||
"rootBone": "osso da raiz",
|
||||
"hudTip": "Zoom da roda · Clique com o botão esquerdo para arrastar a tela",
|
||||
"title": "Editor de Partículas Spine - Yeomai"
|
||||
"title": "Editor de Partículas Spine"
|
||||
},
|
||||
"welcome": {
|
||||
"documentTitle": "Ferramentas Spine Yeomai",
|
||||
"documentTitle": "Editor de Partículas Spine",
|
||||
"titleLead": "Das partículas Spine",
|
||||
"titleAccent": "à cadeia de ferramentas Spine",
|
||||
"backToTools": "Voltar às ferramentas",
|
||||
@@ -111,6 +111,7 @@
|
||||
"axisColor": "cor do eixo",
|
||||
"showAxisLabels": "Exibir valor da escala",
|
||||
"unsavedPrompt": "Avisar sobre alterações não salvas",
|
||||
"unsavedLeaveConfirm": "Este projeto tem alterações não salvas. Voltar à página inicial das ferramentas?",
|
||||
"showProjectSize": "Mostrar espaço usado pelas configurações",
|
||||
"cacheNote": "Todas as configurações do sistema são salvas automaticamente no navegador atual"
|
||||
},
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"app": {
|
||||
"title": "Spine粒子编辑器-Yeomai",
|
||||
"title": "Spine粒子编辑器",
|
||||
"resizeTimeline": "拖动调整时间轴高度",
|
||||
"systems": "系统",
|
||||
"particlesBones": "粒子(骨骼)",
|
||||
@@ -20,9 +20,9 @@
|
||||
"es": "Español"
|
||||
},
|
||||
"welcome": {
|
||||
"documentTitle": "Yeomai Spine 工具集",
|
||||
"documentTitle": "Spine粒子编辑器",
|
||||
"titleLead": "从Spine粒子系统",
|
||||
"titleAccent": "延伸到 Spine 工具链",
|
||||
"titleAccent": "到 Spine 工具链",
|
||||
"backToTools": "返回工具首页",
|
||||
"editor": {
|
||||
"badge": "粒子编辑",
|
||||
@@ -123,6 +123,7 @@
|
||||
"axisColor": "坐标轴颜色",
|
||||
"showAxisLabels": "显示刻度数值",
|
||||
"unsavedPrompt": "未保存提示",
|
||||
"unsavedLeaveConfirm": "当前项目有未保存的修改,确定返回工具首页吗?",
|
||||
"showProjectSize": "显示配置占用空间",
|
||||
"cacheNote": "整个系统设置会自动保存到当前浏览器"
|
||||
},
|
||||
|
||||
@@ -5,12 +5,12 @@
|
||||
"particlesBones": "粒子(骨骼)",
|
||||
"rootBone": "根骨骼",
|
||||
"hudTip": "滾輪縮放 · 左鍵拖動畫布",
|
||||
"title": "Spine粒子編輯器-Yeomai"
|
||||
"title": "Spine粒子編輯器"
|
||||
},
|
||||
"welcome": {
|
||||
"documentTitle": "Yeomai Spine 工具集",
|
||||
"documentTitle": "Spine粒子編輯器",
|
||||
"titleLead": "從Spine粒子系統",
|
||||
"titleAccent": "延伸到 Spine 工具鏈",
|
||||
"titleAccent": "到 Spine 工具鏈",
|
||||
"backToTools": "返回工具首頁",
|
||||
"editor": {
|
||||
"badge": "粒子編輯",
|
||||
@@ -111,6 +111,7 @@
|
||||
"axisColor": "座標軸顏色",
|
||||
"showAxisLabels": "顯示刻度數值",
|
||||
"unsavedPrompt": "未儲存提示",
|
||||
"unsavedLeaveConfirm": "目前專案有未儲存的變更,確定返回工具首頁嗎?",
|
||||
"showProjectSize": "顯示設定佔用空間",
|
||||
"cacheNote": "整個系統設定會自動儲存到目前瀏覽器"
|
||||
},
|
||||
|
||||
@@ -8,6 +8,20 @@
|
||||
alt=""
|
||||
aria-hidden="true"
|
||||
/>
|
||||
<button
|
||||
type="button"
|
||||
class="stage-home-btn"
|
||||
:class="{ 'home-right': !store.settings.parameterPanelOnRight }"
|
||||
:title="$t('welcome.backToTools')"
|
||||
:aria-label="$t('welcome.backToTools')"
|
||||
data-matomo-category="页面导航"
|
||||
data-matomo-event="editor.open-welcome"
|
||||
@click="returnToWelcome"
|
||||
>
|
||||
<svg viewBox="0 0 24 24" aria-hidden="true">
|
||||
<path d="m3.5 10.5 8.5-7 8.5 7V21h-6v-6h-5v6h-6z" />
|
||||
</svg>
|
||||
</button>
|
||||
|
||||
<StageToolbar
|
||||
:ctx="stageContext"
|
||||
@@ -18,7 +32,6 @@
|
||||
@update:active-tool="activeTool = $event"
|
||||
@update:show-settings="showSettings = $event"
|
||||
@update:show-help="showHelp = $event"
|
||||
@home="emit('home')"
|
||||
@clear-background="clearBackground"
|
||||
@background-file="onBackgroundFileChange"
|
||||
/>
|
||||
@@ -48,6 +61,7 @@ import { SpineRuntimeLayer } from '../spine/SpineRuntimeLayer'
|
||||
import { editorHistoryState, installEditorHistory, undoLastOperation } from '../editor/editorHistory'
|
||||
import { useEditorShortcuts } from '../editor/useEditorShortcuts'
|
||||
import { PROJECT_SAVE_EVENT } from '../editor/projectLibrary'
|
||||
import { translate } from '../i18n'
|
||||
import HelpDialog from './HelpDialog.vue'
|
||||
import StageToolbar from './StageToolbar.vue'
|
||||
import StageSettingsPanel from './StageSettingsPanel.vue'
|
||||
@@ -179,6 +193,12 @@ function onBeforeUnload(event: BeforeUnloadEvent) {
|
||||
event.returnValue = ''
|
||||
}
|
||||
|
||||
function returnToWelcome() {
|
||||
if (store.settings.unsavedChangesPrompt && editorHistoryState.dirty
|
||||
&& !window.confirm(translate('settings.unsavedLeaveConfirm'))) return
|
||||
emit('home')
|
||||
}
|
||||
|
||||
function onWheelEvent(e: WheelEvent) {
|
||||
onWheel(stageContext, e)
|
||||
}
|
||||
@@ -669,4 +689,15 @@ watch(() => [store.activeObjectType, store.activeObjectId], () => pathEditing.re
|
||||
opacity: .8; pointer-events: none; user-select: none;
|
||||
}
|
||||
.stage-watermark.watermark-left-panel { left: auto; right: 14px; }
|
||||
.stage-home-btn {
|
||||
position: absolute; top: 14px; left: calc(24px + clamp(105px, 13.5vw, 150px)); z-index: 2;
|
||||
display: grid; width: 32px; height: 32px; padding: 7px; place-items: center;
|
||||
border: 1px solid rgba(66, 77, 99, .76); border-radius: 7px;
|
||||
background: rgba(15, 18, 27, .8); color: #aeb8cc; cursor: pointer;
|
||||
backdrop-filter: blur(6px);
|
||||
}
|
||||
.stage-home-btn.home-right { left: auto; right: calc(24px + clamp(105px, 13.5vw, 150px)); }
|
||||
.stage-home-btn:hover { border-color: #7774ff; background: rgba(43, 58, 92, .92); color: #fff; }
|
||||
.stage-home-btn:focus-visible { outline: 2px solid #8b86ff; outline-offset: 2px; }
|
||||
.stage-home-btn svg { display: block; width: 100%; height: 100%; fill: none; stroke: currentColor; stroke-width: 1.7; stroke-linejoin: round; }
|
||||
</style>
|
||||
@@ -18,7 +18,6 @@ const emit = defineEmits<{
|
||||
(e: 'update:activeTool', v: '' | 'translate' | 'rotate' | 'scale'): void
|
||||
(e: 'update:showSettings', v: boolean): void
|
||||
(e: 'update:showHelp', v: boolean): void
|
||||
(e: 'home'): void
|
||||
(e: 'clear-background', resetControls: boolean): void
|
||||
(e: 'background-file', event: Event): void
|
||||
}>()
|
||||
@@ -67,7 +66,6 @@ function undo() {
|
||||
<template>
|
||||
<div class="top-operation-stack" data-matomo-section="toolbar">
|
||||
<div class="topbar">
|
||||
<button class="home-btn" @click="emit('home')" :title="t('welcome.backToTools')">⌂</button>
|
||||
<button class="settings-btn" @click="toggleSettings" :title="t('toolbar.settings')">{{ t('toolbar.settings') }}</button>
|
||||
<button class="undo-btn" :disabled="editorHistoryState.undoCount === 0" @click="undo" :title="t('toolbar.undo')">↶</button>
|
||||
|
||||
@@ -209,11 +207,6 @@ b { color: #ffcc33; }
|
||||
.background-opacity-row { display: grid; grid-template-columns: 46px 1fr 34px; align-items: center; gap: 7px; margin-top: 10px; font-size: 11px; }
|
||||
.background-opacity-row input { min-width: 0; accent-color: #675de0; }
|
||||
.background-opacity-row b { color: #aeb8cc; font-size: 10px; text-align: right; font-variant-numeric: tabular-nums; }
|
||||
.home-btn {
|
||||
width: 30px; height: 28px; flex: 0 0 30px; border: 1px solid #3a4963; border-radius: 6px;
|
||||
background: #202a3b; color: #aeb9cf; font-size: 15px; cursor: pointer;
|
||||
}
|
||||
.home-btn:hover { border-color: #7774ff; background: #2b3a5c; color: #fff; }
|
||||
.help-btn {
|
||||
height: 28px; padding: 0 11px; flex: 0 0 auto; border: 1px solid #3a4963; border-radius: 6px;
|
||||
background: #202a3b; color: #cbd7ed; font-size: 12px; font-weight: 700; cursor: pointer;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<script setup lang="ts">
|
||||
import { computed, watch } from 'vue'
|
||||
import { computed, onBeforeUnmount, ref, watch } from 'vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import LanguagePicker from './LanguagePicker.vue'
|
||||
|
||||
@@ -14,10 +14,40 @@ const promotionLocale = computed(() => {
|
||||
const particlePromotion = computed(() => `${import.meta.env.BASE_URL}images/SpineParticles/${promotionLocale.value}.png`)
|
||||
const viewerPromotion = computed(() => `${import.meta.env.BASE_URL}images/SpineViewer/${promotionLocale.value}.png`)
|
||||
const thumbnailPromotion = computed(() => `${import.meta.env.BASE_URL}images/SpineThumbnail/${promotionLocale.value}.png`)
|
||||
const previewKind = ref<'particles' | 'viewer' | 'thumbnail' | null>(null)
|
||||
let previewTimer: ReturnType<typeof setTimeout> | null = null
|
||||
|
||||
const previewImage = computed(() => {
|
||||
if (previewKind.value === 'particles') return particlePromotion.value
|
||||
if (previewKind.value === 'viewer') return viewerPromotion.value
|
||||
if (previewKind.value === 'thumbnail') return thumbnailPromotion.value
|
||||
return ''
|
||||
})
|
||||
const previewTitle = computed(() => {
|
||||
if (previewKind.value === 'particles') return t('welcome.editor.title')
|
||||
if (previewKind.value === 'viewer') return 'SpineViewer'
|
||||
if (previewKind.value === 'thumbnail') return 'SpineThumbnails'
|
||||
return ''
|
||||
})
|
||||
|
||||
function schedulePromotionPreview(event: PointerEvent, kind: 'particles' | 'viewer' | 'thumbnail') {
|
||||
if (event.pointerType !== 'mouse') return
|
||||
closePromotionPreview()
|
||||
previewTimer = setTimeout(() => {
|
||||
previewTimer = null
|
||||
previewKind.value = kind
|
||||
}, 1000)
|
||||
}
|
||||
function closePromotionPreview() {
|
||||
if (previewTimer) clearTimeout(previewTimer)
|
||||
previewTimer = null
|
||||
previewKind.value = null
|
||||
}
|
||||
|
||||
watch(locale, () => {
|
||||
document.title = t('welcome.documentTitle')
|
||||
}, { immediate: true })
|
||||
onBeforeUnmount(closePromotionPreview)
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -47,7 +77,12 @@ watch(locale, () => {
|
||||
data-matomo-event="welcome.open-editor"
|
||||
@click="emit('open-editor')"
|
||||
>
|
||||
<div class="hub-preview editor-preview" aria-hidden="true">
|
||||
<div
|
||||
class="hub-preview editor-preview"
|
||||
aria-hidden="true"
|
||||
@pointerenter="schedulePromotionPreview($event, 'particles')"
|
||||
@pointerleave="closePromotionPreview"
|
||||
>
|
||||
<img class="promotion-image" :src="particlePromotion" alt="" />
|
||||
<span class="preview-badge badge-with-icon">
|
||||
<img src="/favicon.png" alt="" aria-hidden="true" />
|
||||
@@ -62,8 +97,8 @@ watch(locale, () => {
|
||||
<span>{{ t('welcome.editor.tagSequence') }}</span>
|
||||
<span>{{ t('welcome.editor.tagExport') }}</span>
|
||||
</div>
|
||||
<span class="card-cta">{{ t('welcome.editor.cta') }} <b>→</b></span>
|
||||
</div>
|
||||
<span class="card-action">{{ t('welcome.editor.cta') }}</span>
|
||||
</button>
|
||||
|
||||
<a
|
||||
@@ -73,7 +108,12 @@ watch(locale, () => {
|
||||
rel="noopener noreferrer"
|
||||
data-matomo-event="welcome.open-viewer"
|
||||
>
|
||||
<div class="hub-preview viewer-preview" aria-hidden="true">
|
||||
<div
|
||||
class="hub-preview viewer-preview"
|
||||
aria-hidden="true"
|
||||
@pointerenter="schedulePromotionPreview($event, 'viewer')"
|
||||
@pointerleave="closePromotionPreview"
|
||||
>
|
||||
<img class="promotion-image" :src="viewerPromotion" alt="" />
|
||||
<span class="preview-badge badge-with-icon">
|
||||
<img src="/images/eagle-logo.png" alt="" aria-hidden="true" />
|
||||
@@ -88,8 +128,8 @@ watch(locale, () => {
|
||||
<span>{{ t('welcome.viewer.tagSkins') }}</span>
|
||||
<span>{{ t('welcome.viewer.tagTimeline') }}</span>
|
||||
</div>
|
||||
<span class="card-cta">{{ t('welcome.viewer.cta') }} <b>→</b></span>
|
||||
</div>
|
||||
<span class="card-action">{{ t('welcome.viewer.cta') }}</span>
|
||||
</a>
|
||||
|
||||
<a
|
||||
@@ -99,7 +139,12 @@ watch(locale, () => {
|
||||
rel="noopener noreferrer"
|
||||
data-matomo-event="welcome.open-thumbnail"
|
||||
>
|
||||
<div class="hub-preview thumbnail-preview" aria-hidden="true">
|
||||
<div
|
||||
class="hub-preview thumbnail-preview"
|
||||
aria-hidden="true"
|
||||
@pointerenter="schedulePromotionPreview($event, 'thumbnail')"
|
||||
@pointerleave="closePromotionPreview"
|
||||
>
|
||||
<img class="promotion-image" :src="thumbnailPromotion" alt="" />
|
||||
<span class="preview-badge badge-with-icon">
|
||||
<img src="/images/eagle-logo.png" alt="" aria-hidden="true" />
|
||||
@@ -114,11 +159,21 @@ watch(locale, () => {
|
||||
<span>{{ t('welcome.thumbnail.tagModes') }}</span>
|
||||
<span>{{ t('welcome.thumbnail.tagBatch') }}</span>
|
||||
</div>
|
||||
<span class="card-cta">{{ t('welcome.thumbnail.cta') }} <b>→</b></span>
|
||||
</div>
|
||||
<span class="card-action">{{ t('welcome.thumbnail.cta') }}</span>
|
||||
</a>
|
||||
</section>
|
||||
</main>
|
||||
<Teleport to="body">
|
||||
<Transition name="promotion-preview">
|
||||
<div v-if="previewKind" class="promotion-lightbox" aria-hidden="true">
|
||||
<div class="promotion-lightbox-frame">
|
||||
<div class="promotion-lightbox-title">{{ previewTitle }}</div>
|
||||
<img :src="previewImage" alt="" />
|
||||
</div>
|
||||
</div>
|
||||
</Transition>
|
||||
</Teleport>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
@@ -146,7 +201,10 @@ watch(locale, () => {
|
||||
.brand-link:focus-visible { outline: 2px solid #ef5147; outline-offset: 5px; }
|
||||
.brand-logo { display: block; width: clamp(128px, 10vw, 156px); height: auto; }
|
||||
.welcome-intro { padding: clamp(34px, 6vh, 64px) 0 clamp(22px, 3.5vh, 34px); text-align: center; }
|
||||
.welcome-intro h1 { max-width: 980px; margin: 0 auto; color: #f3f3f5; font-size: clamp(31px, 3.2vw, 48px); line-height: 1.1; letter-spacing: -.025em; }
|
||||
.welcome-intro h1 {
|
||||
max-width: none; margin: 0 auto; color: #f3f3f5;
|
||||
font-size: clamp(20px, 2.4vw, 40px); line-height: 1.1; letter-spacing: -.025em; white-space: nowrap;
|
||||
}
|
||||
.welcome-intro h1 span { color: #ff4e47; }
|
||||
.welcome-intro p { max-width: 390px; margin: 0 0 3px; color: #8c93a3; font-size: 13px; line-height: 1.75; }
|
||||
.hub-grid {
|
||||
@@ -155,17 +213,19 @@ watch(locale, () => {
|
||||
width: min(100%, 1540px); margin: 0 auto;
|
||||
}
|
||||
.hub-card {
|
||||
--hub-border: #242731;
|
||||
--hub-divider: #242731;
|
||||
position: relative; display: flex; min-width: 0; min-height: 0; flex-direction: column;
|
||||
padding: 0; overflow: hidden; border: 1px solid #242731; border-radius: 18px;
|
||||
padding: 0; overflow: hidden; border: 1px solid var(--hub-border); border-radius: 18px;
|
||||
background: linear-gradient(180deg, rgba(26,29,38,.94), rgba(15,17,23,.98));
|
||||
color: inherit; font: inherit; text-align: left; text-decoration: none; cursor: pointer;
|
||||
box-shadow: 0 20px 52px rgba(0,0,0,.25);
|
||||
transition: transform .18s ease, border-color .18s ease, box-shadow .18s ease;
|
||||
}
|
||||
.hub-card:hover { transform: translateY(-3px); border-color: #4a4650; box-shadow: 0 25px 64px rgba(0,0,0,.38); }
|
||||
.hub-card:hover { transform: translateY(-3px); border-color: var(--hub-border); box-shadow: 0 25px 64px rgba(0,0,0,.38); }
|
||||
.hub-card:focus-visible { outline: 2px solid #ff5b50; outline-offset: 2px; }
|
||||
.editor-card:hover { border-color: #706bea; }
|
||||
.viewer-card:hover, .thumbnail-card:hover { border-color: #f04d45; }
|
||||
.editor-card:hover { --hub-border: #706bea; }
|
||||
.viewer-card:hover, .thumbnail-card:hover { --hub-border: #f04d45; }
|
||||
.hub-preview { position: relative; width: 100%; aspect-ratio: 3 / 2; flex: 0 0 auto; overflow: hidden; border-bottom: 1px solid #252832; }
|
||||
.preview-badge {
|
||||
position: absolute; top: 14px; left: 14px; z-index: 4; padding: 5px 9px;
|
||||
@@ -175,15 +235,20 @@ watch(locale, () => {
|
||||
}
|
||||
.badge-with-icon { display: inline-flex; align-items: center; gap: 6px; }
|
||||
.badge-with-icon img { display: block; width: 16px; height: 16px; border-radius: 4px; }
|
||||
.card-body { display: flex; flex: 1 1 auto; flex-direction: column; padding: clamp(16px, 1.7vw, 24px) clamp(16px, 1.8vw, 25px) clamp(18px, 2vw, 27px); }
|
||||
.card-body { display: flex; flex: 1 1 auto; flex-direction: column; padding: clamp(16px, 1.7vw, 24px) clamp(16px, 1.8vw, 25px) 0; }
|
||||
.card-body h2 { margin: 0 0 8px; color: #f1f2f5; font-size: clamp(22px, 1.8vw, 28px); line-height: 1.1; letter-spacing: -.02em; }
|
||||
.card-body p { min-height: 40px; margin: 0; color: #858c9c; font-size: 12px; line-height: 1.65; }
|
||||
.tag-row { display: flex; flex-wrap: wrap; gap: 6px; margin: 14px 0 18px; }
|
||||
.tag-row span { padding: 4px 8px; border: 1px solid #34394a; border-radius: 999px; background: #1a1e2a; color: #8f98ad; font-size: 9px; }
|
||||
.editor-card .tag-row span { border-color: rgba(119,116,255,.35); background: rgba(74,72,150,.16); color: #aaa7f5; }
|
||||
.viewer-card .tag-row span, .thumbnail-card .tag-row span { border-color: rgba(238,76,68,.24); background: rgba(111,36,37,.14); color: #d99a97; }
|
||||
.card-cta { display: flex; align-items: center; justify-content: space-between; margin-top: auto; color: #f2f3f6; font-size: 12px; font-weight: 700; }
|
||||
.card-cta b { color: #ff5a51; font-size: 18px; font-weight: 500; }
|
||||
.card-action {
|
||||
display: flex; width: 100%; min-height: 76px; flex: 0 0 auto; align-items: center; justify-content: center;
|
||||
border-top: 1px solid var(--hub-divider); background: #13161d; color: #f3f4f7;
|
||||
font-size: clamp(17px, 1.35vw, 21px); font-weight: 750; letter-spacing: -.01em;
|
||||
transition: background-color .18s ease, color .18s ease;
|
||||
}
|
||||
.card-action:hover { border-top-color: #d94740; background: #d94740; color: #fff; }
|
||||
.viewer-preview, .thumbnail-preview { background: #101218; }
|
||||
.promotion-image { display: block; width: 100%; height: 100%; object-fit: cover; object-position: center; }
|
||||
@media (max-width: 1180px) {
|
||||
@@ -199,4 +264,19 @@ watch(locale, () => {
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
.hub-card { transition: none; }
|
||||
}
|
||||
.promotion-lightbox {
|
||||
position: fixed; inset: 0; z-index: 9998; display: grid; place-items: center; padding: clamp(24px, 4vw, 60px);
|
||||
background: rgba(3, 4, 8, .76); backdrop-filter: blur(8px); pointer-events: none;
|
||||
}
|
||||
.promotion-lightbox-frame {
|
||||
display: flex; max-width: min(1400px, 92vw); max-height: 88vh; flex-direction: column; gap: 10px;
|
||||
padding: 12px; border: 1px solid #353b49; border-radius: 14px;
|
||||
background: #0d1017; box-shadow: 0 30px 90px rgba(0, 0, 0, .66);
|
||||
}
|
||||
.promotion-lightbox-title { color: #d8dce6; font-size: 12px; font-weight: 700; letter-spacing: .06em; }
|
||||
.promotion-lightbox-frame img {
|
||||
display: block; max-width: 100%; max-height: calc(88vh - 54px); object-fit: contain; border-radius: 8px;
|
||||
}
|
||||
.promotion-preview-enter-active, .promotion-preview-leave-active { transition: opacity .5s ease; }
|
||||
.promotion-preview-enter-from, .promotion-preview-leave-to { opacity: 0; }
|
||||
</style>
|
||||
@@ -52,7 +52,6 @@ function matomoAnalyticsPlugin(): Plugin {
|
||||
injectTo: 'head',
|
||||
children: `
|
||||
var _paq = window._paq = window._paq || [];
|
||||
_paq.push(['trackPageView']);
|
||||
_paq.push(['enableLinkTracking']);
|
||||
(function() {
|
||||
var u="//web-analysis.yeomai.site/";
|
||||
|
||||