Design-Update 4: Liquid-Metal-Buttons, Glas-Refraktion, neuer Create-Screen mit Fake-Tastatur
- Like/Plus/Nachmachen/Generieren als Liquid-Metal: WebGL-Shader (esm.sh @paper-design/shaders, liquidMetalFragmentShader) ueber Metall-Gradient- Fallback, schwarzer Kern, graues Icon mit Schattenwurf - Nav-Glas: bl-glass-refract (feImage-Displacement-Map mit RGB-Split, aus Nav-Groesse dynamisch generiert) + blur(3px) saturate(1.15), Weiss .12, Ring .4/.3; Layer als echte divs statt Pseudo-Elemente - Create komplett neu (aus BrandLoop.dc.html): Vorschau-Stack mit Ketten- Faecher + Dots + Video-Badge, Optionen-Accordion (Typ/Format/Kette), Prompt-Box mit Border-Beam (border-beam.css), Liquid-Metal-Generate, Fake-iOS-Tastatur mit @Modell-Tokens (inputmode=none gegen echte Tastatur), interner Scroll + body.noscroll auch fuer Create Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
178
border-beam.css
Normal file
178
border-beam.css
Normal file
@@ -0,0 +1,178 @@
|
||||
|
||||
@property --beam-angle-bb {
|
||||
syntax: "<angle>";
|
||||
initial-value: 0deg;
|
||||
inherits: true;
|
||||
}
|
||||
|
||||
@property --beam-opacity-bb {
|
||||
syntax: "<number>";
|
||||
initial-value: 0;
|
||||
inherits: true;
|
||||
}
|
||||
|
||||
[data-beam="bb"] {
|
||||
position: relative;
|
||||
border-radius: 24px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
[data-beam="bb"][data-active] {
|
||||
animation:
|
||||
beam-spin-bb 1.96s linear infinite,
|
||||
beam-fade-in-bb 0.6s ease forwards;
|
||||
}
|
||||
|
||||
[data-beam="bb"][data-active]::after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
border-radius: 23px;
|
||||
padding: 1px;
|
||||
clip-path: inset(0 round 24px);
|
||||
background: conic-gradient(
|
||||
from var(--beam-angle-bb),
|
||||
transparent 0%, transparent 54%,
|
||||
rgba(255, 255, 255, 0.1) 57%,
|
||||
rgba(255, 255, 255, 0.3) 60%,
|
||||
rgba(255, 255, 255, 0.6) 63%,
|
||||
rgba(255, 255, 255, 0.75) 66%,
|
||||
rgba(255, 255, 255, 0.6) 69%,
|
||||
rgba(255, 255, 255, 0.3) 72%,
|
||||
rgba(255, 255, 255, 0.1) 75%,
|
||||
transparent 78%, transparent 100%
|
||||
),radial-gradient(ellipse 70px 40px at 33% -7.4%, rgb(255, 50, 100), transparent),
|
||||
radial-gradient(ellipse 60px 35px at 12% -5%, rgb(40, 140, 255), transparent),
|
||||
radial-gradient(ellipse 40px 70px at 2.1% 68.3%, rgb(50, 200, 80), transparent),
|
||||
radial-gradient(ellipse 20px 35px at 2.1% 68.3%, rgb(30, 185, 170), transparent),
|
||||
radial-gradient(ellipse 180px 32px at 74.4% 100%, rgb(100, 70, 255), transparent),
|
||||
radial-gradient(ellipse 85px 26px at 55% 100%, rgb(40, 140, 255), transparent),
|
||||
radial-gradient(ellipse 74px 32px at 93.9% 0%, rgb(255, 120, 40), transparent),
|
||||
radial-gradient(ellipse 26px 42px at 100% 27.1%, rgb(240, 50, 180), transparent),
|
||||
radial-gradient(ellipse 52px 48px at 100% 27.1%, rgb(180, 40, 240), transparent);
|
||||
-webkit-mask:
|
||||
conic-gradient(
|
||||
from var(--beam-angle-bb),
|
||||
transparent 0%, transparent 30%,
|
||||
rgba(255, 255, 255, 0.1) 36%, rgba(255, 255, 255, 0.35) 44%,
|
||||
white 52%, white 80%,
|
||||
rgba(255, 255, 255, 0.35) 86%, rgba(255, 255, 255, 0.1) 92%,
|
||||
transparent 95%, transparent 100%
|
||||
),
|
||||
linear-gradient(#fff 0 0) content-box,
|
||||
linear-gradient(#fff 0 0);
|
||||
-webkit-mask-composite: source-in, xor;
|
||||
mask:
|
||||
conic-gradient(
|
||||
from var(--beam-angle-bb),
|
||||
transparent 0%, transparent 30%,
|
||||
rgba(255, 255, 255, 0.1) 36%, rgba(255, 255, 255, 0.35) 44%,
|
||||
white 52%, white 80%,
|
||||
rgba(255, 255, 255, 0.35) 86%, rgba(255, 255, 255, 0.1) 92%,
|
||||
transparent 95%, transparent 100%
|
||||
),
|
||||
linear-gradient(#fff 0 0) content-box,
|
||||
linear-gradient(#fff 0 0);
|
||||
mask-composite: intersect, exclude;
|
||||
pointer-events: none;
|
||||
z-index: 2;
|
||||
opacity: calc(var(--beam-opacity-bb) * 0.26 * var(--beam-stroke-opacity, 1) * var(--beam-strength, 1));
|
||||
animation: beam-hue-shift-bb 12s ease-in-out infinite;
|
||||
}
|
||||
|
||||
[data-beam="bb"][data-active]::before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
border-radius: 24px;
|
||||
background: radial-gradient(ellipse 63px 36px at 33% -7.4%, rgba(255, 50, 100, 0.45), transparent),
|
||||
radial-gradient(ellipse 54px 32px at 12% -5%, rgba(40, 140, 255, 0.45), transparent),
|
||||
radial-gradient(ellipse 36px 63px at 2.1% 68.3%, rgba(50, 200, 80, 0.45), transparent),
|
||||
radial-gradient(ellipse 18px 32px at 2.1% 68.3%, rgba(30, 185, 170, 0.45), transparent),
|
||||
radial-gradient(ellipse 162px 29px at 74.4% 100%, rgba(100, 70, 255, 0.45), transparent),
|
||||
radial-gradient(ellipse 77px 23px at 55% 100%, rgba(40, 140, 255, 0.45), transparent),
|
||||
radial-gradient(ellipse 67px 29px at 93.9% 0%, rgba(255, 120, 40, 0.45), transparent),
|
||||
radial-gradient(ellipse 23px 38px at 100% 27.1%, rgba(240, 50, 180, 0.45), transparent),
|
||||
radial-gradient(ellipse 47px 43px at 100% 27.1%, rgba(180, 40, 240, 0.45), transparent);
|
||||
box-shadow: inset 0 0 9px 1px rgba(255, 255, 255, 0.27);
|
||||
-webkit-mask-image:
|
||||
conic-gradient(
|
||||
from var(--beam-angle-bb),
|
||||
transparent 0%, transparent 30%,
|
||||
rgba(255, 255, 255, 0.1) 36%, rgba(255, 255, 255, 0.35) 44%,
|
||||
white 52%, white 80%,
|
||||
rgba(255, 255, 255, 0.35) 86%, rgba(255, 255, 255, 0.1) 92%,
|
||||
transparent 95%, transparent 100%
|
||||
),
|
||||
linear-gradient(white, transparent 28px, transparent calc(100% - 28px), white),
|
||||
linear-gradient(to right, white, transparent 28px, transparent calc(100% - 28px), white);
|
||||
-webkit-mask-composite: source-in, source-over;
|
||||
mask-image:
|
||||
conic-gradient(
|
||||
from var(--beam-angle-bb),
|
||||
transparent 0%, transparent 30%,
|
||||
rgba(255, 255, 255, 0.1) 36%, rgba(255, 255, 255, 0.35) 44%,
|
||||
white 52%, white 80%,
|
||||
rgba(255, 255, 255, 0.35) 86%, rgba(255, 255, 255, 0.1) 92%,
|
||||
transparent 95%, transparent 100%
|
||||
),
|
||||
linear-gradient(white, transparent 28px, transparent calc(100% - 28px), white),
|
||||
linear-gradient(to right, white, transparent 28px, transparent calc(100% - 28px), white);
|
||||
mask-composite: intersect, add;
|
||||
pointer-events: none;
|
||||
z-index: 1;
|
||||
opacity: calc(var(--beam-opacity-bb) * 0.42 * var(--beam-inner-opacity, 1) * var(--beam-strength, 1));
|
||||
clip-path: inset(0 round 24px);
|
||||
animation: beam-hue-shift-bb 12s ease-in-out infinite;
|
||||
}
|
||||
|
||||
[data-beam="bb"] [data-beam-bloom] {
|
||||
display: none;
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
border-radius: 23px;
|
||||
clip-path: inset(0 round 24px);
|
||||
background: conic-gradient(
|
||||
from var(--beam-angle-bb),
|
||||
transparent 0%, transparent 58%,
|
||||
rgba(255, 255, 255, 0.03) 62%,
|
||||
rgba(255, 255, 255, 0.08) 65%,
|
||||
rgba(255, 255, 255, 0.2) 67%,
|
||||
rgba(255, 255, 255, 0.45) 69%,
|
||||
rgba(255, 255, 255, 0.85) 70%,
|
||||
rgba(255, 255, 255, 0.85) 70.5%,
|
||||
rgba(255, 255, 255, 0.45) 71.5%,
|
||||
rgba(255, 255, 255, 0.2) 73%,
|
||||
rgba(255, 255, 255, 0.08) 75%,
|
||||
rgba(255, 255, 255, 0.03) 78%,
|
||||
transparent 82%
|
||||
);
|
||||
-webkit-mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);
|
||||
-webkit-mask-composite: xor;
|
||||
mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0);
|
||||
mask-composite: exclude;
|
||||
padding: 1px;
|
||||
filter: blur(8px) brightness(1.30) saturate(1.20);
|
||||
pointer-events: none;
|
||||
z-index: 3;
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
[data-beam="bb"][data-active] [data-beam-bloom] {
|
||||
display: block;
|
||||
opacity: calc(var(--beam-opacity-bb) * 0.24 * var(--beam-bloom-opacity, 1) * var(--beam-strength, 1));
|
||||
}
|
||||
|
||||
@keyframes beam-spin-bb {
|
||||
to { --beam-angle-bb: 360deg; }
|
||||
}
|
||||
|
||||
@keyframes beam-fade-in-bb {
|
||||
to { --beam-opacity-bb: 1; }
|
||||
}
|
||||
|
||||
@keyframes beam-hue-shift-bb {
|
||||
0% { filter: hue-rotate(calc(var(--beam-hue-base, 0deg) - 30deg)) brightness(1.30) saturate(1.20); }
|
||||
50% { filter: hue-rotate(calc(var(--beam-hue-base, 0deg) + 30deg)) brightness(1.30) saturate(1.20); }
|
||||
100% { filter: hue-rotate(calc(var(--beam-hue-base, 0deg) - 30deg)) brightness(1.30) saturate(1.20); }
|
||||
}
|
||||
@@ -5,6 +5,22 @@
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover">
|
||||
<meta name="theme-color" content="#0a0a0a">
|
||||
<title>BrandLoop – Prototyp</title>
|
||||
<link rel="stylesheet" href="border-beam.css">
|
||||
<script type="module">import('https://esm.sh/@paper-design/shaders').then(function(m){window.__paperShaders=m;var u={u_repetition:4,u_softness:.5,u_shiftRed:.3,u_shiftBlue:.3,u_distortion:0,u_contour:0,u_angle:45,u_scale:8,u_shape:1,u_offsetX:.1,u_offsetY:-.1};setInterval(function(){document.querySelectorAll('.lm-shader:not([data-lm])').forEach(function(el){el.dataset.lm='1';try{new m.ShaderMount(el,m.liquidMetalFragmentShader,u,undefined,0.6)}catch(e){}})},500)}).catch(function(){})</script>
|
||||
<style>
|
||||
/* Liquid-Metal-Buttons (aus BrandLoop.dc.html): Shader-Canvas ueber
|
||||
Metall-Gradient (Fallback ohne WebGL/offline), schwarzer Kern, graues Icon */
|
||||
.lm-shader canvas{width:100%!important;height:100%!important;display:block!important;position:absolute!important;top:0!important;left:0!important;border-radius:100px!important;}
|
||||
.lm-bg{position:absolute; inset:0; border-radius:100px; overflow:hidden;
|
||||
background:linear-gradient(135deg,#e8e8e8,#6f6f6f 35%,#f2f2f2 50%,#5c5c5c 68%,#cfcfcf);}
|
||||
.lm-bg.deg120{background:linear-gradient(120deg,#e8e8e8,#6f6f6f 35%,#f2f2f2 50%,#5c5c5c 68%,#cfcfcf);}
|
||||
.lm-core{position:absolute; inset:2px; border-radius:100px; background:linear-gradient(180deg,#202020,#000);}
|
||||
.lm-ic{position:absolute; inset:0; display:grid; place-items:center;}
|
||||
.lm-btn{position:relative; height:52px; border-radius:100px; cursor:pointer;
|
||||
box-shadow:0 2px 5px rgba(0,0,0,.35), 0 9px 9px rgba(0,0,0,.12);}
|
||||
.lm-label{position:absolute; inset:0; display:flex; align-items:center; justify-content:center; gap:8px;
|
||||
font-size:14.5px; font-weight:700; color:#9a9a9a; text-shadow:0 1px 2px rgba(0,0,0,.5);}
|
||||
</style>
|
||||
<style>
|
||||
:root{
|
||||
--bg:#0a0a0a;
|
||||
@@ -226,11 +242,33 @@
|
||||
display:grid; place-items:center; cursor:pointer; font-size:20px; color:rgba(255,255,255,.8); transition:transform .12s;}
|
||||
.x-act:active{transform:scale(.92);}
|
||||
.x-act.sm{width:44px; height:44px;}
|
||||
.x-act.like{background:var(--accent); border:none; box-shadow:0 0 22px rgba(255,92,57,.27);}
|
||||
.x-act.like{position:relative; background:none; border:none;
|
||||
box-shadow:0 2px 5px rgba(0,0,0,.4), 0 9px 9px rgba(0,0,0,.15);}
|
||||
|
||||
/* ================= DETAIL & CREATE ================= */
|
||||
#detail.active, #create.active{min-height:100dvh;
|
||||
background:radial-gradient(125% 125% at 50% 150%, rgba(241,99,99,.21) 40%, transparent 100%);}
|
||||
/* Create = fixer Vollbild-Screen mit internem Scroll + Fake-Tastatur */
|
||||
#create.active{display:flex; flex-direction:column; height:100dvh; overflow:hidden; position:relative;}
|
||||
.c-scroll{flex:1; overflow-y:auto; min-height:0; margin:0 -20px; padding:8px 18px 110px; scrollbar-width:none;
|
||||
transition:padding-bottom .3s ease;}
|
||||
.c-scroll::-webkit-scrollbar{display:none;}
|
||||
.c-scroll.kb-open{padding-bottom:380px;}
|
||||
.c-optlabel{font-size:11px; font-weight:700; letter-spacing:.12em; color:rgba(255,255,255,.4); margin-bottom:9px;}
|
||||
.c-behind{position:absolute; top:0; left:50%; border-radius:22px; background:#1b1b1b;
|
||||
border:1px solid rgba(255,255,255,.09); transform-origin:top center; z-index:0;}
|
||||
.c-preview{position:relative; border-radius:22px; overflow:hidden; z-index:1;
|
||||
box-shadow:0 18px 44px rgba(0,0,0,.5); transition:width .25s ease, height .25s ease;}
|
||||
.kb{position:fixed; left:0; right:0; bottom:0; z-index:45; max-width:430px; margin:0 auto;
|
||||
transform:translateY(112%); transition:transform .34s cubic-bezier(.22,1,.36,1);}
|
||||
.kb.open{transform:none;}
|
||||
.kb-row{display:flex; gap:5px; margin-bottom:8px;}
|
||||
.kb-key{flex:1; height:38px; border-radius:6px; background:rgba(255,255,255,.16); display:grid; place-items:center;
|
||||
font-size:16px; font-weight:500; color:#fff; cursor:pointer; user-select:none; -webkit-user-select:none; min-width:0;}
|
||||
.kb-key.mod{background:rgba(255,255,255,.28); font-size:15px;}
|
||||
.kb-chip{flex:none; display:flex; align-items:center; gap:7px; padding:8px 13px; border-radius:100px;
|
||||
background:rgba(255,255,255,.12); font-size:12.5px; font-weight:600; cursor:pointer; white-space:nowrap; color:#fff;}
|
||||
.kb-chip .dot{width:8px; height:8px; border-radius:100px; flex:none;}
|
||||
.d-strip{display:flex; gap:10px; overflow-x:auto; margin:0 -18px; padding:0 18px; scrollbar-width:none; scroll-snap-type:x mandatory;}
|
||||
.d-strip::-webkit-scrollbar{display:none;}
|
||||
.d-img{flex:none; width:272px; height:330px; border-radius:20px; position:relative; display:grid; place-items:center; scroll-snap-align:center;}
|
||||
@@ -256,28 +294,28 @@
|
||||
.p-hero p{color:var(--mut); font-size:13px; margin-top:3px;}
|
||||
|
||||
/* ================= Bottom-Navigation ================= */
|
||||
/* Liquid-Glass-Nav (aus BrandLoop.dc.html): verzerrter Glas-Backdrop
|
||||
(bl-glass-distortion mit Specular-Highlight) + heller Weiss-Layer + Kanten-Ring.
|
||||
bottom:14px OHNE Safe-Area-Aufschlag = exakt die Hoehe aus dem Design. */
|
||||
/* Liquid-Glass-Nav (aus BrandLoop.dc.html): echte Refraktion via dynamischer
|
||||
Displacement-Map (bl-glass-refract, RGB-Split) + Blur/Saturate-Backdrop +
|
||||
Weiss-Layer + Kanten-Ring. bottom:14px = exakt die Hoehe aus dem Design. */
|
||||
.nav{position:fixed; bottom:14px; left:50%; transform:translateX(-50%); z-index:30;
|
||||
display:flex; align-items:center; gap:6px; padding:8px 10px; border-radius:100px;
|
||||
background:rgba(255,255,255,.25);
|
||||
box-shadow:0 6px 6px rgba(0,0,0,.2), 0 0 20px rgba(0,0,0,.1);
|
||||
transition:all .7s cubic-bezier(.175,.885,.32,2.2);}
|
||||
.nav::before{content:''; position:absolute; inset:0; z-index:-1; border-radius:100px; overflow:hidden;
|
||||
-webkit-backdrop-filter:blur(3px); backdrop-filter:blur(3px);
|
||||
filter:url(#bl-glass-distortion); isolation:isolate;}
|
||||
.nav::after{content:''; position:absolute; inset:0; z-index:2; border-radius:100px; pointer-events:none;
|
||||
box-shadow:inset 2px 2px 1px 0 rgba(255,255,255,.5), inset -1px -1px 1px 1px rgba(255,255,255,.5);}
|
||||
.nav button{display:flex; align-items:center; gap:8px; background:none; border:none; font-family:inherit;
|
||||
.nav-glass{position:absolute; inset:0; border-radius:100px;}
|
||||
.nav-glass.blur{overflow:hidden; -webkit-backdrop-filter:blur(3px) saturate(1.15); backdrop-filter:blur(3px) saturate(1.15);}
|
||||
.nav-glass.refract{overflow:hidden; -webkit-backdrop-filter:url(#bl-glass-refract); backdrop-filter:url(#bl-glass-refract);}
|
||||
.nav-glass.white{background:rgba(255,255,255,.12); z-index:1;}
|
||||
.nav-glass.ring{z-index:2; pointer-events:none;
|
||||
box-shadow:inset 2px 2px 1px 0 rgba(255,255,255,.4), inset -1px -1px 1px 1px rgba(255,255,255,.3);}
|
||||
.nav button{position:relative; z-index:3; display:flex; align-items:center; gap:8px; background:none; border:none; font-family:inherit;
|
||||
width:40px; height:40px; justify-content:center; border-radius:100px; color:rgba(255,255,255,.6);
|
||||
font-size:13.5px; font-weight:600; cursor:pointer; transition:background .2s, color .2s, width .2s;}
|
||||
.nav button svg{width:20px; height:20px; flex:none;}
|
||||
.nav button span{display:none;}
|
||||
.nav button.on{width:auto; padding:9px 16px 9px 12px; background:rgba(255,255,255,.14); color:#fff;}
|
||||
.nav button.on span{display:inline;}
|
||||
.nav button.plus{background:var(--accent); color:#0a0a0a;}
|
||||
.nav button.plus svg{stroke-width:2.4; width:18px; height:18px;}
|
||||
/* Plus-Button = Liquid-Metal (Shader + schwarzer Kern) */
|
||||
.nav button.plus{background:none; box-shadow:0 2px 5px rgba(0,0,0,.35);}
|
||||
.nav button.plus.on{width:40px; padding:0;}
|
||||
.nav button.plus.on span{display:none;}
|
||||
|
||||
@@ -302,19 +340,17 @@
|
||||
<!-- Lucide-Icon-Sprite + Liquid-Glass-Filter -->
|
||||
<svg width="0" height="0" style="position:absolute" aria-hidden="true">
|
||||
<defs>
|
||||
<filter id="bl-glass-distortion" x="0%" y="0%" width="100%" height="100%" filterUnits="objectBoundingBox">
|
||||
<feTurbulence type="fractalNoise" baseFrequency="0.001 0.005" numOctaves="1" seed="17" result="turbulence"/>
|
||||
<feComponentTransfer in="turbulence" result="mapped">
|
||||
<feFuncR type="gamma" amplitude="1" exponent="10" offset="0.5"/>
|
||||
<feFuncG type="gamma" amplitude="0" exponent="1" offset="0"/>
|
||||
<feFuncB type="gamma" amplitude="0" exponent="1" offset="0.5"/>
|
||||
</feComponentTransfer>
|
||||
<feGaussianBlur in="turbulence" stdDeviation="3" result="softMap"/>
|
||||
<feSpecularLighting in="softMap" surfaceScale="5" specularConstant="1" specularExponent="100" lighting-color="white" result="specLight">
|
||||
<fePointLight x="-200" y="-200" z="300"/>
|
||||
</feSpecularLighting>
|
||||
<feComposite in="specLight" operator="arithmetic" k1="0" k2="1" k3="1" k4="0" result="litImage"/>
|
||||
<feDisplacementMap in="SourceGraphic" in2="softMap" scale="200" xChannelSelector="R" yChannelSelector="G"/>
|
||||
<filter id="bl-glass-refract" color-interpolation-filters="sRGB" x="0%" y="0%" width="100%" height="100%">
|
||||
<feImage id="glassMapImage" x="0" y="0" width="100%" height="100%" preserveAspectRatio="none" href="" result="map"/>
|
||||
<feDisplacementMap in="SourceGraphic" in2="map" scale="-180" xChannelSelector="R" yChannelSelector="G" result="dispRed"/>
|
||||
<feColorMatrix in="dispRed" type="matrix" values="1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0" result="red"/>
|
||||
<feDisplacementMap in="SourceGraphic" in2="map" scale="-170" xChannelSelector="R" yChannelSelector="G" result="dispGreen"/>
|
||||
<feColorMatrix in="dispGreen" type="matrix" values="0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0" result="green"/>
|
||||
<feDisplacementMap in="SourceGraphic" in2="map" scale="-160" xChannelSelector="R" yChannelSelector="G" result="dispBlue"/>
|
||||
<feColorMatrix in="dispBlue" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0" result="blue"/>
|
||||
<feBlend in="red" in2="green" mode="screen" result="rg"/>
|
||||
<feBlend in="rg" in2="blue" mode="screen" result="out"/>
|
||||
<feGaussianBlur in="out" stdDeviation="0.7"/>
|
||||
</filter>
|
||||
<symbol id="i-back" viewBox="0 0 24 24"><path d="m15 18-6-6 6-6"/></symbol>
|
||||
<symbol id="i-chev" viewBox="0 0 24 24"><path d="m9 18 6-6-6-6"/></symbol>
|
||||
@@ -359,7 +395,11 @@
|
||||
<div class="x-actions">
|
||||
<div class="x-act" id="btnSkip" role="button" aria-label="Skip">✕</div>
|
||||
<div class="x-act sm" id="btnDetail" role="button" aria-label="Details / Nachmachen"><svg class="ic" style="width:18px;height:18px;color:rgba(255,255,255,.8)"><use href="#i-refresh"/></svg></div>
|
||||
<div class="x-act like" id="btnLike" role="button" aria-label="Like"><svg width="24" height="24" viewBox="0 0 24 24" fill="#0a0a0a"><path d="M12 21 C5 15.5 2.5 12 2.5 8.5 A4.7 4.7 0 0 1 12 6.2 A4.7 4.7 0 0 1 21.5 8.5 C21.5 12 19 15.5 12 21 Z"/></svg></div>
|
||||
<div class="x-act like" id="btnLike" role="button" aria-label="Like">
|
||||
<div class="lm-shader lm-bg"></div>
|
||||
<div class="lm-core"></div>
|
||||
<div class="lm-ic"><svg width="24" height="24" viewBox="0 0 24 24" fill="#9a9a9a" style="filter:drop-shadow(0 1px 2px rgba(0,0,0,.5))"><path d="M12 21 C5 15.5 2.5 12 2.5 8.5 A4.7 4.7 0 0 1 12 6.2 A4.7 4.7 0 0 1 21.5 8.5 C21.5 12 19 15.5 12 21 Z"/></svg></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -384,41 +424,50 @@
|
||||
</div>
|
||||
<div style="font-size:15px; font-weight:800; margin-bottom:10px;">Mit deinem Modell nachmachen</div>
|
||||
<div class="chiprow" id="detailModels"></div>
|
||||
<button class="btn" id="remakeBtn" style="margin-top:16px;"></button>
|
||||
<div class="lm-btn" id="remakeBtn" role="button" style="margin-top:16px;">
|
||||
<div class="lm-shader lm-bg deg120"></div>
|
||||
<div class="lm-core"></div>
|
||||
<div class="lm-label"><svg width="15" height="15" viewBox="0 0 24 24" fill="#9a9a9a" style="filter:drop-shadow(0 1px 2px rgba(0,0,0,.5))"><path d="M12 2 L14.4 9.6 L22 12 L14.4 14.4 L12 22 L9.6 14.4 L2 12 L9.6 9.6 Z"/></svg><span id="remakeLabel"></span></div>
|
||||
</div>
|
||||
<div style="text-align:center; font-size:11.5px; color:rgba(255,255,255,.4); margin-top:10px;">Prompt + Einstellungen werden übernommen, dein Modell wird eingesetzt</div>
|
||||
</div>
|
||||
|
||||
<!-- ============ POST ERSTELLEN (neu) ============ -->
|
||||
<!-- ============ POST ERSTELLEN (neu, aus BrandLoop.dc.html v4) ============ -->
|
||||
<div class="screen" id="create">
|
||||
<div class="topbar">
|
||||
<button class="backpill" onclick="go('explore')"><span class="ar">‹</span> Zurück</button>
|
||||
<h1 style="flex:1; text-align:center; margin-right:80px;">Neuer KI-Post</h1>
|
||||
</div>
|
||||
<label style="margin:6px 0 2px;">Prompt</label>
|
||||
<textarea id="createPrompt" placeholder="Beschreibe deinen Post … z.B. Sneaker auf Betonboden, goldenes Abendlicht"></textarea>
|
||||
<label>Dein Modell</label>
|
||||
<div class="chiprow" id="createModels" style="margin-top:8px;"></div>
|
||||
<div style="display:flex; gap:24px; margin-top:18px;">
|
||||
<div style="flex:1;">
|
||||
<label style="margin-bottom:8px;">Kette</label>
|
||||
<div class="pill-row" style="margin-top:0;" id="countRow">
|
||||
<div class="pill" data-count="1">1 Bild</div>
|
||||
<div class="pill on" data-count="3">3er</div>
|
||||
<div class="pill" data-count="5">5er</div>
|
||||
<div class="c-scroll" id="cScroll">
|
||||
<div style="display:flex; flex-direction:column; align-items:center; padding:10px 0 4px;">
|
||||
<div id="cStack" onclick="toggleOpts()" style="position:relative; cursor:pointer;"></div>
|
||||
<div onclick="toggleOpts()" style="display:flex; align-items:center; gap:8px; margin-top:14px; padding:9px 10px 9px 16px; border-radius:100px; background:rgba(255,255,255,.08); cursor:pointer;">
|
||||
<span style="font-size:13px; font-weight:600;" id="cSelLabel"></span>
|
||||
<svg id="cChevron" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="rgba(255,255,255,.6)" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="transition:transform .2s;"><path d="M6 9 l6 6 l6 -6"/></svg>
|
||||
</div>
|
||||
<div id="cOpts" style="display:none; width:100%; margin-top:14px; border-radius:20px; background:#161616; border:1px solid rgba(255,255,255,.09); padding:16px; box-sizing:border-box;">
|
||||
<div class="c-optlabel">TYP</div>
|
||||
<div class="pill-row" style="margin:0 0 16px;" id="typeRow"></div>
|
||||
<div class="c-optlabel">FORMAT</div>
|
||||
<div class="pill-row" style="margin:0 0 16px;" id="formatRow"></div>
|
||||
<div class="c-optlabel">KETTE</div>
|
||||
<div class="pill-row" style="margin:0;" id="countRow"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div style="flex:1;">
|
||||
<label style="margin-bottom:8px;">Format</label>
|
||||
<div class="pill-row" style="margin-top:0;" id="formatRow">
|
||||
<div class="pill" data-format="1:1">1:1</div>
|
||||
<div class="pill on" data-format="4:5">4:5</div>
|
||||
<div class="pill" data-format="9:16">9:16</div>
|
||||
<label style="margin:22px 0 8px;">Dein Modell</label>
|
||||
<div class="chiprow" id="createModels"></div>
|
||||
<label style="margin:20px 0 8px;">Prompt</label>
|
||||
<div data-beam="bb" data-active="true" style="border-radius:24px;">
|
||||
<div style="border-radius:24px; background:#171717; border:1px solid rgba(255,255,255,.05); box-shadow:0 12px 34px rgba(0,0,0,.4);">
|
||||
<textarea id="createPrompt" inputmode="none" placeholder="Beschreibe deinen Post … z.B. Sneaker auf Betonboden, goldenes Abendlicht" style="display:block; width:100%; box-sizing:border-box; height:104px; resize:none; border:none; border-radius:23px; background:transparent; color:#fff; font-size:13.5px; line-height:1.55; padding:16px 18px; outline:none;"></textarea>
|
||||
</div>
|
||||
<div data-beam-bloom="true"></div>
|
||||
</div>
|
||||
<div class="lm-btn" id="generateBtn" role="button" style="margin-top:22px;">
|
||||
<div class="lm-shader lm-bg deg120"></div>
|
||||
<div class="lm-core"></div>
|
||||
<div class="lm-label"><svg width="15" height="15" viewBox="0 0 24 24" fill="#9a9a9a" style="filter:drop-shadow(0 1px 2px rgba(0,0,0,.5))"><path d="M12 2 L14.4 9.6 L22 12 L14.4 14.4 L12 22 L9.6 14.4 L2 12 L9.6 9.6 Z"/></svg><span id="generateLabel">Post generieren</span></div>
|
||||
</div>
|
||||
<label style="margin:20px 0 8px;">Vorschau der Kette</label>
|
||||
<div class="frames" id="previewFrames"></div>
|
||||
<button class="btn" id="generateBtn" style="margin-top:22px;">Post generieren</button>
|
||||
|
||||
<h3 style="margin-top:28px;">Mehr erstellen</h3>
|
||||
<div class="card click" onclick="go('tut1')">
|
||||
@@ -435,6 +484,16 @@
|
||||
<svg class="ic chev"><use href="#i-chev"/></svg>
|
||||
</div>
|
||||
</div>
|
||||
</div><!-- /c-scroll -->
|
||||
|
||||
<!-- Fake-Tastatur (Prototyp): erscheint beim Fokus aufs Prompt-Feld -->
|
||||
<div class="kb" id="kbOverlay">
|
||||
<div style="display:flex; align-items:center; gap:8px; padding:10px 12px; background:rgba(24,24,24,.96); border-top:1px solid rgba(255,255,255,.08);">
|
||||
<div style="display:flex; gap:8px; overflow-x:auto; flex:1; scrollbar-width:none;" id="kbModels"></div>
|
||||
<div id="kbDone" style="flex:none; padding:8px 14px; border-radius:100px; background:rgba(255,255,255,.14); font-size:12px; font-weight:700; cursor:pointer;">Fertig</div>
|
||||
</div>
|
||||
<div style="padding:8px 4px 24px; background:rgba(30,30,32,.98); backdrop-filter:blur(20px); -webkit-backdrop-filter:blur(20px);" id="kbKeys"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- ============ PROFIL / MENSCHLEIN (neu, enthält Knowledge Base) ============ -->
|
||||
@@ -841,10 +900,18 @@ TEXT-OVERLAY: keins (Brand-Stil: clean)</textarea>
|
||||
</div>
|
||||
|
||||
<!-- ============ NAVIGATION (neu: Feed · Profil · Plus · Dev) ============ -->
|
||||
<nav class="nav">
|
||||
<nav class="nav" id="navBar">
|
||||
<div class="nav-glass blur"></div>
|
||||
<div class="nav-glass refract"></div>
|
||||
<div class="nav-glass white"></div>
|
||||
<div class="nav-glass ring"></div>
|
||||
<button id="n-feed" class="on" onclick="go('explore')"><svg class="ic"><use href="#i-home"/></svg><span>Feed</span></button>
|
||||
<button id="n-profile" onclick="go('profile')"><svg class="ic"><use href="#i-user"/></svg><span>Profil</span></button>
|
||||
<button id="n-create" class="plus" onclick="go('create')" aria-label="Neuer KI-Post"><svg class="ic"><use href="#i-plus"/></svg></button>
|
||||
<button id="n-create" class="plus" onclick="go('create')" aria-label="Neuer KI-Post">
|
||||
<div class="lm-shader lm-bg"></div>
|
||||
<div class="lm-core"></div>
|
||||
<div class="lm-ic"><svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="#9a9a9a" stroke-width="2.4" stroke-linecap="round" style="filter:drop-shadow(0 1px 2px rgba(0,0,0,.5))"><path d="M12 5 V19 M5 12 H19"/></svg></div>
|
||||
</button>
|
||||
<button id="n-dev" onclick="go('devmode')" style="opacity:.55;" title="Nur intern sichtbar"><svg class="ic"><use href="#i-gear"/></svg><span>Dev</span></button>
|
||||
</nav>
|
||||
|
||||
@@ -880,7 +947,7 @@ function go(id){
|
||||
};
|
||||
document.querySelectorAll('.nav button').forEach(b=>b.classList.remove('on'));
|
||||
if(navMap[id]) document.getElementById(navMap[id]).classList.add('on');
|
||||
document.body.classList.toggle('noscroll', id==='explore');
|
||||
document.body.classList.toggle('noscroll', id==='explore'||id==='create');
|
||||
window.scrollTo(0,0);
|
||||
}
|
||||
function pick(el){
|
||||
@@ -924,7 +991,7 @@ function preloadPics(){
|
||||
POSTS.forEach(function(p){ (p.pics||[]).forEach(function(u){ all[u]=1; }); if(p.avatar) all[p.avatar]=1; });
|
||||
Object.keys(all).forEach(function(u){
|
||||
var im=new Image();
|
||||
im.onload=function(){ PICS_OK[u]=true; renderDeck(); renderDetailStrip(); };
|
||||
im.onload=function(){ PICS_OK[u]=true; renderDeck(); renderDetailStrip(); renderCreateStack(); };
|
||||
im.src=u;
|
||||
});
|
||||
}
|
||||
@@ -1148,7 +1215,7 @@ document.querySelectorAll('.x-tab').forEach(function(el){
|
||||
});
|
||||
});
|
||||
window.addEventListener('resize',function(){
|
||||
measureTabs(); setHood(centerOf(X.tab), halfOf(X.tab));
|
||||
measureTabs(); setHood(centerOf(X.tab), halfOf(X.tab)); updateGlassMap();
|
||||
});
|
||||
document.getElementById('btnSkip').onclick=function(){ fling(-1); };
|
||||
document.getElementById('btnLike').onclick=function(){ fling(1); };
|
||||
@@ -1184,9 +1251,8 @@ function renderDetailModels(){
|
||||
host.querySelectorAll('.chip').forEach(function(c){
|
||||
c.onclick=function(){ D.model=+c.dataset.i; D.remade=false; renderDetailModels(); };
|
||||
});
|
||||
var btn=document.getElementById('remakeBtn');
|
||||
btn.textContent=D.remade ? '✓ Übernommen — im Editor geöffnet' : 'Nachmachen mit „'+MODELS[D.model].split(' – ')[1]+'“';
|
||||
btn.classList.toggle('sec', D.remade);
|
||||
document.getElementById('remakeLabel').textContent=
|
||||
D.remade ? '✓ Übernommen — im Editor geöffnet' : 'Nachmachen mit „'+MODELS[D.model].split(' – ')[1]+'“';
|
||||
}
|
||||
document.getElementById('remakeBtn').onclick=function(){
|
||||
if(D.remade) return;
|
||||
@@ -1199,49 +1265,187 @@ document.getElementById('remakeBtn').onclick=function(){
|
||||
},900);
|
||||
};
|
||||
|
||||
/* ---------- Create: Modell / Kette / Format / Vorschau ---------- */
|
||||
var C={model:0, count:3, format:'4:5', generating:0};
|
||||
var RATIOS={'1:1':[130,130],'4:5':[124,155],'9:16':[96,170]};
|
||||
/* ---------- Create: Vorschau-Stack / Optionen / Prompt-Beam / Fake-Tastatur ---------- */
|
||||
var C={model:0, count:1, format:'4:5', mediaType:'image', optOpen:false, kbOpen:false, generating:0};
|
||||
var C_MODELS=[
|
||||
{name:'Ich (Avatar)', token:'@Ich', hue:260},
|
||||
{name:'Kerze Studio', token:'@Kerze', hue:40},
|
||||
{name:'Showroom', token:'@Showroom', hue:170}
|
||||
];
|
||||
function renderCreateStack(){
|
||||
var host=document.getElementById('cStack');
|
||||
if(!host) return;
|
||||
var isVideo=C.mediaType==='video';
|
||||
var isChain=!isVideo&&C.count>1;
|
||||
var pr={'1:1':1,'4:5':.8,'9:16':.5625}[C.format];
|
||||
var ph=258, pw=Math.round(ph*pr);
|
||||
var cp=POSTS[1], u=pic(cp,0);
|
||||
var bg=u?'#141414 url("'+u+'") center / cover no-repeat':dummy(150);
|
||||
var html='';
|
||||
var nBehind=isChain?Math.min(C.count-1,2):0;
|
||||
for(var k=nBehind;k>=1;k--){
|
||||
html+='<div class="c-behind" style="width:'+pw+'px; height:'+ph+'px; transform:translateX(-50%) rotate('+(k===1?-6:6)+'deg) translateY('+(4*k)+'px) scale('+(1-.04*k)+');"></div>';
|
||||
}
|
||||
html+='<div class="c-preview" style="width:'+pw+'px; height:'+ph+'px; background:'+bg+';">';
|
||||
if(isVideo){
|
||||
html+='<div style="position:absolute; inset:0; display:grid; place-items:center; pointer-events:none;"><div style="width:62px; height:62px; border-radius:100px; background:rgba(10,10,10,.5); backdrop-filter:blur(8px); display:grid; place-items:center;"><svg width="20" height="20" viewBox="0 0 24 24" fill="#fff"><path d="M8 5 L19 12 L8 19 Z"/></svg></div></div>';
|
||||
html+='<div style="position:absolute; top:12px; left:12px; padding:5px 10px; border-radius:100px; background:rgba(10,10,10,.55); font-size:11px; font-weight:700; letter-spacing:.06em;">VIDEO · 0:08</div>';
|
||||
}
|
||||
if(isChain){
|
||||
html+='<div style="position:absolute; top:12px; right:12px; padding:5px 10px; border-radius:100px; background:rgba(10,10,10,.55); font-size:11px; font-weight:700;">1/'+C.count+'</div>';
|
||||
html+='<div style="position:absolute; left:0; right:0; bottom:14px; display:flex; justify-content:center; align-items:center; gap:5px;">';
|
||||
for(var i=0;i<C.count;i++){
|
||||
html+='<div style="width:'+(i===0?16:6)+'px; height:6px; border-radius:100px; background:'+(i===0?'#fff':'rgba(255,255,255,.45)')+'; transition:width .2s;"></div>';
|
||||
}
|
||||
html+='</div>';
|
||||
}
|
||||
html+='</div>';
|
||||
host.innerHTML=html;
|
||||
document.getElementById('cSelLabel').textContent = isVideo ? ('Video · '+C.format) : ((C.count===1?'Bild':C.count+'er-Kette')+' · '+C.format);
|
||||
document.getElementById('cChevron').style.transform=C.optOpen?'rotate(180deg)':'none';
|
||||
document.getElementById('cOpts').style.display=C.optOpen?'block':'none';
|
||||
}
|
||||
function pills(hostId, items, activeVal, onPick){
|
||||
var host=document.getElementById(hostId);
|
||||
host.innerHTML=items.map(function(it){
|
||||
return '<div class="pill'+(it.v===activeVal?' on':'')+'" data-v="'+it.v+'">'+it.label+'</div>';
|
||||
}).join('');
|
||||
host.querySelectorAll('.pill').forEach(function(p){
|
||||
p.onclick=function(){ onPick(p.dataset.v); };
|
||||
});
|
||||
}
|
||||
function renderCreateOpts(){
|
||||
pills('typeRow',[{v:'image',label:'Bild'},{v:'video',label:'Video'}],C.mediaType,function(v){C.mediaType=v; renderCreateOpts(); renderCreateStack();});
|
||||
pills('formatRow',[{v:'1:1',label:'1:1'},{v:'4:5',label:'4:5'},{v:'9:16',label:'9:16'}],C.format,function(v){C.format=v; renderCreateOpts(); renderCreateStack();});
|
||||
pills('countRow',[{v:'1',label:'1 Bild'},{v:'3',label:'3er'},{v:'5',label:'5er'}],String(C.count),function(v){C.count=+v; renderCreateOpts(); renderCreateStack();});
|
||||
}
|
||||
function toggleOpts(){ C.optOpen=!C.optOpen; renderCreateStack(); }
|
||||
function renderCreateModels(){
|
||||
var host=document.getElementById('createModels');
|
||||
host.innerHTML=MODELS.map(function(m,i){
|
||||
return '<div class="chip'+(i===C.model?' on':'')+'" data-i="'+i+'"><div class="dot"></div>'+m+'</div>';
|
||||
host.innerHTML=C_MODELS.map(function(m,i){
|
||||
return '<div class="chip'+(i===C.model?' on':'')+'" data-i="'+i+'"><div class="dot"></div>'+m.name+'</div>';
|
||||
}).join('');
|
||||
host.querySelectorAll('.chip').forEach(function(c){
|
||||
c.onclick=function(){ C.model=+c.dataset.i; renderCreateModels(); };
|
||||
});
|
||||
}
|
||||
function renderFrames(){
|
||||
var r=RATIOS[C.format], host=document.getElementById('previewFrames'), html='';
|
||||
for(var i=0;i<C.count;i++){
|
||||
html+='<div class="frame" style="width:'+r[0]+'px; height:'+r[1]+'px;"><span>Bild '+(i+1)+'</span></div>';
|
||||
}
|
||||
host.innerHTML=html;
|
||||
/* Prompt-Editing über die Fake-Tastatur (Caret-genau wie im Design) */
|
||||
function editPrompt(mutate){
|
||||
var ta=document.getElementById('createPrompt');
|
||||
var p=ta.value, s=ta.selectionStart, e=ta.selectionEnd;
|
||||
var r=mutate(p,s,e);
|
||||
ta.value=r.val;
|
||||
ta.focus(); ta.setSelectionRange(r.caret,r.caret);
|
||||
}
|
||||
document.querySelectorAll('#countRow .pill').forEach(function(p){
|
||||
p.onclick=function(){ pick(p); C.count=+p.dataset.count; renderFrames(); };
|
||||
});
|
||||
document.querySelectorAll('#formatRow .pill').forEach(function(p){
|
||||
p.onclick=function(){ pick(p); C.format=p.dataset.format; renderFrames(); };
|
||||
});
|
||||
function applyKey(code){
|
||||
editPrompt(function(p,s,e){
|
||||
if(code==='del'){
|
||||
if(s!==e) return {val:p.slice(0,s)+p.slice(e), caret:s};
|
||||
return {val:p.slice(0,Math.max(0,s-1))+p.slice(e), caret:Math.max(0,s-1)};
|
||||
}
|
||||
var ins=code==='space'?' ':code==='ret'?'\n':code;
|
||||
return {val:p.slice(0,s)+ins+p.slice(e), caret:s+ins.length};
|
||||
});
|
||||
}
|
||||
function insertToken(tok){
|
||||
editPrompt(function(p,s,e){
|
||||
var before=p.slice(0,s);
|
||||
var lead=before&&!/\s$/.test(before)?' ':'';
|
||||
var ins=lead+tok+' ';
|
||||
return {val:before+ins+p.slice(e), caret:s+ins.length};
|
||||
});
|
||||
}
|
||||
function setKb(open){
|
||||
C.kbOpen=open;
|
||||
document.getElementById('kbOverlay').classList.toggle('open',open);
|
||||
document.getElementById('cScroll').classList.toggle('kb-open',open);
|
||||
if(open){
|
||||
C.optOpen=false; renderCreateStack();
|
||||
requestAnimationFrame(function(){requestAnimationFrame(function(){
|
||||
var el=document.getElementById('cScroll'); el.scrollTop=el.scrollHeight;
|
||||
});});
|
||||
}
|
||||
}
|
||||
function renderKb(){
|
||||
var mh=document.getElementById('kbModels');
|
||||
mh.innerHTML=C_MODELS.map(function(m,i){
|
||||
return '<div class="kb-chip" data-i="'+i+'"><div class="dot" style="background:oklch(.7 .13 '+m.hue+');"></div>'+m.name+'</div>';
|
||||
}).join('');
|
||||
mh.querySelectorAll('.kb-chip').forEach(function(c){
|
||||
function ins(e){ e.preventDefault(); insertToken(C_MODELS[+c.dataset.i].token); }
|
||||
c.addEventListener('mousedown',ins);
|
||||
c.addEventListener('touchstart',ins,{passive:false});
|
||||
});
|
||||
var rows=[
|
||||
{pad:0, keys:'qwertyuiop'.split('').map(function(l){return {label:l, code:l};})},
|
||||
{pad:16, keys:'asdfghjkl'.split('').map(function(l){return {label:l, code:l};})},
|
||||
{pad:0, keys:[{label:'⇧', code:null, cls:'mod', flex:1.5}].concat('zxcvbnm'.split('').map(function(l){return {label:l, code:l};})).concat([{label:'⌫', code:'del', cls:'mod', flex:1.5}])},
|
||||
{pad:0, keys:[{label:'123', code:null, cls:'mod', flex:1.6, fs:13},{label:'', code:'space', flex:5},{label:'return', code:'ret', flex:1.9, fs:13, bg:'rgba(122,162,255,.9)'}]}
|
||||
];
|
||||
var kh=document.getElementById('kbKeys'); var html='';
|
||||
rows.forEach(function(row,ri){
|
||||
html+='<div class="kb-row" style="padding:0 '+row.pad+'px;">';
|
||||
row.keys.forEach(function(k,ki){
|
||||
var st='';
|
||||
if(k.flex) st+='flex:'+k.flex+';';
|
||||
if(k.fs) st+='font-size:'+k.fs+'px;';
|
||||
if(k.bg) st+='background:'+k.bg+';';
|
||||
html+='<div class="kb-key'+(k.cls?' '+k.cls:'')+'" data-r="'+ri+'" data-k="'+ki+'" style="'+st+'">'+k.label+'</div>';
|
||||
});
|
||||
html+='</div>';
|
||||
});
|
||||
kh.innerHTML=html;
|
||||
kh.querySelectorAll('.kb-key').forEach(function(el){
|
||||
var k=rows[+el.dataset.r].keys[+el.dataset.k];
|
||||
function press(e){ e.preventDefault(); if(k.code) applyKey(k.code); }
|
||||
el.addEventListener('mousedown',press);
|
||||
el.addEventListener('touchstart',press,{passive:false});
|
||||
});
|
||||
function done(e){ e.preventDefault(); document.getElementById('createPrompt').blur(); setKb(false); }
|
||||
document.getElementById('kbDone').addEventListener('mousedown',done);
|
||||
document.getElementById('kbDone').addEventListener('touchstart',done,{passive:false});
|
||||
}
|
||||
(function(){
|
||||
var ta=document.getElementById('createPrompt');
|
||||
ta.addEventListener('focus',function(){ setKb(true); });
|
||||
ta.addEventListener('blur',function(){ setKb(false); });
|
||||
})();
|
||||
document.getElementById('generateBtn').onclick=function(){
|
||||
if(C.generating) return;
|
||||
var btn=this;
|
||||
C.generating=1; btn.classList.add('sec'); btn.textContent='Generiere '+C.count+' Bilder …';
|
||||
setTimeout(function(){ C.generating=2; btn.textContent='✓ In der Warteschlange'; },1400);
|
||||
setTimeout(function(){ C.generating=0; btn.classList.remove('sec'); btn.textContent='Post generieren'; },3200);
|
||||
var lbl=document.getElementById('generateLabel');
|
||||
C.generating=1; lbl.textContent='Generiere '+C.count+' Bilder …';
|
||||
setTimeout(function(){ C.generating=2; lbl.textContent='✓ In der Warteschlange'; },1400);
|
||||
setTimeout(function(){ C.generating=0; lbl.textContent='Post generieren'; },3200);
|
||||
};
|
||||
|
||||
/* ---------- Nav-Glas: dynamische Displacement-Map (aus dem Design) ---------- */
|
||||
function updateGlassMap(){
|
||||
var nav=document.getElementById('navBar'), img=document.getElementById('glassMapImage');
|
||||
if(!nav||!img) return;
|
||||
var w=nav.offsetWidth||286, h=nav.offsetHeight||56;
|
||||
var r=Math.min(100,h/2), e=Math.min(w,h)*0.035;
|
||||
var svg='<svg viewBox="0 0 '+w+' '+h+'" xmlns="http://www.w3.org/2000/svg">'+
|
||||
'<defs><linearGradient id="rg" x1="100%" y1="0%" x2="0%" y2="0%"><stop offset="0%" stop-color="#0000"/><stop offset="100%" stop-color="red"/></linearGradient>'+
|
||||
'<linearGradient id="bg" x1="0%" y1="0%" x2="0%" y2="100%"><stop offset="0%" stop-color="#0000"/><stop offset="100%" stop-color="blue"/></linearGradient></defs>'+
|
||||
'<rect width="'+w+'" height="'+h+'" fill="black"/>'+
|
||||
'<rect width="'+w+'" height="'+h+'" rx="'+r+'" fill="url(#rg)"/>'+
|
||||
'<rect width="'+w+'" height="'+h+'" rx="'+r+'" fill="url(#bg)" style="mix-blend-mode:difference"/>'+
|
||||
'<rect x="'+e+'" y="'+e+'" width="'+(w-e*2)+'" height="'+(h-e*2)+'" rx="'+r+'" fill="hsl(0 0% 50% / 0.93)" style="filter:blur(11px)"/></svg>';
|
||||
img.setAttribute('href','data:image/svg+xml,'+encodeURIComponent(svg));
|
||||
}
|
||||
|
||||
/* ---------- Init ---------- */
|
||||
setHood(centerOf(X.tab), halfOf(X.tab));
|
||||
requestAnimationFrame(function(){ measureTabs(); setHood(centerOf(X.tab), halfOf(X.tab)); });
|
||||
requestAnimationFrame(function(){ measureTabs(); setHood(centerOf(X.tab), halfOf(X.tab)); updateGlassMap(); });
|
||||
renderTabs();
|
||||
renderDeck();
|
||||
renderDetailStrip();
|
||||
preloadPics();
|
||||
renderDetailModels();
|
||||
renderCreateModels();
|
||||
renderFrames();
|
||||
renderCreateOpts();
|
||||
renderCreateStack();
|
||||
renderKb();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
Reference in New Issue
Block a user