403Webshell
Server IP : 202.61.199.114  /  Your IP : 216.73.217.139
Web Server : nginx/1.22.1
System : Linux de.arni-solutions.de 6.1.0-49-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.1.174-1 (2026-05-26) x86_64
User : web20 ( 1018)
PHP Version : 8.4.23
Disable Function : NONE
MySQL : OFF  |  cURL : ON  |  WGET : ON  |  Perl : ON  |  Python : OFF  |  Sudo : ON  |  Pkexec : ON
Directory :  /proc/3951572/root/tmp/rrpkg/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Command :


[ Back ]     

Current File : /proc/3951572/root/tmp/rrpkg/AnimationEngine.js
/* Reel Royale – AnimationEngine
   Gewinnlinien, Zellen-Highlights, Counter-Animation, Win-Stufen. */
import { $, money } from '../util.js';

const SVGNS = 'http://www.w3.org/2000/svg';
const LINE_COLORS = ['#ffce53', '#56d6ff', '#4ad991', '#ff5d6c', '#c77dff', '#ff9f1b', '#7CFFB2', '#ff79c6', '#8be9fd', '#f1fa8c'];

export class AnimationEngine {
  constructor({ reels, particles, audio }) {
    this.reels = reels;
    this.particles = particles;
    this.audio = audio;
    this.svg = $('winLines');
    this.winPop = $('winPop');
  }

  clear() {
    this.svg.innerHTML = '';
    this.winPop.hidden = true;
    this.winPop.classList.remove('show');
    document.querySelectorAll('.rr-cell.is-win,.rr-cell.is-special,.rr-cell.is-collected,.rr-cell.is-dance')
      .forEach((c) => c.classList.remove('is-win', 'is-special', 'is-collected', 'is-dance'));
    document.querySelectorAll('.rr-cell-coin').forEach((n) => n.remove());
  }

  /** Nur BESONDERE Symbole (Scatter/Bonus) wackeln & hüpfen – und auch nur dann,
      wenn sie tatsächlich gewinnen bzw. ein Feature auslösen (in einer Reihe auftreten).
      Normale Gewinnsymbole leuchten lediglich (is-win), ohne zu tanzen. */
  danceSpecial(game) {
    document.querySelectorAll('.rr-cell').forEach((cell) => {
      const sym = game.symbols[cell.dataset.code];
      const t = sym && sym.type;
      const isSpecial = t === 'scatter' || t === 'bonus';
      const significant = cell.classList.contains('is-win') || cell.classList.contains('is-special');
      if (isSpecial && significant) cell.classList.add('is-dance');
    });
  }

  _center(col, row, svgRect) {
    const cell = this.reels.cellAt(col, row);
    if (!cell) return null;
    const r = cell.getBoundingClientRect();
    return { x: r.left - svgRect.left + r.width / 2, y: r.top - svgRect.top + r.height / 2 };
  }

  highlightWins(wins) {
    // Niemals auf sich drehenden Walzen zeichnen (verhindert Geisterlinien)
    if (this.reels.spinning) return;
    const svgRect = this.svg.getBoundingClientRect();
    if (svgRect.width < 10 || svgRect.height < 10) return;
    // Kein dynamisches viewBox → 1:1 px-Mapping, kein Skalieren bei Layout-Änderungen
    this.svg.removeAttribute('viewBox');
    const inBounds = (p) => p && p.x >= -8 && p.x <= svgRect.width + 8 && p.y >= -8 && p.y <= svgRect.height + 8;
    let colorIdx = 0;
    wins.forEach((win) => {
      (win.positions || []).forEach(([col, row]) => {
        const cell = this.reels.cellAt(col, row);
        if (cell) cell.classList.add('is-win');
      });
      if (win.path && win.path.length && !win.is_scatter) {
        const pts = win.path.map(([col, row]) => this._center(col, row, svgRect));
        // Nur zeichnen, wenn ALLE Punkte gültig & im Rahmen sind (sonst veraltete Zelle → überspringen)
        if (pts.length > 1 && pts.every(inBounds)) {
          const poly = document.createElementNS(SVGNS, 'polyline');
          poly.setAttribute('points', pts.map((p) => `${p.x},${p.y}`).join(' '));
          poly.setAttribute('class', 'rr-winline');
          poly.style.color = LINE_COLORS[colorIdx++ % LINE_COLORS.length];
          poly.style.stroke = poly.style.color;
          this.svg.appendChild(poly);
        }
      }
    });
  }

