summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEltrac <hi@guhub.cn>2025-09-16 14:29:26 +0800
committerEltrac <hi@guhub.cn>2025-09-16 14:29:26 +0800
commit0971f24549ea47868a8c0c207680a7bdcacfd05b (patch)
treef180237ddb58d61aff58a5ff4b7d511bc39477d3
parentb0204119949adf3bb273473c605e1c8696023e11 (diff)
refactor: move animation logic to individual module
-rw-r--r--src/animation.js49
-rw-r--r--src/shadow.js78
2 files changed, 66 insertions, 61 deletions
diff --git a/src/animation.js b/src/animation.js
new file mode 100644
index 0000000..b62fc21
--- /dev/null
+++ b/src/animation.js
@@ -0,0 +1,49 @@
+export default class Animation {
+ static calculateFinalState(element) {
+ let finals = {}
+
+ const margin = 50
+ const ratio = element.naturalWidth / element.naturalHeight;
+ const ww = window.innerWidth - 2*margin;
+ const wh = window.innerHeight - 2*margin;
+
+ if (element.naturalWidth > ww) {
+ finals.width = ww;
+ finals.height = ww / ratio;
+ if (finals.height > wh) {
+ finals.height = wh;
+ finals.width = wh * ratio;
+ }
+ } else {
+ finals.width = element.offsetWidth;
+ finals.height = element.offsetHeight;
+ }
+
+ finals.top = (wh - finals.height) / 2 + window.scrollY + margin;
+ finals.left = (ww - finals.width) / 2 + window.scrollX + margin;
+
+ return finals;
+ }
+
+ static transformMatrix(element, starts, finals) {
+ // Calculate scaling factors based on width and height interpolation
+ const scaleX = finals.width / starts.width;
+ const scaleY = finals.height / starts.height;
+
+ // Calculate the center of the starting and final positions
+ const startCenterX = starts.left + starts.width / 2;
+ const startCenterY = starts.top + starts.height / 2;
+ const finalCenterX = finals.left + finals.width / 2;
+ const finalCenterY = finals.top + finals.height / 2;
+
+ const translateX = finalCenterX - startCenterX;
+ const translateY = finalCenterY - startCenterY;
+
+ // Apply the transform with matrix (scale + translate)
+ element.style.transform = `matrix(${scaleX}, 0, 0, ${scaleY}, ${translateX}, ${translateY})`;
+ }
+
+ static resetTransformMatrix(element) {
+ element.style.transform = `matrix(1, 0, 0, 1, 0, 0)`;
+ }
+}
diff --git a/src/shadow.js b/src/shadow.js
index c0374b1..995b9c2 100644
--- a/src/shadow.js
+++ b/src/shadow.js
@@ -1,3 +1,5 @@
+import Animation from './animation.js'
+
export default class Shadow {
zIndex = '1000'
isOpen = false
@@ -10,6 +12,14 @@ export default class Shadow {
constructor(image) {
this.create(image);
+
+ this.startingState = {
+ top: this.element.offsetTop,
+ left: this.element.offsetLeft,
+ width: this.element.offsetWidth,
+ height: this.element.offsetHeight
+ }
+
return this;
}
@@ -31,43 +41,6 @@ export default class Shadow {
this.element = shadowImage;
}
- calculateStartsAndFinals() {
- // snapshot current state
- const starts = {
- top: this.element.offsetTop,
- left: this.element.offsetLeft,
- width: this.element.offsetWidth,
- height: this.element.offsetHeight
- };
-
- let finals = {}
-
- const margin = 50
- const ratio = this.element.naturalWidth / this.element.naturalHeight;
- const ww = window.innerWidth - 2*margin;
- const wh = window.innerHeight - 2*margin;
-
- if (this.element.naturalWidth > ww) {
- finals.width = ww;
- finals.height = ww / ratio;
- if (finals.height > wh) {
- finals.height = wh;
- finals.width = wh * ratio;
- }
- } else {
- finals.width = this.element.offsetWidth;
- finals.height = this.element.offsetHeight;
- }
-
- finals.top = (wh - finals.height) / 2 + window.scrollY + margin;
- finals.left = (ww - finals.width) / 2 + window.scrollX + margin;
-
- this.startingState = starts;
- this.finalState = finals;
-
- return { starts, finals };
- }
-
/**
* ============
* Actions
@@ -76,34 +49,17 @@ export default class Shadow {
open() {
this.isOpen = true;
- this.calculateStartsAndFinals();
- this.animate(this.startingState, this.finalState)
+ Animation.transformMatrix(
+ this.element,
+ this.startingState,
+ Animation.calculateFinalState(this.element)
+ );
}
close() {
this.isOpen = false;
- this.element.style.transform = `matrix(1, 0, 0, 1, 0, 0)`;
- setTimeout(() => {
- this.destroyItself();
- }, 300);
- }
-
- animate(starts, finals) {
- // Calculate scaling factors based on width and height interpolation
- const scaleX = finals.width / starts.width;
- const scaleY = finals.height / starts.height;
-
- // Calculate the center of the starting and final positions
- const startCenterX = starts.left + starts.width / 2;
- const startCenterY = starts.top + starts.height / 2;
- const finalCenterX = finals.left + finals.width / 2;
- const finalCenterY = finals.top + finals.height / 2;
-
- const translateX = finalCenterX - startCenterX;
- const translateY = finalCenterY - startCenterY;
-
- // Apply the transform with matrix (scale + translate)
- this.element.style.transform = `matrix(${scaleX}, 0, 0, ${scaleY}, ${translateX}, ${translateY})`;
+ Animation.resetTransformMatrix(this.element);
+ setTimeout(() => this.destroyItself(), 300);
}
placeItself() {