@simhub2/justflipit 4.0.0 → 4.0.1

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.
@@ -28,14 +28,16 @@ var JustFlipItModule = (() => {
28
28
  var css = `
29
29
  ._justFlipIt_panel{position:relative;display:grid;perspective:var(--jfi-perspective,1000px);isolation:isolate}
30
30
  ._justFlipIt_panel>[data-jfi-face]{grid-area:1/1;min-width:0;backface-visibility:hidden;-webkit-backface-visibility:hidden;transition:transform var(--jfi-duration) var(--jfi-easing),opacity var(--jfi-duration) var(--jfi-easing);transform-origin:center}
31
- ._justFlipIt_panel>[data-jfi-face=front]{transform:rotateY(0deg)}
32
- ._justFlipIt_panel>[data-jfi-face=back]{transform:rotateY(-180deg);pointer-events:none}
33
- ._justFlipIt_panel[data-jfi-flipped=true]>[data-jfi-face=front]{transform:rotateY(180deg);pointer-events:none}
34
- ._justFlipIt_panel[data-jfi-flipped=true]>[data-jfi-face=back]{transform:rotateY(0deg);pointer-events:auto}
35
- ._justFlipIt_panel[data-jfi-axis=x]>[data-jfi-face=back]{transform:rotateX(-180deg)}
36
- ._justFlipIt_panel[data-jfi-axis=x][data-jfi-flipped=true]>[data-jfi-face=front]{transform:rotateX(180deg)}
37
- ._justFlipIt_panel[data-jfi-axis=x][data-jfi-flipped=true]>[data-jfi-face=back]{transform:rotateX(0deg)}
38
- ._justFlipIt_panel[data-jfi-effect=fade]>[data-jfi-face],._justFlipIt_panel[data-jfi-effect=scale]>[data-jfi-face]{transform:none}
31
+ ._justFlipIt_panel>[data-jfi-face=back],._justFlipIt_panel[data-jfi-flipped=true]>[data-jfi-face=front]{pointer-events:none}
32
+ ._justFlipIt_panel[data-jfi-flipped=true]>[data-jfi-face=back]{pointer-events:auto}
33
+ ._justFlipIt_panel[data-jfi-effect=flip]>[data-jfi-face=front]{transform:rotateY(0deg)}
34
+ ._justFlipIt_panel[data-jfi-effect=flip]>[data-jfi-face=back]{transform:rotateY(-180deg)}
35
+ ._justFlipIt_panel[data-jfi-effect=flip][data-jfi-flipped=true]>[data-jfi-face=front]{transform:rotateY(180deg)}
36
+ ._justFlipIt_panel[data-jfi-effect=flip][data-jfi-flipped=true]>[data-jfi-face=back]{transform:rotateY(0deg)}
37
+ ._justFlipIt_panel[data-jfi-effect=flip][data-jfi-axis=x]>[data-jfi-face=front]{transform:rotateX(0deg)}
38
+ ._justFlipIt_panel[data-jfi-effect=flip][data-jfi-axis=x]>[data-jfi-face=back]{transform:rotateX(-180deg)}
39
+ ._justFlipIt_panel[data-jfi-effect=flip][data-jfi-axis=x][data-jfi-flipped=true]>[data-jfi-face=front]{transform:rotateX(180deg)}
40
+ ._justFlipIt_panel[data-jfi-effect=flip][data-jfi-axis=x][data-jfi-flipped=true]>[data-jfi-face=back]{transform:rotateX(0deg)}
39
41
  ._justFlipIt_panel[data-jfi-effect=fade]>[data-jfi-face=back],._justFlipIt_panel[data-jfi-effect=scale]>[data-jfi-face=back]{opacity:0}
40
42
  ._justFlipIt_panel[data-jfi-effect=fade][data-jfi-flipped=true]>[data-jfi-face=front],._justFlipIt_panel[data-jfi-effect=scale][data-jfi-flipped=true]>[data-jfi-face=front]{opacity:0}
41
43
  ._justFlipIt_panel[data-jfi-effect=fade][data-jfi-flipped=true]>[data-jfi-face=back],._justFlipIt_panel[data-jfi-effect=scale][data-jfi-flipped=true]>[data-jfi-face=back]{opacity:1}
@@ -163,33 +165,63 @@ var JustFlipItModule = (() => {
163
165
  this.listen("pointerenter", (event) => {
164
166
  if (!this.settings.Click && this.settings.Tilt !== "only" && event.pointerType !== "touch") this.flip(true);
165
167
  });
166
- this.listen("pointerleave", () => {
168
+ this.listen("pointerleave", (event) => {
169
+ if (event.pointerType === "touch") return;
167
170
  this.resetTilt();
168
171
  if (!this.settings.Click && this.settings.Tilt !== "only") this.flip(false);
169
172
  });
170
- this.listen("pointercancel", () => this.resetTilt());
171
- this.listen("pointerup", (event) => {
172
- if (event.pointerType === "touch") {
173
- this.resetTilt();
174
- if (!this.settings.Click && this.settings.Tilt !== "only") this.toggle();
175
- }
176
- });
173
+ this.listen("pointerdown", (event) => {
174
+ if (event.pointerType !== "touch" || event.isPrimary === false || this.touch) return;
175
+ this.resetTilt();
176
+ this.touch = { id: event.pointerId, x: event.clientX, y: event.clientY, moved: false };
177
+ this.queueTilt(event, this.touch);
178
+ }, { passive: true });
177
179
  this.listen("pointermove", (event) => {
178
- if (!this.settings.Tilt || this.reduced || event.pointerType === "touch") return;
179
- this.point = [event.clientX, event.clientY];
180
- if (this.frame) return;
181
- this.frame = this.win.requestAnimationFrame(() => {
182
- this.frame = 0;
183
- const rect = this.hoverPanel.getBoundingClientRect();
184
- if (!rect.width || !rect.height) return;
185
- const t = { max: 10, perspective: 1e3, scale: 1.03, ...typeof this.settings.Tilt === "object" ? this.settings.Tilt : {} };
186
- const x = Math.max(-1, Math.min(1, (this.point[0] - rect.left) / rect.width * 2 - 1));
187
- const y = Math.max(-1, Math.min(1, (this.point[1] - rect.top) / rect.height * 2 - 1));
188
- this.hoverPanel.style.transform = `perspective(${t.perspective}px) rotateX(${-y * t.max}deg) rotateY(${x * t.max}deg) scale(${t.scale})`;
189
- });
180
+ if (event.pointerType !== "touch") {
181
+ if (!this.touch) this.queueTilt(event);
182
+ return;
183
+ }
184
+ const touch = this.touch;
185
+ if (!touch || touch.id !== event.pointerId) return;
186
+ touch.moved || (touch.moved = this.touchMoved(event, touch));
187
+ this.queueTilt(event, touch);
190
188
  }, { passive: true });
189
+ this.listen("pointerup", (event) => {
190
+ const touch = this.finishTouch(event);
191
+ if (!touch || touch.moved || this.touchMoved(event, touch)) return;
192
+ if (!this.settings.Click && this.settings.Tilt !== "only") this.toggle();
193
+ });
194
+ this.listen("pointercancel", (event) => {
195
+ if (event.pointerType === "touch") this.finishTouch(event);
196
+ else this.resetTilt();
197
+ });
198
+ this.listen("lostpointercapture", (event) => this.finishTouch(event));
191
199
  this.baseTransform = this.hoverPanel.style.transform;
192
200
  }
201
+ touchMoved(event, touch) {
202
+ return Math.hypot(event.clientX - touch.x, event.clientY - touch.y) > 10;
203
+ }
204
+ finishTouch(event) {
205
+ const touch = this.touch;
206
+ if (event.pointerType !== "touch" || !touch || touch.id !== event.pointerId) return;
207
+ this.touch = null;
208
+ this.resetTilt();
209
+ return touch;
210
+ }
211
+ queueTilt(event, touch) {
212
+ if (!this.settings.Tilt || this.reduced) return;
213
+ this.point = [event.clientX, event.clientY];
214
+ if (this.frame) return;
215
+ this.frame = this.win.requestAnimationFrame(() => {
216
+ this.frame = 0;
217
+ const rect = touch ? touch.rect ?? (touch.rect = this.hoverPanel.getBoundingClientRect()) : this.hoverPanel.getBoundingClientRect();
218
+ if (!rect.width || !rect.height) return;
219
+ const { max = 10, perspective = 1e3, scale = 1.03 } = this.settings.Tilt;
220
+ const x = Math.max(-1, Math.min(1, (this.point[0] - rect.left) / rect.width * 2 - 1));
221
+ const y = Math.max(-1, Math.min(1, (this.point[1] - rect.top) / rect.height * 2 - 1));
222
+ this.hoverPanel.style.transform = `perspective(${perspective}px) rotateX(${-y * max}deg) rotateY(${x * max}deg) scale(${scale})`;
223
+ });
224
+ }
193
225
  resetTilt() {
194
226
  if (this.frame) this.win.cancelAnimationFrame(this.frame);
195
227
  this.frame = 0;
@@ -1,14 +1,16 @@
1
- var JustFlipItModule=(()=>{var p=Object.defineProperty;var g=Object.getOwnPropertyDescriptor;var v=Object.getOwnPropertyNames;var b=Object.prototype.hasOwnProperty;var T=(i,t)=>{for(var e in t)p(i,e,{get:t[e],enumerable:!0})},w=(i,t,e,a)=>{if(t&&typeof t=="object"||typeof t=="function")for(let s of v(t))!b.call(i,s)&&s!==e&&p(i,s,{get:()=>t[s],enumerable:!(a=g(t,s))||a.enumerable});return i};var _=i=>w(p({},"__esModule",{value:!0}),i);var x={};T(x,{FlipController:()=>o,default:()=>c});var n=new WeakMap,k={Click:!1,FlipX:!1,Duration:400,Easing:"cubic-bezier(.22,.61,.36,1)",Tilt:!1,Effect:"flip",ReducedMotion:!0,preserveClasses:!0,preserveStyles:!0,Style:[]},E=`
1
+ var JustFlipItModule=(()=>{var d=Object.defineProperty;var g=Object.getOwnPropertyDescriptor;var T=Object.getOwnPropertyNames;var v=Object.prototype.hasOwnProperty;var b=(i,t)=>{for(var e in t)d(i,e,{get:t[e],enumerable:!0})},_=(i,t,e,a)=>{if(t&&typeof t=="object"||typeof t=="function")for(let s of T(t))!v.call(i,s)&&s!==e&&d(i,s,{get:()=>t[s],enumerable:!(a=g(t,s))||a.enumerable});return i};var w=i=>_(d({},"__esModule",{value:!0}),i);var I={};b(I,{FlipController:()=>c,default:()=>h});var n=new WeakMap,k={Click:!1,FlipX:!1,Duration:400,Easing:"cubic-bezier(.22,.61,.36,1)",Tilt:!1,Effect:"flip",ReducedMotion:!0,preserveClasses:!0,preserveStyles:!0,Style:[]},F=`
2
2
  ._justFlipIt_panel{position:relative;display:grid;perspective:var(--jfi-perspective,1000px);isolation:isolate}
3
3
  ._justFlipIt_panel>[data-jfi-face]{grid-area:1/1;min-width:0;backface-visibility:hidden;-webkit-backface-visibility:hidden;transition:transform var(--jfi-duration) var(--jfi-easing),opacity var(--jfi-duration) var(--jfi-easing);transform-origin:center}
4
- ._justFlipIt_panel>[data-jfi-face=front]{transform:rotateY(0deg)}
5
- ._justFlipIt_panel>[data-jfi-face=back]{transform:rotateY(-180deg);pointer-events:none}
6
- ._justFlipIt_panel[data-jfi-flipped=true]>[data-jfi-face=front]{transform:rotateY(180deg);pointer-events:none}
7
- ._justFlipIt_panel[data-jfi-flipped=true]>[data-jfi-face=back]{transform:rotateY(0deg);pointer-events:auto}
8
- ._justFlipIt_panel[data-jfi-axis=x]>[data-jfi-face=back]{transform:rotateX(-180deg)}
9
- ._justFlipIt_panel[data-jfi-axis=x][data-jfi-flipped=true]>[data-jfi-face=front]{transform:rotateX(180deg)}
10
- ._justFlipIt_panel[data-jfi-axis=x][data-jfi-flipped=true]>[data-jfi-face=back]{transform:rotateX(0deg)}
11
- ._justFlipIt_panel[data-jfi-effect=fade]>[data-jfi-face],._justFlipIt_panel[data-jfi-effect=scale]>[data-jfi-face]{transform:none}
4
+ ._justFlipIt_panel>[data-jfi-face=back],._justFlipIt_panel[data-jfi-flipped=true]>[data-jfi-face=front]{pointer-events:none}
5
+ ._justFlipIt_panel[data-jfi-flipped=true]>[data-jfi-face=back]{pointer-events:auto}
6
+ ._justFlipIt_panel[data-jfi-effect=flip]>[data-jfi-face=front]{transform:rotateY(0deg)}
7
+ ._justFlipIt_panel[data-jfi-effect=flip]>[data-jfi-face=back]{transform:rotateY(-180deg)}
8
+ ._justFlipIt_panel[data-jfi-effect=flip][data-jfi-flipped=true]>[data-jfi-face=front]{transform:rotateY(180deg)}
9
+ ._justFlipIt_panel[data-jfi-effect=flip][data-jfi-flipped=true]>[data-jfi-face=back]{transform:rotateY(0deg)}
10
+ ._justFlipIt_panel[data-jfi-effect=flip][data-jfi-axis=x]>[data-jfi-face=front]{transform:rotateX(0deg)}
11
+ ._justFlipIt_panel[data-jfi-effect=flip][data-jfi-axis=x]>[data-jfi-face=back]{transform:rotateX(-180deg)}
12
+ ._justFlipIt_panel[data-jfi-effect=flip][data-jfi-axis=x][data-jfi-flipped=true]>[data-jfi-face=front]{transform:rotateX(180deg)}
13
+ ._justFlipIt_panel[data-jfi-effect=flip][data-jfi-axis=x][data-jfi-flipped=true]>[data-jfi-face=back]{transform:rotateX(0deg)}
12
14
  ._justFlipIt_panel[data-jfi-effect=fade]>[data-jfi-face=back],._justFlipIt_panel[data-jfi-effect=scale]>[data-jfi-face=back]{opacity:0}
13
15
  ._justFlipIt_panel[data-jfi-effect=fade][data-jfi-flipped=true]>[data-jfi-face=front],._justFlipIt_panel[data-jfi-effect=scale][data-jfi-flipped=true]>[data-jfi-face=front]{opacity:0}
14
16
  ._justFlipIt_panel[data-jfi-effect=fade][data-jfi-flipped=true]>[data-jfi-face=back],._justFlipIt_panel[data-jfi-effect=scale][data-jfi-flipped=true]>[data-jfi-face=back]{opacity:1}
@@ -16,6 +18,6 @@ var JustFlipItModule=(()=>{var p=Object.defineProperty;var g=Object.getOwnProper
16
18
  ._justFlipIt_panel[data-jfi-effect=scale][data-jfi-flipped=true]>[data-jfi-face=back]{transform:scale(1)}
17
19
  ._justFlipIt_panel[data-jfi-reduced=true]>[data-jfi-face]{transition:none!important}
18
20
  @media(prefers-reduced-motion:reduce){._justFlipIt_panel:not([data-jfi-motion=allow])>[data-jfi-face]{transition:none!important}}
19
- `;function F(i){if(i.querySelector('style[data-justflipitstyle="v4"]'))return;let t=i.createElement("style");t.dataset.justflipitstyle="v4",t.textContent=E,i.head.append(t)}function u(i){if(i.Duration!==void 0&&(!Number.isFinite(i.Duration)||i.Duration<0))throw new TypeError("Duration must be a non-negative finite number");if(i.Effect!==void 0&&!["flip","fade","scale"].includes(i.Effect))throw new TypeError("Unknown Effect");if(i.Tilt&&typeof i.Tilt=="object"){for(let t of["max","perspective","scale"])if(i.Tilt[t]!==void 0&&(!Number.isFinite(i.Tilt[t])||i.Tilt[t]<0))throw new TypeError(`Invalid Tilt.${t}`)}}var o=class{constructor(t,e={}){if(u(e),!t||t.nodeType!==1)throw new TypeError("Expected an HTML element");this.element=t,this.settings={...k,...e},this.flipped=!1,this.destroyed=!1,this.cleanups=[],this.restores=[],this.win=t.ownerDocument.defaultView;let a=t.ownerDocument;if(F(a),this.managed=!!e.Faces,this.managed){if(this.hoverPanel=t,this.frontWrapper=t.querySelector(e.Faces.front),this.backWrapper=t.querySelector(e.Faces.back),!this.frontWrapper||!this.backWrapper||this.frontWrapper===this.backWrapper||this.frontWrapper.parentNode!==t||this.backWrapper.parentNode!==t)throw new TypeError("Faces must select two distinct direct children")}else{if(!t.parentNode)throw new TypeError("Element must have a parent");if(this.hoverPanel=a.createElement("div"),this.frontWrapper=a.createElement("div"),this.backWrapper=a.createElement("div"),this.settings.preserveClasses&&(this.hoverPanel.className=t.className),this.settings.preserveStyles&&(this.hoverPanel.style.cssText=t.style.cssText),t.before(this.hoverPanel),this.hoverPanel.append(this.frontWrapper,this.backWrapper),this.frontWrapper.append(t),e.Template!==void 0)this.backWrapper.innerHTML=e.Template;else{let r=t.cloneNode(!0);r.removeAttribute("id"),r.querySelectorAll("[id]").forEach(d=>d.removeAttribute("id")),this.backWrapper.append(r)}}let s=this.hoverPanel;for(let r of[s,this.frontWrapper,this.backWrapper]){let m=(r===s?["class","style","tabindex","data-jfi-axis","data-jfi-effect","data-jfi-motion","data-jfi-flipped","data-jfi-reduced"]:["style","data-jfi-face","aria-hidden","inert"]).map(l=>[l,r.getAttribute(l)]),y=r.inert||!1;this.restores.push(()=>{r.inert=y;for(let[l,h]of m)h===null?r.removeAttribute(l):r.setAttribute(l,h)})}s.classList.add("_justFlipIt_panel"),this.frontWrapper.dataset.jfiFace="front",this.backWrapper.dataset.jfiFace="back",this.motion=this.win.matchMedia?.("(prefers-reduced-motion: reduce)");let f=()=>{this.resetTilt(),this.render()};this.motion?.addEventListener("change",f),this.cleanups.push(()=>this.motion?.removeEventListener("change",f)),this.configure(),this.events(),this.render(),n.set(t,this),n.set(s,this)}listen(t,e,a){this.hoverPanel.addEventListener(t,e,a),this.cleanups.push(()=>this.hoverPanel.removeEventListener(t,e,a))}get reduced(){return this.settings.ReducedMotion!==!1&&!!this.motion?.matches}configure(){let t=this.settings,e=this.hoverPanel;e.style.setProperty("--jfi-duration",`${t.Duration}ms`),e.style.setProperty("--jfi-easing",t.Easing),e.dataset.jfiAxis=t.FlipX?"x":"y",e.dataset.jfiEffect=t.Effect,e.dataset.jfiMotion=t.ReducedMotion===!1?"allow":"respect";for(let a of t.Style||[])(a.el==="self"?[e]:e.querySelectorAll(a.el)).forEach(f=>Object.assign(f.style,a.style));t.Tilt!=="only"&&!e.hasAttribute("tabindex")&&(e.tabIndex=0)}events(){this.listen("click",t=>{if(this.settings.Tilt==="only")return;let e=this.settings.Click;(e===!0||e&&[].concat(e).some(a=>t.target.closest?.(a)&&this.hoverPanel.contains(t.target.closest(a))))&&this.toggle()}),this.listen("keydown",t=>{t.target!==this.hoverPanel||this.settings.Tilt==="only"||((t.key==="Enter"||t.key===" ")&&(t.preventDefault(),this.toggle()),t.key==="Escape"&&this.flip(!1))}),this.listen("pointerenter",t=>{!this.settings.Click&&this.settings.Tilt!=="only"&&t.pointerType!=="touch"&&this.flip(!0)}),this.listen("pointerleave",()=>{this.resetTilt(),!this.settings.Click&&this.settings.Tilt!=="only"&&this.flip(!1)}),this.listen("pointercancel",()=>this.resetTilt()),this.listen("pointerup",t=>{t.pointerType==="touch"&&(this.resetTilt(),!this.settings.Click&&this.settings.Tilt!=="only"&&this.toggle())}),this.listen("pointermove",t=>{!this.settings.Tilt||this.reduced||t.pointerType==="touch"||(this.point=[t.clientX,t.clientY],!this.frame&&(this.frame=this.win.requestAnimationFrame(()=>{this.frame=0;let e=this.hoverPanel.getBoundingClientRect();if(!e.width||!e.height)return;let a={max:10,perspective:1e3,scale:1.03,...typeof this.settings.Tilt=="object"?this.settings.Tilt:{}},s=Math.max(-1,Math.min(1,(this.point[0]-e.left)/e.width*2-1)),f=Math.max(-1,Math.min(1,(this.point[1]-e.top)/e.height*2-1));this.hoverPanel.style.transform=`perspective(${a.perspective}px) rotateX(${-f*a.max}deg) rotateY(${s*a.max}deg) scale(${a.scale})`})))},{passive:!0}),this.baseTransform=this.hoverPanel.style.transform}resetTilt(){this.frame&&this.win.cancelAnimationFrame(this.frame),this.frame=0,this.hoverPanel.style.transform=this.baseTransform||""}render(){this.hoverPanel.dataset.jfiFlipped=String(this.flipped),this.hoverPanel.dataset.jfiReduced=String(this.reduced);for(let[t,e]of[[this.frontWrapper,this.flipped],[this.backWrapper,!this.flipped]])t.setAttribute("aria-hidden",String(e)),t.inert=e}flip(t=!0){if(this.destroyed||this.flipped===!!t)return this;let e=this.element.ownerDocument.activeElement;return(t?this.frontWrapper:this.backWrapper).contains(e)&&this.hoverPanel.focus({preventScroll:!0}),this.flipped=!!t,this.render(),this.hoverPanel.dispatchEvent(new this.win.CustomEvent("justflipit:change",{bubbles:!0,detail:this.getState()})),this}toggle(){return this.flip(!this.flipped)}update(t={}){if(this.destroyed)return this;if("Faces"in t)throw new TypeError("Faces cannot change after initialization");if(u(t),this.managed&&"Template"in t)throw new TypeError("Render framework face content with the framework");if(this.settings={...this.settings,...t},"Template"in t){if(this.managed)throw new TypeError("Render framework face content with the framework");this.backWrapper.innerHTML=t.Template}return this.resetTilt(),this.configure(),this.render(),this}getState(){return{flipped:this.flipped,destroyed:this.destroyed,effect:this.settings.Effect}}destroy(){this.destroyed||(this.resetTilt(),this.cleanups.forEach(t=>t()),this.restores.forEach(t=>t()),this.managed||this.hoverPanel.replaceWith(this.element),n.delete(this.element),n.delete(this.hoverPanel),this.destroyed=!0)}};function j(i){return typeof i=="string"?typeof document>"u"?[]:Array.from(document.querySelectorAll(i)):i?.nodeType===1?[i]:i?Array.from(i):[]}function c(i,t){let e=j(i).map(a=>n.get(a)||new o(a,t));return i?.nodeType===1?e[0]:e}c.destroy=i=>j(i).forEach(t=>n.get(t)?.destroy());c.get=i=>n.get(i);return _(x);})();
21
+ `;function E(i){if(i.querySelector('style[data-justflipitstyle="v4"]'))return;let t=i.createElement("style");t.dataset.justflipitstyle="v4",t.textContent=F,i.head.append(t)}function j(i){if(i.Duration!==void 0&&(!Number.isFinite(i.Duration)||i.Duration<0))throw new TypeError("Duration must be a non-negative finite number");if(i.Effect!==void 0&&!["flip","fade","scale"].includes(i.Effect))throw new TypeError("Unknown Effect");if(i.Tilt&&typeof i.Tilt=="object"){for(let t of["max","perspective","scale"])if(i.Tilt[t]!==void 0&&(!Number.isFinite(i.Tilt[t])||i.Tilt[t]<0))throw new TypeError(`Invalid Tilt.${t}`)}}var c=class{constructor(t,e={}){if(j(e),!t||t.nodeType!==1)throw new TypeError("Expected an HTML element");this.element=t,this.settings={...k,...e},this.flipped=!1,this.destroyed=!1,this.cleanups=[],this.restores=[],this.win=t.ownerDocument.defaultView;let a=t.ownerDocument;if(E(a),this.managed=!!e.Faces,this.managed){if(this.hoverPanel=t,this.frontWrapper=t.querySelector(e.Faces.front),this.backWrapper=t.querySelector(e.Faces.back),!this.frontWrapper||!this.backWrapper||this.frontWrapper===this.backWrapper||this.frontWrapper.parentNode!==t||this.backWrapper.parentNode!==t)throw new TypeError("Faces must select two distinct direct children")}else{if(!t.parentNode)throw new TypeError("Element must have a parent");if(this.hoverPanel=a.createElement("div"),this.frontWrapper=a.createElement("div"),this.backWrapper=a.createElement("div"),this.settings.preserveClasses&&(this.hoverPanel.className=t.className),this.settings.preserveStyles&&(this.hoverPanel.style.cssText=t.style.cssText),t.before(this.hoverPanel),this.hoverPanel.append(this.frontWrapper,this.backWrapper),this.frontWrapper.append(t),e.Template!==void 0)this.backWrapper.innerHTML=e.Template;else{let r=t.cloneNode(!0);r.removeAttribute("id"),r.querySelectorAll("[id]").forEach(l=>l.removeAttribute("id")),this.backWrapper.append(r)}}let s=this.hoverPanel;for(let r of[s,this.frontWrapper,this.backWrapper]){let p=(r===s?["class","style","tabindex","data-jfi-axis","data-jfi-effect","data-jfi-motion","data-jfi-flipped","data-jfi-reduced"]:["style","data-jfi-face","aria-hidden","inert"]).map(o=>[o,r.getAttribute(o)]),y=r.inert||!1;this.restores.push(()=>{r.inert=y;for(let[o,u]of p)u===null?r.removeAttribute(o):r.setAttribute(o,u)})}s.classList.add("_justFlipIt_panel"),this.frontWrapper.dataset.jfiFace="front",this.backWrapper.dataset.jfiFace="back",this.motion=this.win.matchMedia?.("(prefers-reduced-motion: reduce)");let f=()=>{this.resetTilt(),this.render()};this.motion?.addEventListener("change",f),this.cleanups.push(()=>this.motion?.removeEventListener("change",f)),this.configure(),this.events(),this.render(),n.set(t,this),n.set(s,this)}listen(t,e,a){this.hoverPanel.addEventListener(t,e,a),this.cleanups.push(()=>this.hoverPanel.removeEventListener(t,e,a))}get reduced(){return this.settings.ReducedMotion!==!1&&!!this.motion?.matches}configure(){let t=this.settings,e=this.hoverPanel;e.style.setProperty("--jfi-duration",`${t.Duration}ms`),e.style.setProperty("--jfi-easing",t.Easing),e.dataset.jfiAxis=t.FlipX?"x":"y",e.dataset.jfiEffect=t.Effect,e.dataset.jfiMotion=t.ReducedMotion===!1?"allow":"respect";for(let a of t.Style||[])(a.el==="self"?[e]:e.querySelectorAll(a.el)).forEach(f=>Object.assign(f.style,a.style));t.Tilt!=="only"&&!e.hasAttribute("tabindex")&&(e.tabIndex=0)}events(){this.listen("click",t=>{if(this.settings.Tilt==="only")return;let e=this.settings.Click;(e===!0||e&&[].concat(e).some(a=>t.target.closest?.(a)&&this.hoverPanel.contains(t.target.closest(a))))&&this.toggle()}),this.listen("keydown",t=>{t.target!==this.hoverPanel||this.settings.Tilt==="only"||((t.key==="Enter"||t.key===" ")&&(t.preventDefault(),this.toggle()),t.key==="Escape"&&this.flip(!1))}),this.listen("pointerenter",t=>{!this.settings.Click&&this.settings.Tilt!=="only"&&t.pointerType!=="touch"&&this.flip(!0)}),this.listen("pointerleave",t=>{t.pointerType!=="touch"&&(this.resetTilt(),!this.settings.Click&&this.settings.Tilt!=="only"&&this.flip(!1))}),this.listen("pointerdown",t=>{t.pointerType!=="touch"||t.isPrimary===!1||this.touch||(this.resetTilt(),this.touch={id:t.pointerId,x:t.clientX,y:t.clientY,moved:!1},this.queueTilt(t,this.touch))},{passive:!0}),this.listen("pointermove",t=>{if(t.pointerType!=="touch"){this.touch||this.queueTilt(t);return}let e=this.touch;!e||e.id!==t.pointerId||(e.moved||(e.moved=this.touchMoved(t,e)),this.queueTilt(t,e))},{passive:!0}),this.listen("pointerup",t=>{let e=this.finishTouch(t);!e||e.moved||this.touchMoved(t,e)||!this.settings.Click&&this.settings.Tilt!=="only"&&this.toggle()}),this.listen("pointercancel",t=>{t.pointerType==="touch"?this.finishTouch(t):this.resetTilt()}),this.listen("lostpointercapture",t=>this.finishTouch(t)),this.baseTransform=this.hoverPanel.style.transform}touchMoved(t,e){return Math.hypot(t.clientX-e.x,t.clientY-e.y)>10}finishTouch(t){let e=this.touch;if(!(t.pointerType!=="touch"||!e||e.id!==t.pointerId))return this.touch=null,this.resetTilt(),e}queueTilt(t,e){!this.settings.Tilt||this.reduced||(this.point=[t.clientX,t.clientY],!this.frame&&(this.frame=this.win.requestAnimationFrame(()=>{this.frame=0;let a=e?e.rect??(e.rect=this.hoverPanel.getBoundingClientRect()):this.hoverPanel.getBoundingClientRect();if(!a.width||!a.height)return;let{max:s=10,perspective:f=1e3,scale:r=1.03}=this.settings.Tilt,l=Math.max(-1,Math.min(1,(this.point[0]-a.left)/a.width*2-1)),p=Math.max(-1,Math.min(1,(this.point[1]-a.top)/a.height*2-1));this.hoverPanel.style.transform=`perspective(${f}px) rotateX(${-p*s}deg) rotateY(${l*s}deg) scale(${r})`})))}resetTilt(){this.frame&&this.win.cancelAnimationFrame(this.frame),this.frame=0,this.hoverPanel.style.transform=this.baseTransform||""}render(){this.hoverPanel.dataset.jfiFlipped=String(this.flipped),this.hoverPanel.dataset.jfiReduced=String(this.reduced);for(let[t,e]of[[this.frontWrapper,this.flipped],[this.backWrapper,!this.flipped]])t.setAttribute("aria-hidden",String(e)),t.inert=e}flip(t=!0){if(this.destroyed||this.flipped===!!t)return this;let e=this.element.ownerDocument.activeElement;return(t?this.frontWrapper:this.backWrapper).contains(e)&&this.hoverPanel.focus({preventScroll:!0}),this.flipped=!!t,this.render(),this.hoverPanel.dispatchEvent(new this.win.CustomEvent("justflipit:change",{bubbles:!0,detail:this.getState()})),this}toggle(){return this.flip(!this.flipped)}update(t={}){if(this.destroyed)return this;if("Faces"in t)throw new TypeError("Faces cannot change after initialization");if(j(t),this.managed&&"Template"in t)throw new TypeError("Render framework face content with the framework");if(this.settings={...this.settings,...t},"Template"in t){if(this.managed)throw new TypeError("Render framework face content with the framework");this.backWrapper.innerHTML=t.Template}return this.resetTilt(),this.configure(),this.render(),this}getState(){return{flipped:this.flipped,destroyed:this.destroyed,effect:this.settings.Effect}}destroy(){this.destroyed||(this.resetTilt(),this.cleanups.forEach(t=>t()),this.restores.forEach(t=>t()),this.managed||this.hoverPanel.replaceWith(this.element),n.delete(this.element),n.delete(this.hoverPanel),this.destroyed=!0)}};function m(i){return typeof i=="string"?typeof document>"u"?[]:Array.from(document.querySelectorAll(i)):i?.nodeType===1?[i]:i?Array.from(i):[]}function h(i,t){let e=m(i).map(a=>n.get(a)||new c(a,t));return i?.nodeType===1?e[0]:e}h.destroy=i=>m(i).forEach(t=>n.get(t)?.destroy());h.get=i=>n.get(i);return w(I);})();
20
22
  globalThis.justFlipIt = JustFlipItModule.default;
21
23
  //# sourceMappingURL=justFlipIt.min.js.map
@@ -28,14 +28,16 @@ var JustFlipItModule = (() => {
28
28
  var css = `
29
29
  ._justFlipIt_panel{position:relative;display:grid;perspective:var(--jfi-perspective,1000px);isolation:isolate}
30
30
  ._justFlipIt_panel>[data-jfi-face]{grid-area:1/1;min-width:0;backface-visibility:hidden;-webkit-backface-visibility:hidden;transition:transform var(--jfi-duration) var(--jfi-easing),opacity var(--jfi-duration) var(--jfi-easing);transform-origin:center}
31
- ._justFlipIt_panel>[data-jfi-face=front]{transform:rotateY(0deg)}
32
- ._justFlipIt_panel>[data-jfi-face=back]{transform:rotateY(-180deg);pointer-events:none}
33
- ._justFlipIt_panel[data-jfi-flipped=true]>[data-jfi-face=front]{transform:rotateY(180deg);pointer-events:none}
34
- ._justFlipIt_panel[data-jfi-flipped=true]>[data-jfi-face=back]{transform:rotateY(0deg);pointer-events:auto}
35
- ._justFlipIt_panel[data-jfi-axis=x]>[data-jfi-face=back]{transform:rotateX(-180deg)}
36
- ._justFlipIt_panel[data-jfi-axis=x][data-jfi-flipped=true]>[data-jfi-face=front]{transform:rotateX(180deg)}
37
- ._justFlipIt_panel[data-jfi-axis=x][data-jfi-flipped=true]>[data-jfi-face=back]{transform:rotateX(0deg)}
38
- ._justFlipIt_panel[data-jfi-effect=fade]>[data-jfi-face],._justFlipIt_panel[data-jfi-effect=scale]>[data-jfi-face]{transform:none}
31
+ ._justFlipIt_panel>[data-jfi-face=back],._justFlipIt_panel[data-jfi-flipped=true]>[data-jfi-face=front]{pointer-events:none}
32
+ ._justFlipIt_panel[data-jfi-flipped=true]>[data-jfi-face=back]{pointer-events:auto}
33
+ ._justFlipIt_panel[data-jfi-effect=flip]>[data-jfi-face=front]{transform:rotateY(0deg)}
34
+ ._justFlipIt_panel[data-jfi-effect=flip]>[data-jfi-face=back]{transform:rotateY(-180deg)}
35
+ ._justFlipIt_panel[data-jfi-effect=flip][data-jfi-flipped=true]>[data-jfi-face=front]{transform:rotateY(180deg)}
36
+ ._justFlipIt_panel[data-jfi-effect=flip][data-jfi-flipped=true]>[data-jfi-face=back]{transform:rotateY(0deg)}
37
+ ._justFlipIt_panel[data-jfi-effect=flip][data-jfi-axis=x]>[data-jfi-face=front]{transform:rotateX(0deg)}
38
+ ._justFlipIt_panel[data-jfi-effect=flip][data-jfi-axis=x]>[data-jfi-face=back]{transform:rotateX(-180deg)}
39
+ ._justFlipIt_panel[data-jfi-effect=flip][data-jfi-axis=x][data-jfi-flipped=true]>[data-jfi-face=front]{transform:rotateX(180deg)}
40
+ ._justFlipIt_panel[data-jfi-effect=flip][data-jfi-axis=x][data-jfi-flipped=true]>[data-jfi-face=back]{transform:rotateX(0deg)}
39
41
  ._justFlipIt_panel[data-jfi-effect=fade]>[data-jfi-face=back],._justFlipIt_panel[data-jfi-effect=scale]>[data-jfi-face=back]{opacity:0}
40
42
  ._justFlipIt_panel[data-jfi-effect=fade][data-jfi-flipped=true]>[data-jfi-face=front],._justFlipIt_panel[data-jfi-effect=scale][data-jfi-flipped=true]>[data-jfi-face=front]{opacity:0}
41
43
  ._justFlipIt_panel[data-jfi-effect=fade][data-jfi-flipped=true]>[data-jfi-face=back],._justFlipIt_panel[data-jfi-effect=scale][data-jfi-flipped=true]>[data-jfi-face=back]{opacity:1}
@@ -163,33 +165,63 @@ var JustFlipItModule = (() => {
163
165
  this.listen("pointerenter", (event) => {
164
166
  if (!this.settings.Click && this.settings.Tilt !== "only" && event.pointerType !== "touch") this.flip(true);
165
167
  });
166
- this.listen("pointerleave", () => {
168
+ this.listen("pointerleave", (event) => {
169
+ if (event.pointerType === "touch") return;
167
170
  this.resetTilt();
168
171
  if (!this.settings.Click && this.settings.Tilt !== "only") this.flip(false);
169
172
  });
170
- this.listen("pointercancel", () => this.resetTilt());
171
- this.listen("pointerup", (event) => {
172
- if (event.pointerType === "touch") {
173
- this.resetTilt();
174
- if (!this.settings.Click && this.settings.Tilt !== "only") this.toggle();
175
- }
176
- });
173
+ this.listen("pointerdown", (event) => {
174
+ if (event.pointerType !== "touch" || event.isPrimary === false || this.touch) return;
175
+ this.resetTilt();
176
+ this.touch = { id: event.pointerId, x: event.clientX, y: event.clientY, moved: false };
177
+ this.queueTilt(event, this.touch);
178
+ }, { passive: true });
177
179
  this.listen("pointermove", (event) => {
178
- if (!this.settings.Tilt || this.reduced || event.pointerType === "touch") return;
179
- this.point = [event.clientX, event.clientY];
180
- if (this.frame) return;
181
- this.frame = this.win.requestAnimationFrame(() => {
182
- this.frame = 0;
183
- const rect = this.hoverPanel.getBoundingClientRect();
184
- if (!rect.width || !rect.height) return;
185
- const t = { max: 10, perspective: 1e3, scale: 1.03, ...typeof this.settings.Tilt === "object" ? this.settings.Tilt : {} };
186
- const x = Math.max(-1, Math.min(1, (this.point[0] - rect.left) / rect.width * 2 - 1));
187
- const y = Math.max(-1, Math.min(1, (this.point[1] - rect.top) / rect.height * 2 - 1));
188
- this.hoverPanel.style.transform = `perspective(${t.perspective}px) rotateX(${-y * t.max}deg) rotateY(${x * t.max}deg) scale(${t.scale})`;
189
- });
180
+ if (event.pointerType !== "touch") {
181
+ if (!this.touch) this.queueTilt(event);
182
+ return;
183
+ }
184
+ const touch = this.touch;
185
+ if (!touch || touch.id !== event.pointerId) return;
186
+ touch.moved || (touch.moved = this.touchMoved(event, touch));
187
+ this.queueTilt(event, touch);
190
188
  }, { passive: true });
189
+ this.listen("pointerup", (event) => {
190
+ const touch = this.finishTouch(event);
191
+ if (!touch || touch.moved || this.touchMoved(event, touch)) return;
192
+ if (!this.settings.Click && this.settings.Tilt !== "only") this.toggle();
193
+ });
194
+ this.listen("pointercancel", (event) => {
195
+ if (event.pointerType === "touch") this.finishTouch(event);
196
+ else this.resetTilt();
197
+ });
198
+ this.listen("lostpointercapture", (event) => this.finishTouch(event));
191
199
  this.baseTransform = this.hoverPanel.style.transform;
192
200
  }
201
+ touchMoved(event, touch) {
202
+ return Math.hypot(event.clientX - touch.x, event.clientY - touch.y) > 10;
203
+ }
204
+ finishTouch(event) {
205
+ const touch = this.touch;
206
+ if (event.pointerType !== "touch" || !touch || touch.id !== event.pointerId) return;
207
+ this.touch = null;
208
+ this.resetTilt();
209
+ return touch;
210
+ }
211
+ queueTilt(event, touch) {
212
+ if (!this.settings.Tilt || this.reduced) return;
213
+ this.point = [event.clientX, event.clientY];
214
+ if (this.frame) return;
215
+ this.frame = this.win.requestAnimationFrame(() => {
216
+ this.frame = 0;
217
+ const rect = touch ? touch.rect ?? (touch.rect = this.hoverPanel.getBoundingClientRect()) : this.hoverPanel.getBoundingClientRect();
218
+ if (!rect.width || !rect.height) return;
219
+ const { max = 10, perspective = 1e3, scale = 1.03 } = this.settings.Tilt;
220
+ const x = Math.max(-1, Math.min(1, (this.point[0] - rect.left) / rect.width * 2 - 1));
221
+ const y = Math.max(-1, Math.min(1, (this.point[1] - rect.top) / rect.height * 2 - 1));
222
+ this.hoverPanel.style.transform = `perspective(${perspective}px) rotateX(${-y * max}deg) rotateY(${x * max}deg) scale(${scale})`;
223
+ });
224
+ }
193
225
  resetTilt() {
194
226
  if (this.frame) this.win.cancelAnimationFrame(this.frame);
195
227
  this.frame = 0;
@@ -1,14 +1,16 @@
1
- var JustFlipItModule=(()=>{var p=Object.defineProperty;var g=Object.getOwnPropertyDescriptor;var v=Object.getOwnPropertyNames;var b=Object.prototype.hasOwnProperty;var T=(i,t)=>{for(var e in t)p(i,e,{get:t[e],enumerable:!0})},w=(i,t,e,a)=>{if(t&&typeof t=="object"||typeof t=="function")for(let s of v(t))!b.call(i,s)&&s!==e&&p(i,s,{get:()=>t[s],enumerable:!(a=g(t,s))||a.enumerable});return i};var _=i=>w(p({},"__esModule",{value:!0}),i);var x={};T(x,{FlipController:()=>o,default:()=>c});var n=new WeakMap,k={Click:!1,FlipX:!1,Duration:400,Easing:"cubic-bezier(.22,.61,.36,1)",Tilt:!1,Effect:"flip",ReducedMotion:!0,preserveClasses:!0,preserveStyles:!0,Style:[]},E=`
1
+ var JustFlipItModule=(()=>{var d=Object.defineProperty;var g=Object.getOwnPropertyDescriptor;var T=Object.getOwnPropertyNames;var v=Object.prototype.hasOwnProperty;var b=(i,t)=>{for(var e in t)d(i,e,{get:t[e],enumerable:!0})},_=(i,t,e,a)=>{if(t&&typeof t=="object"||typeof t=="function")for(let s of T(t))!v.call(i,s)&&s!==e&&d(i,s,{get:()=>t[s],enumerable:!(a=g(t,s))||a.enumerable});return i};var w=i=>_(d({},"__esModule",{value:!0}),i);var I={};b(I,{FlipController:()=>c,default:()=>h});var n=new WeakMap,k={Click:!1,FlipX:!1,Duration:400,Easing:"cubic-bezier(.22,.61,.36,1)",Tilt:!1,Effect:"flip",ReducedMotion:!0,preserveClasses:!0,preserveStyles:!0,Style:[]},F=`
2
2
  ._justFlipIt_panel{position:relative;display:grid;perspective:var(--jfi-perspective,1000px);isolation:isolate}
3
3
  ._justFlipIt_panel>[data-jfi-face]{grid-area:1/1;min-width:0;backface-visibility:hidden;-webkit-backface-visibility:hidden;transition:transform var(--jfi-duration) var(--jfi-easing),opacity var(--jfi-duration) var(--jfi-easing);transform-origin:center}
4
- ._justFlipIt_panel>[data-jfi-face=front]{transform:rotateY(0deg)}
5
- ._justFlipIt_panel>[data-jfi-face=back]{transform:rotateY(-180deg);pointer-events:none}
6
- ._justFlipIt_panel[data-jfi-flipped=true]>[data-jfi-face=front]{transform:rotateY(180deg);pointer-events:none}
7
- ._justFlipIt_panel[data-jfi-flipped=true]>[data-jfi-face=back]{transform:rotateY(0deg);pointer-events:auto}
8
- ._justFlipIt_panel[data-jfi-axis=x]>[data-jfi-face=back]{transform:rotateX(-180deg)}
9
- ._justFlipIt_panel[data-jfi-axis=x][data-jfi-flipped=true]>[data-jfi-face=front]{transform:rotateX(180deg)}
10
- ._justFlipIt_panel[data-jfi-axis=x][data-jfi-flipped=true]>[data-jfi-face=back]{transform:rotateX(0deg)}
11
- ._justFlipIt_panel[data-jfi-effect=fade]>[data-jfi-face],._justFlipIt_panel[data-jfi-effect=scale]>[data-jfi-face]{transform:none}
4
+ ._justFlipIt_panel>[data-jfi-face=back],._justFlipIt_panel[data-jfi-flipped=true]>[data-jfi-face=front]{pointer-events:none}
5
+ ._justFlipIt_panel[data-jfi-flipped=true]>[data-jfi-face=back]{pointer-events:auto}
6
+ ._justFlipIt_panel[data-jfi-effect=flip]>[data-jfi-face=front]{transform:rotateY(0deg)}
7
+ ._justFlipIt_panel[data-jfi-effect=flip]>[data-jfi-face=back]{transform:rotateY(-180deg)}
8
+ ._justFlipIt_panel[data-jfi-effect=flip][data-jfi-flipped=true]>[data-jfi-face=front]{transform:rotateY(180deg)}
9
+ ._justFlipIt_panel[data-jfi-effect=flip][data-jfi-flipped=true]>[data-jfi-face=back]{transform:rotateY(0deg)}
10
+ ._justFlipIt_panel[data-jfi-effect=flip][data-jfi-axis=x]>[data-jfi-face=front]{transform:rotateX(0deg)}
11
+ ._justFlipIt_panel[data-jfi-effect=flip][data-jfi-axis=x]>[data-jfi-face=back]{transform:rotateX(-180deg)}
12
+ ._justFlipIt_panel[data-jfi-effect=flip][data-jfi-axis=x][data-jfi-flipped=true]>[data-jfi-face=front]{transform:rotateX(180deg)}
13
+ ._justFlipIt_panel[data-jfi-effect=flip][data-jfi-axis=x][data-jfi-flipped=true]>[data-jfi-face=back]{transform:rotateX(0deg)}
12
14
  ._justFlipIt_panel[data-jfi-effect=fade]>[data-jfi-face=back],._justFlipIt_panel[data-jfi-effect=scale]>[data-jfi-face=back]{opacity:0}
13
15
  ._justFlipIt_panel[data-jfi-effect=fade][data-jfi-flipped=true]>[data-jfi-face=front],._justFlipIt_panel[data-jfi-effect=scale][data-jfi-flipped=true]>[data-jfi-face=front]{opacity:0}
14
16
  ._justFlipIt_panel[data-jfi-effect=fade][data-jfi-flipped=true]>[data-jfi-face=back],._justFlipIt_panel[data-jfi-effect=scale][data-jfi-flipped=true]>[data-jfi-face=back]{opacity:1}
@@ -16,6 +18,6 @@ var JustFlipItModule=(()=>{var p=Object.defineProperty;var g=Object.getOwnProper
16
18
  ._justFlipIt_panel[data-jfi-effect=scale][data-jfi-flipped=true]>[data-jfi-face=back]{transform:scale(1)}
17
19
  ._justFlipIt_panel[data-jfi-reduced=true]>[data-jfi-face]{transition:none!important}
18
20
  @media(prefers-reduced-motion:reduce){._justFlipIt_panel:not([data-jfi-motion=allow])>[data-jfi-face]{transition:none!important}}
19
- `;function F(i){if(i.querySelector('style[data-justflipitstyle="v4"]'))return;let t=i.createElement("style");t.dataset.justflipitstyle="v4",t.textContent=E,i.head.append(t)}function u(i){if(i.Duration!==void 0&&(!Number.isFinite(i.Duration)||i.Duration<0))throw new TypeError("Duration must be a non-negative finite number");if(i.Effect!==void 0&&!["flip","fade","scale"].includes(i.Effect))throw new TypeError("Unknown Effect");if(i.Tilt&&typeof i.Tilt=="object"){for(let t of["max","perspective","scale"])if(i.Tilt[t]!==void 0&&(!Number.isFinite(i.Tilt[t])||i.Tilt[t]<0))throw new TypeError(`Invalid Tilt.${t}`)}}var o=class{constructor(t,e={}){if(u(e),!t||t.nodeType!==1)throw new TypeError("Expected an HTML element");this.element=t,this.settings={...k,...e},this.flipped=!1,this.destroyed=!1,this.cleanups=[],this.restores=[],this.win=t.ownerDocument.defaultView;let a=t.ownerDocument;if(F(a),this.managed=!!e.Faces,this.managed){if(this.hoverPanel=t,this.frontWrapper=t.querySelector(e.Faces.front),this.backWrapper=t.querySelector(e.Faces.back),!this.frontWrapper||!this.backWrapper||this.frontWrapper===this.backWrapper||this.frontWrapper.parentNode!==t||this.backWrapper.parentNode!==t)throw new TypeError("Faces must select two distinct direct children")}else{if(!t.parentNode)throw new TypeError("Element must have a parent");if(this.hoverPanel=a.createElement("div"),this.frontWrapper=a.createElement("div"),this.backWrapper=a.createElement("div"),this.settings.preserveClasses&&(this.hoverPanel.className=t.className),this.settings.preserveStyles&&(this.hoverPanel.style.cssText=t.style.cssText),t.before(this.hoverPanel),this.hoverPanel.append(this.frontWrapper,this.backWrapper),this.frontWrapper.append(t),e.Template!==void 0)this.backWrapper.innerHTML=e.Template;else{let r=t.cloneNode(!0);r.removeAttribute("id"),r.querySelectorAll("[id]").forEach(d=>d.removeAttribute("id")),this.backWrapper.append(r)}}let s=this.hoverPanel;for(let r of[s,this.frontWrapper,this.backWrapper]){let m=(r===s?["class","style","tabindex","data-jfi-axis","data-jfi-effect","data-jfi-motion","data-jfi-flipped","data-jfi-reduced"]:["style","data-jfi-face","aria-hidden","inert"]).map(l=>[l,r.getAttribute(l)]),y=r.inert||!1;this.restores.push(()=>{r.inert=y;for(let[l,h]of m)h===null?r.removeAttribute(l):r.setAttribute(l,h)})}s.classList.add("_justFlipIt_panel"),this.frontWrapper.dataset.jfiFace="front",this.backWrapper.dataset.jfiFace="back",this.motion=this.win.matchMedia?.("(prefers-reduced-motion: reduce)");let f=()=>{this.resetTilt(),this.render()};this.motion?.addEventListener("change",f),this.cleanups.push(()=>this.motion?.removeEventListener("change",f)),this.configure(),this.events(),this.render(),n.set(t,this),n.set(s,this)}listen(t,e,a){this.hoverPanel.addEventListener(t,e,a),this.cleanups.push(()=>this.hoverPanel.removeEventListener(t,e,a))}get reduced(){return this.settings.ReducedMotion!==!1&&!!this.motion?.matches}configure(){let t=this.settings,e=this.hoverPanel;e.style.setProperty("--jfi-duration",`${t.Duration}ms`),e.style.setProperty("--jfi-easing",t.Easing),e.dataset.jfiAxis=t.FlipX?"x":"y",e.dataset.jfiEffect=t.Effect,e.dataset.jfiMotion=t.ReducedMotion===!1?"allow":"respect";for(let a of t.Style||[])(a.el==="self"?[e]:e.querySelectorAll(a.el)).forEach(f=>Object.assign(f.style,a.style));t.Tilt!=="only"&&!e.hasAttribute("tabindex")&&(e.tabIndex=0)}events(){this.listen("click",t=>{if(this.settings.Tilt==="only")return;let e=this.settings.Click;(e===!0||e&&[].concat(e).some(a=>t.target.closest?.(a)&&this.hoverPanel.contains(t.target.closest(a))))&&this.toggle()}),this.listen("keydown",t=>{t.target!==this.hoverPanel||this.settings.Tilt==="only"||((t.key==="Enter"||t.key===" ")&&(t.preventDefault(),this.toggle()),t.key==="Escape"&&this.flip(!1))}),this.listen("pointerenter",t=>{!this.settings.Click&&this.settings.Tilt!=="only"&&t.pointerType!=="touch"&&this.flip(!0)}),this.listen("pointerleave",()=>{this.resetTilt(),!this.settings.Click&&this.settings.Tilt!=="only"&&this.flip(!1)}),this.listen("pointercancel",()=>this.resetTilt()),this.listen("pointerup",t=>{t.pointerType==="touch"&&(this.resetTilt(),!this.settings.Click&&this.settings.Tilt!=="only"&&this.toggle())}),this.listen("pointermove",t=>{!this.settings.Tilt||this.reduced||t.pointerType==="touch"||(this.point=[t.clientX,t.clientY],!this.frame&&(this.frame=this.win.requestAnimationFrame(()=>{this.frame=0;let e=this.hoverPanel.getBoundingClientRect();if(!e.width||!e.height)return;let a={max:10,perspective:1e3,scale:1.03,...typeof this.settings.Tilt=="object"?this.settings.Tilt:{}},s=Math.max(-1,Math.min(1,(this.point[0]-e.left)/e.width*2-1)),f=Math.max(-1,Math.min(1,(this.point[1]-e.top)/e.height*2-1));this.hoverPanel.style.transform=`perspective(${a.perspective}px) rotateX(${-f*a.max}deg) rotateY(${s*a.max}deg) scale(${a.scale})`})))},{passive:!0}),this.baseTransform=this.hoverPanel.style.transform}resetTilt(){this.frame&&this.win.cancelAnimationFrame(this.frame),this.frame=0,this.hoverPanel.style.transform=this.baseTransform||""}render(){this.hoverPanel.dataset.jfiFlipped=String(this.flipped),this.hoverPanel.dataset.jfiReduced=String(this.reduced);for(let[t,e]of[[this.frontWrapper,this.flipped],[this.backWrapper,!this.flipped]])t.setAttribute("aria-hidden",String(e)),t.inert=e}flip(t=!0){if(this.destroyed||this.flipped===!!t)return this;let e=this.element.ownerDocument.activeElement;return(t?this.frontWrapper:this.backWrapper).contains(e)&&this.hoverPanel.focus({preventScroll:!0}),this.flipped=!!t,this.render(),this.hoverPanel.dispatchEvent(new this.win.CustomEvent("justflipit:change",{bubbles:!0,detail:this.getState()})),this}toggle(){return this.flip(!this.flipped)}update(t={}){if(this.destroyed)return this;if("Faces"in t)throw new TypeError("Faces cannot change after initialization");if(u(t),this.managed&&"Template"in t)throw new TypeError("Render framework face content with the framework");if(this.settings={...this.settings,...t},"Template"in t){if(this.managed)throw new TypeError("Render framework face content with the framework");this.backWrapper.innerHTML=t.Template}return this.resetTilt(),this.configure(),this.render(),this}getState(){return{flipped:this.flipped,destroyed:this.destroyed,effect:this.settings.Effect}}destroy(){this.destroyed||(this.resetTilt(),this.cleanups.forEach(t=>t()),this.restores.forEach(t=>t()),this.managed||this.hoverPanel.replaceWith(this.element),n.delete(this.element),n.delete(this.hoverPanel),this.destroyed=!0)}};function j(i){return typeof i=="string"?typeof document>"u"?[]:Array.from(document.querySelectorAll(i)):i?.nodeType===1?[i]:i?Array.from(i):[]}function c(i,t){let e=j(i).map(a=>n.get(a)||new o(a,t));return i?.nodeType===1?e[0]:e}c.destroy=i=>j(i).forEach(t=>n.get(t)?.destroy());c.get=i=>n.get(i);return _(x);})();
21
+ `;function E(i){if(i.querySelector('style[data-justflipitstyle="v4"]'))return;let t=i.createElement("style");t.dataset.justflipitstyle="v4",t.textContent=F,i.head.append(t)}function j(i){if(i.Duration!==void 0&&(!Number.isFinite(i.Duration)||i.Duration<0))throw new TypeError("Duration must be a non-negative finite number");if(i.Effect!==void 0&&!["flip","fade","scale"].includes(i.Effect))throw new TypeError("Unknown Effect");if(i.Tilt&&typeof i.Tilt=="object"){for(let t of["max","perspective","scale"])if(i.Tilt[t]!==void 0&&(!Number.isFinite(i.Tilt[t])||i.Tilt[t]<0))throw new TypeError(`Invalid Tilt.${t}`)}}var c=class{constructor(t,e={}){if(j(e),!t||t.nodeType!==1)throw new TypeError("Expected an HTML element");this.element=t,this.settings={...k,...e},this.flipped=!1,this.destroyed=!1,this.cleanups=[],this.restores=[],this.win=t.ownerDocument.defaultView;let a=t.ownerDocument;if(E(a),this.managed=!!e.Faces,this.managed){if(this.hoverPanel=t,this.frontWrapper=t.querySelector(e.Faces.front),this.backWrapper=t.querySelector(e.Faces.back),!this.frontWrapper||!this.backWrapper||this.frontWrapper===this.backWrapper||this.frontWrapper.parentNode!==t||this.backWrapper.parentNode!==t)throw new TypeError("Faces must select two distinct direct children")}else{if(!t.parentNode)throw new TypeError("Element must have a parent");if(this.hoverPanel=a.createElement("div"),this.frontWrapper=a.createElement("div"),this.backWrapper=a.createElement("div"),this.settings.preserveClasses&&(this.hoverPanel.className=t.className),this.settings.preserveStyles&&(this.hoverPanel.style.cssText=t.style.cssText),t.before(this.hoverPanel),this.hoverPanel.append(this.frontWrapper,this.backWrapper),this.frontWrapper.append(t),e.Template!==void 0)this.backWrapper.innerHTML=e.Template;else{let r=t.cloneNode(!0);r.removeAttribute("id"),r.querySelectorAll("[id]").forEach(l=>l.removeAttribute("id")),this.backWrapper.append(r)}}let s=this.hoverPanel;for(let r of[s,this.frontWrapper,this.backWrapper]){let p=(r===s?["class","style","tabindex","data-jfi-axis","data-jfi-effect","data-jfi-motion","data-jfi-flipped","data-jfi-reduced"]:["style","data-jfi-face","aria-hidden","inert"]).map(o=>[o,r.getAttribute(o)]),y=r.inert||!1;this.restores.push(()=>{r.inert=y;for(let[o,u]of p)u===null?r.removeAttribute(o):r.setAttribute(o,u)})}s.classList.add("_justFlipIt_panel"),this.frontWrapper.dataset.jfiFace="front",this.backWrapper.dataset.jfiFace="back",this.motion=this.win.matchMedia?.("(prefers-reduced-motion: reduce)");let f=()=>{this.resetTilt(),this.render()};this.motion?.addEventListener("change",f),this.cleanups.push(()=>this.motion?.removeEventListener("change",f)),this.configure(),this.events(),this.render(),n.set(t,this),n.set(s,this)}listen(t,e,a){this.hoverPanel.addEventListener(t,e,a),this.cleanups.push(()=>this.hoverPanel.removeEventListener(t,e,a))}get reduced(){return this.settings.ReducedMotion!==!1&&!!this.motion?.matches}configure(){let t=this.settings,e=this.hoverPanel;e.style.setProperty("--jfi-duration",`${t.Duration}ms`),e.style.setProperty("--jfi-easing",t.Easing),e.dataset.jfiAxis=t.FlipX?"x":"y",e.dataset.jfiEffect=t.Effect,e.dataset.jfiMotion=t.ReducedMotion===!1?"allow":"respect";for(let a of t.Style||[])(a.el==="self"?[e]:e.querySelectorAll(a.el)).forEach(f=>Object.assign(f.style,a.style));t.Tilt!=="only"&&!e.hasAttribute("tabindex")&&(e.tabIndex=0)}events(){this.listen("click",t=>{if(this.settings.Tilt==="only")return;let e=this.settings.Click;(e===!0||e&&[].concat(e).some(a=>t.target.closest?.(a)&&this.hoverPanel.contains(t.target.closest(a))))&&this.toggle()}),this.listen("keydown",t=>{t.target!==this.hoverPanel||this.settings.Tilt==="only"||((t.key==="Enter"||t.key===" ")&&(t.preventDefault(),this.toggle()),t.key==="Escape"&&this.flip(!1))}),this.listen("pointerenter",t=>{!this.settings.Click&&this.settings.Tilt!=="only"&&t.pointerType!=="touch"&&this.flip(!0)}),this.listen("pointerleave",t=>{t.pointerType!=="touch"&&(this.resetTilt(),!this.settings.Click&&this.settings.Tilt!=="only"&&this.flip(!1))}),this.listen("pointerdown",t=>{t.pointerType!=="touch"||t.isPrimary===!1||this.touch||(this.resetTilt(),this.touch={id:t.pointerId,x:t.clientX,y:t.clientY,moved:!1},this.queueTilt(t,this.touch))},{passive:!0}),this.listen("pointermove",t=>{if(t.pointerType!=="touch"){this.touch||this.queueTilt(t);return}let e=this.touch;!e||e.id!==t.pointerId||(e.moved||(e.moved=this.touchMoved(t,e)),this.queueTilt(t,e))},{passive:!0}),this.listen("pointerup",t=>{let e=this.finishTouch(t);!e||e.moved||this.touchMoved(t,e)||!this.settings.Click&&this.settings.Tilt!=="only"&&this.toggle()}),this.listen("pointercancel",t=>{t.pointerType==="touch"?this.finishTouch(t):this.resetTilt()}),this.listen("lostpointercapture",t=>this.finishTouch(t)),this.baseTransform=this.hoverPanel.style.transform}touchMoved(t,e){return Math.hypot(t.clientX-e.x,t.clientY-e.y)>10}finishTouch(t){let e=this.touch;if(!(t.pointerType!=="touch"||!e||e.id!==t.pointerId))return this.touch=null,this.resetTilt(),e}queueTilt(t,e){!this.settings.Tilt||this.reduced||(this.point=[t.clientX,t.clientY],!this.frame&&(this.frame=this.win.requestAnimationFrame(()=>{this.frame=0;let a=e?e.rect??(e.rect=this.hoverPanel.getBoundingClientRect()):this.hoverPanel.getBoundingClientRect();if(!a.width||!a.height)return;let{max:s=10,perspective:f=1e3,scale:r=1.03}=this.settings.Tilt,l=Math.max(-1,Math.min(1,(this.point[0]-a.left)/a.width*2-1)),p=Math.max(-1,Math.min(1,(this.point[1]-a.top)/a.height*2-1));this.hoverPanel.style.transform=`perspective(${f}px) rotateX(${-p*s}deg) rotateY(${l*s}deg) scale(${r})`})))}resetTilt(){this.frame&&this.win.cancelAnimationFrame(this.frame),this.frame=0,this.hoverPanel.style.transform=this.baseTransform||""}render(){this.hoverPanel.dataset.jfiFlipped=String(this.flipped),this.hoverPanel.dataset.jfiReduced=String(this.reduced);for(let[t,e]of[[this.frontWrapper,this.flipped],[this.backWrapper,!this.flipped]])t.setAttribute("aria-hidden",String(e)),t.inert=e}flip(t=!0){if(this.destroyed||this.flipped===!!t)return this;let e=this.element.ownerDocument.activeElement;return(t?this.frontWrapper:this.backWrapper).contains(e)&&this.hoverPanel.focus({preventScroll:!0}),this.flipped=!!t,this.render(),this.hoverPanel.dispatchEvent(new this.win.CustomEvent("justflipit:change",{bubbles:!0,detail:this.getState()})),this}toggle(){return this.flip(!this.flipped)}update(t={}){if(this.destroyed)return this;if("Faces"in t)throw new TypeError("Faces cannot change after initialization");if(j(t),this.managed&&"Template"in t)throw new TypeError("Render framework face content with the framework");if(this.settings={...this.settings,...t},"Template"in t){if(this.managed)throw new TypeError("Render framework face content with the framework");this.backWrapper.innerHTML=t.Template}return this.resetTilt(),this.configure(),this.render(),this}getState(){return{flipped:this.flipped,destroyed:this.destroyed,effect:this.settings.Effect}}destroy(){this.destroyed||(this.resetTilt(),this.cleanups.forEach(t=>t()),this.restores.forEach(t=>t()),this.managed||this.hoverPanel.replaceWith(this.element),n.delete(this.element),n.delete(this.hoverPanel),this.destroyed=!0)}};function m(i){return typeof i=="string"?typeof document>"u"?[]:Array.from(document.querySelectorAll(i)):i?.nodeType===1?[i]:i?Array.from(i):[]}function h(i,t){let e=m(i).map(a=>n.get(a)||new c(a,t));return i?.nodeType===1?e[0]:e}h.destroy=i=>m(i).forEach(t=>n.get(t)?.destroy());h.get=i=>n.get(i);return w(I);})();
20
22
  globalThis.justFlipIt = JustFlipItModule.default;
21
23
  //# sourceMappingURL=justFlipIt.min.js.map
@@ -28,14 +28,16 @@ var defaults = { Click: false, FlipX: false, Duration: 400, Easing: "cubic-bezie
28
28
  var css = `
29
29
  ._justFlipIt_panel{position:relative;display:grid;perspective:var(--jfi-perspective,1000px);isolation:isolate}
30
30
  ._justFlipIt_panel>[data-jfi-face]{grid-area:1/1;min-width:0;backface-visibility:hidden;-webkit-backface-visibility:hidden;transition:transform var(--jfi-duration) var(--jfi-easing),opacity var(--jfi-duration) var(--jfi-easing);transform-origin:center}
31
- ._justFlipIt_panel>[data-jfi-face=front]{transform:rotateY(0deg)}
32
- ._justFlipIt_panel>[data-jfi-face=back]{transform:rotateY(-180deg);pointer-events:none}
33
- ._justFlipIt_panel[data-jfi-flipped=true]>[data-jfi-face=front]{transform:rotateY(180deg);pointer-events:none}
34
- ._justFlipIt_panel[data-jfi-flipped=true]>[data-jfi-face=back]{transform:rotateY(0deg);pointer-events:auto}
35
- ._justFlipIt_panel[data-jfi-axis=x]>[data-jfi-face=back]{transform:rotateX(-180deg)}
36
- ._justFlipIt_panel[data-jfi-axis=x][data-jfi-flipped=true]>[data-jfi-face=front]{transform:rotateX(180deg)}
37
- ._justFlipIt_panel[data-jfi-axis=x][data-jfi-flipped=true]>[data-jfi-face=back]{transform:rotateX(0deg)}
38
- ._justFlipIt_panel[data-jfi-effect=fade]>[data-jfi-face],._justFlipIt_panel[data-jfi-effect=scale]>[data-jfi-face]{transform:none}
31
+ ._justFlipIt_panel>[data-jfi-face=back],._justFlipIt_panel[data-jfi-flipped=true]>[data-jfi-face=front]{pointer-events:none}
32
+ ._justFlipIt_panel[data-jfi-flipped=true]>[data-jfi-face=back]{pointer-events:auto}
33
+ ._justFlipIt_panel[data-jfi-effect=flip]>[data-jfi-face=front]{transform:rotateY(0deg)}
34
+ ._justFlipIt_panel[data-jfi-effect=flip]>[data-jfi-face=back]{transform:rotateY(-180deg)}
35
+ ._justFlipIt_panel[data-jfi-effect=flip][data-jfi-flipped=true]>[data-jfi-face=front]{transform:rotateY(180deg)}
36
+ ._justFlipIt_panel[data-jfi-effect=flip][data-jfi-flipped=true]>[data-jfi-face=back]{transform:rotateY(0deg)}
37
+ ._justFlipIt_panel[data-jfi-effect=flip][data-jfi-axis=x]>[data-jfi-face=front]{transform:rotateX(0deg)}
38
+ ._justFlipIt_panel[data-jfi-effect=flip][data-jfi-axis=x]>[data-jfi-face=back]{transform:rotateX(-180deg)}
39
+ ._justFlipIt_panel[data-jfi-effect=flip][data-jfi-axis=x][data-jfi-flipped=true]>[data-jfi-face=front]{transform:rotateX(180deg)}
40
+ ._justFlipIt_panel[data-jfi-effect=flip][data-jfi-axis=x][data-jfi-flipped=true]>[data-jfi-face=back]{transform:rotateX(0deg)}
39
41
  ._justFlipIt_panel[data-jfi-effect=fade]>[data-jfi-face=back],._justFlipIt_panel[data-jfi-effect=scale]>[data-jfi-face=back]{opacity:0}
40
42
  ._justFlipIt_panel[data-jfi-effect=fade][data-jfi-flipped=true]>[data-jfi-face=front],._justFlipIt_panel[data-jfi-effect=scale][data-jfi-flipped=true]>[data-jfi-face=front]{opacity:0}
41
43
  ._justFlipIt_panel[data-jfi-effect=fade][data-jfi-flipped=true]>[data-jfi-face=back],._justFlipIt_panel[data-jfi-effect=scale][data-jfi-flipped=true]>[data-jfi-face=back]{opacity:1}
@@ -163,33 +165,63 @@ var FlipController = class {
163
165
  this.listen("pointerenter", (event) => {
164
166
  if (!this.settings.Click && this.settings.Tilt !== "only" && event.pointerType !== "touch") this.flip(true);
165
167
  });
166
- this.listen("pointerleave", () => {
168
+ this.listen("pointerleave", (event) => {
169
+ if (event.pointerType === "touch") return;
167
170
  this.resetTilt();
168
171
  if (!this.settings.Click && this.settings.Tilt !== "only") this.flip(false);
169
172
  });
170
- this.listen("pointercancel", () => this.resetTilt());
171
- this.listen("pointerup", (event) => {
172
- if (event.pointerType === "touch") {
173
- this.resetTilt();
174
- if (!this.settings.Click && this.settings.Tilt !== "only") this.toggle();
175
- }
176
- });
173
+ this.listen("pointerdown", (event) => {
174
+ if (event.pointerType !== "touch" || event.isPrimary === false || this.touch) return;
175
+ this.resetTilt();
176
+ this.touch = { id: event.pointerId, x: event.clientX, y: event.clientY, moved: false };
177
+ this.queueTilt(event, this.touch);
178
+ }, { passive: true });
177
179
  this.listen("pointermove", (event) => {
178
- if (!this.settings.Tilt || this.reduced || event.pointerType === "touch") return;
179
- this.point = [event.clientX, event.clientY];
180
- if (this.frame) return;
181
- this.frame = this.win.requestAnimationFrame(() => {
182
- this.frame = 0;
183
- const rect = this.hoverPanel.getBoundingClientRect();
184
- if (!rect.width || !rect.height) return;
185
- const t = { max: 10, perspective: 1e3, scale: 1.03, ...typeof this.settings.Tilt === "object" ? this.settings.Tilt : {} };
186
- const x = Math.max(-1, Math.min(1, (this.point[0] - rect.left) / rect.width * 2 - 1));
187
- const y = Math.max(-1, Math.min(1, (this.point[1] - rect.top) / rect.height * 2 - 1));
188
- this.hoverPanel.style.transform = `perspective(${t.perspective}px) rotateX(${-y * t.max}deg) rotateY(${x * t.max}deg) scale(${t.scale})`;
189
- });
180
+ if (event.pointerType !== "touch") {
181
+ if (!this.touch) this.queueTilt(event);
182
+ return;
183
+ }
184
+ const touch = this.touch;
185
+ if (!touch || touch.id !== event.pointerId) return;
186
+ touch.moved || (touch.moved = this.touchMoved(event, touch));
187
+ this.queueTilt(event, touch);
190
188
  }, { passive: true });
189
+ this.listen("pointerup", (event) => {
190
+ const touch = this.finishTouch(event);
191
+ if (!touch || touch.moved || this.touchMoved(event, touch)) return;
192
+ if (!this.settings.Click && this.settings.Tilt !== "only") this.toggle();
193
+ });
194
+ this.listen("pointercancel", (event) => {
195
+ if (event.pointerType === "touch") this.finishTouch(event);
196
+ else this.resetTilt();
197
+ });
198
+ this.listen("lostpointercapture", (event) => this.finishTouch(event));
191
199
  this.baseTransform = this.hoverPanel.style.transform;
192
200
  }
201
+ touchMoved(event, touch) {
202
+ return Math.hypot(event.clientX - touch.x, event.clientY - touch.y) > 10;
203
+ }
204
+ finishTouch(event) {
205
+ const touch = this.touch;
206
+ if (event.pointerType !== "touch" || !touch || touch.id !== event.pointerId) return;
207
+ this.touch = null;
208
+ this.resetTilt();
209
+ return touch;
210
+ }
211
+ queueTilt(event, touch) {
212
+ if (!this.settings.Tilt || this.reduced) return;
213
+ this.point = [event.clientX, event.clientY];
214
+ if (this.frame) return;
215
+ this.frame = this.win.requestAnimationFrame(() => {
216
+ this.frame = 0;
217
+ const rect = touch ? touch.rect ?? (touch.rect = this.hoverPanel.getBoundingClientRect()) : this.hoverPanel.getBoundingClientRect();
218
+ if (!rect.width || !rect.height) return;
219
+ const { max = 10, perspective = 1e3, scale = 1.03 } = this.settings.Tilt;
220
+ const x = Math.max(-1, Math.min(1, (this.point[0] - rect.left) / rect.width * 2 - 1));
221
+ const y = Math.max(-1, Math.min(1, (this.point[1] - rect.top) / rect.height * 2 - 1));
222
+ this.hoverPanel.style.transform = `perspective(${perspective}px) rotateX(${-y * max}deg) rotateY(${x * max}deg) scale(${scale})`;
223
+ });
224
+ }
193
225
  resetTilt() {
194
226
  if (this.frame) this.win.cancelAnimationFrame(this.frame);
195
227
  this.frame = 0;