diff options
| author | Eltrac <hi@guhub.cn> | 2025-09-16 14:07:00 +0800 |
|---|---|---|
| committer | Eltrac <hi@guhub.cn> | 2025-09-16 14:07:00 +0800 |
| commit | ce5cec5257981c48b8181213f6616e5467f7dafc (patch) | |
| tree | 9f827770666b6eebce74c3f750af9271ad7ae8df /src | |
| parent | 883a2bd5f1a3bd336d5f8a56abe4ae56df504f8c (diff) | |
fix: smoother zoom-in animation, more accurate positioning
Diffstat (limited to 'src')
| -rw-r--r-- | src/libra.css | 2 | ||||
| -rw-r--r-- | src/shadow.js | 55 |
2 files changed, 30 insertions, 27 deletions
diff --git a/src/libra.css b/src/libra.css index 71ed6ef..2118d14 100644 --- a/src/libra.css +++ b/src/libra.css @@ -24,7 +24,7 @@ } .libra-shadow { - position: fixed; + position: absolute; transition-duration: 0.2s; transition-property: transform; display: block; diff --git a/src/shadow.js b/src/shadow.js index c893b55..9babfcf 100644 --- a/src/shadow.js +++ b/src/shadow.js @@ -10,7 +10,6 @@ export default class Shadow { constructor(image) { this.create(image); - this.calculateStartsAndFinals(); return this; } @@ -33,39 +32,40 @@ export default class Shadow { } calculateStartsAndFinals() { - // get starting state - const s = { + // 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; } - const f = {}; - const margin = 50; - - // calculate final size - const nw = this.element.naturalWidth; - const nh = this.element.naturalHeight; - const ratio = nw / nh; - - const ww = window.innerWidth - margin*2; - const wh = window.innerHeight - margin*2; - - f.width = Math.min(nw, ww); - f.height = f.width / ratio; + finals.top = (wh - finals.height) / 2 + window.scrollY + margin; + finals.left = (ww - finals.width) / 2 + window.scrollX + margin; - if (f.height >= wh) { - f.height = wh; - f.width = f.height * ratio; - } - - // calculate final position - f.left = (ww - f.width) / 2 + margin; - f.top = (wh - f.height) / 2 + margin; + this.startingState = starts; + this.finalState = finals; - this.finalState = f; - this.startingState = s; + return { starts, finals }; } /** @@ -76,12 +76,15 @@ export default class Shadow { open() { this.isOpen = true; + this.calculateStartsAndFinals(); this.animate(this.startingState, this.finalState) } close() { this.isOpen = false; this.element.style.transform = `matrix(1, 0, 0, 1, 0, 0)`; + this.calculateStartsAndFinals(); + this.animate(this.finalState, this.startingState) setTimeout(() => { this.destroyItself(); }, 300); |
