pagewave 1.0.0 → 1.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.
Files changed (3) hide show
  1. package/package.json +3 -3
  2. package/transition.js +69 -22
  3. package/guide.txt +0 -56
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "pagewave",
3
- "version": "1.0.0",
4
- "description": "NPM Package for implementing page transitions in both SSR and CSR apps",
3
+ "version": "1.0.1",
4
+ "description": "NPM Package for implementing page transitions in both SSR and CSR apps. Utilize both custom and preset animations. Choose between transitions, keyframe animations, and overlays.",
5
5
  "main": "transition.js",
6
6
  "scripts": {
7
7
  "test": "echo \"Error: no test specified\" && exit 1"
@@ -17,6 +17,6 @@
17
17
  "license": "ISC",
18
18
  "repository": {
19
19
  "type": "git",
20
- "url": "https://github.com/toasterstrudelz/pagewave.git"
20
+ "url": "https://github.com/danielpagano202/pagewave.git"
21
21
  }
22
22
  }
package/transition.js CHANGED
@@ -1,3 +1,4 @@
1
+ //Default Options
1
2
  let defaultOptions = {
2
3
  mainContentIdName: "main-content",
3
4
  overlayClass: "a-overlay",
@@ -13,7 +14,10 @@ let defaultOptions = {
13
14
  animateIgnoredLinks: false,
14
15
  animateSelfLink: true,
15
16
  loadEvent: "DOMContentLoaded",
17
+ usePresets: true,
18
+ cleanUpDivs: false,
16
19
  }
20
+ //Options object that will contain the actual options used by the program
17
21
  let finalOptions = {
18
22
  mainContentIdName: "main-content",
19
23
  overlayClass: "a-overlay",
@@ -29,22 +33,28 @@ let finalOptions = {
29
33
  animateIgnoredLinks: false,
30
34
  animateSelfLink: true,
31
35
  loadEvent: "DOMContentLoaded",
36
+ usePresets: true,
37
+ cleanUpDivs: false,
32
38
  }
33
39
 
40
+ //Sets Up Page Transition Capability. Not necessary if you don't need options or presets
34
41
  function SetUp(options = {}) {
35
42
  //Merge default options with user options
36
43
  finalOptions = { ...defaultOptions, ...options };
37
- //Import css files into HTNL document
38
- let cssFiles = ["OverlayPreset.css", "KeyFramePreset.css"];
39
- for (let i = 0; i < cssFiles.length; i++) {
40
- let link = document.createElement('link');
41
- link.rel = 'stylesheet';
42
- link.type = 'text/css';
43
- link.href = cssFiles[i];
44
- document.getElementsByTagName('HEAD')[0].appendChild(link);
44
+ //Import css files into HTML document automatically
45
+ if(finalOptions.usePresets){
46
+ let cssFiles = ["OverlayPreset.css", "KeyFramePreset.css"];
47
+ for (let i = 0; i < cssFiles.length; i++) {
48
+ let link = document.createElement('link');
49
+ link.rel = 'stylesheet';
50
+ link.type = 'text/css';
51
+ link.href = cssFiles[i];
52
+ document.getElementsByTagName('HEAD')[0].appendChild(link);
53
+ }
45
54
  }
46
55
  }
47
56
  exports.SetUp = SetUp;
57
+ //Overlay Preset Types to Choose From
48
58
  const overlayType = Object.freeze({
49
59
  slide: Symbol("slide"),
50
60
  inverseSlide: Symbol("inverseSlide"),
@@ -54,12 +64,14 @@ const overlayType = Object.freeze({
54
64
  bubble: Symbol("bubble"),
55
65
  });
56
66
  exports.overlayType = overlayType;
67
+ //Keyframe Preset Types to Choose From
57
68
  const keyframeType = Object.freeze({
58
69
  fade: Symbol("fade"),
59
70
  fadeaway: Symbol("fadeaway"),
60
71
  });
61
72
  exports.keyframeType = keyframeType;
62
73
 
74
+ //Function to apply animation to element and keep its properties and remove the animation
63
75
  function ApplyAnimation(element, animationName, duration, timing, direction) {
64
76
  element.style.animation = `${animationName} ${duration}ms ${timing} both ${direction}`;
65
77
  if (direction == "reverse") {
@@ -86,6 +98,7 @@ function ApplyAnimation(element, animationName, duration, timing, direction) {
86
98
  element.addEventListener("animationend", handleAnimation,);
87
99
  }
88
100
  }
101
+ //Dispatch an event for the hooks
89
102
  function CallHook(hookName, details) {
90
103
  const event = new CustomEvent(hookName, {
91
104
  detail: details
@@ -104,6 +117,7 @@ class KeyFramePreset {
104
117
  fade: "fade",
105
118
  fadeaway: "fadeaway"
106
119
  };
120
+ //Uses keyframeType to run Keyframe Custom
107
121
  if (animationMap[this.kfType.description]) {
108
122
  AnimatePageTransition(new KeyFrameCustom(animationMap[this.kfType.description], this.duration, this.timing), direction);
109
123
  }
@@ -117,6 +131,7 @@ class KeyFrameCustom {
117
131
  this.timing = timing;
118
132
  }
119
133
  handle(direction, mainElement) {
134
+ //Reveals element and applys the animation
120
135
  mainElement.hidden = false;
121
136
  ApplyAnimation(mainElement, this.animationName, this.duration, this.timing, direction)
122
137
  }
@@ -131,6 +146,7 @@ class StyleTransition {
131
146
  this.timing = timing;
132
147
  }
133
148
  handle(direction, mainElement) {
149
+ //Applys the transition in the right direction
134
150
  if (direction == "normal") {
135
151
  mainElement.style[this.styleString] = this.startValue;
136
152
  mainElement.style.transition = this.styleString + " " + this.duration.toString() + "ms " + this.timing;
@@ -138,6 +154,7 @@ class StyleTransition {
138
154
  } else if (direction == "reverse") {
139
155
  mainElement.style[this.styleString] = this.endValue;
140
156
  mainElement.style.transition = this.styleString + " " + this.duration.toString() + "ms " + this.timing;
157
+ //Timeout is needed for some reason. Need to test further but it works
141
158
  setTimeout(
142
159
  () => {
143
160
  mainElement.style[this.styleString] = this.startValue;
@@ -158,9 +175,11 @@ class MultiElementAnimation {
158
175
  handle(direction, mainElement) {
159
176
  mainElement.hidden = false;
160
177
  let timing = this.timing;
178
+ //Goes through every animation selector, finds all of those elements, and applies the proper animation to them
161
179
  for (const [selector, animationName] of Object.entries(this.animateableObjects)) {
162
180
  document.querySelectorAll(selector).forEach(element => ApplyAnimation(element, animationName, this.duration, timing, direction));
163
181
  }
182
+ //Animates main element if animation is given
164
183
  if (this.mainElementAnimation != "") {
165
184
  ApplyAnimation(mainElement, this.mainElementAnimation, this.duration, timing, direction);
166
185
  }
@@ -175,6 +194,7 @@ class OverlayPreset {
175
194
  this.timing = timing;
176
195
  }
177
196
  handle(direction) {
197
+ //Finds the proper preset and runs OverlayCustom appropriately
178
198
  const overlayMap = {
179
199
  slide: { firstOverlayElement: "slide" },
180
200
  inverseSlide: { firstOverlayElement: "inverseSlide" },
@@ -201,21 +221,26 @@ class OverlayCustom {
201
221
  var r = document.querySelector(':root');
202
222
  r.style.setProperty('--div-color', this.color);
203
223
  let timing = this.timing;
204
- /*
224
+ //Removes divs when animation is finished
205
225
  function RemoveDiv(event) {
206
226
  if (event.target.animateName == event.animationName) {
207
227
  event.target.removeEventListener("animationend", RemoveDiv);
208
228
  event.target.remove();
209
229
  }
210
- }*/
230
+ }
231
+ //Loops through divs, creating them, adding the provided class, and giving them an animation
211
232
  for (const [className, animationName] of Object.entries(this.divAnimationObject)) {
212
233
  let divElement = document.createElement("div");
213
234
  divElement.className = className;
214
235
  divElement.style.animation = `${animationName} ${this.duration.toString()}ms ${timing} both ${direction}`;
215
236
  mainElement.appendChild(divElement);
216
- //divElement.animateName = animationName;
217
- //divElement.addEventListener("animationend", RemoveDiv);
237
+ //Removes divs at end of animation
238
+ if(finalOptions.cleanUpDivs){
239
+ divElement.animateName = animationName;
240
+ divElement.addEventListener("animationend", RemoveDiv);
241
+ }
218
242
  }
243
+ //Animates main element if animation is given
219
244
  if (this.mainElementAnimation != "") {
220
245
  mainElement.style.animation = `${this.mainElementAnimation} ${this.duration.toString()}ms ${timing} both ${direction}`;
221
246
  }
@@ -232,7 +257,7 @@ function AddFileToCache(file) {
232
257
  }
233
258
  }
234
259
  }*/
235
-
260
+ //Adds service worker to cache presets and this script. Returns a boolean true if it is already active or useServiceWorker was overrided; false otherwise
236
261
  function AddServiceWorker() {
237
262
  if (!finalOptions.useServiceWorker) {
238
263
  return true;
@@ -248,7 +273,7 @@ function AddServiceWorker() {
248
273
  }
249
274
  return isServiceWorker;
250
275
  }
251
-
276
+ //Checks if navigation is from same site. Returns false if referrer and current host are different of refferer is empty
252
277
  function isNavigationFromSameSite() {
253
278
  const referrer = document.referrer;
254
279
  if (referrer == "") {
@@ -259,7 +284,7 @@ function isNavigationFromSameSite() {
259
284
 
260
285
  return referrerHost === currentHost;
261
286
  }
262
-
287
+ //Returns true if animation is overlay type, false if animation type
263
288
  function IsOverlay(transitionStyle) {
264
289
  if (transitionStyle instanceof OverlayPreset || transitionStyle instanceof OverlayCustom) {
265
290
  return true;
@@ -268,6 +293,7 @@ function IsOverlay(transitionStyle) {
268
293
  }
269
294
  }
270
295
  exports.IsOverlay = IsOverlay;
296
+ //Checks if element exists. If it does, it runs functionToExecute. Otherwise, waits until element exists to run the function
271
297
  function WaitForElementLoad(selector, functionToExecute) {
272
298
  if(document.querySelector(selector) != null){
273
299
  functionToExecute(document.querySelector(selector));
@@ -287,20 +313,25 @@ function WaitForElementLoad(selector, functionToExecute) {
287
313
  observer.observe(document.body, { childList: true, subtree: true });
288
314
  }
289
315
  exports.WaitForElementLoad = WaitForElementLoad;
316
+ //Shorthand for SendPoint and EndPoint
290
317
  function ListenForChange(aStyle, aOverlay = aStyle, aAnimation = aStyle, leaveFunction = (link) => {window.location = link;}) {
291
318
  EndPoint(aStyle, aOverlay, aAnimation, leaveFunction);
292
319
  SendPoint(aStyle, aOverlay, aAnimation);
293
320
  }
294
321
  exports.ListenForChange = ListenForChange;
322
+ //Listens for clicks and plays animation and then redirects
295
323
  function SendPoint(aStyle, aOverlay = aStyle, aAnimation = aStyle, leaveFunction = (link) => {window.location = link;}) {
324
+ //True if service worker is active or ignored with useServiceWorker=false, false otherwise
296
325
  let allowAnimate = AddServiceWorker();
297
326
 
298
327
  function HandleClickAnimation(e) {
299
- //console.log(e.target.tagName, e.target.classList, e.target.href == window.location.href, finalOptions.animateSelfLink)
300
- if (e.target.tagName.toLowerCase() == "a" && !(e.target.classList.contains(finalOptions.classToIgnoreLink)) && !(e.target.href == window.location.href && !finalOptions.animateSelfLink)) {
328
+ //Checks to see if target is a link, it is not a link to ignore, not a self link + animateSelfLink=false
329
+ if (e.target.tagName == "A" && !(e.target.classList.contains(finalOptions.classToIgnoreLink)) && !(e.target.href == window.location.href && !finalOptions.animateSelfLink)) {
330
+ //Prevents link from redirecting
301
331
  e.preventDefault();
302
332
  let duration = aStyle.duration;
303
333
  CallHook("animateSSP", { style: aStyle, overlayStyle: aOverlay, animationStyle: aAnimation, clickEvent: e });
334
+ //Plays the right animation depending on link type and sets proper duration
304
335
  if (e.target.classList.contains(finalOptions.overlayClass)) {
305
336
  AnimatePageTransition(aOverlay, "normal");
306
337
  duration = aOverlay.duration;
@@ -311,6 +342,7 @@ function SendPoint(aStyle, aOverlay = aStyle, aAnimation = aStyle, leaveFunction
311
342
  AnimatePageTransition(aStyle, "normal");
312
343
  duration = aStyle.duration;
313
344
  }
345
+ //Calls the leave function when duration timer finishes
314
346
  setTimeout(
315
347
  () => {
316
348
  CallHook("animateESP", { style: aStyle, overlayStyle: aOverlay, animationStyle: aAnimation, clickEvent: e });
@@ -320,6 +352,7 @@ function SendPoint(aStyle, aOverlay = aStyle, aAnimation = aStyle, leaveFunction
320
352
  }
321
353
  }, parseInt(duration)
322
354
  );
355
+ //We set the storage to ignore so we don't play an animation when we go to another page.
323
356
  } else if (e.target.classList.contains(finalOptions.classToIgnoreLink) || (e.target.href == window.location.href && !finalOptions.animateSelfLink)) {
324
357
  sessionStorage.setItem("animationType", "ignore");
325
358
  }
@@ -329,9 +362,11 @@ function SendPoint(aStyle, aOverlay = aStyle, aAnimation = aStyle, leaveFunction
329
362
  function AddListeners() {
330
363
  window.addEventListener("click", HandleClickAnimation);
331
364
  }
365
+ //If service worker active, can immediately listen
332
366
  if (allowAnimate) {
333
367
  AddListeners();
334
368
  }
369
+ //Else, wait until the loadEvent provided is triggered
335
370
  else {
336
371
  window.addEventListener(finalOptions.loadEvent, () => {
337
372
  AddListeners();
@@ -339,7 +374,9 @@ function SendPoint(aStyle, aOverlay = aStyle, aAnimation = aStyle, leaveFunction
339
374
  }
340
375
  }
341
376
  exports.SendPoint = SendPoint;
377
+ //Waits for the document to load and plays the reverse animation
342
378
  function EndPoint(aStyle, aOverlay = aStyle, aAnimation = aStyle) {
379
+ //Checks to see what kind of receiving animation to play
343
380
  if (aOverlay != aStyle || aAnimation != aStyle) {
344
381
  if (sessionStorage.getItem("animationType") === "true") {
345
382
  aStyle = aOverlay;
@@ -373,9 +410,9 @@ function EndPoint(aStyle, aOverlay = aStyle, aAnimation = aStyle) {
373
410
  }
374
411
  }
375
412
  }
376
-
413
+ //True if service worker is active or ignored with useServiceWorker=false, false otherwise
377
414
  let allowAnimate = AddServiceWorker();
378
- //console.log("allow animating");
415
+ //Figures out what kind of animation it is and hides the document properly
379
416
  if (IsOverlay(aStyle)) {
380
417
  RevealPage(true);
381
418
  let pageBlocker = document.createElement('div');
@@ -394,16 +431,19 @@ function EndPoint(aStyle, aOverlay = aStyle, aAnimation = aStyle) {
394
431
  document.getElementById(finalOptions.mainContentIdName).hidden = true;
395
432
  }
396
433
  }
397
- //console.log(allowAnimate, !(!finalOptions.animateIgnoredLinks && sessionStorage.getItem("animationType") == "ignore"), !(!finalOptions.animateSelfLink && sessionStorage.getItem("animationType") == "ignore"))
398
- if (allowAnimate && !(!finalOptions.animateIgnoredLinks && sessionStorage.getItem("animationType") == "ignore") && !(!finalOptions.animateSelfLink && sessionStorage.getItem("animationType") == "ignore")) {
434
+ //Checks to see if allowAnimate=true and we aren't supposed to be ignoring the link
435
+ if (allowAnimate && !(sessionStorage.getItem("animationType") === "ignore" && (finalOptions.animateIgnoredLinks || finalOptions.animateSelfLink))){
436
+ //Once the load evnet is triggered, it registers a listener
399
437
  window.addEventListener(finalOptions.loadEvent, (e) => {
400
438
  e.stopPropagation();
401
439
  CallHook("animateSEP", { style: aStyle });
402
- //console.log(window.performance.getEntriesByType("navigation")[0].type, isNavigationFromSameSite(), finalOptions.runAnimationOnCrossSite)
440
+ //If we reloaded, we want to make sure runAnimationOnPageReload is false and if we came from a different site, we want to make sure we can run animation on cross site
403
441
  if ((window.performance.getEntriesByType("navigation")[0].type != "reload" || finalOptions.runAnimationOnPageReload) && (isNavigationFromSameSite() || finalOptions.runAnimationOnCrossSite)) {
442
+ //Uses a delay between this to keep the document hidden for extra if the load event isn't trusted
404
443
  setTimeout(
405
444
  () => {
406
445
  AnimatePageTransition(aStyle, "reverse");
446
+ //Delay between animation and reveal
407
447
  setTimeout(
408
448
  () => {
409
449
  CallHook("animateEEP", { style: aStyle });
@@ -413,11 +453,13 @@ function EndPoint(aStyle, aOverlay = aStyle, aAnimation = aStyle) {
413
453
  }, finalOptions.pageAnimationDelay
414
454
  );
415
455
  } else {
456
+ //Reveals page after document is built
416
457
  CallHook("animateEPNA", { style: aStyle })
417
458
  RevealPage();
418
459
  }
419
460
  }, { once: true });
420
461
  } else {
462
+ //Waits for load and Reveals the Page
421
463
  window.addEventListener(finalOptions.loadEvent, () => {
422
464
  CallHook("animateEPNSW", { style: aStyle })
423
465
  RevealPage();
@@ -425,9 +467,12 @@ function EndPoint(aStyle, aOverlay = aStyle, aAnimation = aStyle) {
425
467
  }
426
468
  }
427
469
  exports.EndPoint = EndPoint;
470
+ //Animates the page transition
428
471
  function AnimatePageTransition(aStyle, direction = "normal") {
429
472
  let mainElement = document.getElementById(finalOptions.mainContentIdName);
473
+ //If we don't have a preset, we can call a hook because presets also call their custom variant
430
474
  if (!(aStyle instanceof OverlayPreset) && !(aStyle instanceof KeyFramePreset)) {
475
+ //Sets animationType in storage to allow EndPoint to change page transition element depending on type
431
476
  sessionStorage.setItem("animationType", IsOverlay(aStyle).toString());
432
477
  if (direction == "normal") {
433
478
  CallHook("animateSF", { style: aStyle, ele: mainElement, });
@@ -435,7 +480,9 @@ function AnimatePageTransition(aStyle, direction = "normal") {
435
480
  CallHook("animateSR", { style: aStyle, ele: mainElement, });
436
481
  }
437
482
  }
483
+ //Calls handle function of style element
438
484
  aStyle.handle(direction, mainElement);
485
+ //Same logic as above except for end hooks
439
486
  if (!(aStyle instanceof OverlayPreset) && !(aStyle instanceof KeyFramePreset)) {
440
487
  setTimeout(
441
488
  () => {
package/guide.txt DELETED
@@ -1,56 +0,0 @@
1
- Types of Animation Containers:
2
- -KeyFramePreset
3
- -KeyFrameCustom
4
- -StyleTransition
5
- -OverlayPreset
6
- -OverlayCustom
7
- -MultiElementAnimation
8
-
9
- Preset Types:
10
- -Overlay Presets
11
- -Keyframe Presets
12
-
13
- Animation Function:
14
- -AnimatePageTransition
15
-
16
- Listener Functions:
17
- -ListenForChange
18
- -SendPoint
19
- -EndPoint
20
-
21
- Hooks:
22
- -animateSF - animation start forward
23
- -animateSR - animation start reverse
24
- -animateEF - animation end forward
25
- -animateER - animation end reverse
26
- -animateSSP - start of send point listen
27
- -animateESP - end of send point listen
28
- -animateSEP - start of end point listen
29
- -animateEPNSW - end point no service worker exists
30
- -animateEEP - end of end point
31
- -animateEPNA - end point no animation played
32
-
33
- Features:
34
- -Built-in animations
35
- -Hooks
36
- -Doesn't touch history or use push state, allowing
37
- for you to use it with routers like sveltekit
38
- -Manual page transition animations can be run to avoid
39
- conflicts with any frameworks
40
- -Customizable ids for divs to avoid conflict with elements
41
- in your body
42
- -Allows for custom overlay animations, keyframe animations, or
43
- transition animations
44
- -Separate listener animations for different types of animations
45
- -Separate types of links for overlay or other animations
46
-
47
- What I Learned:
48
- -Expanded knowledge on HTML, JS, and CSS Knowledge
49
- -Session storage
50
- -Service workers
51
- -Polymorphism
52
- -Event dispatcher
53
-
54
- Common Issues:
55
- -White Flash
56
- -Issues with using absolute positioning on main content and calling overlay animations