litecanvas 0.80.0 → 0.81.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/README.md +2 -2
- package/dist/dist.dev.js +204 -127
- package/dist/dist.js +189 -116
- package/dist/dist.min.js +1 -1
- package/package.json +3 -3
- package/src/index.js +255 -161
- package/types/index.d.ts +68 -29
- package/types/types.d.ts +67 -46
- package/src/types.js +0 -55
package/dist/dist.js
CHANGED
|
@@ -45,39 +45,33 @@
|
|
|
45
45
|
animate: true
|
|
46
46
|
};
|
|
47
47
|
settings = Object.assign(defaults, settings);
|
|
48
|
-
let _initialized = false, _plugins = [], _canvas, _scale = 1, _ctx, _outline_fix = 0.5, _timeScale = 1, _lastFrameTime, _deltaTime = 1 / 60, _accumulated = 0, _rafid, _fontFamily = "sans-serif", _fontSize = 20, _rng_seed = Date.now(), _colors = defaultPalette, _events = {
|
|
49
|
-
init:
|
|
50
|
-
update:
|
|
51
|
-
draw:
|
|
52
|
-
resized:
|
|
53
|
-
tap:
|
|
54
|
-
untap:
|
|
55
|
-
tapping:
|
|
56
|
-
tapped:
|
|
57
|
-
}, _helpers = {
|
|
58
|
-
settings: Object.assign({}, settings)
|
|
48
|
+
let _initialized = false, _plugins = [], _canvas, _scale = 1, _ctx, _outline_fix = 0.5, _timeScale = 1, _lastFrameTime, _deltaTime = 1 / 60, _accumulated = 0, _rafid, _fontFamily = "sans-serif", _fontSize = 20, _rng_seed = Date.now(), _colors = defaultPalette, _default_sound = [0.5, 0, 1750, , , 0.3, 1, , , , 600, 0.1], _events = {
|
|
49
|
+
init: null,
|
|
50
|
+
update: null,
|
|
51
|
+
draw: null,
|
|
52
|
+
resized: null,
|
|
53
|
+
tap: null,
|
|
54
|
+
untap: null,
|
|
55
|
+
tapping: null,
|
|
56
|
+
tapped: null
|
|
59
57
|
};
|
|
60
58
|
const instance = {
|
|
59
|
+
/** @type {HTMLCanvasElement} */
|
|
60
|
+
CANVAS: null,
|
|
61
61
|
/** @type {number} */
|
|
62
|
-
|
|
62
|
+
W: 0,
|
|
63
63
|
/** @type {number} */
|
|
64
|
-
|
|
65
|
-
/** @type {HTMLCanvasElement} */
|
|
66
|
-
CANVAS: false,
|
|
64
|
+
H: 0,
|
|
67
65
|
/** @type {number} */
|
|
68
|
-
|
|
66
|
+
T: 0,
|
|
69
67
|
/** @type {number} */
|
|
70
|
-
|
|
68
|
+
CX: 0,
|
|
71
69
|
/** @type {number} */
|
|
72
|
-
|
|
70
|
+
CY: 0,
|
|
73
71
|
/** @type {number} */
|
|
74
|
-
|
|
72
|
+
MX: -1,
|
|
75
73
|
/** @type {number} */
|
|
76
|
-
|
|
77
|
-
/** @type {number[]} */
|
|
78
|
-
DEFAULT_SFX: [0.5, 0, 1750, , , 0.3, 1, , , , 600, 0.1],
|
|
79
|
-
/** @type {string[]} */
|
|
80
|
-
COLORS: _colors,
|
|
74
|
+
MY: -1,
|
|
81
75
|
/** MATH API */
|
|
82
76
|
/**
|
|
83
77
|
* Twice the value of the mathematical constant PI (π).
|
|
@@ -194,6 +188,15 @@
|
|
|
194
188
|
norm: (value, start, stop) => {
|
|
195
189
|
return instance.map(value, start, stop, 0, 1);
|
|
196
190
|
},
|
|
191
|
+
/**
|
|
192
|
+
* Interpolate between 2 values using a periodic function.
|
|
193
|
+
*
|
|
194
|
+
* @param {number} from - the lower bound
|
|
195
|
+
* @param {number} to - the higher bound
|
|
196
|
+
* @param {number} t - the amount
|
|
197
|
+
* @param {(n: number) => number} fn - the periodic function (which default to `Math.sin`)
|
|
198
|
+
*/
|
|
199
|
+
wave: (from, to, t, fn = Math.sin) => from + (fn(t) + 1) / 2 * (to - from),
|
|
197
200
|
/** RNG API */
|
|
198
201
|
/**
|
|
199
202
|
* Generates a pseudorandom float between min (inclusive) and max (exclusive)
|
|
@@ -221,14 +224,14 @@
|
|
|
221
224
|
return math.floor(instance.rand(min, max + 1));
|
|
222
225
|
},
|
|
223
226
|
/**
|
|
224
|
-
*
|
|
225
|
-
*
|
|
227
|
+
* Initializes the random number generator with an explicit seed value.
|
|
228
|
+
*
|
|
229
|
+
* Note: The seed should be a integer number greater than or equal to zero.
|
|
226
230
|
*
|
|
227
231
|
* @param {number} value
|
|
228
|
-
* @returns {number} the seed state
|
|
229
232
|
*/
|
|
230
|
-
|
|
231
|
-
|
|
233
|
+
rseed(value) {
|
|
234
|
+
_rng_seed = ~~value;
|
|
232
235
|
},
|
|
233
236
|
/** BASIC GRAPHICS API */
|
|
234
237
|
/**
|
|
@@ -368,7 +371,7 @@
|
|
|
368
371
|
*/
|
|
369
372
|
text(x, y, message, color = 3, fontStyle = "normal") {
|
|
370
373
|
_ctx.font = `${fontStyle} ${_fontSize}px ${_fontFamily}`;
|
|
371
|
-
_ctx.fillStyle =
|
|
374
|
+
_ctx.fillStyle = _colors[~~color % _colors.length];
|
|
372
375
|
_ctx.fillText(message, ~~x, ~~y);
|
|
373
376
|
},
|
|
374
377
|
/**
|
|
@@ -390,8 +393,8 @@
|
|
|
390
393
|
/**
|
|
391
394
|
* Sets the alignment used when drawing texts
|
|
392
395
|
*
|
|
393
|
-
* @param {
|
|
394
|
-
* @param {
|
|
396
|
+
* @param {CanvasTextAlign} align the horizontal alignment. Possible values: "left", "right", "center", "start" or "end"
|
|
397
|
+
* @param {CanvasTextBaseline} baseline the vertical alignment. Possible values: "top", "bottom", "middle", "hanging" or "ideographic"
|
|
395
398
|
* @see https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/textBaseline
|
|
396
399
|
* @see https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/textAlign
|
|
397
400
|
*/
|
|
@@ -418,7 +421,7 @@
|
|
|
418
421
|
* @param {string[]|drawCallback} drawing
|
|
419
422
|
* @param {object} [options]
|
|
420
423
|
* @param {number} [options.scale=1]
|
|
421
|
-
* @param {OffscreenCanvas
|
|
424
|
+
* @param {OffscreenCanvas} [options.canvas]
|
|
422
425
|
* @returns {ImageBitmap}
|
|
423
426
|
* @see https://developer.mozilla.org/en-US/docs/Web/API/OffscreenCanvas
|
|
424
427
|
*/
|
|
@@ -527,7 +530,7 @@
|
|
|
527
530
|
* @param {Path2D} [path]
|
|
528
531
|
*/
|
|
529
532
|
fill(color, path) {
|
|
530
|
-
_ctx.fillStyle =
|
|
533
|
+
_ctx.fillStyle = _colors[~~color % _colors.length];
|
|
531
534
|
if (path) {
|
|
532
535
|
_ctx.fill(path);
|
|
533
536
|
} else {
|
|
@@ -541,7 +544,7 @@
|
|
|
541
544
|
* @param {Path2D} [path]
|
|
542
545
|
*/
|
|
543
546
|
stroke(color, path) {
|
|
544
|
-
_ctx.strokeStyle =
|
|
547
|
+
_ctx.strokeStyle = _colors[~~color % _colors.length];
|
|
545
548
|
if (path) {
|
|
546
549
|
_ctx.stroke(path);
|
|
547
550
|
} else {
|
|
@@ -573,7 +576,7 @@
|
|
|
573
576
|
if (root.zzfxV <= 0 || navigator.userActivation && !navigator.userActivation.hasBeenActive) {
|
|
574
577
|
return false;
|
|
575
578
|
}
|
|
576
|
-
zzfxParams = zzfxParams ||
|
|
579
|
+
zzfxParams = zzfxParams || _default_sound;
|
|
577
580
|
if (pitchSlide !== 0 || volumeFactor !== 1) {
|
|
578
581
|
zzfxParams = zzfxParams.slice();
|
|
579
582
|
zzfxParams[0] = volumeFactor * (zzfxParams[0] || 1);
|
|
@@ -635,26 +638,14 @@
|
|
|
635
638
|
*/
|
|
636
639
|
pal(colors = defaultPalette) {
|
|
637
640
|
_colors = colors;
|
|
638
|
-
instance.setvar("COLORS", _colors);
|
|
639
|
-
},
|
|
640
|
-
/**
|
|
641
|
-
* Get a color by index
|
|
642
|
-
*
|
|
643
|
-
* @param {number} [index=0] The color number
|
|
644
|
-
* @returns {string} the color code
|
|
645
|
-
*/
|
|
646
|
-
getcolor: (index) => {
|
|
647
|
-
return _colors[~~index % _colors.length];
|
|
648
641
|
},
|
|
649
642
|
/**
|
|
650
|
-
*
|
|
643
|
+
* Define or update a instance property.
|
|
651
644
|
*
|
|
652
645
|
* @param {string} key
|
|
653
646
|
* @param {*} value
|
|
654
647
|
*/
|
|
655
|
-
|
|
656
|
-
if (null == value) {
|
|
657
|
-
}
|
|
648
|
+
def(key, value) {
|
|
658
649
|
instance[key] = value;
|
|
659
650
|
if (settings.global) {
|
|
660
651
|
root[key] = value;
|
|
@@ -671,23 +662,67 @@
|
|
|
671
662
|
_timeScale = value;
|
|
672
663
|
},
|
|
673
664
|
/**
|
|
674
|
-
* Set the target FPS
|
|
665
|
+
* Set the target FPS (frames per second).
|
|
675
666
|
*
|
|
676
667
|
* @param {number} value
|
|
677
668
|
*/
|
|
678
|
-
|
|
669
|
+
framerate(value) {
|
|
679
670
|
_deltaTime = 1 / ~~value;
|
|
680
671
|
},
|
|
672
|
+
/**
|
|
673
|
+
* Returns information about that engine instance.
|
|
674
|
+
*
|
|
675
|
+
* n = 0: the settings passed to that instance
|
|
676
|
+
* n = 1: returns true if the "init" event has already been emitted
|
|
677
|
+
* n = 2: the current ID returned by last requestAnimationFrame
|
|
678
|
+
* n = 3: the current canvas element scale (not the context 2D scale)
|
|
679
|
+
* n = 4: the attached event callbacks
|
|
680
|
+
* n = 5: the current color palette
|
|
681
|
+
* n = 6: the default sound used by `sfx()`
|
|
682
|
+
* n = 7: the current time scale
|
|
683
|
+
* n = 8: the current volume used by ZzFX
|
|
684
|
+
* n = 9: the current RNG state
|
|
685
|
+
*
|
|
686
|
+
* n = any other value: returns undefined
|
|
687
|
+
*
|
|
688
|
+
* @param {number} n
|
|
689
|
+
* @returns {any}
|
|
690
|
+
*/
|
|
691
|
+
stat(n) {
|
|
692
|
+
const list = [
|
|
693
|
+
// 0
|
|
694
|
+
settings,
|
|
695
|
+
// 1
|
|
696
|
+
_initialized,
|
|
697
|
+
// 2
|
|
698
|
+
_rafid,
|
|
699
|
+
// 3
|
|
700
|
+
_scale,
|
|
701
|
+
// 4
|
|
702
|
+
_events,
|
|
703
|
+
// 5
|
|
704
|
+
_colors,
|
|
705
|
+
// 6
|
|
706
|
+
_default_sound,
|
|
707
|
+
// 7
|
|
708
|
+
_timeScale,
|
|
709
|
+
// 8
|
|
710
|
+
root.zzfxV || 1,
|
|
711
|
+
// 9
|
|
712
|
+
_rng_seed
|
|
713
|
+
];
|
|
714
|
+
return list[n];
|
|
715
|
+
},
|
|
681
716
|
/**
|
|
682
717
|
* Stops the litecanvas instance and remove all event listeners.
|
|
683
718
|
*/
|
|
684
719
|
quit() {
|
|
685
720
|
cancelAnimationFrame(_rafid);
|
|
686
721
|
instance.emit("quit");
|
|
687
|
-
_events = [];
|
|
688
722
|
for (const removeListener of _browserEventListeners) {
|
|
689
723
|
removeListener();
|
|
690
724
|
}
|
|
725
|
+
_events = {};
|
|
691
726
|
if (settings.global) {
|
|
692
727
|
for (const key in instance) {
|
|
693
728
|
delete root[key];
|
|
@@ -700,7 +735,6 @@
|
|
|
700
735
|
instance[k] = math[k];
|
|
701
736
|
}
|
|
702
737
|
function init() {
|
|
703
|
-
_initialized = true;
|
|
704
738
|
const source = settings.loop ? settings.loop : root;
|
|
705
739
|
for (const event in _events) {
|
|
706
740
|
if (source[event]) instance.listen(event, source[event]);
|
|
@@ -732,55 +766,90 @@
|
|
|
732
766
|
tap.y = y;
|
|
733
767
|
}, _checkTapped = (tap) => tap && performance.now() - tap.ts <= 300, preventDefault = (ev) => ev.preventDefault();
|
|
734
768
|
let _pressingMouse = false;
|
|
735
|
-
on(
|
|
736
|
-
|
|
769
|
+
on(
|
|
770
|
+
_canvas,
|
|
771
|
+
"mousedown",
|
|
772
|
+
/**
|
|
773
|
+
* @param {MouseEvent} ev
|
|
774
|
+
*/
|
|
775
|
+
(ev) => {
|
|
776
|
+
if (ev.button === 0) {
|
|
777
|
+
preventDefault(ev);
|
|
778
|
+
const [x, y] = _getXY(ev.pageX, ev.pageY);
|
|
779
|
+
instance.emit("tap", x, y, 0);
|
|
780
|
+
_registerTap(0, x, y);
|
|
781
|
+
_pressingMouse = true;
|
|
782
|
+
}
|
|
783
|
+
}
|
|
784
|
+
);
|
|
785
|
+
on(
|
|
786
|
+
_canvas,
|
|
787
|
+
"mouseup",
|
|
788
|
+
/**
|
|
789
|
+
* @param {MouseEvent} ev
|
|
790
|
+
*/
|
|
791
|
+
(ev) => {
|
|
792
|
+
if (ev.button === 0) {
|
|
793
|
+
preventDefault(ev);
|
|
794
|
+
const tap = _taps.get(0);
|
|
795
|
+
const [x, y] = _getXY(ev.pageX, ev.pageY);
|
|
796
|
+
if (_checkTapped(tap)) {
|
|
797
|
+
instance.emit("tapped", tap.startX, tap.startY, 0);
|
|
798
|
+
}
|
|
799
|
+
instance.emit("untap", x, y, 0);
|
|
800
|
+
_taps.delete(0);
|
|
801
|
+
_pressingMouse = false;
|
|
802
|
+
}
|
|
803
|
+
}
|
|
804
|
+
);
|
|
805
|
+
on(
|
|
806
|
+
_canvas,
|
|
807
|
+
"mousemove",
|
|
808
|
+
/**
|
|
809
|
+
* @param {MouseEvent} ev
|
|
810
|
+
*/
|
|
811
|
+
(ev) => {
|
|
737
812
|
preventDefault(ev);
|
|
738
813
|
const [x, y] = _getXY(ev.pageX, ev.pageY);
|
|
739
|
-
instance.
|
|
740
|
-
|
|
741
|
-
_pressingMouse
|
|
814
|
+
instance.def("MX", x);
|
|
815
|
+
instance.def("MY", y);
|
|
816
|
+
if (!_pressingMouse) return;
|
|
817
|
+
instance.emit("tapping", x, y, 0);
|
|
818
|
+
_updateTap(0, x, y);
|
|
742
819
|
}
|
|
743
|
-
|
|
744
|
-
on(
|
|
745
|
-
|
|
820
|
+
);
|
|
821
|
+
on(
|
|
822
|
+
_canvas,
|
|
823
|
+
"touchstart",
|
|
824
|
+
/**
|
|
825
|
+
* @param {TouchEvent} ev
|
|
826
|
+
*/
|
|
827
|
+
(ev) => {
|
|
746
828
|
preventDefault(ev);
|
|
747
|
-
const
|
|
748
|
-
const
|
|
749
|
-
|
|
750
|
-
instance.emit("
|
|
829
|
+
const touches = ev.changedTouches;
|
|
830
|
+
for (const touch of touches) {
|
|
831
|
+
const [x, y] = _getXY(touch.pageX, touch.pageY);
|
|
832
|
+
instance.emit("tap", x, y, touch.identifier + 1);
|
|
833
|
+
_registerTap(touch.identifier + 1, x, y);
|
|
751
834
|
}
|
|
752
|
-
instance.emit("untap", x, y, 0);
|
|
753
|
-
_taps.delete(0);
|
|
754
|
-
_pressingMouse = false;
|
|
755
|
-
}
|
|
756
|
-
});
|
|
757
|
-
on(_canvas, "mousemove", (ev) => {
|
|
758
|
-
preventDefault(ev);
|
|
759
|
-
const [x, y] = _getXY(ev.pageX, ev.pageY);
|
|
760
|
-
instance.setvar("MOUSEX", x);
|
|
761
|
-
instance.setvar("MOUSEY", y);
|
|
762
|
-
if (!_pressingMouse) return;
|
|
763
|
-
instance.emit("tapping", x, y, 0);
|
|
764
|
-
_updateTap(0, x, y);
|
|
765
|
-
});
|
|
766
|
-
on(_canvas, "touchstart", (ev) => {
|
|
767
|
-
preventDefault(ev);
|
|
768
|
-
const touches = ev.changedTouches;
|
|
769
|
-
for (const touch of touches) {
|
|
770
|
-
const [x, y] = _getXY(touch.pageX, touch.pageY);
|
|
771
|
-
instance.emit("tap", x, y, touch.identifier + 1);
|
|
772
|
-
_registerTap(touch.identifier + 1, x, y);
|
|
773
835
|
}
|
|
774
|
-
|
|
775
|
-
on(
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
836
|
+
);
|
|
837
|
+
on(
|
|
838
|
+
_canvas,
|
|
839
|
+
"touchmove",
|
|
840
|
+
/**
|
|
841
|
+
* @param {TouchEvent} ev
|
|
842
|
+
*/
|
|
843
|
+
(ev) => {
|
|
844
|
+
preventDefault(ev);
|
|
845
|
+
const touches = ev.changedTouches;
|
|
846
|
+
for (const touch of touches) {
|
|
847
|
+
const [x, y] = _getXY(touch.pageX, touch.pageY);
|
|
848
|
+
instance.emit("tapping", x, y, touch.identifier + 1);
|
|
849
|
+
_updateTap(touch.identifier + 1, x, y);
|
|
850
|
+
}
|
|
782
851
|
}
|
|
783
|
-
|
|
852
|
+
);
|
|
784
853
|
const _touchEndHandler = (ev) => {
|
|
785
854
|
preventDefault(ev);
|
|
786
855
|
const existing = [];
|
|
@@ -828,7 +897,7 @@
|
|
|
828
897
|
});
|
|
829
898
|
on(root, "blur", () => _keysDown.clear());
|
|
830
899
|
instance.listen("after:draw", () => _keysPress.clear());
|
|
831
|
-
instance.
|
|
900
|
+
instance.def(
|
|
832
901
|
"iskeydown",
|
|
833
902
|
/**
|
|
834
903
|
* Checks if a which key is pressed (down) on the keyboard.
|
|
@@ -841,7 +910,7 @@
|
|
|
841
910
|
return keyCheck(_keysDown, key);
|
|
842
911
|
}
|
|
843
912
|
);
|
|
844
|
-
instance.
|
|
913
|
+
instance.def(
|
|
845
914
|
"iskeypressed",
|
|
846
915
|
/**
|
|
847
916
|
* Checks if a which key just got pressed on the keyboard.
|
|
@@ -866,6 +935,7 @@
|
|
|
866
935
|
}
|
|
867
936
|
});
|
|
868
937
|
}
|
|
938
|
+
_initialized = true;
|
|
869
939
|
instance.emit("init", instance);
|
|
870
940
|
_lastFrameTime = performance.now();
|
|
871
941
|
_rafid = raf(drawFrame);
|
|
@@ -881,10 +951,7 @@
|
|
|
881
951
|
_accumulated += frameTime;
|
|
882
952
|
while (_accumulated >= _deltaTime) {
|
|
883
953
|
instance.emit("update", _deltaTime * _timeScale);
|
|
884
|
-
instance.
|
|
885
|
-
"ELAPSED",
|
|
886
|
-
instance.ELAPSED + _deltaTime * _timeScale
|
|
887
|
-
);
|
|
954
|
+
instance.def("T", instance.T + _deltaTime * _timeScale);
|
|
888
955
|
updated++;
|
|
889
956
|
_accumulated -= _deltaTime;
|
|
890
957
|
}
|
|
@@ -897,39 +964,45 @@
|
|
|
897
964
|
}
|
|
898
965
|
}
|
|
899
966
|
function setupCanvas() {
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
967
|
+
if ("string" === typeof settings.canvas) {
|
|
968
|
+
_canvas = document.querySelector(settings.canvas);
|
|
969
|
+
} else {
|
|
970
|
+
_canvas = settings.canvas || document.createElement("canvas");
|
|
971
|
+
}
|
|
972
|
+
instance.def("CANVAS", _canvas);
|
|
903
973
|
_ctx = _canvas.getContext("2d");
|
|
904
974
|
on(_canvas, "click", () => root.focus());
|
|
905
975
|
_canvas.style = "";
|
|
906
976
|
resizeCanvas();
|
|
907
|
-
if (!_canvas.parentNode)
|
|
977
|
+
if (!_canvas.parentNode) {
|
|
978
|
+
document.body.appendChild(_canvas);
|
|
979
|
+
}
|
|
908
980
|
}
|
|
909
981
|
function resizeCanvas() {
|
|
910
982
|
const width = settings.width || root.innerWidth, height = settings.height || settings.width || root.innerHeight;
|
|
911
|
-
instance.
|
|
912
|
-
instance.
|
|
913
|
-
instance.
|
|
914
|
-
instance.
|
|
983
|
+
instance.def("W", _canvas.width = width);
|
|
984
|
+
instance.def("H", _canvas.height = height);
|
|
985
|
+
instance.def("CX", instance.W / 2);
|
|
986
|
+
instance.def("CY", instance.H / 2);
|
|
915
987
|
if (settings.autoscale) {
|
|
916
988
|
if (!_canvas.style.display) {
|
|
917
989
|
_canvas.style.display = "block";
|
|
918
990
|
_canvas.style.margin = "auto";
|
|
919
991
|
}
|
|
920
992
|
_scale = math.min(
|
|
921
|
-
root.innerWidth / instance.
|
|
922
|
-
root.innerHeight / instance.
|
|
993
|
+
root.innerWidth / instance.W,
|
|
994
|
+
root.innerHeight / instance.H
|
|
923
995
|
);
|
|
924
996
|
_scale = (settings.pixelart ? ~~_scale : _scale) || 1;
|
|
925
|
-
_canvas.style.width = instance.
|
|
926
|
-
_canvas.style.height = instance.
|
|
997
|
+
_canvas.style.width = instance.W * _scale + "px";
|
|
998
|
+
_canvas.style.height = instance.H * _scale + "px";
|
|
927
999
|
}
|
|
928
1000
|
if (!settings.antialias || settings.pixelart) {
|
|
929
1001
|
_ctx.imageSmoothingEnabled = false;
|
|
930
1002
|
_canvas.style.imageRendering = "pixelated";
|
|
931
1003
|
}
|
|
932
1004
|
instance.emit("resized", _scale);
|
|
1005
|
+
instance.cls(0);
|
|
933
1006
|
if (!settings.animate) {
|
|
934
1007
|
raf(drawFrame);
|
|
935
1008
|
}
|
|
@@ -941,9 +1014,9 @@
|
|
|
941
1014
|
}
|
|
942
1015
|
}
|
|
943
1016
|
function loadPlugin(callback, config) {
|
|
944
|
-
const pluginData = callback(instance,
|
|
1017
|
+
const pluginData = callback(instance, config);
|
|
945
1018
|
for (const key in pluginData) {
|
|
946
|
-
instance.
|
|
1019
|
+
instance.def(key, pluginData[key]);
|
|
947
1020
|
}
|
|
948
1021
|
}
|
|
949
1022
|
if (settings.global) {
|
package/dist/dist.min.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
(()=>{var e=new AudioContext,t=(t=1,a=.05,
|
|
1
|
+
(()=>{var e=new AudioContext,t=(t=1,a=.05,l=220,n=0,i=0,r=.1,o=0,s=1,f=0,c=0,d=0,u=0,p=0,h=0,g=0,m=0,b=0,v=1,w=0,x=0,y=0)=>{let k=Math,E=2*k.PI,T=f*=500*E/44100/44100,A=l*=(1-a+2*a*k.random(a=[]))*E/44100,C=0,z=0,I=0,P=1,S=0,X=0,Y=0,M=y<0?-1:1,N=E*M*y*2/44100,H=k.cos(N),W=k.sin,B=W(N)/4,D=1+B,F=-2*H/D,L=(1-B)/D,O=(1+M*H)/2/D,V=-(M+H)/D,q=0,R=0,G=0,$=0;for(n=44100*n+9,w*=44100,i*=44100,r*=44100,b*=44100,c*=500*E/85766121e6,g*=E/44100,d*=E/44100,u*=44100,p=44100*p|0,t*=.3*(globalThis.zzfxV||1),M=n+w+i+r+b|0;I<M;a[I++]=Y*t)++X%(100*m|0)||(Y=o?1<o?2<o?3<o?W(C*C):k.max(k.min(k.tan(C),1),-1):1-(2*C/E%2+2)%2:1-4*k.abs(k.round(C/E)-C/E):W(C),Y=(p?1-x+x*W(E*I/p):1)*(Y<0?-1:1)*k.abs(Y)**s*(I<n?I/n:I<n+w?1-(I-n)/w*(1-v):I<n+w+i?v:I<M-b?(M-I-b)/r*v:0),Y=b?Y/2+(b>I?0:(I<M-b?1:(M-I)/b)*a[I-b|0]/2/t):Y,y&&(Y=$=O*q+V*(q=R)+O*(R=Y)-L*G-F*(G=$))),C+=(N=(l+=f+=c)*k.cos(g*z++))+N*h*W(I**5),P&&++P>u&&(l+=d,A+=d,P=0),!p||++S%p||(l=A,f=T,P=P||1);(t=e.createBuffer(1,M,44100)).getChannelData(0).set(a),(l=e.createBufferSource()).buffer=t,l.connect(e.destination),l.start()},a=["#111","#6a7799","#aec2c2","#FFF1E8","#e83b3b","#fabc20","#155fd9","#3cbcfc","#327345","#63c64d","#6c2c1f","#ac7c00"];globalThis.litecanvas=function(e={}){let l=globalThis,n=Math,i=2*n.PI,r=requestAnimationFrame,o=[],s=(e,t,a)=>{e.addEventListener(t,a,!1),o.push(()=>e.removeEventListener(t,a,!1))};e=Object.assign({width:null,height:null,autoscale:!0,pixelart:!1,antialias:!1,canvas:null,global:!0,loop:null,pauseOnBlur:!0,tapEvents:!0,keyboardEvents:!0,animate:!0},e);let f=!1,c=[],d,u=1,p,h=.5,g=1,m,b=1/60,v=0,w,x="sans-serif",y=20,k=Date.now(),E=a,T=[.5,0,1750,,,.3,1,,,,600,.1],A={init:null,update:null,draw:null,resized:null,tap:null,untap:null,tapping:null,tapped:null},C={CANVAS:null,W:0,H:0,T:0,CX:0,CY:0,MX:-1,MY:-1,TWO_PI:i,HALF_PI:n.PI/2,lerp:(e,t,a)=>a*(t-e)+e,deg2rad:e=>n.PI/180*e,rad2deg:e=>180/n.PI*e,round:(e,t=0)=>{if(!t)return n.round(e);let a=10**t;return n.round(e*a)/a},clamp:(e,t,a)=>e<t?t:e>a?a:e,wrap:(e,t,a)=>e-(a-t)*n.floor((e-t)/(a-t)),map(e,t,a,l,n,i){let r=(e-t)/(a-t)*(n-l)+l;return i?C.clamp(r,l,n):r},norm:(e,t,a)=>C.map(e,t,a,0,1),wave:(e,t,a,l=Math.sin)=>e+(l(a)+1)/2*(t-e),rand:(e=0,t=1)=>(k=(1664525*k+0x3c6ef35f)%0x100000000)/0x100000000*(t-e)+e,randi:(e=0,t=1)=>n.floor(C.rand(e,t+1)),rseed(e){k=~~e},cls(e){null==e?p.clearRect(0,0,p.canvas.width,p.canvas.height):C.rectfill(0,0,p.canvas.width,p.canvas.height,e)},rect(e,t,a,l,n,i){p.beginPath(),p[i?"roundRect":"rect"](~~e-h,~~t-h,~~a+2*h,~~l+2*h,i),C.stroke(n)},rectfill(e,t,a,l,n,i){p.beginPath(),p[i?"roundRect":"rect"](~~e,~~t,~~a,~~l,i),C.fill(n)},circ(e,t,a,l){p.beginPath(),p.arc(~~e,~~t,~~a,0,i),C.stroke(l)},circfill(e,t,a,l){p.beginPath(),p.arc(~~e,~~t,~~a,0,i),C.fill(l)},line(e,t,a,l,n){p.beginPath();let i=.5*(0!==h&&~~e==~~a),r=.5*(0!==h&&~~t==~~l);p.moveTo(~~e+i,~~t+r),p.lineTo(~~a+i,~~l+r),C.stroke(n)},linewidth(e){p.lineWidth=~~e,h=.5*(0!=~~e%2)},linedash(e,t=0){p.setLineDash(e),p.lineDashOffset=t},text(e,t,a,l=3,n="normal"){p.font=`${n} ${y}px ${x}`,p.fillStyle=E[~~l%E.length],p.fillText(a,~~e,~~t)},textfont(e){x=e},textsize(e){y=e},textalign(e,t){e&&(p.textAlign=e),t&&(p.textBaseline=t)},image(e,t,a){p.drawImage(a,~~e,~~t)},paint(e,t,a,l={}){let n=l.canvas||new OffscreenCanvas(1,1),i=l.scale||1,r=p;if(n.width=e*i,n.height=t*i,(p=n.getContext("2d")).scale(i,i),a.push){let e=0,t=0;for(let l of(p.imageSmoothingEnabled=!1,a)){for(let a of l)" "!==a&&"."!==a&&C.rectfill(e,t,1,1,parseInt(a,16)),e++;t++,e=0}}else a(p);return p=r,n.transferToImageBitmap()},ctx:e=>(e&&(p=e),p),push:()=>p.save(),pop:()=>p.restore(),translate:(e,t)=>p.translate(~~e,~~t),scale:(e,t)=>p.scale(e,t||e),rotate:e=>p.rotate(e),alpha(e){p.globalAlpha=C.clamp(e,0,1)},path:e=>new Path2D(e),fill(e,t){p.fillStyle=E[~~e%E.length],t?p.fill(t):p.fill()},stroke(e,t){p.strokeStyle=E[~~e%E.length],t?p.stroke(t):p.stroke()},clip(e){p.clip(e)},sfx:(e,a=0,n=1)=>!(l.zzfxV<=0)&&(!navigator.userActivation||!!navigator.userActivation.hasBeenActive)&&(e=e||T,(0!==a||1!==n)&&((e=e.slice())[0]=n*(e[0]||1),e[10]=~~e[10]+a),t.apply(0,e),e),volume(e){l.zzfxV=e},use(e,t={}){f?X(e,t):c.push([e,t])},listen:(e,t)=>(A[e]=A[e]||new Set,A[e].add(t),()=>A[e].delete(t)),emit(e,t,a,l,n){f&&(S("before:"+e,t,a,l,n),S(e,t,a,l,n),S("after:"+e,t,a,l,n))},pal(e=a){E=e},def(t,a){C[t]=a,e.global&&(l[t]=a)},timescale(e){g=e},framerate(e){b=1/~~e},stat:t=>[e,f,w,u,A,E,T,g,l.zzfxV||1,k][t],quit(){for(let e of(cancelAnimationFrame(w),C.emit("quit"),o))e();if(A={},e.global){for(let e in C)delete l[e];delete l.ENGINE}}};for(let e of"PI,sin,cos,atan2,hypot,tan,abs,ceil,floor,trunc,min,max,pow,sqrt,sign,exp".split(","))C[e]=n[e];function z(){let t=e.loop?e.loop:l;for(let e in A)t[e]&&C.listen(e,t[e]);for(let[e,t]of c)X(e,t);if(e.autoscale&&s(l,"resize",P),e.tapEvents){let e=(e,t)=>[(e-d.offsetLeft)/u,(t-d.offsetTop)/u],t=new Map,a=(e,a,l)=>{let n={x:a,y:l,startX:a,startY:l,ts:performance.now()};return t.set(e,n),n},n=(e,l,n)=>{let i=t.get(e)||a(e);i.x=l,i.y=n},i=e=>e&&performance.now()-e.ts<=300,r=e=>e.preventDefault(),o=!1;s(d,"mousedown",t=>{if(0===t.button){r(t);let[l,n]=e(t.pageX,t.pageY);C.emit("tap",l,n,0),a(0,l,n),o=!0}}),s(d,"mouseup",a=>{if(0===a.button){r(a);let l=t.get(0),[n,s]=e(a.pageX,a.pageY);i(l)&&C.emit("tapped",l.startX,l.startY,0),C.emit("untap",n,s,0),t.delete(0),o=!1}}),s(d,"mousemove",t=>{r(t);let[a,l]=e(t.pageX,t.pageY);C.def("MX",a),C.def("MY",l),o&&(C.emit("tapping",a,l,0),n(0,a,l))}),s(d,"touchstart",t=>{for(let l of(r(t),t.changedTouches)){let[t,n]=e(l.pageX,l.pageY);C.emit("tap",t,n,l.identifier+1),a(l.identifier+1,t,n)}}),s(d,"touchmove",t=>{for(let a of(r(t),t.changedTouches)){let[t,l]=e(a.pageX,a.pageY);C.emit("tapping",t,l,a.identifier+1),n(a.identifier+1,t,l)}});let f=e=>{r(e);let a=[];if(e.targetTouches.length>0)for(let t of e.targetTouches)a.push(t.identifier+1);for(let[e,l]of t)a.includes(e)||(i(l)&&C.emit("tapped",l.startX,l.startY,e),C.emit("untap",l.x,l.y,e),t.delete(e))};s(d,"touchend",f),s(d,"touchcancel",f),s(l,"blur",()=>{for(let[e,a]of(o=!1,t))C.emit("untap",a.x,a.y,e),t.delete(e)})}if(e.keyboardEvents){let e=e=>e.toLowerCase(),t=new Set,a=new Set,n=(t,a)=>a?t.has("space"===e(a)?" ":e(a)):t.size>0;s(l,"keydown",l=>{t.has(e(l.key))||(t.add(e(l.key)),a.add(e(l.key)))}),s(l,"keyup",a=>{t.delete(e(a.key))}),s(l,"blur",()=>t.clear()),C.listen("after:draw",()=>a.clear()),C.def("iskeydown",e=>n(t,e)),C.def("iskeypressed",e=>n(a,e))}e.pauseOnBlur&&(s(l,"blur",()=>{w=cancelAnimationFrame(w)}),s(l,"focus",()=>{w||(v=0,w=r(I))})),f=!0,C.emit("init",C),m=performance.now(),w=r(I)}function I(t){let a=0,l=(t-m)/1e3;if(m=t,e.animate){if(w=r(I),l>.3)return;for(v+=l;v>=b;)C.emit("update",b*g),C.def("T",C.T+b*g),a++,v-=b}else a=1;a&&(C.textalign("start","top"),C.emit("draw"))}function P(){let t=e.width||l.innerWidth,a=e.height||e.width||l.innerHeight;C.def("W",d.width=t),C.def("H",d.height=a),C.def("CX",C.W/2),C.def("CY",C.H/2),e.autoscale&&(d.style.display||(d.style.display="block",d.style.margin="auto"),u=n.min(l.innerWidth/C.W,l.innerHeight/C.H),u=(e.pixelart?~~u:u)||1,d.style.width=C.W*u+"px",d.style.height=C.H*u+"px"),(!e.antialias||e.pixelart)&&(p.imageSmoothingEnabled=!1,d.style.imageRendering="pixelated"),C.emit("resized",u),C.cls(0),e.animate||r(I)}function S(e,t,a,l,n){if(A[e])for(let i of A[e])i(t,a,l,n)}function X(e,t){let a=e(C,t);for(let e in a)C.def(e,a[e])}if(e.global){if(l.ENGINE)throw Error("two global litecanvas detected");Object.assign(l,C),l.ENGINE=C}return d="string"==typeof e.canvas?document.querySelector(e.canvas):e.canvas||document.createElement("canvas"),C.def("CANVAS",d),p=d.getContext("2d"),s(d,"click",()=>l.focus()),d.style="",P(),d.parentNode||document.body.appendChild(d),"loading"===document.readyState?s(l,"DOMContentLoaded",()=>r(z)):r(z),C}})();
|
package/package.json
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "litecanvas",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.81.0",
|
|
4
4
|
"description": "Lightweight HTML5 canvas 2D game engine suitable for small projects and creative coding. Inspired by PICO-8 and P5/Processing.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Luiz Bills <luizbills@pm.me>",
|
|
7
7
|
"contributors": [],
|
|
8
8
|
"devDependencies": {
|
|
9
|
-
"@swc/core": "^1.11.
|
|
10
|
-
"ava": "^6.
|
|
9
|
+
"@swc/core": "^1.11.31",
|
|
10
|
+
"ava": "^6.4.0",
|
|
11
11
|
"esbuild": "^0.25.5",
|
|
12
12
|
"gzip-size": "^7.0.0",
|
|
13
13
|
"prettier": "^3.5.3"
|