@mulsense/xnew 0.5.1 → 0.5.3

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/xnew.mjs CHANGED
@@ -103,7 +103,6 @@ class AnimationTicker {
103
103
  const self = this;
104
104
  this.id = null;
105
105
  let previous = 0;
106
- ticker();
107
106
  function ticker() {
108
107
  const delta = Date.now() - previous;
109
108
  if (delta > (1000 / fps) * 0.9) {
@@ -112,6 +111,7 @@ class AnimationTicker {
112
111
  }
113
112
  self.id = requestAnimationFrame(ticker);
114
113
  }
114
+ self.id = requestAnimationFrame(ticker);
115
115
  }
116
116
  clear() {
117
117
  if (this.id !== null) {
@@ -122,7 +122,6 @@ class AnimationTicker {
122
122
  }
123
123
  class Timer {
124
124
  constructor(options) {
125
- var _a, _b;
126
125
  this.options = options;
127
126
  this.id = null;
128
127
  this.time = 0.0;
@@ -138,17 +137,17 @@ class Timer {
138
137
  else if (this.options.easing === 'ease-in') {
139
138
  p = Math.pow((1.0 - Math.pow((1.0 - p), 0.5)), 2.0);
140
139
  }
141
- else if (this.options.easing === 'ease') {
142
- p = (1.0 - Math.cos(p * Math.PI)) / 2.0; // todo
143
- }
144
- else if (this.options.easing === 'ease-in-out') {
145
- p = (1.0 - Math.cos(p * Math.PI)) / 2.0;
140
+ else if (this.options.easing === 'ease' || this.options.easing === 'ease-in-out') {
141
+ // p = (1.0 - Math.cos(p * Math.PI)) / 2.0;
142
+ const bias = (this.options.easing === 'ease') ? 0.7 : 1.0;
143
+ const s = Math.pow(p, bias);
144
+ p = s * s * (3 - 2 * s);
146
145
  }
147
146
  (_b = (_a = this.options).transition) === null || _b === void 0 ? void 0 : _b.call(_a, p);
148
147
  });
149
148
  this.visibilitychange = () => document.hidden === false ? this._start() : this._stop();
150
149
  document.addEventListener('visibilitychange', this.visibilitychange);
151
- (_b = (_a = this.options).transition) === null || _b === void 0 ? void 0 : _b.call(_a, 0.0);
150
+ // this.options.transition?.(0.0);
152
151
  this.start();
153
152
  }
154
153
  clear() {
@@ -200,7 +199,7 @@ class Timer {
200
199
  }
201
200
  }
202
201
 
203
- class EventManager {
202
+ class Eventor {
204
203
  constructor() {
205
204
  this.map = new MapMap();
206
205
  }
@@ -520,12 +519,93 @@ function pointer(element, event) {
520
519
  // utils
521
520
  //----------------------------------------------------------------------------------------------------
522
521
  const SYSTEM_EVENTS = ['start', 'update', 'render', 'stop', 'finalize'];
522
+ class UnitPromise {
523
+ constructor(promise, component) {
524
+ this.promise = promise;
525
+ this.component = component;
526
+ }
527
+ then(callback) {
528
+ const snapshot = Unit.snapshot(Unit.currentUnit);
529
+ this.promise = this.promise.then((...args) => Unit.scope(snapshot, callback, ...args));
530
+ return this;
531
+ }
532
+ catch(callback) {
533
+ const snapshot = Unit.snapshot(Unit.currentUnit);
534
+ this.promise = this.promise.catch((...args) => Unit.scope(snapshot, callback, ...args));
535
+ return this;
536
+ }
537
+ finally(callback) {
538
+ const snapshot = Unit.snapshot(Unit.currentUnit);
539
+ this.promise = this.promise.finally(() => Unit.scope(snapshot, callback));
540
+ return this;
541
+ }
542
+ }
543
+ class UnitTimer {
544
+ constructor(options) {
545
+ this.stack = [];
546
+ this.unit = new Unit(Unit.currentUnit, null, UnitTimer.Component, { options, snapshot: Unit.snapshot(Unit.currentUnit) });
547
+ }
548
+ clear() {
549
+ this.stack = [];
550
+ this.unit.finalize();
551
+ }
552
+ timeout(timeout, duration = 0) {
553
+ UnitTimer.execute(this, { timeout, duration, iterations: 1 });
554
+ return this;
555
+ }
556
+ iteration(timeout, duration = 0, iterations = -1) {
557
+ UnitTimer.execute(this, { timeout, duration, iterations });
558
+ return this;
559
+ }
560
+ transition(transition, duration = 0, easing) {
561
+ UnitTimer.execute(this, { transition, duration, iterations: 1, easing });
562
+ return this;
563
+ }
564
+ static execute(timer, options) {
565
+ if (timer.unit._.state === 'finalized') {
566
+ timer.unit = new Unit(Unit.currentUnit, null, UnitTimer.Component, { options, snapshot: Unit.snapshot(Unit.currentUnit) });
567
+ }
568
+ else if (timer.stack.length === 0) {
569
+ timer.stack.push({ options, snapshot: Unit.snapshot(Unit.currentUnit) });
570
+ timer.unit.on('finalize', () => UnitTimer.next(timer));
571
+ }
572
+ else {
573
+ timer.stack.push({ options, snapshot: Unit.snapshot(Unit.currentUnit) });
574
+ }
575
+ }
576
+ static next(timer) {
577
+ if (timer.stack.length > 0) {
578
+ timer.unit = new Unit(Unit.currentUnit, null, UnitTimer.Component, timer.stack.shift());
579
+ timer.unit.on('finalize', () => UnitTimer.next(timer));
580
+ }
581
+ }
582
+ static Component(unit, { options, snapshot }) {
583
+ let counter = 0;
584
+ const timer = new Timer({
585
+ transition: (p) => {
586
+ if (options.transition)
587
+ Unit.scope(snapshot, options.transition, p);
588
+ },
589
+ timeout: () => {
590
+ if (options.transition)
591
+ Unit.scope(snapshot, options.transition, 1.0);
592
+ if (options.timeout)
593
+ Unit.scope(snapshot, options.timeout);
594
+ if (options.iterations && counter >= options.iterations - 1) {
595
+ unit.finalize();
596
+ }
597
+ counter++;
598
+ }, duration: options.duration, iterations: options.iterations, easing: options.easing
599
+ });
600
+ unit.on('finalize', () => timer.clear());
601
+ }
602
+ }
523
603
  //----------------------------------------------------------------------------------------------------
524
604
  // unit
525
605
  //----------------------------------------------------------------------------------------------------
526
606
  class Unit {
527
- constructor(parent, target, component, props, config) {
528
- var _a, _b;
607
+ constructor(parent, target, component, props) {
608
+ var _a;
529
609
  let baseElement;
530
610
  if (target instanceof HTMLElement || target instanceof SVGElement) {
531
611
  baseElement = target;
@@ -540,15 +620,14 @@ class Unit {
540
620
  if (typeof component === 'function') {
541
621
  baseComponent = component;
542
622
  }
543
- else if (typeof component === 'string') {
544
- baseComponent = (unit) => { unit.element.textContent = component; };
623
+ else if (component !== undefined) {
624
+ baseComponent = (unit) => { unit.element.textContent = component.toString(); };
545
625
  }
546
626
  else {
547
627
  baseComponent = (unit) => { };
548
628
  }
549
629
  const baseContext = (_a = parent === null || parent === void 0 ? void 0 : parent._.currentContext) !== null && _a !== void 0 ? _a : { stack: null };
550
- const protect = (_b = config === null || config === void 0 ? void 0 : config.protect) !== null && _b !== void 0 ? _b : false;
551
- this._ = { parent, target, baseElement, baseContext, baseComponent, props, config: { protect } };
630
+ this._ = { parent, target, baseElement, baseContext, baseComponent, props };
552
631
  parent === null || parent === void 0 ? void 0 : parent._.children.push(this);
553
632
  Unit.initialize(this, null);
554
633
  }
@@ -577,7 +656,6 @@ class Unit {
577
656
  Unit.initialize(this, anchor);
578
657
  }
579
658
  static initialize(unit, anchor) {
580
- var _a, _b;
581
659
  const backup = Unit.currentUnit;
582
660
  Unit.currentUnit = unit;
583
661
  unit._ = Object.assign(unit._, {
@@ -587,7 +665,8 @@ class Unit {
587
665
  anchor,
588
666
  state: 'invoked',
589
667
  tostart: true,
590
- ancestors: [...(unit._.parent ? [unit._.parent] : []), ...((_b = (_a = unit._.parent) === null || _a === void 0 ? void 0 : _a._.ancestors) !== null && _b !== void 0 ? _b : [])],
668
+ protected: false,
669
+ ancestors: unit._.parent ? [unit._.parent, ...unit._.parent._.ancestors] : [],
591
670
  children: [],
592
671
  elements: [],
593
672
  promises: [],
@@ -595,7 +674,7 @@ class Unit {
595
674
  listeners: new MapMap(),
596
675
  defines: {},
597
676
  systems: { start: [], update: [], render: [], stop: [], finalize: [] },
598
- eventManager: new EventManager(),
677
+ eventor: new Eventor(),
599
678
  });
600
679
  // nest html element
601
680
  if (typeof unit._.target === 'string') {
@@ -628,11 +707,8 @@ class Unit {
628
707
  unit._.state = 'finalized';
629
708
  }
630
709
  }
631
- static nest(unit, htmlString, textContent) {
632
- if (unit._.state !== 'invoked') {
633
- throw new Error('This function can not be called after initialized.');
634
- }
635
- const match = htmlString.match(/<((\w+)[^>]*?)\/?>/);
710
+ static nest(unit, tag, textContent) {
711
+ const match = tag.match(/<((\w+)[^>]*?)\/?>/);
636
712
  if (match !== null) {
637
713
  let element;
638
714
  if (unit._.anchor !== null) {
@@ -646,20 +722,17 @@ class Unit {
646
722
  }
647
723
  unit._.currentElement = element;
648
724
  if (textContent !== undefined) {
649
- element.textContent = textContent;
725
+ element.textContent = textContent.toString();
650
726
  }
651
727
  unit._.elements.push(element);
652
728
  return element;
653
729
  }
654
730
  else {
655
- throw new Error(`Invalid html string: ${htmlString}`);
731
+ throw new Error(`xnew.nest: invalid html string [${tag}]`);
656
732
  }
657
733
  }
658
734
  static extend(unit, component, props) {
659
735
  var _a;
660
- if (unit._.state !== 'invoked') {
661
- throw new Error('This function can not be called after initialized.');
662
- }
663
736
  unit._.components.push(component);
664
737
  Unit.component2units.add(component, unit);
665
738
  const backupComponent = unit._.currentComponent;
@@ -672,12 +745,13 @@ class Unit {
672
745
  }
673
746
  const descriptor = Object.getOwnPropertyDescriptor(defines, key);
674
747
  const wrapper = { configurable: true, enumerable: true };
748
+ const snapshot = Unit.snapshot(unit);
675
749
  if (descriptor === null || descriptor === void 0 ? void 0 : descriptor.get)
676
- wrapper.get = Unit.wrap(unit, descriptor.get);
750
+ wrapper.get = (...args) => Unit.scope(snapshot, descriptor.get, ...args);
677
751
  if (descriptor === null || descriptor === void 0 ? void 0 : descriptor.set)
678
- wrapper.set = Unit.wrap(unit, descriptor.set);
752
+ wrapper.set = (...args) => Unit.scope(snapshot, descriptor.set, ...args);
679
753
  if (typeof (descriptor === null || descriptor === void 0 ? void 0 : descriptor.value) === 'function') {
680
- wrapper.value = Unit.wrap(unit, descriptor.value);
754
+ wrapper.value = (...args) => Unit.scope(snapshot, descriptor.value, ...args);
681
755
  }
682
756
  else if ((descriptor === null || descriptor === void 0 ? void 0 : descriptor.value) !== undefined) {
683
757
  wrapper.writable = true;
@@ -730,10 +804,6 @@ class Unit {
730
804
  });
731
805
  Unit.rootUnit.on('finalize', () => ticker.clear());
732
806
  }
733
- static wrap(unit, listener) {
734
- const snapshot = Unit.snapshot(unit);
735
- return (...args) => Unit.scope(snapshot, listener, ...args);
736
- }
737
807
  static scope(snapshot, func, ...args) {
738
808
  if (snapshot.unit._.state === 'finalized') {
739
809
  return;
@@ -784,15 +854,16 @@ class Unit {
784
854
  types.forEach((type) => Unit.off(this, type, listener));
785
855
  }
786
856
  static on(unit, type, listener, options) {
857
+ const snapshot = Unit.snapshot(Unit.currentUnit);
858
+ const execute = (...args) => Unit.scope(snapshot, listener, ...args);
787
859
  if (SYSTEM_EVENTS.includes(type)) {
788
- unit._.systems[type].push({ listener, execute: Unit.wrap(Unit.currentUnit, listener) });
860
+ unit._.systems[type].push({ listener, execute });
789
861
  }
790
862
  if (unit._.listeners.has(type, listener) === false) {
791
- const execute = Unit.wrap(Unit.currentUnit, listener);
792
863
  unit._.listeners.set(type, listener, { element: unit.element, component: unit._.currentComponent, execute });
793
864
  Unit.type2units.add(type, unit);
794
865
  if (/^[A-Za-z]/.test(type)) {
795
- unit._.eventManager.add(unit.element, type, execute, options);
866
+ unit._.eventor.add(unit.element, type, execute, options);
796
867
  }
797
868
  }
798
869
  }
@@ -806,7 +877,7 @@ class Unit {
806
877
  return;
807
878
  unit._.listeners.delete(type, listener);
808
879
  if (/^[A-Za-z]/.test(type)) {
809
- unit._.eventManager.remove(type, item.execute);
880
+ unit._.eventor.remove(type, item.execute);
810
881
  }
811
882
  });
812
883
  if (unit._.listeners.has(type) === false) {
@@ -819,7 +890,7 @@ class Unit {
819
890
  if (type[0] === '+') {
820
891
  (_a = Unit.type2units.get(type)) === null || _a === void 0 ? void 0 : _a.forEach((unit) => {
821
892
  var _a;
822
- const find = [unit, ...unit._.ancestors].find(u => u._.config.protect === true);
893
+ const find = [unit, ...unit._.ancestors].find(u => u._.protected === true);
823
894
  if (find === undefined || current._.ancestors.includes(find) === true || current === find) {
824
895
  (_a = unit._.listeners.get(type)) === null || _a === void 0 ? void 0 : _a.forEach((item) => item.execute(...args));
825
896
  }
@@ -836,92 +907,10 @@ Unit.component2units = new MapSet();
836
907
  // event
837
908
  //----------------------------------------------------------------------------------------------------
838
909
  Unit.type2units = new MapSet();
839
- //----------------------------------------------------------------------------------------------------
840
- // unit promise
841
- //----------------------------------------------------------------------------------------------------
842
- class UnitPromise {
843
- constructor(promise, component) {
844
- this.promise = promise;
845
- this.component = component;
846
- }
847
- then(callback) {
848
- this.promise = this.promise.then(Unit.wrap(Unit.currentUnit, callback));
849
- return this;
850
- }
851
- catch(callback) {
852
- this.promise = this.promise.catch(Unit.wrap(Unit.currentUnit, callback));
853
- return this;
854
- }
855
- finally(callback) {
856
- this.promise = this.promise.finally(Unit.wrap(Unit.currentUnit, callback));
857
- return this;
858
- }
859
- }
860
- //----------------------------------------------------------------------------------------------------
861
- // unit timer
862
- //----------------------------------------------------------------------------------------------------
863
- class UnitTimer {
864
- constructor(options) {
865
- this.stack = [];
866
- this.unit = new Unit(Unit.currentUnit, null, UnitTimer.Component, Object.assign({ snapshot: Unit.snapshot(Unit.currentUnit) }, options));
867
- }
868
- clear() {
869
- this.stack = [];
870
- this.unit.finalize();
871
- }
872
- timeout(timeout, duration = 0) {
873
- UnitTimer.execute(this, { timeout, duration, iterations: 1 });
874
- return this;
875
- }
876
- iteration(timeout, duration = 0, iterations = -1) {
877
- UnitTimer.execute(this, { timeout, duration, iterations });
878
- return this;
879
- }
880
- transition(transition, duration = 0, easing) {
881
- UnitTimer.execute(this, { transition, duration, iterations: 1, easing });
882
- return this;
883
- }
884
- static execute(timer, options) {
885
- if (timer.unit._.state === 'finalized') {
886
- timer.unit = new Unit(Unit.currentUnit, null, UnitTimer.Component, Object.assign({ snapshot: Unit.snapshot(Unit.currentUnit) }, options));
887
- }
888
- else if (timer.stack.length === 0) {
889
- timer.stack.push(Object.assign({ snapshot: Unit.snapshot(Unit.currentUnit) }, options));
890
- timer.unit.on('finalize', () => { UnitTimer.next(timer); });
891
- }
892
- else {
893
- timer.stack.push(Object.assign({ snapshot: Unit.snapshot(Unit.currentUnit) }, options));
894
- }
895
- }
896
- static next(timer) {
897
- if (timer.stack.length > 0) {
898
- timer.unit = new Unit(Unit.currentUnit, null, UnitTimer.Component, timer.stack.shift());
899
- timer.unit.on('finalize', () => { UnitTimer.next(timer); });
900
- }
901
- }
902
- static Component(unit, options) {
903
- let counter = 0;
904
- const timer = new Timer({
905
- transition: (p) => {
906
- if (options.transition)
907
- Unit.scope(options.snapshot, options.transition, p);
908
- },
909
- timeout: () => {
910
- if (options.transition)
911
- Unit.scope(options.snapshot, options.transition, 1.0);
912
- if (options.timeout)
913
- Unit.scope(options.snapshot, options.timeout);
914
- if (options.iterations && counter >= options.iterations - 1) {
915
- unit.finalize();
916
- }
917
- counter++;
918
- }, duration: options.duration, iterations: options.iterations, easing: options.easing
919
- });
920
- unit.on('finalize', () => timer.clear());
921
- }
922
- }
923
910
 
924
- function parseArguments(...args) {
911
+ const xnew$1 = Object.assign(function (...args) {
912
+ if (Unit.rootUnit === undefined)
913
+ Unit.reset();
925
914
  let target;
926
915
  if (args[0] instanceof HTMLElement || args[0] instanceof SVGElement) {
927
916
  target = args.shift(); // an existing html element
@@ -934,29 +923,26 @@ function parseArguments(...args) {
934
923
  }
935
924
  const component = args.shift();
936
925
  const props = args.shift();
937
- return { target, component, props };
938
- }
939
- const xnew$1 = Object.assign(function (...args) {
940
- if (Unit.rootUnit === undefined)
941
- Unit.reset();
942
- const { target, component, props } = parseArguments(...args);
943
- return new Unit(Unit.currentUnit, target, component, props, { protect: false });
926
+ return new Unit(Unit.currentUnit, target, component, props);
944
927
  }, {
945
928
  /**
946
929
  * Creates a nested HTML/SVG element within the current component
947
- * @param htmlString - HTML or SVG tag name (e.g., '<div>', '<span>', '<svg>')
930
+ * @param tag - HTML or SVG tag name (e.g., '<div>', '<span>', '<svg>')
948
931
  * @returns The created HTML/SVG element
949
932
  * @throws Error if called after component initialization
950
933
  * @example
951
934
  * const div = xnew.nest('<div>')
952
935
  * div.textContent = 'Hello'
953
936
  */
954
- nest(htmlString, textContent) {
937
+ nest(tag, textContent) {
955
938
  try {
956
- return Unit.nest(Unit.currentUnit, htmlString, textContent);
939
+ if (Unit.currentUnit._.state !== 'invoked') {
940
+ throw new Error('xnew.nest can not be called after initialized.');
941
+ }
942
+ return Unit.nest(Unit.currentUnit, tag, textContent);
957
943
  }
958
944
  catch (error) {
959
- console.error('xnew.nest(htmlString: string): ', error);
945
+ console.error('xnew.nest(tag: string): ', error);
960
946
  throw error;
961
947
  }
962
948
  },
@@ -971,6 +957,9 @@ const xnew$1 = Object.assign(function (...args) {
971
957
  */
972
958
  extend(component, props) {
973
959
  try {
960
+ if (Unit.currentUnit._.state !== 'invoked') {
961
+ throw new Error('xnew.extend can not be called after initialized.');
962
+ }
974
963
  return Unit.extend(Unit.currentUnit, component, props);
975
964
  }
976
965
  catch (error) {
@@ -1105,6 +1094,15 @@ const xnew$1 = Object.assign(function (...args) {
1105
1094
  throw error;
1106
1095
  }
1107
1096
  },
1097
+ /**
1098
+ * Emits a custom event to components
1099
+ * @param type - Event type to emit (prefix with '+' for global events, '-' for local events)
1100
+ * @param args - Additional arguments to pass to event listeners
1101
+ * @returns void
1102
+ * @example
1103
+ * xnew.emit('+globalevent', { data: 123 }); // Global event
1104
+ * xnew.emit('-localevent', { data: 123 }); // Local event
1105
+ */
1108
1106
  emit(type, ...args) {
1109
1107
  try {
1110
1108
  return Unit.emit(type, ...args);
@@ -1154,100 +1152,114 @@ const xnew$1 = Object.assign(function (...args) {
1154
1152
  transition(transition, duration = 0, easing = 'linear') {
1155
1153
  return new UnitTimer({ transition, duration, easing, iterations: 1 });
1156
1154
  },
1157
- protect(...args) {
1158
- if (Unit.rootUnit === undefined)
1159
- Unit.reset();
1160
- const { target, component, props } = parseArguments(...args);
1161
- return new Unit(Unit.currentUnit, target, component, props, { protect: true });
1155
+ /**
1156
+ * Call this method within a component function to enable protection.
1157
+ * Protected components will not respond to global events emitted via xnew.emit,
1158
+ * and will be excluded from xnew.find searches.
1159
+ * @example
1160
+ * function MyComponent(unit) {
1161
+ * xnew.protect();
1162
+ * // Component logic here
1163
+ * }
1164
+ */
1165
+ protect() {
1166
+ Unit.currentUnit._.protected = true;
1162
1167
  },
1163
1168
  });
1164
1169
 
1165
1170
  function Accordion(unit, { open = false, duration = 200, easing = 'ease' } = {}) {
1166
1171
  xnew$1.context('xnew.accordion', unit);
1167
- unit.on('-transition', ({ state }) => unit.state = state);
1168
- xnew$1.timeout(() => xnew$1.emit('-transition', { state: open ? 1.0 : 0.0 }));
1172
+ let state = open ? 1.0 : 0.0;
1173
+ let sign = open ? +1 : -1;
1174
+ let timer = xnew$1.timeout(() => xnew$1.emit('-transition', { state }));
1169
1175
  return {
1170
- state: open ? 1.0 : 0.0,
1171
1176
  toggle() {
1172
- if (unit.state === 1.0) {
1173
- unit.close();
1174
- }
1175
- else if (unit.state === 0.0) {
1176
- unit.open();
1177
- }
1177
+ sign > 0 ? unit.close() : unit.open();
1178
1178
  },
1179
1179
  open() {
1180
- if (unit.state === 0.0) {
1181
- xnew$1.transition((x) => xnew$1.emit('-transition', { state: x }), duration, easing);
1182
- }
1180
+ if (sign < 0)
1181
+ transition();
1183
1182
  },
1184
1183
  close() {
1185
- if (unit.state === 1.0) {
1186
- xnew$1.transition((x) => xnew$1.emit('-transition', { state: 1.0 - x }), duration, easing);
1187
- }
1188
- }
1184
+ if (sign > 0)
1185
+ transition();
1186
+ },
1187
+ };
1188
+ function transition() {
1189
+ sign *= -1;
1190
+ const d = sign > 0 ? 1 - state : state;
1191
+ timer.clear();
1192
+ timer = xnew$1.transition((x) => {
1193
+ const y = x < 1.0 ? (1 - x) * d : 0.0;
1194
+ state = sign > 0 ? 1.0 - y : y;
1195
+ xnew$1.emit('-transition', { state });
1196
+ }, duration * d, easing);
1197
+ }
1198
+ }
1199
+ function Modal(unit, { duration = 200, easing = 'ease' } = {}) {
1200
+ xnew$1.context('xnew.modal', unit);
1201
+ let state = 0.0;
1202
+ let timer = xnew$1.transition((x) => {
1203
+ state = x;
1204
+ xnew$1.emit('-transition', { state });
1205
+ }, duration, easing);
1206
+ return {
1207
+ close() {
1208
+ const d = state;
1209
+ timer.clear();
1210
+ timer = xnew$1.transition((x) => {
1211
+ state = x < 1.0 ? (1 - x) * d : 0.0;
1212
+ xnew$1.emit('-transition', { state });
1213
+ }, duration * d, easing)
1214
+ .timeout(() => unit.finalize());
1215
+ },
1189
1216
  };
1190
1217
  }
1191
1218
 
1192
- function Screen(unit, { width = 640, height = 480, fit = 'contain' } = {}) {
1193
- const size = { width, height };
1194
- const wrapper = xnew$1.nest('<div style="position: relative; width: 100%; height: 100%; overflow: hidden;">');
1195
- unit.on('resize', resize);
1219
+ function Screen(unit, { width, height, fit = 'contain' } = {}) {
1220
+ const size = { width: width !== null && width !== void 0 ? width : 800, height: height !== null && height !== void 0 ? height : 600 };
1221
+ const outer = xnew$1.nest('<div style="position: relative; width: 100%; height: 100%; overflow: hidden;">');
1222
+ xnew$1().on('resize', resize);
1196
1223
  const absolute = xnew$1.nest('<div style="position: absolute; margin: auto; container-type: size; overflow: hidden;">');
1197
- const canvas = xnew$1(`<canvas width="${width}" height="${height}" style="width: 100%; height: 100%; vertical-align: bottom; user-select: none; user-drag: none; pointer-events: auto;">`);
1224
+ const canvas = xnew$1(`<canvas width="${size.width}" height="${size.height}" style="width: 100%; height: 100%; vertical-align: bottom; user-select: none; user-drag: none; pointer-events: auto;">`);
1198
1225
  resize();
1199
1226
  function resize() {
1200
- const aspect = size.width / size.height;
1201
1227
  const style = { width: '100%', height: '100%', top: 0, left: 0, bottom: 0, right: 0 };
1202
1228
  if (fit === 'contain') {
1203
- if (wrapper.clientWidth < wrapper.clientHeight * aspect) {
1204
- style.height = Math.floor(wrapper.clientWidth / aspect) + 'px';
1229
+ const aspect = size.width / size.height;
1230
+ if (outer.clientWidth < outer.clientHeight * aspect) {
1231
+ style.height = Math.floor(outer.clientWidth / aspect) + 'px';
1205
1232
  }
1206
1233
  else {
1207
- style.width = Math.floor(wrapper.clientHeight * aspect) + 'px';
1234
+ style.width = Math.floor(outer.clientHeight * aspect) + 'px';
1208
1235
  }
1209
1236
  }
1210
1237
  else if (fit === 'cover') {
1211
- if (wrapper.clientWidth < wrapper.clientHeight * aspect) {
1212
- style.width = Math.floor(wrapper.clientHeight * aspect) + 'px';
1213
- style.left = Math.floor((wrapper.clientWidth - wrapper.clientHeight * aspect) / 2) + 'px';
1238
+ const aspect = size.width / size.height;
1239
+ if (outer.clientWidth < outer.clientHeight * aspect) {
1240
+ style.width = Math.floor(outer.clientHeight * aspect) + 'px';
1241
+ style.left = Math.floor((outer.clientWidth - outer.clientHeight * aspect) / 2) + 'px';
1214
1242
  style.right = 'auto';
1215
1243
  }
1216
1244
  else {
1217
- style.height = Math.floor(wrapper.clientWidth / aspect) + 'px';
1218
- style.top = Math.floor((wrapper.clientHeight - wrapper.clientWidth / aspect) / 2) + 'px';
1245
+ style.height = Math.floor(outer.clientWidth / aspect) + 'px';
1246
+ style.top = Math.floor((outer.clientHeight - outer.clientWidth / aspect) / 2) + 'px';
1219
1247
  style.bottom = 'auto';
1220
1248
  }
1221
1249
  }
1222
- else ;
1250
+ else if (fit === 'resize') {
1251
+ size.width = outer.clientWidth > 0 ? outer.clientWidth : size.width;
1252
+ size.height = outer.clientHeight > 0 ? outer.clientHeight : size.height;
1253
+ console.log(size);
1254
+ canvas.element.setAttribute('width', size.width + 'px');
1255
+ canvas.element.setAttribute('height', size.height + 'px');
1256
+ }
1223
1257
  Object.assign(absolute.style, style);
1224
1258
  }
1225
1259
  return {
1226
1260
  get canvas() {
1227
1261
  return canvas.element;
1228
1262
  },
1229
- resize(width, height) {
1230
- size.width = width;
1231
- size.height = height;
1232
- canvas.element.setAttribute('width', width + 'px');
1233
- canvas.element.setAttribute('height', height + 'px');
1234
- resize();
1235
- },
1236
- };
1237
- }
1238
-
1239
- function Modal(unit, { duration = 200, easing = 'ease' } = {}) {
1240
- xnew$1.context('xnew.modalframe', unit);
1241
- xnew$1.nest('<div style="position: fixed; inset: 0; z-index: 1000;">');
1242
- unit.on('click', ({ event }) => unit.close());
1243
- unit.on('-transition', ({ state }) => unit.state = state);
1244
- xnew$1.transition((x) => xnew$1.emit('-transition', { state: x }), duration, easing);
1245
- return {
1246
- state: 0.0,
1247
- close() {
1248
- xnew$1.transition((x) => xnew$1.emit('-transition', { state: 1.0 - x }), duration, easing)
1249
- .timeout(() => unit.finalize());
1250
- }
1251
1263
  };
1252
1264
  }
1253
1265
 
@@ -1302,7 +1314,7 @@ function AnalogStick(unit, { stroke = 'currentColor', strokeOpacity = 0.8, strok
1302
1314
  xnew$1.emit('-up', { type: '-up', vector });
1303
1315
  });
1304
1316
  }
1305
- function DirectionalPad(unit, { diagonal = true, stroke = 'currentColor', strokeOpacity = 0.8, strokeWidth = 2, strokeLinejoin = 'round', fill = '#FFF', fillOpacity = 0.8 } = {}) {
1317
+ function DPad(unit, { diagonal = true, stroke = 'currentColor', strokeOpacity = 0.8, strokeWidth = 2, strokeLinejoin = 'round', fill = '#FFF', fillOpacity = 0.8 } = {}) {
1306
1318
  const outer = xnew$1.nest(`<div style="position: relative; width: 100%; height: 100%;">`);
1307
1319
  let newsize = Math.min(outer.clientWidth, outer.clientHeight);
1308
1320
  const inner = xnew$1.nest(`<div style="position: absolute; width: ${newsize}px; height: ${newsize}px; margin: auto; inset: 0; cursor: pointer; pointer-select: none; pointer-events: auto; overflow: hidden;">`);
@@ -1598,7 +1610,7 @@ const basics = {
1598
1610
  Modal,
1599
1611
  Accordion,
1600
1612
  AnalogStick,
1601
- DirectionalPad,
1613
+ DPad,
1602
1614
  };
1603
1615
  const audio = {
1604
1616
  load(path) {
package/package.json CHANGED
@@ -4,7 +4,7 @@
4
4
  "keywords": [
5
5
  "Component-Oriented Programming"
6
6
  ],
7
- "version": "0.5.1",
7
+ "version": "0.5.3",
8
8
  "main": "dist/xnew.js",
9
9
  "module": "dist/xnew.mjs",
10
10
  "types": "dist/xnew.d.ts",