q5 2.16.0 → 2.17.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.
Files changed (5) hide show
  1. package/deno.json +1 -1
  2. package/package.json +2 -2
  3. package/q5.d.ts +570 -213
  4. package/q5.js +267 -5
  5. package/q5.min.js +2 -2
package/q5.js CHANGED
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * q5.js
3
- * @version 2.16
3
+ * @version 2.17
4
4
  * @author quinton-ashley, Tezumie, and LingDong-
5
5
  * @license LGPL-3.0
6
6
  * @class Q5
@@ -311,7 +311,7 @@ function createCanvas(w, h, opt) {
311
311
  }
312
312
  }
313
313
 
314
- Q5.version = Q5.VERSION = '2.16';
314
+ Q5.version = Q5.VERSION = '2.17';
315
315
 
316
316
  if (typeof document == 'object') {
317
317
  document.addEventListener('DOMContentLoaded', () => {
@@ -464,8 +464,10 @@ Q5.modules.canvas = ($, q) => {
464
464
  };
465
465
 
466
466
  $._setCanvasSize = (w, h) => {
467
+ if (!w) h ??= window.innerHeight;
468
+ else h ??= w;
467
469
  w ??= window.innerWidth;
468
- h ??= window.innerHeight;
470
+
469
471
  $.defaultWidth = c.w = w = Math.ceil(w);
470
472
  $.defaultHeight = c.h = h = Math.ceil(h);
471
473
  c.hw = w / 2;
@@ -1761,7 +1763,7 @@ Q5.renderers.c2d.soft_filters = ($) => {
1761
1763
 
1762
1764
  $._softFilter = (typ, x) => {
1763
1765
  if (!$._filters) initSoftFilters();
1764
- let imgData = $.ctx._getImageData(0, 0, $.canvas.width, $.canvas.height);
1766
+ let imgData = $._getImageData(0, 0, $.canvas.width, $.canvas.height);
1765
1767
  $._filters[typ](imgData.data, x);
1766
1768
  $.ctx.putImageData(imgData, 0, 0);
1767
1769
  };
@@ -2538,7 +2540,9 @@ main {
2538
2540
  }
2539
2541
  if (displayMode == 'center') displayMode = 'centered';
2540
2542
  Object.assign(c, { displayMode, renderQuality, displayScale });
2543
+ if ($.ctx) $.pushStyles();
2541
2544
  $._adjustDisplay();
2545
+ if ($.ctx) $.popStyles();
2542
2546
  };
2543
2547
 
2544
2548
  $.fullscreen = (v) => {
@@ -2547,6 +2551,264 @@ main {
2547
2551
  else document.body.exitFullscreen();
2548
2552
  };
2549
2553
  };
2554
+ Q5.modules.dom = ($) => {
2555
+ $.elementMode = (mode) => ($._elementMode = mode);
2556
+
2557
+ $.createElement = (tag, content) => {
2558
+ let el = document.createElement(tag);
2559
+
2560
+ if ($._elementMode == 'center') {
2561
+ el.style.transform = 'translate(-50%, -50%)';
2562
+ }
2563
+
2564
+ if (content) el.innerHTML = content;
2565
+
2566
+ Object.defineProperty(el, 'x', {
2567
+ get: () => el._x,
2568
+ set: (v) => {
2569
+ let pos = el.style.position;
2570
+ if (!pos || pos == 'relative') {
2571
+ el.style.position = 'absolute';
2572
+ }
2573
+ let x = $.canvas.offsetLeft + v;
2574
+ el.style.left = x + 'px';
2575
+ el._x = x;
2576
+ }
2577
+ });
2578
+
2579
+ Object.defineProperty(el, 'y', {
2580
+ get: () => el._y,
2581
+ set: (v) => {
2582
+ let pos = el.style.position;
2583
+ if (!pos || pos == 'relative') {
2584
+ el.style.position = 'absolute';
2585
+ }
2586
+ let y = $.canvas.offsetTop + v;
2587
+ el.style.top = y + 'px';
2588
+ el._y = y;
2589
+ }
2590
+ });
2591
+
2592
+ Object.defineProperty(el, 'width', {
2593
+ get: () => el.style.width,
2594
+ set: (v) => (el.style.width = v + 'px')
2595
+ });
2596
+
2597
+ Object.defineProperty(el, 'height', {
2598
+ get: () => el.style.height,
2599
+ set: (v) => (el.style.height = v + 'px')
2600
+ });
2601
+
2602
+ el.position = (x, y, scheme) => {
2603
+ if (scheme) el.style.position = scheme;
2604
+ el.x = x;
2605
+ el.y = y;
2606
+ return el;
2607
+ };
2608
+
2609
+ // overwrite size
2610
+ Object.defineProperty(el, 'size', {
2611
+ writable: true
2612
+ });
2613
+
2614
+ el.size = (w, h) => {
2615
+ el.width = w;
2616
+ el.height = h;
2617
+ return el;
2618
+ };
2619
+
2620
+ el.center = () => {
2621
+ el.style.position = 'absolute';
2622
+ el.x = $.canvas.hw;
2623
+ el.y = $.canvas.hh;
2624
+ return el;
2625
+ };
2626
+
2627
+ el.show = () => {
2628
+ el.style.display = 'block';
2629
+ return el;
2630
+ };
2631
+
2632
+ el.hide = () => {
2633
+ el.style.display = 'none';
2634
+ return el;
2635
+ };
2636
+
2637
+ el.parent = (parent) => {
2638
+ parent.append(el);
2639
+ return el;
2640
+ };
2641
+
2642
+ $._elements.push(el);
2643
+ $.canvas.parentElement.append(el);
2644
+
2645
+ return el;
2646
+ };
2647
+ $.createEl = $.createElement;
2648
+
2649
+ $.createA = (href, content, newTab) => {
2650
+ let el = $.createEl('a', content);
2651
+ el.href = href;
2652
+ el.target = newTab ? '_blank' : '_self';
2653
+ return el;
2654
+ };
2655
+
2656
+ $.createButton = (content) => $.createEl('button', content);
2657
+
2658
+ $.createCheckbox = (label = '', checked = false) => {
2659
+ let el = $.createEl('input');
2660
+ el.type = 'checkbox';
2661
+ el.checked = checked;
2662
+ let lbl = $.createEl('label', label);
2663
+ lbl.addEventListener('click', () => {
2664
+ el.checked = !el.checked;
2665
+ el.dispatchEvent(new Event('change', { bubbles: true }));
2666
+ });
2667
+ el.insertAdjacentElement('afterend', lbl);
2668
+ el.label = lbl;
2669
+ return el;
2670
+ };
2671
+
2672
+ $.createColorPicker = (value = '#ffffff') => {
2673
+ let el = $.createEl('input');
2674
+ el.type = 'color';
2675
+ el.value = value.toString();
2676
+ return el;
2677
+ };
2678
+
2679
+ $.createDiv = (content) => $.createEl('div', content);
2680
+
2681
+ $.createImg = (src) => {
2682
+ let el = $.createEl('img');
2683
+ el.crossOrigin = 'anonymous';
2684
+ el.src = src;
2685
+ return el;
2686
+ };
2687
+
2688
+ $.createInput = (value = '', type = 'text') => {
2689
+ let el = $.createEl('input');
2690
+ el.value = value;
2691
+ el.type = type;
2692
+ el.style.boxSizing = 'border-box';
2693
+ return el;
2694
+ };
2695
+
2696
+ $.createP = (content) => $.createEl('p', content);
2697
+
2698
+ let radioCount = 0;
2699
+ $.createRadio = (name) => {
2700
+ let el = $.createEl('div');
2701
+ el.name = name || 'radio' + radioCount++;
2702
+ el.buttons = [];
2703
+ Object.defineProperty(el, 'value', {
2704
+ get: () => el.selected?.value,
2705
+ set: (v) => {
2706
+ let btn = el.buttons.find((b) => b.value == v);
2707
+ if (btn) {
2708
+ btn.checked = true;
2709
+ el.selected = btn;
2710
+ }
2711
+ }
2712
+ });
2713
+ el.option = (label, value) => {
2714
+ let btn = $.createEl('input');
2715
+ btn.type = 'radio';
2716
+ btn.name = el.name;
2717
+ btn.value = value || label;
2718
+ btn.addEventListener('change', () => (el.selected = btn));
2719
+
2720
+ let lbl = $.createEl('label', label);
2721
+ lbl.addEventListener('click', () => {
2722
+ btn.checked = true;
2723
+ el.selected = btn;
2724
+ btn.dispatchEvent(new Event('change', { bubbles: true }));
2725
+ });
2726
+
2727
+ btn.label = lbl;
2728
+ el.append(btn);
2729
+ el.append(lbl);
2730
+ el.buttons.push(btn);
2731
+ return el;
2732
+ };
2733
+
2734
+ return el;
2735
+ };
2736
+
2737
+ $.createSelect = (placeholder) => {
2738
+ let el = $.createEl('select');
2739
+ if (placeholder) {
2740
+ let opt = $.createEl('option', placeholder);
2741
+ opt.disabled = true;
2742
+ opt.selected = true;
2743
+ el.append(opt);
2744
+ }
2745
+ Object.defineProperty(el, 'selected', {
2746
+ get: () => {
2747
+ if (el.multiple) return Array.from(el.selectedOptions);
2748
+ return el.selectedOptions[0];
2749
+ },
2750
+ set: (v) => {
2751
+ if (el.multiple) {
2752
+ el.options.forEach((o) => (o.selected = v.includes(o)));
2753
+ } else {
2754
+ v.selected = true;
2755
+ }
2756
+ }
2757
+ });
2758
+ Object.defineProperty(el, 'value', {
2759
+ get: () => {
2760
+ if (el.multiple) {
2761
+ return Array.from(el.selectedOptions).map((o) => o.value);
2762
+ }
2763
+ return el.selectedOptions[0]?.value;
2764
+ },
2765
+ set: (v) => {
2766
+ if (el.multiple) {
2767
+ el.options.forEach((o) => (o.selected = v.includes(o.value)));
2768
+ } else {
2769
+ let opt;
2770
+ for (let i = 0; i < el.options.length; i++) {
2771
+ if (el.options[i].value == v) {
2772
+ opt = el.options[i];
2773
+ break;
2774
+ }
2775
+ }
2776
+ if (opt) opt.selected = true;
2777
+ }
2778
+ }
2779
+ });
2780
+ el.option = (label, value) => {
2781
+ let opt = $.createEl('option', label);
2782
+ opt.value = value || label;
2783
+ el.append(opt);
2784
+ return el;
2785
+ };
2786
+ return el;
2787
+ };
2788
+
2789
+ $.createSlider = (min, max, value, step) => {
2790
+ let el = $.createEl('input');
2791
+ el.type = 'range';
2792
+ el.min = min;
2793
+ el.max = max;
2794
+ el.value = value;
2795
+ el.step = step;
2796
+ el.val = () => parseFloat(el.value);
2797
+ return el;
2798
+ };
2799
+
2800
+ $.createSpan = (content) => $.createEl('span', content);
2801
+
2802
+ $.createVideo = (src) => {
2803
+ let el = $.createEl('video');
2804
+ el.crossOrigin = 'anonymous';
2805
+ el.src = src;
2806
+ return el;
2807
+ };
2808
+
2809
+ $.findElement = (selector) => document.querySelector(selector);
2810
+ $.findElements = (selector) => document.querySelectorAll(selector);
2811
+ };
2550
2812
  Q5.modules.input = ($, q) => {
2551
2813
  if ($._scope == 'graphics') return;
2552
2814
 
@@ -4954,7 +5216,7 @@ fn fragmentMain(@location(0) color: vec4f) -> @location(0) vec4f {
4954
5216
  $.background = (r, g, b, a) => {
4955
5217
  $.push();
4956
5218
  $.resetMatrix();
4957
- if (r.src) {
5219
+ if (r.canvas) {
4958
5220
  let img = r;
4959
5221
  $._imageMode = 'corner';
4960
5222
  $.image(img, -c.hw, -c.hh, c.w, c.h);