@open-slot-ui/pixi 0.12.0 → 0.13.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -2491,6 +2491,9 @@ function buildBlockColumn(blocks, controls, ui, ticker, bodyW, opts = {}) {
2491
2491
  case "paytable":
2492
2492
  placeAuto(paytableNode(b, ui, innerW));
2493
2493
  break;
2494
+ case "paylines":
2495
+ placeAuto(paylinesNode(b, ui, innerW));
2496
+ break;
2494
2497
  case "media":
2495
2498
  placeAuto(mediaNode(b, ui, innerW));
2496
2499
  break;
@@ -2736,6 +2739,42 @@ function imageBoxNode(src, w, h, ui) {
2736
2739
  }
2737
2740
  return box;
2738
2741
  }
2742
+ function paylinesNode(b, ui, innerW) {
2743
+ const t = ui.theme;
2744
+ const c = new pixi_js.Container();
2745
+ const GAP_X = 12;
2746
+ const ITEM_MIN = 76;
2747
+ const cols = Math.max(1, Math.floor((innerW + GAP_X) / (ITEM_MIN + GAP_X)));
2748
+ const itemW = (innerW - GAP_X * (cols - 1)) / cols;
2749
+ const cellGap = 2;
2750
+ const gridW = Math.min(72, itemW);
2751
+ const cell = (gridW - cellGap * (b.reels - 1)) / b.reels;
2752
+ const drawnW = cell * b.reels + cellGap * (b.reels - 1);
2753
+ const drawnH = cell * b.rows + cellGap * (b.rows - 1);
2754
+ const labelH = 16;
2755
+ const itemH = drawnH + 5 + labelH;
2756
+ const gridRows = Math.ceil(b.lines.length / cols);
2757
+ const totalH = gridRows * itemH + (gridRows - 1) * GAP_X;
2758
+ b.lines.forEach((line, i) => {
2759
+ const col = i % cols;
2760
+ const row = Math.floor(i / cols);
2761
+ const itemCx = -innerW / 2 + col * (itemW + GAP_X) + itemW / 2;
2762
+ const gy0 = -totalH / 2 + row * (itemH + GAP_X);
2763
+ const gx0 = itemCx - drawnW / 2;
2764
+ const g = new pixi_js.Graphics();
2765
+ for (let r = 0; r < b.rows; r++) {
2766
+ for (let re = 0; re < b.reels; re++) {
2767
+ g.rect(gx0 + re * (cell + cellGap), gy0 + r * (cell + cellGap), cell, cell).fill({ color: line[re] === r ? 1118481 : 14869994 });
2768
+ }
2769
+ }
2770
+ const idx = new pixi_js.Text({ text: String(i + 1), style: { fontFamily: t.type.family, fontSize: 11, fill: t.color.textDim, fontWeight: "700" } });
2771
+ idx.anchor.set(0.5, 0);
2772
+ idx.position.set(itemCx, gy0 + drawnH + 5);
2773
+ c.addChild(g, idx);
2774
+ });
2775
+ c.addChild(new pixi_js.Graphics().rect(-innerW / 2, -totalH / 2, 1, totalH).fill({ color: 16777215, alpha: 0 }));
2776
+ return c;
2777
+ }
2739
2778
  function paytableNode(b, ui, innerW) {
2740
2779
  const want = Math.max(1, b.columns ?? 1);
2741
2780
  const fit = Math.max(1, Math.floor(innerW / 170));
@@ -2830,8 +2869,8 @@ function paytableCell(r, ui, cellW, lineH) {
2830
2869
 
2831
2870
  // src/views/MenuView.ts
2832
2871
  var MARGIN = 16;
2833
- var HEADER_H = 60;
2834
- var INSET = 22;
2872
+ var HEADER_H = 62;
2873
+ var INSET = 24;
2835
2874
  var LIGHT = {
2836
2875
  surface: "#ffffff",
2837
2876
  surfaceAlt: "#eef1f6",
@@ -2850,13 +2889,13 @@ var MenuView = class extends ControlView {
2850
2889
  this.opts = opts;
2851
2890
  this.zIndex = 120;
2852
2891
  this.titleKey = opts.title ?? "Menu";
2853
- this.maxWidth = opts.maxWidth ?? 1600;
2892
+ this.maxWidth = opts.maxWidth ?? 760;
2854
2893
  const lightTheme = { ...ui.theme, color: { ...ui.theme.color, surface: LIGHT.surface, surfaceAlt: LIGHT.surfaceAlt, text: LIGHT.text, textDim: LIGHT.textDim, accent: LIGHT.accent } };
2855
2894
  this.lightUi = new Proxy(ui, { get: (t, p) => p === "theme" ? lightTheme : Reflect.get(t, p) });
2856
2895
  this.backdrop.eventMode = "static";
2857
2896
  this.backdrop.on("pointertap", () => this.panel.closePanel());
2858
- this.title = new pixi_js.Text({ text: ui.t(this.titleKey), style: { fontFamily: ui.theme.type.family, fontSize: 24, fill: LIGHT.text, fontWeight: "800", letterSpacing: 1 } });
2859
- this.title.anchor.set(0, 0.5);
2897
+ this.title = new pixi_js.Text({ text: ui.t(this.titleKey), style: { fontFamily: ui.theme.type.family, fontSize: 28, fill: LIGHT.text, fontWeight: "900", letterSpacing: 1 } });
2898
+ this.title.anchor.set(0.5, 0.5);
2860
2899
  this.buildClose();
2861
2900
  this.viewport.addChild(this.catcher, this.content);
2862
2901
  this.viewport.mask = this.maskG;
@@ -2932,17 +2971,17 @@ var MenuView = class extends ControlView {
2932
2971
  const H = screen.height;
2933
2972
  this.position.set(0, 0);
2934
2973
  this.scale.set(1);
2935
- this.backdrop.clear().rect(0, 0, W, H).fill({ color: 0, alpha: 0.5 });
2974
+ this.backdrop.clear().rect(0, 0, W, H).fill({ color: 657414, alpha: 0.42 });
2936
2975
  this.backdrop.hitArea = new pixi_js.Rectangle(0, 0, W, H);
2937
- const marginX = Math.max(MARGIN, Math.round(W * 0.05));
2976
+ const marginX = Math.max(MARGIN, Math.round(W * 0.04));
2938
2977
  const cardW = Math.min(W - marginX * 2, this.maxWidth);
2939
2978
  const cardH = H - MARGIN * 2;
2940
2979
  const cx = (W - cardW) / 2;
2941
2980
  const cy = MARGIN;
2942
- this.card.clear().roundRect(cx, cy, cardW, cardH, 14).fill({ color: LIGHT.surface }).stroke({ width: 2.5, color: LIGHT.border });
2943
- this.headerBar.clear().roundRect(cx, cy, cardW, HEADER_H, 14).fill({ color: LIGHT.surfaceAlt }).moveTo(cx + INSET, cy + HEADER_H).lineTo(cx + cardW - INSET, cy + HEADER_H).stroke({ width: 1, color: LIGHT.textDim, alpha: 0.4 });
2944
- this.title.position.set(cx + INSET, cy + HEADER_H / 2);
2945
- this.closeBtn.position.set(cx + cardW - INSET - 8, cy + HEADER_H / 2);
2981
+ this.card.clear().roundRect(cx, cy, cardW, cardH, 8).fill({ color: LIGHT.surface }).stroke({ width: 1.5, color: LIGHT.border });
2982
+ this.headerBar.clear();
2983
+ this.title.position.set(cx + cardW / 2, cy + HEADER_H / 2);
2984
+ this.closeBtn.position.set(cx + cardW - INSET, cy + INSET);
2946
2985
  const vpX = cx + INSET;
2947
2986
  const vpY = cy + HEADER_H + INSET;
2948
2987
  const newVpW = cardW - INSET * 2;
@@ -4653,7 +4692,7 @@ function showBootError(opts = {}) {
4653
4692
  host.innerHTML = `
4654
4693
  <div class="openui-be-card">
4655
4694
  <div class="openui-be-icon" aria-hidden="true">
4656
- <svg viewBox="0 0 48 48" width="48" height="48"><path d="M24 4 3 42h42L24 4Z" fill="none" stroke="#ffc935" stroke-width="3" stroke-linejoin="round"/><rect x="22" y="18" width="4" height="12" rx="2" fill="#ffc935"/><circle cx="24" cy="35" r="2.4" fill="#ffc935"/></svg>
4695
+ <svg viewBox="0 0 48 48" width="46" height="46"><path d="M24 5 4 41h40L24 5Z" fill="none" stroke="#000" stroke-width="4" stroke-linejoin="round"/><rect x="22" y="19" width="4" height="12" rx="2" fill="#000"/><circle cx="24" cy="35.5" r="2.5" fill="#000"/></svg>
4657
4696
  </div>
4658
4697
  <h1 class="openui-be-title">${esc2(title)}</h1>
4659
4698
  <p class="openui-be-msg">${esc2(message)}</p>
@@ -4661,19 +4700,23 @@ function showBootError(opts = {}) {
4661
4700
  ${showReload ? `<button class="openui-be-reload" type="button">${esc2(opts.reloadLabel ?? "Reload")}</button>` : ""}
4662
4701
  </div>
4663
4702
  <style>
4703
+ /* MONOCHROME by design \u2014 a neutral black-and-white system card, no theme accent. */
4664
4704
  .openui-boot-error { position: fixed; inset: 0; z-index: 2147483000; display: grid; place-items: center;
4665
- font-family: system-ui, -apple-system, "Segoe UI", Roboto, sans-serif; color: #e9edf2;
4666
- background: rgba(6,8,11,.92); backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px); }
4667
- .openui-be-card { width: min(90%, 440px); text-align: center; padding: 38px 32px 34px;
4668
- background: #161b22; border: 1.5px solid #ffc935; border-radius: 16px; box-shadow: 0 30px 80px rgba(0,0,0,.6); }
4669
- .openui-be-icon { margin-bottom: 14px; line-height: 0; }
4670
- .openui-be-title { margin: 0 0 12px; font-size: 24px; font-weight: 800; color: #ffc935; letter-spacing: .3px; }
4671
- .openui-be-msg { margin: 0 0 20px; font-size: 15px; line-height: 1.55; color: #c4ccd6; }
4672
- .openui-be-detail { margin: 0 0 20px; font-size: 12px; line-height: 1.4; color: #78828f; word-break: break-word; }
4673
- .openui-be-reload { appearance: none; border: 0; cursor: pointer; padding: 13px 42px; border-radius: 999px;
4674
- background: #ffc935; color: #161b22; font-weight: 800; font-size: 15px; letter-spacing: .3px;
4675
- box-shadow: 0 8px 22px rgba(255,201,53,.32); transition: transform .12s, filter .12s; }
4676
- .openui-be-reload:hover { filter: brightness(1.06); }
4705
+ font-family: system-ui, -apple-system, "Segoe UI", Roboto, sans-serif; color: #181b20;
4706
+ background: rgba(8,8,8,.62); backdrop-filter: blur(8px); -webkit-backdrop-filter: blur(8px); }
4707
+ .openui-be-card { width: min(90%, 440px); text-align: center; padding: 40px 36px 32px;
4708
+ display: flex; flex-direction: column; align-items: center; gap: 14px;
4709
+ background: #fff; border: 4px solid #000; border-radius: 24px; box-shadow: 0 24px 60px rgba(0,0,0,.55); }
4710
+ .openui-be-icon { display: grid; place-items: center; width: 72px; height: 72px; border-radius: 999px;
4711
+ border: 4px solid #000; line-height: 0; }
4712
+ .openui-be-title { margin: 0; font-size: 26px; font-weight: 800; color: #000; letter-spacing: .01em; }
4713
+ .openui-be-msg { margin: 0; font-size: 16px; line-height: 1.5; font-weight: 600; color: #3a3f47; max-width: 34ch; }
4714
+ .openui-be-detail { margin: 0; font-size: 12px; line-height: 1.4; color: #8a9099; word-break: break-word;
4715
+ font-family: ui-monospace, "SF Mono", Menlo, monospace; max-width: 40ch; }
4716
+ .openui-be-reload { appearance: none; cursor: pointer; margin-top: 8px; padding: 14px 42px; border-radius: 999px;
4717
+ border: 4px solid #000; background: #000; color: #fff; font-weight: 800; font-size: 16px; letter-spacing: .03em;
4718
+ transition: transform .1s ease, background .12s ease; }
4719
+ .openui-be-reload:hover { background: #1c1c1c; }
4677
4720
  .openui-be-reload:active { transform: scale(.96); }
4678
4721
  </style>`;
4679
4722
  if (showReload) {