/* pf-live.js — сюжет с курсорами для фона Portfolio. Подключается одной строкой в HEAD. */ (function(){if(document.getElementById('pfLiveCss'))return;var s=document.createElement('style');s.id='pfLiveCss';s.textContent="@media(min-width:981px){.pfX_overlay{--pfc:clamp(44px,3.89vw,100px)}.pfX_overlay::before{background-size:calc(var(--pfc) * 5) calc(var(--pfc) * 5),calc(var(--pfc) * 5) calc(var(--pfc) * 5),var(--pfc) var(--pfc),var(--pfc) var(--pfc)}}.pfCv{--k:1;position:absolute;left:-30%;right:-30%;top:-20%;bottom:-6%;z-index:0;pointer-events:none;transform-origin:50% 100%;opacity:0;transform:perspective(1600px) rotateX(58deg) translateY(6%) scale(1.12);transition:opacity .3s ease,transform .5s ease;font-family:var(--pf-font,Arial,sans-serif)}.pfX_overlayClip.isOpen .pfCv{opacity:1;transform:perspective(1600px) rotateX(12deg) scale(1);transition:opacity .9s ease .42s,transform 1.9s cubic-bezier(.22,1,.36,1) .42s}.pfA,.pfF,.pfCm,.pfRx{position:absolute;left:50%;top:100%}.pfA{width:0;height:0;z-index:3}.pfAIn{position:absolute;left:0;top:0;display:flex;align-items:flex-start;scale:var(--k);transform-origin:0 0;animation:pfWob 3.2s ease-in-out infinite alternate}.pfD .pfAIn{animation-duration:3.8s;animation-delay:-1.3s}.pfAIn svg{display:block;width:24px;height:30px;margin:-1px 0 0 -1px;overflow:visible;filter:drop-shadow(0 3px 4px rgba(20,6,80,.35))}.pfAIn path{fill:var(--c);stroke:#fff;stroke-width:1.3px;stroke-linejoin:round}.pfAIn span{margin:22px 0 0 -4px;padding:5px 10px 6px;border-radius:2px 11px 11px 11px;background:var(--c);color:var(--t);font-size:14px;line-height:1;white-space:nowrap;box-shadow:0 4px 12px rgba(20,6,80,.3)}.pfY{--c:#B8FF1A;--t:#1C1030}.pfD{--c:#FFFFFF;--t:#4A22D8}.pfE{--c:#FF6BB5;--t:#FFFFFF}.pfE .pfAIn{left:-27px;top:-17px;flex-direction:column;align-items:center;transform-origin:27px 17px;animation-duration:4.6s}.pfE svg{width:54px;height:34px;margin:0;transform-origin:50% 50%}.pfE .pfAIn path{fill:#fff;stroke:#FF6BB5;stroke-width:2px}.pfE .pfIr{fill:#FF6BB5}.pfE .pfDt{fill:#1C1030}.pfE .pfAIn span{margin:6px 0 0;border-radius:11px}.pfF{z-index:1;box-sizing:border-box;border:1.5px solid rgba(255,255,255,.85);background-color:rgba(255,255,255,.07);transition:background-color .6s,border-color .6s,border-radius .6s}.pfF::before{content:attr(data-n);position:absolute;left:-1px;bottom:100%;margin-bottom:calc(5px * var(--k));font-size:calc(11px * var(--k));line-height:1;color:rgba(255,255,255,.75);white-space:nowrap}.pfSz{position:absolute;left:50%;top:100%;margin-top:calc(7px * var(--k));transform:translateX(-50%);padding:.27em .55em;border-radius:3px;background:#B8FF1A;color:#1C1030;font-size:calc(11px * var(--k));line-height:1;white-space:nowrap}.pfIm{position:absolute;overflow:hidden;border-radius:4px;background:linear-gradient(135deg,#C4B3FF,#8A6AFF);transition:border-radius .6s}.pfIm::before{content:\"\";position:absolute;right:18%;top:18%;width:calc(14px * var(--k));height:calc(14px * var(--k));border-radius:50%;background:#B8FF1A}.pfIm::after{content:\"\";position:absolute;left:0;right:0;bottom:0;height:55%;background:rgba(40,14,140,.45);clip-path:polygon(0 100%,0 60%,28% 10%,52% 62%,70% 34%,100% 78%,100% 100%)}.pfPen{position:absolute;left:0;top:0;width:100%;height:100%;overflow:visible}.pfPen path{fill:none;stroke:#B8FF1A;stroke-width:calc(2.5px * var(--k));stroke-linecap:round;vector-effect:non-scaling-stroke}.pfPen circle{fill:#fff;stroke:#B8FF1A;stroke-width:1.5px;vector-effect:non-scaling-stroke}.pfBr{position:absolute;height:calc(6px * var(--k));border-radius:3px;background:rgba(255,255,255,.8);transform-origin:0 50%;transition:background .6s}.pfF.vDark{background-color:#1C1030;border-color:#fff}.pfF.vDark .pfBr{background:#B8FF1A}.pfF.vDark .pfIm{background:linear-gradient(135deg,#5B3BD6,#2A1680)}.pfF.vAccent{border-color:#B8FF1A}.pfF.vAccent .pfIm{background:linear-gradient(135deg,#EAFFB0,#B8FF1A)}.pfF.vAccent .pfIm::after{background:rgba(74,34,216,.55)}.pfF.vAccent .pfBr:first-of-type{background:#B8FF1A}.pfF.vSoft{border-radius:calc(14px * var(--k))}.pfF.vSoft .pfIm{border-radius:calc(12px * var(--k))}.pfF.vSoft .pfBr{border-radius:9px}.pfT,.pfN{position:absolute;z-index:1;box-sizing:border-box;border-radius:calc(6px * var(--k));box-shadow:0 4px 14px rgba(20,6,80,.28)}.pfT1{background:linear-gradient(135deg,#C4B3FF,#8A6AFF)}.pfT2{background:linear-gradient(135deg,#EAFFB0,#B8FF1A)}.pfT3{background:linear-gradient(135deg,#FFC2E0,#FF6BB5)}.pfN{padding:calc(9px * var(--k)) calc(10px * var(--k));border-radius:calc(3px * var(--k));background:#fff;border-top:calc(5px * var(--k)) solid #FF6BB5;color:#1C1030;font-size:calc(13px * var(--k));line-height:1.25}.pfCm{z-index:2}.pfCmIn{position:absolute;left:0;bottom:0;scale:var(--k);transform-origin:0 100%}.pfPin{position:absolute;left:0;bottom:0;width:28px;height:28px;border-radius:14px 14px 14px 3px;background:#fff;color:#4A22D8;font-size:12px;font-weight:700;line-height:28px;text-align:center;box-shadow:0 4px 12px rgba(20,6,80,.3);transform-origin:0 100%}.pfBub{position:absolute;left:36px;bottom:0;width:max-content;min-width:120px;max-width:180px;padding:8px 11px 9px;border-radius:12px 12px 12px 4px;background:#fff;color:#1C1030;font-size:13px;line-height:1.3;box-shadow:0 6px 18px rgba(20,6,80,.3);transform-origin:0 100%}.pfBub b{display:block;margin-bottom:2px;font-size:11px;color:#6B5AA8}.pfBub p{margin:0;min-height:1.3em}.pfBub p+b{margin-top:7px;padding-top:7px;border-top:1px solid #ECE8F8}.pfRe{display:inline-block;margin-top:7px;padding:2px 8px;border-radius:10px;background:#F1ECFF;font-size:12px;line-height:1.4}.pfCar{display:inline-block;width:1.5px;height:1em;margin-left:1px;vertical-align:-2px;background:currentColor;animation:pfBl 1s steps(1) infinite}.pfRx{z-index:4;width:0;height:0;font-size:28px;line-height:1}.pfRx span{position:absolute;left:22px;top:-30px;scale:var(--k)}@keyframes pfWob{0%{transform:translate(0,0) rotate(0)}35%{transform:translate(3px,-2px) rotate(-3deg)}70%{transform:translate(-2px,2px) rotate(2deg)}100%{transform:translate(1px,-3px) rotate(-1deg)}}@keyframes pfBl{50%{opacity:0}}@media(max-width:980px){.pfAIn svg{width:20px;height:25px}.pfAIn span{margin-top:18px;font-size:12px;padding:4px 8px 5px}.pfBub{max-width:150px;font-size:12px}}@media(prefers-reduced-motion:reduce){.pfCv{display:none}}";document.head.appendChild(s);})(); (function(){ /* LIVE CANVAS — сюжет на фоне Portfolio. Отдельный скрипт: только читает класс isOpen у #pfX_overlayClip и добавляет свой слой в #pfX_overlay. Существующий JS не трогает. */ var clip = document.getElementById('pfX_overlayClip'); var ov = document.getElementById('pfX_overlay'); var scene = document.getElementById('pfProjectScene'); if(!clip || !ov || !scene || window.pfLiveInit || !Element.prototype.animate){ return; } window.pfLiveInit = true; if(window.matchMedia && matchMedia('(prefers-reduced-motion: reduce)').matches){ return; } var EASE = 'cubic-bezier(.45,0,.2,1)'; var ARROW = ''; /* арт-директор не правит ошибки, а подкидывает идеи; yourich начинает делать вариант, пока тот ещё печатает */ var IDEAS = [ {ad:'огонь. а в тёмной теме?', y:'уже', v:'vDark', n:'dark'}, {ad:'круто. а мобильную?', y:'держи', v:'vMobile', n:'mobile'}, {ad:'нравится. а с акцентом?', y:'готово, смотри', v:'vAccent', n:'accent'}, {ad:'чисто. а если помягче?', y:'вот так', v:'vSoft', n:'soft'} ]; var AD_RE = ['🔥', '🙌', '💯', '😍']; var AD_NOTE = ['референсы', 'палитра', 'мудборд', 'идеи']; var E_REACT = ['😍', '👍', '🔥', '👀']; var cv = document.createElement('div'); cv.className = 'pfCv'; cv.setAttribute('aria-hidden', 'true'); ov.insertBefore(cv, scene); function mk(cls, html, parent){ var e = document.createElement('div'); e.className = cls; if(html){ e.innerHTML = html; } (parent || cv).appendChild(e); return e; } function actor(cls, inner){ var a = mk('pfA ' + cls, '
' + inner + '
'); a.p = {x:0, y:0}; return a; } var Y = actor('pfY', ARROW + 'yourich'); var D = actor('pfD', ARROW + 'арт-директор'); var E = actor('pfE', '' + '' + 'заказчик'); var eyeSvg = E.querySelector('svg'); var pupil = E.querySelector('.pfPu'); /* ---------- утилиты ---------- */ var run = 0, anims = [], focus = null, isOn = false; function isM(){ return window.innerWidth <= 980; } /* клетка сетки: та же формула, что в CSS (--pfc) */ function baseCell(){ return isM() ? 36 : Math.min(100, Math.max(44, window.innerWidth * .0389)); } /* на невысоких экранах (ноутбуки) уменьшаем клетку, чтобы верх сцены и глаз-«заказчик» не залезали под хедер */ function headerBottom(){ var b = 0; document.querySelectorAll('.pfX_leftGroup,.pfX_rightGroup,.pfX_centerGroup').forEach(function(e){ var r = e.getBoundingClientRect(); if(r.height){ b = Math.max(b, r.bottom); } }); return b || 70; } /* экранная Y точки «пола» на высоте y (та же геометрия, что у сетки: rotateX 12°, perspective 1600) */ function planeScreenY(y){ var a = 12 * Math.PI / 180; return window.innerHeight * 1.06 - y * Math.cos(a) * 1600 / (1600 + y * Math.sin(a)); } var CELL = 0; function fitCell(){ var C = baseCell(); if(isM()){ return C; } var need = headerBottom() + 16; while(C > 34 && planeScreenY(13.9 * C) - 24 * C / 56 < need){ C -= .5; } return C; } function applyCell(){ CELL = fitCell(); if(!isM()){ ov.style.setProperty('--pfc', CELL + 'px'); } cv.style.setProperty('--k', kk().toFixed(3)); } function cell(){ return CELL || baseCell(); } function kk(){ return isM() ? 1 : cell() / 56; } function snapX(v){ var c = cell(); return Math.round((v + c / 2) / c) * c - c / 2; } function T(p){ return 'translate(' + p.x.toFixed(1) + 'px,' + (-p.y).toFixed(1) + 'px)'; } function place(el, x, y){ el.p = {x:x, y:y}; el.style.transform = T(el.p); } function wait(ms){ return new Promise(function(r){ setTimeout(r, ms); }); } function ck(g){ if(g !== run){ throw 0; } } function rnd(a, b){ return a + Math.random() * (b - a); } function an(el, kf, o){ var opt = {fill:'forwards', easing:EASE}; for(var k in o){ opt[k] = o[k]; } var a = el.animate(kf, opt); anims.push(a); return a.finished.then(function(){ try{ a.commitStyles(); a.cancel(); }catch(e){} anims.splice(anims.indexOf(a), 1); }, function(){}); } /* движение по мягкой дуге, как рука */ function move(a, x, y, ms){ var s = a.p, e = {x:x, y:y}; var dx = e.x - s.x, dy = e.y - s.y, d = Math.hypot(dx, dy) || 1; var k = rnd(-.28, .28) * d; var c = {x: s.x + dx / 2 - dy / d * k, y: s.y + dy / 2 + dx / d * k}; var kf = []; for(var i = 0; i <= 10; i++){ var t = i / 10, u = 1 - t; kf.push({transform: T({x: u*u*s.x + 2*u*t*c.x + t*t*e.x, y: u*u*s.y + 2*u*t*c.y + t*t*e.y})}); } a.p = e; if(a !== E){ focus = a; } return an(a, kf, {duration: ms || Math.min(2300, 520 + d * 2.1)}); } /* движение по списку точек (следом за пером) */ function follow(a, pts, ms){ a.p = pts[pts.length - 1]; focus = a; return an(a, pts.map(function(p){ return {transform:T(p)}; }), {duration:ms, easing:'ease-in-out'}); } function press(a){ return an(a.firstChild, [{transform:'scale(1)'}, {transform:'scale(.84)'}, {transform:'scale(1)'}], {duration:240, fill:'none'}); } function pop(el, ms){ return an(el, [{transform:'scale(0)', opacity:0}, {transform:'scale(1.08)', opacity:1, offset:.7}, {transform:'scale(1)', opacity:1}], {duration:ms || 360, easing:'ease-out'}); } function type(p, text, g){ var car = document.createElement('i'); car.className = 'pfCar'; var node = document.createTextNode(''); p.appendChild(node); p.appendChild(car); var i = 0; return new Promise(function(res, rej){ (function tick(){ if(g !== run){ rej(0); return; } if(i >= text.length){ setTimeout(function(){ car.remove(); res(); }, 450); return; } node.data += text[i++]; setTimeout(tick, text[i - 1] === ' ' ? rnd(90, 160) : rnd(45, 115)); })(); }); } /* ---------- глаз: следит и моргает ---------- */ var pu = {x:0, y:0}; function track(){ if(!isOn){ return; } if(focus){ var r1 = focus.getBoundingClientRect(), r2 = eyeSvg.getBoundingClientRect(); var dx = r1.left - (r2.left + r2.width / 2), dy = r1.top - (r2.top + r2.height / 2); var d = Math.hypot(dx, dy) || 1; pu.x += (dx / d * 5 - pu.x) * .12; pu.y += (dy / d * 3 - pu.y) * .12; pupil.setAttribute('transform', 'translate(' + pu.x.toFixed(2) + ',' + pu.y.toFixed(2) + ')'); } requestAnimationFrame(track); } function blink(g){ if(g !== run){ return; } var twice = Math.random() < .3; var kf = [{transform:'scaleY(1)'}, {transform:'scaleY(.08)', offset:.5}, {transform:'scaleY(1)'}]; an(eyeSvg, kf, {duration:170, easing:'ease-in-out', fill:'none'}).then(function(){ if(twice && g === run){ an(eyeSvg, kf, {duration:170, easing:'ease-in-out', fill:'none'}); } }); setTimeout(function(){ blink(g); }, rnd(2200, 5200)); } /* ---------- сюжет ---------- */ /* арт-директор тем временем собирает мудборд на другой стороне */ async function adBoard(g, n, side, C, K){ var vw = window.innerWidth; var zc2 = -side * vw * .41; var bx = snapX(zc2 - 1.5 * C), g4 = 4 * K; var items = []; function box(cls, x, yTop, w, h){ var e = mk(cls); e.style.left = 'calc(50% + ' + (x + g4) + 'px)'; e.style.top = 'calc(100% - ' + (yTop - g4) + 'px)'; e.style.width = (w - 2 * g4) + 'px'; e.style.height = (h - 2 * g4) + 'px'; e.style.opacity = '0'; items.push(e); return e; } var tiles = [[0, 7, 'pfT pfT1'], [1, 7, 'pfT pfT2'], [2, 7, 'pfT pfT3'], [0, 6, 'pfT pfT2'], [1, 6, 'pfT pfT3']]; await move(D, bx + .5 * C, 6.5 * C, 1600); ck(g); for(var i = 0; i < tiles.length; i++){ var t = tiles[i], cx = bx + (t[0] + .5) * C, cy = (t[1] - .5) * C; await move(D, cx, cy, rnd(420, 620)); ck(g); press(D); var el = box(t[2], bx + t[0] * C, t[1] * C, C, C); await pop(el, 340); ck(g); if(Math.random() < .35){ await wait(rnd(200, 500)); ck(g); } } var nx = bx + 2 * C, ny = 6 * C; await move(D, nx + .2 * C, ny - .2 * C, 700); ck(g); press(D); var note = box('pfN', nx, ny, C * 1.9, C * 1.9); note.style.transformOrigin = '0 0'; await pop(note, 380); ck(g); await move(D, nx + 1.5 * C, ny - 1.4 * C, 600); ck(g); await type(note, AD_NOTE[n % AD_NOTE.length], g); ck(g); await wait(600); ck(g); return items; } async function episode(g, n){ applyCell(); var C = cell(), K = kk(), m = isM(), idea = IDEAS[n % IDEAS.length]; cv.style.setProperty('--k', K.toFixed(3)); var side = m ? 0 : (n % 2 ? -1 : 1); var vw = window.innerWidth; var zc = m ? 0 : side * vw * .41; var fw = 3 * C, fh = (m ? 3 : 3.5) * C, pad = Math.round(C * .18); var fx = snapX(zc - fw / 2), fy = m ? C : 2 * C; var top = fy + fh; var fy2 = top + (m ? 3.6 : 3) * C, top2 = fy2 + fh; function at(px, py, t){ return {x: fx + px, y: (t || top) - py}; } /* глаз наблюдает сверху */ move(E, zc + (m ? 0 : side * .3 * C), top2 + (m ? 1.6 : 1.9) * C, 1800); var boardP = m ? Promise.resolve([]) : adBoard(g, n, side, C, K); boardP.catch(function(){}); /* 1. yourich собирает макет */ var F = mk('pfF'); F.setAttribute('data-n', 'Frame ' + (n + 1)); F.style.left = 'calc(50% + ' + fx + 'px)'; F.style.top = 'calc(100% - ' + top + 'px)'; F.style.width = '0px'; F.style.height = '0px'; F.style.opacity = '0'; await move(Y, fx, top); ck(g); await press(Y); ck(g); F.style.opacity = '1'; var sz = mk('pfSz', Math.round(fw / K) + ' × ' + Math.round(fh / K), F); await Promise.all([ an(F, [{width:'0px', height:'0px'}, {width:fw + 'px', height:fh + 'px'}], {duration:900}), move(Y, fx + fw, fy, 900) ]); ck(g); await wait(400); ck(g); an(sz, [{opacity:1}, {opacity:0}], {duration:300}); var iw = fw - 2 * pad, ih = Math.round(fh * .42); var im = mk('pfIm', '', F); im.style.left = pad + 'px'; im.style.top = pad + 'px'; im.style.width = '0px'; im.style.height = '0px'; var p0 = at(pad, pad), p1 = at(pad + iw, pad + ih); await move(Y, p0.x, p0.y, 700); ck(g); await press(Y); ck(g); await Promise.all([ an(im, [{width:'0px', height:'0px'}, {width:iw + 'px', height:ih + 'px'}], {duration:750}), move(Y, p1.x, p1.y, 750) ]); ck(g); im.style.width = 'calc(100% - ' + 2 * pad + 'px)'; var py0 = ih + pad * 2.4, NS = 'http://www.w3.org/2000/svg'; var d = 'M' + pad + ' ' + (py0 + C * .3) + ' C' + (fw * .3) + ' ' + (py0 - C * .25) + ' ' + (fw * .62) + ' ' + (py0 + C * .8) + ' ' + (fw - pad) + ' ' + (py0 + C * .1); var svg = document.createElementNS(NS, 'svg'); svg.setAttribute('class', 'pfPen'); svg.setAttribute('viewBox', '0 0 ' + fw + ' ' + fh); svg.setAttribute('preserveAspectRatio', 'none'); var path = document.createElementNS(NS, 'path'); path.setAttribute('d', d); svg.appendChild(path); F.appendChild(svg); var L = path.getTotalLength(); path.style.strokeDasharray = L; path.style.strokeDashoffset = L; var pts = []; for(var i = 0; i <= 16; i++){ var q = path.getPointAtLength(L * i / 16); pts.push(at(q.x, q.y)); } await move(Y, pts[0].x, pts[0].y, 600); ck(g); await press(Y); ck(g); await Promise.all([ an(path, [{strokeDashoffset:L}, {strokeDashoffset:0}], {duration:1200, easing:'ease-in-out'}), follow(Y, pts, 1200) ]); ck(g); [0, 16].forEach(function(j){ var q = path.getPointAtLength(L * j / 16); var c = document.createElementNS(NS, 'circle'); c.setAttribute('cx', q.x); c.setAttribute('cy', q.y); c.setAttribute('r', 3.5 * K); svg.appendChild(c); }); var bars = [[fh - pad * 1.9 - 7 * K, .72], [fh - pad - 5 * K, .46]]; for(var b = 0; b < bars.length; b++){ var br = mk('pfBr', '', F); br.style.left = pad + 'px'; br.style.top = bars[b][0] + 'px'; br.style.width = 'calc((100% - ' + 2 * pad + 'px) * ' + bars[b][1] + ')'; br.style.transform = 'scaleX(0)'; var bp = at(pad + 2, bars[b][0] + 3 * K); await move(Y, bp.x, bp.y, 480); ck(g); press(Y); await an(br, [{transform:'scaleX(0)'}, {transform:'scaleX(1)'}], {duration:400, easing:'cubic-bezier(.2,.8,.2,1)'}); ck(g); } F.classList.add('ok'); /* yourich отходит полюбоваться */ move(Y, fx + fw * .5 - side * C * .6, fy - C * .7, 900); /* 2. арт-директор заканчивает мудборд, приходит и подкидывает идею */ var board = await boardP; ck(g); await move(D, fx + fw * .7, top - C * .6, 2200); ck(g); await wait(500); ck(g); var cp = {x: fx, y: top + C * .45}; await move(D, cp.x + 8 * K, cp.y + 8 * K, 800); ck(g); await press(D); ck(g); var cm = mk('pfCm', '
А
арт-директор

'); place(cm, cp.x, cp.y); var pin = cm.querySelector('.pfPin'), bub = cm.querySelector('.pfBub'), pA = bub.querySelector('p'); bub.style.opacity = '0'; await pop(pin); ck(g); move(D, cp.x + 90 * K, cp.y - 34 * K, 700); await pop(bub, 320); ck(g); var typing = type(pA, idea.ad, g); /* 3. пока он печатает, yourich уже делает вариант */ await wait(700); ck(g); var mid = at(fw / 2, fh * .75); await move(Y, mid.x, mid.y, 700); ck(g); await press(Y); ck(g); var F2 = F.cloneNode(true); F2.setAttribute('data-n', 'Frame ' + (n + 1) + ' / ' + idea.n); F2.querySelectorAll('.pfSz').forEach(function(x){ x.remove(); }); cv.insertBefore(F2, F); F2.style.top = 'calc(100% - ' + top + 'px)'; var dy = top2 - top; await Promise.all([ an(F2, [{top:'calc(100% - ' + top + 'px)', opacity:.6}, {top:'calc(100% - ' + top2 + 'px)', opacity:1}], {duration:1300}), move(Y, mid.x, mid.y + dy, 1300) ]); ck(g); if(idea.v === 'vMobile'){ var re = at(fw, fh / 2, top2), nw = Math.round(1.75 * C); await move(Y, re.x, re.y, 600); ck(g); await press(Y); ck(g); await Promise.all([ an(F2, [{width:fw + 'px'}, {width:nw + 'px'}], {duration:900}), move(Y, fx + nw, re.y, 900) ]); ck(g); } else { await press(Y); ck(g); F2.classList.add(idea.v); await wait(300); ck(g); } /* 4. yourich отвечает в треде, арт-директор ставит реакцию */ await typing; ck(g); await move(Y, cp.x + 120 * K, cp.y - 10 * K, 900); ck(g); await press(Y); ck(g); var bY = document.createElement('b'), pY = document.createElement('p'); bY.textContent = 'yourich'; bub.appendChild(bY); bub.appendChild(pY); await type(pY, idea.y, g); ck(g); await move(D, cp.x + 60 * K, cp.y + 8 * K, 600); ck(g); await press(D); ck(g); var chip = document.createElement('div'); chip.className = 'pfRe'; chip.textContent = AD_RE[n % AD_RE.length] + ' 1'; bub.appendChild(chip); await pop(chip, 300); ck(g); /* 5. заказчик сравнивает оба макета и доволен */ focus = F2; await wait(900); ck(g); focus = F; await wait(900); ck(g); focus = F2; await wait(600); ck(g); an(eyeSvg, [{transform:'scale(1)'}, {transform:'scale(1.18)', offset:.4}, {transform:'scale(1)'}], {duration:520, fill:'none'}); var rx = mk('pfRx', '' + E_REACT[n % E_REACT.length] + ''); place(rx, E.p.x, E.p.y); an(rx, [{transform:T(E.p) + ' scale(.4)', opacity:0}, {transform:T({x:E.p.x, y:E.p.y + 18 * K}) + ' scale(1.1)', opacity:1, offset:.35}, {transform:T({x:E.p.x, y:E.p.y + 38 * K}) + ' scale(1)', opacity:0}], {duration:1800, easing:'ease-out'}); move(D, -side * vw * .45 + (m ? -140 : 0), top2 + rnd(0, 2) * C, 2400); move(Y, zc - side * C * 1.4, fy - C * .4, 1600); await wait(2200); ck(g); /* 6. сцена гаснет, следующий эпизод — на другой стороне */ var gone = [F, F2, cm].concat(board); await Promise.all(gone.map(function(el){ return an(el, [{opacity:getComputedStyle(el).opacity}, {opacity:0}], {duration:700}); })); ck(g); gone.forEach(function(el){ el.remove(); }); rx.remove(); await wait(500); ck(g); } async function loop(g){ var n = 0; try{ await wait(1500); ck(g); while(true){ await episode(g, n++); } }catch(e){} } function start(){ if(isOn){ return; } isOn = true; var g = ++run; applyCell(); var vw = window.innerWidth, C = cell(), m = isM(); if(!Y.started){ Y.started = true; place(Y, m ? -120 : vw * .2, 2 * C); place(D, m ? 150 : -vw * .45, 8 * C); place(E, m ? 0 : vw * .41, (m ? 7 : 11) * C); cv.style.setProperty('--k', kk().toFixed(3)); } loop(g); setTimeout(function(){ blink(g); }, 1800); requestAnimationFrame(track); } function stop(){ if(!isOn){ return; } isOn = false; run++; anims.slice().forEach(function(a){ try{ a.commitStyles(); }catch(e){} a.cancel(); }); anims = []; setTimeout(function(){ if(isOn){ return; } cv.querySelectorAll('.pfF,.pfCm,.pfRx,.pfT,.pfN').forEach(function(el){ el.remove(); }); }, 800); } function sync(){ var open = clip.classList.contains('isOpen') && !clip.classList.contains('isClosing'); if(open){ start(); } else { stop(); } } new MutationObserver(sync).observe(clip, {attributes:true, attributeFilter:['class']}); sync(); })();