summaryrefslogtreecommitdiff
path: root/src/shadow.js
diff options
context:
space:
mode:
authorEltrac <hi@guhub.cn>2025-09-18 18:54:52 +0800
committerGitHub <noreply@github.com>2025-09-18 18:54:52 +0800
commit2afcb97eeab22b2ae7b3dc697e0cfab318aa0722 (patch)
tree9a101095d390ea3a336427e295210d11eab824f3 /src/shadow.js
parentd26860e424227003122b077c8d2e76223d760e67 (diff)
parent7113655e17a38d9d73cffe469c28b6ddf5b0636f (diff)
Merge pull request #2 from QuarkPixel/master
Fix Multiple UI/UX Issues and Improve Configuration Management
Diffstat (limited to 'src/shadow.js')
-rw-r--r--src/shadow.js75
1 files changed, 48 insertions, 27 deletions
diff --git a/src/shadow.js b/src/shadow.js
index 9889240..50e3345 100644
--- a/src/shadow.js
+++ b/src/shadow.js
@@ -2,8 +2,7 @@ import Animation from './animation.js'
import config from './config'
export default class Shadow {
- zIndex = '1000'
- isOpen = false
+ isOpen = false;
/**
* ============
@@ -13,15 +12,7 @@ export default class Shadow {
constructor(image) {
this.original = image;
-
- const rect = this.original.getBoundingClientRect();
- this.originalPosition = {
- top: rect.top + window.scrollY + config.offset.y,
- left: rect.left + window.scrollX + config.offset.x,
- width: rect.width,
- height: rect.height
- }
-
+ this.fetchOriginalPosition();
this.create(image);
return this;
@@ -33,16 +24,30 @@ export default class Shadow {
shadow.src = image.src;
shadow.id = `libra-shadow-${image.id}`;
shadow.classList.add('libra-shadow');
+ shadow.style.transitionDuration = config.transitionDuration + 'ms';
- // style and position shadow image
- shadow.style.top = `${this.originalPosition.top}px`;
- shadow.style.left = `${this.originalPosition.left}px`;
- shadow.style.width = `${this.originalPosition.width}px`;
- shadow.style.height = `${this.originalPosition.height}px`;
- shadow.style.zIndex = this.zIndex;
-
- document.body.appendChild(shadow);
this.element = shadow;
+
+ // set positioning and place shadow element
+ this.positionShadow();
+ this.placeItself();
+ }
+
+ fetchOriginalPosition() {
+ const rect = this.original.getBoundingClientRect();
+ this.originalPosition = {
+ top: rect.top + window.scrollY + config.offset.y,
+ left: rect.left + window.scrollX + config.offset.x,
+ width: rect.width,
+ height: rect.height,
+ };
+ }
+
+ positionShadow() {
+ this.element.style.top = this.originalPosition.top + 'px';
+ this.element.style.left = this.originalPosition.left + 'px';
+ this.element.style.width = this.originalPosition.width + 'px';
+ this.element.style.height = this.originalPosition.height + 'px';
}
/**
@@ -55,24 +60,40 @@ export default class Shadow {
this.isOpen = true;
this.element.classList.add('open');
+ // Update original position before animation in case viewport changed
+ this.fetchOriginalPosition();
+ this.positionShadow();
+
this.original.style.visibility = 'hidden';
if (!document.body.contains(this.element)) this.placeItself();
- Animation.transformMatrix(
- this.element,
- this.originalPosition,
- Animation.calculateFinalState(this.element)
- );
+ // play animation
+ const animate = () =>
+ Animation.transformMatrix(
+ this.element,
+ this.originalPosition,
+ Animation.calculateFinalState(this.element),
+ );
+
+ if (this.element.naturalWidth === 0 || this.element.naturalHeight === 0) {
+ // Wait for image to load before animating
+ this.element.addEventListener('load', animate, { once: true });
+ } else {
+ // animate directly if loaded
+ animate();
+ }
}
close() {
this.isOpen = false;
this.element.classList.remove('open');
- this.original.style.visibility = 'visible';
-
Animation.resetTransformMatrix(this.element);
- setTimeout(() => this.destroyItself(), 300);
+ // Wait for animation to complete before showing original and destroying shadow
+ setTimeout(() => {
+ this.original.style.visibility = 'visible';
+ this.destroyItself();
+ }, config.transitionDuration);
}
placeItself() {