spinit-js 1.0.1 → 1.0.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.
Files changed (3) hide show
  1. package/README.md +5 -0
  2. package/package.json +1 -1
  3. package/src/SpinIT.js +50 -15
package/README.md CHANGED
@@ -2,6 +2,10 @@
2
2
 
3
3
  A lightweight, high-performance JavaScript library for 360-degree image rotation. Perfect for product displays and interactive image viewers.
4
4
 
5
+ [**Explore the Live Demo Showcase**](https://static.billgr17.click/spinit/)
6
+
7
+
8
+
5
9
  ## Features
6
10
 
7
11
  - **No Dependencies**: No external libraries required.
@@ -62,6 +66,7 @@ const spinit = new SpinIT("#spinit-container", ["img_##.jpg", 1, 90], {
62
66
  | `autoplay` | `Boolean` \| `Number` | `true` | If true, spins automatically until user interaction. If a number, auto-spins until that frame index. |
63
67
  | `autoplaySpeed` | `Number` | `24` | Autoplay speed in Frames Per Second (FPS). |
64
68
  | `debug` | `Boolean` | `false` | Enables debug mode. |
69
+ | `lazyload` | `Boolean` | `true` | Enables lazy load the SpinIT container. |
65
70
 
66
71
 
67
72
  ## License
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "spinit-js",
3
- "version": "1.0.1",
3
+ "version": "1.0.3",
4
4
  "description": "A lightweight, high-performance JavaScript library for 360-degree image rotation.",
5
5
  "main": "src/index.js",
6
6
  "type": "module",
package/src/SpinIT.js CHANGED
@@ -30,6 +30,7 @@ export class SpinIT {
30
30
  preload: options.preload ?? "all",
31
31
  autoplay: options.autoplay ?? true,
32
32
  autoplaySpeed: options.autoplaySpeed ?? 24,
33
+ lazyload: options.lazyload ?? true,
33
34
  debug: options.debug ?? false
34
35
  };
35
36
 
@@ -48,8 +49,32 @@ export class SpinIT {
48
49
 
49
50
  this.canvas = null;
50
51
  this.ctx = null;
52
+ this.observer = null;
53
+ this.isDestroyed = false;
51
54
 
52
- this.#init(source);
55
+ if (this.options.lazyload && 'IntersectionObserver' in window) {
56
+ this.#setupLazyLoad(source);
57
+ } else {
58
+ this.#init(source);
59
+ }
60
+ }
61
+
62
+ #setupLazyLoad(source) {
63
+ this.#log("SpinIT: Setting up lazyload...");
64
+
65
+ this.observer = new IntersectionObserver((entries) => {
66
+ entries.forEach(entry => {
67
+ if (entry.isIntersecting) {
68
+ this.#log("SpinIT: Container is visible, initializing...");
69
+ this.#init(source);
70
+ this.observer.unobserve(this.container);
71
+ this.observer.disconnect();
72
+ this.observer = null;
73
+ }
74
+ });
75
+ }, { rootMargin: '50px' });
76
+
77
+ this.observer.observe(this.container);
53
78
  }
54
79
 
55
80
  #log(...args) {
@@ -62,7 +87,7 @@ export class SpinIT {
62
87
 
63
88
  async #init(source) {
64
89
  this.#log("SpinIT: Initializing with source:", source);
65
-
90
+
66
91
  // 1. Inject styles and show loader
67
92
  Renderer.injectStyles();
68
93
  Renderer.showLoader(this.container);
@@ -72,10 +97,12 @@ export class SpinIT {
72
97
  const preloadCount = isPreloadingAll ? 1 : Math.max(1, this.options.preload);
73
98
 
74
99
  const preloadUrls = urls.slice(0, preloadCount);
75
-
100
+
76
101
  // 2. Preload the specified number of images to show something immediately
77
102
  const preloadedImages = await Loader.preloadImages(preloadUrls, this.options.debug);
78
-
103
+
104
+ if (this.isDestroyed) return;
105
+
79
106
  if (preloadedImages.length === 0) {
80
107
  this.#error("SpinIT Error: Could not load the initial images.");
81
108
  Renderer.hideLoader(this.container);
@@ -85,10 +112,10 @@ export class SpinIT {
85
112
  // Initialize this.images array with the correct length to allow correct math in physics
86
113
  this.images = new Array(urls.length);
87
114
  for (let i = 0; i < preloadedImages.length; i++) {
88
- this.images[i] = preloadedImages[i];
115
+ this.images[i] = preloadedImages[i];
89
116
  }
90
117
  const { width, height } = preloadedImages[0];
91
-
118
+
92
119
  // 3. Initialize canvas
93
120
  const { canvas, ctx } = Renderer.initCanvas(this.container, width, height, this.options.responsive);
94
121
  this.canvas = canvas;
@@ -109,6 +136,7 @@ export class SpinIT {
109
136
  this.#log("SpinIT: First frame rendered with blur. Loading remaining images...");
110
137
 
111
138
  Loader.preloadImages(urls, this.options.debug).then(allImages => {
139
+ if (this.isDestroyed) return;
112
140
  this.#log(`SpinIT: Preloaded ${allImages.length} images. Clearing loading state...`);
113
141
  this.images = allImages;
114
142
  Renderer.applyBlur(this.canvas, false);
@@ -128,10 +156,11 @@ export class SpinIT {
128
156
  const remainingUrls = urls.slice(preloadCount);
129
157
  const remainingPromises = remainingUrls.map((url, i) => {
130
158
  return Loader.preloadImages([url], this.options.debug).then(([img]) => {
159
+ if (this.isDestroyed) return;
131
160
  const index = preloadCount + i;
132
161
  this.images[index] = img;
133
162
  if (this.currentFrame === index) {
134
- this.render();
163
+ this.render();
135
164
  }
136
165
  });
137
166
  });
@@ -255,11 +284,11 @@ export class SpinIT {
255
284
  */
256
285
  render() {
257
286
  Renderer.renderFrame(
258
- this.ctx,
259
- this.images[this.currentFrame],
260
- this.canvas.width,
261
- this.canvas.height,
262
- this.options.debug,
287
+ this.ctx,
288
+ this.images[this.currentFrame],
289
+ this.canvas.width,
290
+ this.canvas.height,
291
+ this.options.debug,
263
292
  this.currentFrame
264
293
  );
265
294
  }
@@ -268,7 +297,13 @@ export class SpinIT {
268
297
  * Destroys the SpinIT instance and cleans up.
269
298
  */
270
299
  destroy() {
300
+ this.isDestroyed = true;
271
301
  this.#stopAutoPlay();
302
+ if (this.observer) {
303
+ this.observer.unobserve(this.container);
304
+ this.observer.disconnect();
305
+ this.observer = null;
306
+ }
272
307
  if (this.resizeObserver) {
273
308
  this.resizeObserver.disconnect();
274
309
  }
@@ -283,9 +318,9 @@ export class SpinIT {
283
318
 
284
319
  #startAutoPlay() {
285
320
  if (this.options.autoplay === false) return;
286
-
321
+
287
322
  this.isAutoPlaying = true;
288
-
323
+
289
324
  let targetFrame = null;
290
325
  if (typeof this.options.autoplay === 'number') {
291
326
  targetFrame = this.options.autoplay;
@@ -299,7 +334,7 @@ export class SpinIT {
299
334
  }
300
335
 
301
336
  this.updateFrame(-this.options.sensitivity);
302
-
337
+
303
338
  if (targetFrame !== null && this.currentFrame === targetFrame) {
304
339
  this.#stopAutoPlay();
305
340
  } else if (!this.options.loop && this.currentFrame === this.images.length - 1) {