  markSpecial(positions, cls = 'is-special') {
    (positions || []).forEach(([col, row]) => {
      const cell = this.reels.cellAt(col, row);
      if (cell) cell.classList.add(cls);
    });
  }

  showCollected(collected) {
    const svgRect = this.svg.getBoundingClientRect();
    (collected || []).forEach((c, i) => {
      const cell = this.reels.cellAt(c.col, c.row);
      if (!cell) return;
      cell.classList.add('is-special');
      const badge = document.createElement('div');
      badge.className = 'rr-cell-coin';
      badge.textContent = money(c.win);
      cell.appendChild(badge);
      const ctr = this._center(c.col, c.row, svgRect);
      if (ctr) setTimeout(() => this.particles.burst(svgRect.left + ctr.x, svgRect.top + ctr.y, 'gold', 10), i * 90);
    });
  }

  countUp(el, to, dur = 900) {
    const from = 0;
    const start = performance.now();
    const step = (now) => {
      const t = Math.min(1, (now - start) / dur);
      const eased = 1 - Math.pow(1 - t, 3);
      el.textContent = money(from + (to - from) * eased);
      if (t < 1) requestAnimationFrame(step);
      else el.textContent = money(to);
    };
    requestAnimationFrame(step);
  }

  /** Liefert die Gewinnstufe als {key,label} oder null. */
  tier(amount, totalBet, tiers) {
    if (amount <= 0 || totalBet <= 0) return null;
    const m = amount / totalBet;
    if (m >= (tiers.epic || 60)) return { key: 'epic', label: 'EPIC WIN' };
    if (m >= (tiers.mega || 25)) return { key: 'mega', label: 'MEGA WIN' };
    if (m >= (tiers.big || 12)) return { key: 'big', label: 'BIG WIN' };
    if (m >= (tiers.nice || 5)) return { key: 'nice', label: 'NICE WIN' };
    return { key: 'small', label: '' };
  }

  /** Win-Pop in der Reel-Mitte (kleinere Gewinne). */
  popWin(amount) {
    this.winPop.textContent = `+${money(amount)}`;
    this.winPop.hidden = false;
    this.winPop.classList.remove('show');
    void this.winPop.offsetWidth;
    this.winPop.classList.add('show');
  }

  /** Big/Mega/Epic-Gewinn als seitlich eingeblendetes Panel (kein Vollbild) mit Counter.
      Konfetti + Feuerwerk bei besonders großen Gewinnen. Nach ~4 s geht es automatisch weiter. */
  bigWin(label, amount, tierKey) {
    const dock = $('bigWin');
    $('bigWinTitle').textContent = label;
    const amtEl = $('bigWinAmount');
    dock.hidden = false;
    this.audio.play('bigwin');
    this.particles.coinShower(tierKey === 'epic' ? 80 : 50);
    if (tierKey === 'mega' || tierKey === 'epic') this.particles.confetti(tierKey === 'epic' ? 110 : 70);
    if (tierKey === 'epic') this.particles.fireworks(6);
    this.countUp(amtEl, amount, 900);
    // Etwas längere Wartezeit (~4 s), dann automatisch weiter; Klick schließt sofort.
    return new Promise((resolve) => {
      let done = false;
      let timer = null;
      const close = () => {
        if (done) return;
        done = true;
        if (timer) clearTimeout(timer);
        dock.hidden = true;
        $('bigWinClose').removeEventListener('click', close);
        resolve();
      };
      $('bigWinClose').addEventListener('click', close);
      timer = setTimeout(close, 4000);
    });
  }
}

Youez - 2016 - github.com/yon3zu
LinuXploit