@readdy/anim 0.0.21
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.
- package/animations/button/3d-flip/index.js +60 -0
- package/animations/button/3d-flip/react.tsx +29 -0
- package/animations/button/3d-flip/style.css +17 -0
- package/animations/button/blur-fade-in/index.js +21 -0
- package/animations/button/blur-fade-in/react.tsx +26 -0
- package/animations/button/blur-fade-in/style.css +27 -0
- package/animations/button/border-beam/index.js +172 -0
- package/animations/button/border-beam/react.tsx +55 -0
- package/animations/button/border-beam/style.css +59 -0
- package/animations/button/bounce-elastic/index.js +21 -0
- package/animations/button/bounce-elastic/react.tsx +26 -0
- package/animations/button/bounce-elastic/style.css +31 -0
- package/animations/button/bubble-button/index.js +317 -0
- package/animations/button/bubble-button/react.tsx +19 -0
- package/animations/button/bubble-button/style.css +245 -0
- package/animations/button/confetti-button/index.js +66 -0
- package/animations/button/confetti-button/react.tsx +30 -0
- package/animations/button/confetti-button/style.css +48 -0
- package/animations/button/glow-cta/index.js +69 -0
- package/animations/button/glow-cta/react.tsx +45 -0
- package/animations/button/glow-cta/style.css +78 -0
- package/animations/button/magnetic-hover/index.js +61 -0
- package/animations/button/magnetic-hover/react.tsx +29 -0
- package/animations/button/magnetic-hover/style.css +18 -0
- package/animations/button/pulse/index.js +21 -0
- package/animations/button/pulse/react.tsx +26 -0
- package/animations/button/pulse/style.css +24 -0
- package/animations/button/rainbow-button/index.js +21 -0
- package/animations/button/rainbow-button/react.tsx +26 -0
- package/animations/button/rainbow-button/style.css +54 -0
- package/animations/button/shimmer-border/index.js +28 -0
- package/animations/button/shimmer-border/react.tsx +41 -0
- package/animations/button/shimmer-border/style.css +53 -0
- package/animations/button/sketch-button/index.js +16 -0
- package/animations/button/sketch-button/react.tsx +19 -0
- package/animations/button/sketch-button/style.css +25 -0
- package/animations/card/blur-rise/index.js +21 -0
- package/animations/card/blur-rise/react.tsx +26 -0
- package/animations/card/blur-rise/style.css +27 -0
- package/animations/card/bounce-in-bottom/index.js +21 -0
- package/animations/card/bounce-in-bottom/react.tsx +26 -0
- package/animations/card/bounce-in-bottom/style.css +31 -0
- package/animations/card/card-fan-spread/index.js +146 -0
- package/animations/card/card-fan-spread/react.tsx +35 -0
- package/animations/card/card-fan-spread/style.css +90 -0
- package/animations/card/card-flip/index.js +203 -0
- package/animations/card/card-flip/react.tsx +35 -0
- package/animations/card/card-flip/style.css +71 -0
- package/animations/card/float-idle/index.js +21 -0
- package/animations/card/float-idle/react.tsx +26 -0
- package/animations/card/float-idle/style.css +21 -0
- package/animations/card/image-magnifier/index.js +333 -0
- package/animations/card/image-magnifier/react.tsx +31 -0
- package/animations/card/image-magnifier/style.css +42 -0
- package/animations/card/image-zoom-rotate/index.js +48 -0
- package/animations/card/image-zoom-rotate/react.tsx +31 -0
- package/animations/card/image-zoom-rotate/style.css +20 -0
- package/animations/card/pop-in-stack/index.js +25 -0
- package/animations/card/pop-in-stack/react.tsx +33 -0
- package/animations/card/pop-in-stack/style.css +25 -0
- package/animations/card/reveal-from-top/index.js +21 -0
- package/animations/card/reveal-from-top/react.tsx +26 -0
- package/animations/card/reveal-from-top/style.css +28 -0
- package/animations/card/rgb-split-glitch/index.js +28 -0
- package/animations/card/rgb-split-glitch/react.tsx +41 -0
- package/animations/card/rgb-split-glitch/style.css +33 -0
- package/animations/card/tilted-card/index.js +64 -0
- package/animations/card/tilted-card/react.tsx +33 -0
- package/animations/card/tilted-card/style.css +27 -0
- package/animations/header/anime-splittext/index.js +108 -0
- package/animations/header/anime-splittext/react.tsx +30 -0
- package/animations/header/anime-splittext/style.css +71 -0
- package/animations/header/bounce-in-down/index.js +40 -0
- package/animations/header/bounce-in-down/react.tsx +29 -0
- package/animations/header/bounce-in-down/style.css +40 -0
- package/animations/header/fly-in-chars/index.js +46 -0
- package/animations/header/fly-in-chars/react.tsx +30 -0
- package/animations/header/fly-in-chars/style.css +29 -0
- package/animations/header/gradient-text/index.js +21 -0
- package/animations/header/gradient-text/react.tsx +26 -0
- package/animations/header/gradient-text/style.css +28 -0
- package/animations/header/letter-bounce/index.js +33 -0
- package/animations/header/letter-bounce/react.tsx +34 -0
- package/animations/header/letter-bounce/style.css +25 -0
- package/animations/header/roll-in/index.js +40 -0
- package/animations/header/roll-in/react.tsx +29 -0
- package/animations/header/roll-in/style.css +31 -0
- package/animations/header/shimmer-text/index.js +16 -0
- package/animations/header/shimmer-text/react.tsx +28 -0
- package/animations/header/shimmer-text/style.css +29 -0
- package/animations/header/shuffle/index.js +118 -0
- package/animations/header/shuffle/react.tsx +50 -0
- package/animations/header/shuffle/style.css +25 -0
- package/animations/header/split-text/index.js +72 -0
- package/animations/header/split-text/react.tsx +38 -0
- package/animations/header/split-text/style.css +31 -0
- package/animations/header/text-type/index.js +267 -0
- package/animations/header/text-type/react.tsx +63 -0
- package/animations/header/text-type/style.css +37 -0
- package/animations/header/word-curtain-reveal/index.js +97 -0
- package/animations/header/word-curtain-reveal/react.tsx +30 -0
- package/animations/header/word-curtain-reveal/style.css +39 -0
- package/dist/button/3d-flip/react.js +21 -0
- package/dist/button/3d-flip.js +61 -0
- package/dist/button/blur-fade-in/react.js +28 -0
- package/dist/button/blur-fade-in.js +17 -0
- package/dist/button/border-beam/react.js +22 -0
- package/dist/button/border-beam.js +168 -0
- package/dist/button/bounce-elastic/react.js +28 -0
- package/dist/button/bounce-elastic.js +17 -0
- package/dist/button/bubble-button/react.js +20 -0
- package/dist/button/bubble-button.js +318 -0
- package/dist/button/confetti-button/react.js +21 -0
- package/dist/button/confetti-button.js +67 -0
- package/dist/button/glow-cta/react.js +23 -0
- package/dist/button/glow-cta.js +65 -0
- package/dist/button/magnetic-hover/react.js +21 -0
- package/dist/button/magnetic-hover.js +62 -0
- package/dist/button/pulse/react.js +28 -0
- package/dist/button/pulse.js +17 -0
- package/dist/button/rainbow-button/react.js +28 -0
- package/dist/button/rainbow-button.js +17 -0
- package/dist/button/shimmer-border/react.js +22 -0
- package/dist/button/shimmer-border.js +24 -0
- package/dist/button/sketch-button/react.js +20 -0
- package/dist/button/sketch-button.js +17 -0
- package/dist/card/blur-rise/react.js +28 -0
- package/dist/card/blur-rise.js +17 -0
- package/dist/card/bounce-in-bottom/react.js +28 -0
- package/dist/card/bounce-in-bottom.js +17 -0
- package/dist/card/card-fan-spread/react.js +20 -0
- package/dist/card/card-fan-spread.js +147 -0
- package/dist/card/float-idle/react.js +28 -0
- package/dist/card/float-idle.js +17 -0
- package/dist/card/image-magnifier/react.js +22 -0
- package/dist/card/image-magnifier.js +334 -0
- package/dist/card/image-zoom-rotate/react.js +21 -0
- package/dist/card/image-zoom-rotate.js +49 -0
- package/dist/card/pop-in-stack/react.js +20 -0
- package/dist/card/pop-in-stack.js +26 -0
- package/dist/card/reveal-from-top/react.js +28 -0
- package/dist/card/reveal-from-top.js +17 -0
- package/dist/card/rgb-split-glitch/react.js +22 -0
- package/dist/card/rgb-split-glitch.js +24 -0
- package/dist/card/tilted-card/react.js +21 -0
- package/dist/card/tilted-card.js +65 -0
- package/dist/chunks/constants-EnH6-Pz4.js +66 -0
- package/dist/chunks/constants-ZTHic1pf.js +66 -0
- package/dist/chunks/pointer-follow-B3RFnn_q.js +93 -0
- package/dist/chunks/pointer-follow-BETANySn.js +93 -0
- package/dist/chunks/reduced-motion-BpQYuEzK.js +17 -0
- package/dist/chunks/reduced-motion-HX79Ac8G.js +17 -0
- package/dist/chunks/resolve-card-media-Cj3V_oms.js +43 -0
- package/dist/chunks/resolve-card-media-DBIU-duL.js +43 -0
- package/dist/chunks/text-split-D02jltVh.js +191 -0
- package/dist/chunks/text-split-frOR4UpH.js +191 -0
- package/dist/full.css +1 -0
- package/dist/full.js +3192 -0
- package/dist/header/anime-splittext/react.js +22 -0
- package/dist/header/anime-splittext.js +109 -0
- package/dist/header/bounce-in-down/react.js +32 -0
- package/dist/header/bounce-in-down.js +36 -0
- package/dist/header/fly-in-chars/react.js +23 -0
- package/dist/header/fly-in-chars.js +47 -0
- package/dist/header/gradient-text/react.js +28 -0
- package/dist/header/gradient-text.js +17 -0
- package/dist/header/letter-bounce/react.js +23 -0
- package/dist/header/letter-bounce.js +34 -0
- package/dist/header/roll-in/react.js +32 -0
- package/dist/header/roll-in.js +36 -0
- package/dist/header/shimmer-text/react.js +27 -0
- package/dist/header/shimmer-text.js +17 -0
- package/dist/header/shuffle/react.js +30 -0
- package/dist/header/shuffle.js +119 -0
- package/dist/header/split-text/react.js +26 -0
- package/dist/header/split-text.js +73 -0
- package/dist/header/text-type/react.js +43 -0
- package/dist/header/text-type.js +268 -0
- package/dist/header/word-curtain-reveal/react.js +22 -0
- package/dist/header/word-curtain-reveal.js +98 -0
- package/dist/meta.json +6 -0
- package/dist/metadata.json +1051 -0
- package/dist/react.css +1 -0
- package/dist/types/animations/button/3d-flip/index.d.ts +3 -0
- package/dist/types/animations/button/3d-flip/react.d.ts +8 -0
- package/dist/types/animations/button/blur-fade-in/index.d.ts +3 -0
- package/dist/types/animations/button/blur-fade-in/react.d.ts +13 -0
- package/dist/types/animations/button/border-beam/index.d.ts +3 -0
- package/dist/types/animations/button/border-beam/react.d.ts +25 -0
- package/dist/types/animations/button/bounce-elastic/index.d.ts +3 -0
- package/dist/types/animations/button/bounce-elastic/react.d.ts +13 -0
- package/dist/types/animations/button/bubble-button/index.d.ts +3 -0
- package/dist/types/animations/button/bubble-button/react.d.ts +4 -0
- package/dist/types/animations/button/confetti-button/index.d.ts +3 -0
- package/dist/types/animations/button/confetti-button/react.d.ts +8 -0
- package/dist/types/animations/button/glow-cta/index.d.ts +3 -0
- package/dist/types/animations/button/glow-cta/react.d.ts +20 -0
- package/dist/types/animations/button/magnetic-hover/index.d.ts +3 -0
- package/dist/types/animations/button/magnetic-hover/react.d.ts +8 -0
- package/dist/types/animations/button/pulse/index.d.ts +3 -0
- package/dist/types/animations/button/pulse/react.d.ts +13 -0
- package/dist/types/animations/button/rainbow-button/index.d.ts +3 -0
- package/dist/types/animations/button/rainbow-button/react.d.ts +13 -0
- package/dist/types/animations/button/shimmer-border/index.d.ts +3 -0
- package/dist/types/animations/button/shimmer-border/react.d.ts +18 -0
- package/dist/types/animations/button/sketch-button/index.d.ts +3 -0
- package/dist/types/animations/button/sketch-button/react.d.ts +4 -0
- package/dist/types/animations/card/blur-rise/index.d.ts +3 -0
- package/dist/types/animations/card/blur-rise/react.d.ts +13 -0
- package/dist/types/animations/card/bounce-in-bottom/index.d.ts +3 -0
- package/dist/types/animations/card/bounce-in-bottom/react.d.ts +13 -0
- package/dist/types/animations/card/card-fan-spread/index.d.ts +3 -0
- package/dist/types/animations/card/card-fan-spread/react.d.ts +11 -0
- package/dist/types/animations/card/card-flip/index.d.ts +3 -0
- package/dist/types/animations/card/card-flip/react.d.ts +11 -0
- package/dist/types/animations/card/float-idle/index.d.ts +3 -0
- package/dist/types/animations/card/float-idle/react.d.ts +13 -0
- package/dist/types/animations/card/image-magnifier/index.d.ts +3 -0
- package/dist/types/animations/card/image-magnifier/react.d.ts +9 -0
- package/dist/types/animations/card/image-zoom-rotate/index.d.ts +3 -0
- package/dist/types/animations/card/image-zoom-rotate/react.d.ts +9 -0
- package/dist/types/animations/card/pop-in-stack/index.d.ts +3 -0
- package/dist/types/animations/card/pop-in-stack/react.d.ts +10 -0
- package/dist/types/animations/card/reveal-from-top/index.d.ts +3 -0
- package/dist/types/animations/card/reveal-from-top/react.d.ts +13 -0
- package/dist/types/animations/card/rgb-split-glitch/index.d.ts +3 -0
- package/dist/types/animations/card/rgb-split-glitch/react.d.ts +18 -0
- package/dist/types/animations/card/tilted-card/index.d.ts +3 -0
- package/dist/types/animations/card/tilted-card/react.d.ts +10 -0
- package/dist/types/animations/header/anime-splittext/index.d.ts +3 -0
- package/dist/types/animations/header/anime-splittext/react.d.ts +8 -0
- package/dist/types/animations/header/bounce-in-down/index.d.ts +3 -0
- package/dist/types/animations/header/bounce-in-down/react.d.ts +13 -0
- package/dist/types/animations/header/fly-in-chars/index.d.ts +3 -0
- package/dist/types/animations/header/fly-in-chars/react.d.ts +8 -0
- package/dist/types/animations/header/gradient-text/index.d.ts +3 -0
- package/dist/types/animations/header/gradient-text/react.d.ts +13 -0
- package/dist/types/animations/header/letter-bounce/index.d.ts +3 -0
- package/dist/types/animations/header/letter-bounce/react.d.ts +10 -0
- package/dist/types/animations/header/roll-in/index.d.ts +3 -0
- package/dist/types/animations/header/roll-in/react.d.ts +13 -0
- package/dist/types/animations/header/shimmer-text/index.d.ts +3 -0
- package/dist/types/animations/header/shimmer-text/react.d.ts +4 -0
- package/dist/types/animations/header/shuffle/index.d.ts +3 -0
- package/dist/types/animations/header/shuffle/react.d.ts +14 -0
- package/dist/types/animations/header/split-text/index.d.ts +3 -0
- package/dist/types/animations/header/split-text/react.d.ts +10 -0
- package/dist/types/animations/header/text-type/index.d.ts +3 -0
- package/dist/types/animations/header/text-type/react.d.ts +13 -0
- package/dist/types/animations/header/word-curtain-reveal/index.d.ts +3 -0
- package/dist/types/animations/header/word-curtain-reveal/react.d.ts +8 -0
- package/dist/types/react-barrel.d.ts +34 -0
- package/dist/types/scripts/bundle-all.d.ts +173 -0
- package/dist/types/scripts/check-metadata.d.ts +1 -0
- package/dist/types/scripts/copy-metadata.d.ts +1 -0
- package/dist/types/scripts/generate-animation-id-map.d.ts +1 -0
- package/dist/types/scripts/generate-dist-meta.d.ts +1 -0
- package/dist/types/scripts/generate-preview-manifest.d.ts +1 -0
- package/dist/types/scripts/update-metadata.d.ts +1 -0
- package/dist/types/shared/constants.d.ts +34 -0
- package/dist/types/shared/meta.d.ts +18 -0
- package/dist/types/shared/pointer-follow.d.ts +8 -0
- package/dist/types/shared/reduced-motion.d.ts +11 -0
- package/dist/types/shared/resolve-card-media.d.ts +1 -0
- package/dist/types/shared/text-split.d.ts +19 -0
- package/dist/types/stories/3d-flip.stories.d.ts +7 -0
- package/dist/types/stories/_helpers.d.ts +24 -0
- package/dist/types/stories/anime-splittext.stories.d.ts +8 -0
- package/dist/types/stories/blur-fade-in.stories.d.ts +8 -0
- package/dist/types/stories/blur-rise.stories.d.ts +8 -0
- package/dist/types/stories/blur-to-sharp-rise-header.stories.d.ts +8 -0
- package/dist/types/stories/border-beam.stories.d.ts +8 -0
- package/dist/types/stories/bounce-elastic.stories.d.ts +8 -0
- package/dist/types/stories/bounce-in-bottom.stories.d.ts +8 -0
- package/dist/types/stories/bounce-in-down.stories.d.ts +9 -0
- package/dist/types/stories/bubble-button.stories.d.ts +8 -0
- package/dist/types/stories/card-fan-spread.stories.d.ts +7 -0
- package/dist/types/stories/card-flip.stories.d.ts +7 -0
- package/dist/types/stories/confetti-button.stories.d.ts +7 -0
- package/dist/types/stories/float-idle.stories.d.ts +8 -0
- package/dist/types/stories/fly-in-chars.stories.d.ts +8 -0
- package/dist/types/stories/glow-cta.stories.d.ts +9 -0
- package/dist/types/stories/gradient-text.stories.d.ts +9 -0
- package/dist/types/stories/image-magnifier.stories.d.ts +10 -0
- package/dist/types/stories/image-zoom-rotate.stories.d.ts +7 -0
- package/dist/types/stories/letter-bounce.stories.d.ts +8 -0
- package/dist/types/stories/magic-ui-border-beam-card.stories.d.ts +8 -0
- package/dist/types/stories/magnetic-hover.stories.d.ts +7 -0
- package/dist/types/stories/pop-in-stack.stories.d.ts +7 -0
- package/dist/types/stories/pulse.stories.d.ts +8 -0
- package/dist/types/stories/rainbow-button.stories.d.ts +8 -0
- package/dist/types/stories/reveal-from-top.stories.d.ts +8 -0
- package/dist/types/stories/rgb-split-glitch.stories.d.ts +8 -0
- package/dist/types/stories/roll-in.stories.d.ts +9 -0
- package/dist/types/stories/shimmer-border.stories.d.ts +9 -0
- package/dist/types/stories/shimmer-text.stories.d.ts +8 -0
- package/dist/types/stories/shuffle.stories.d.ts +8 -0
- package/dist/types/stories/sketch-button.stories.d.ts +7 -0
- package/dist/types/stories/split-text.stories.d.ts +8 -0
- package/dist/types/stories/text-type.stories.d.ts +8 -0
- package/dist/types/stories/tilted-card.stories.d.ts +7 -0
- package/dist/types/stories/word-curtain-reveal.stories.d.ts +8 -0
- package/package.json +166 -0
- package/react-barrel.js +44 -0
- package/shared/constants.js +64 -0
- package/shared/meta.js +21 -0
- package/shared/pointer-follow.js +91 -0
- package/shared/reduced-motion.js +15 -0
- package/shared/resolve-card-media.js +41 -0
- package/shared/text-split.js +188 -0
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { b as buildAnimId, a as buildAnimClass } from '../chunks/constants-EnH6-Pz4.js';
|
|
2
|
+
|
|
3
|
+
const ANIMATION_ID = buildAnimId('reveal-from-top');
|
|
4
|
+
|
|
5
|
+
const CSS_CLASS = buildAnimClass('reveal-from-top');
|
|
6
|
+
|
|
7
|
+
function init(el, options = {}) {
|
|
8
|
+
if (!el.classList.contains(CSS_CLASS)) {
|
|
9
|
+
el.classList.add(CSS_CLASS);
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
function destroy(el) {
|
|
14
|
+
el.classList.remove(CSS_CLASS);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export { ANIMATION_ID, destroy, init };
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import React, { useRef, useEffect } from 'react';
|
|
2
|
+
import { p as prefersReducedMotion } from '../../chunks/reduced-motion-HX79Ac8G.js';
|
|
3
|
+
import { init, destroy } from '../rgb-split-glitch.js';
|
|
4
|
+
import '../../chunks/constants-EnH6-Pz4.js';
|
|
5
|
+
|
|
6
|
+
function AnimRgbSplitGlitch({ children, duration, shift, shadowOffset, }) {
|
|
7
|
+
const ref = useRef(null);
|
|
8
|
+
useEffect(() => {
|
|
9
|
+
const el = ref.current;
|
|
10
|
+
if (!el)
|
|
11
|
+
return;
|
|
12
|
+
if (prefersReducedMotion())
|
|
13
|
+
return;
|
|
14
|
+
init(el, { duration, shift, shadowOffset });
|
|
15
|
+
return () => {
|
|
16
|
+
destroy(el);
|
|
17
|
+
};
|
|
18
|
+
}, [duration, shift, shadowOffset]);
|
|
19
|
+
return React.cloneElement(React.Children.only(children), { ref });
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export { AnimRgbSplitGlitch };
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { b as buildAnimId, a as buildAnimClass } from '../chunks/constants-EnH6-Pz4.js';
|
|
2
|
+
|
|
3
|
+
const ANIMATION_ID = buildAnimId('rgb-split-glitch');
|
|
4
|
+
|
|
5
|
+
const CSS_CLASS = buildAnimClass('rgb-split-glitch');
|
|
6
|
+
|
|
7
|
+
function init(el, options = {}) {
|
|
8
|
+
if (!el.classList.contains(CSS_CLASS)) {
|
|
9
|
+
el.classList.add(CSS_CLASS);
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
el.style.setProperty('--readdy-anim-rgb-glitch-duration', `${options.duration ?? 1100}ms`);
|
|
13
|
+
el.style.setProperty('--readdy-anim-rgb-glitch-shift', `${options.shift ?? 3}px`);
|
|
14
|
+
el.style.setProperty('--readdy-anim-rgb-glitch-shadow', `${options.shadowOffset ?? 2}px`);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
function destroy(el) {
|
|
18
|
+
el.classList.remove(CSS_CLASS);
|
|
19
|
+
el.style.removeProperty('--readdy-anim-rgb-glitch-duration');
|
|
20
|
+
el.style.removeProperty('--readdy-anim-rgb-glitch-shift');
|
|
21
|
+
el.style.removeProperty('--readdy-anim-rgb-glitch-shadow');
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export { ANIMATION_ID, destroy, init };
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import React, { useRef, useEffect } from 'react';
|
|
2
|
+
import { init, destroy } from '../tilted-card.js';
|
|
3
|
+
import { p as prefersReducedMotion } from '../../chunks/reduced-motion-HX79Ac8G.js';
|
|
4
|
+
import '../../chunks/pointer-follow-BETANySn.js';
|
|
5
|
+
import '../../chunks/constants-EnH6-Pz4.js';
|
|
6
|
+
|
|
7
|
+
function AnimTiltedCard({ children, maxTilt, scale, perspective, duration, }) {
|
|
8
|
+
const ref = useRef(null);
|
|
9
|
+
useEffect(() => {
|
|
10
|
+
const el = ref.current;
|
|
11
|
+
if (!el || prefersReducedMotion())
|
|
12
|
+
return;
|
|
13
|
+
init(el, { maxTilt, scale, perspective, duration });
|
|
14
|
+
return () => {
|
|
15
|
+
destroy(el);
|
|
16
|
+
};
|
|
17
|
+
}, [maxTilt, scale, perspective, duration]);
|
|
18
|
+
return React.cloneElement(React.Children.only(children), { ref });
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export { AnimTiltedCard };
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { p as prefersReducedMotion } from '../chunks/reduced-motion-HX79Ac8G.js';
|
|
2
|
+
import { a as attachPointerFollow, g as getPointerMetrics } from '../chunks/pointer-follow-BETANySn.js';
|
|
3
|
+
import { b as buildAnimId, a as buildAnimClass } from '../chunks/constants-EnH6-Pz4.js';
|
|
4
|
+
|
|
5
|
+
const ANIMATION_ID = buildAnimId('tilted-card');
|
|
6
|
+
|
|
7
|
+
const CSS_CLASS = buildAnimClass('tilted-card');
|
|
8
|
+
const stateMap = new WeakMap();
|
|
9
|
+
|
|
10
|
+
function reset(el) {
|
|
11
|
+
el.style.setProperty('--readdy-anim-card-tilt-x', '0deg');
|
|
12
|
+
el.style.setProperty('--readdy-anim-card-tilt-y', '0deg');
|
|
13
|
+
el.style.setProperty('--readdy-anim-card-scale', '1');
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
function init(el, options = {}) {
|
|
17
|
+
destroy(el);
|
|
18
|
+
|
|
19
|
+
el.classList.add(CSS_CLASS);
|
|
20
|
+
reset(el);
|
|
21
|
+
|
|
22
|
+
const perspective = options.perspective ?? 900;
|
|
23
|
+
const duration = options.duration ?? 550;
|
|
24
|
+
el.style.setProperty('--readdy-anim-card-tilt-perspective', `${perspective}px`);
|
|
25
|
+
el.style.setProperty('--readdy-anim-card-tilt-duration', `${duration}ms`);
|
|
26
|
+
|
|
27
|
+
if (prefersReducedMotion()) {
|
|
28
|
+
return
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const maxTilt = options.maxTilt ?? 10;
|
|
32
|
+
const scale = options.scale ?? 1.02;
|
|
33
|
+
|
|
34
|
+
const onMove = (event, context) => {
|
|
35
|
+
const { relativeX, relativeY } = getPointerMetrics(context.rect, event);
|
|
36
|
+
|
|
37
|
+
el.style.setProperty('--readdy-anim-card-tilt-x', `${relativeY * -maxTilt * 2}deg`);
|
|
38
|
+
el.style.setProperty('--readdy-anim-card-tilt-y', `${relativeX * maxTilt * 2}deg`);
|
|
39
|
+
el.style.setProperty('--readdy-anim-card-scale', `${scale}`);
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
const onLeave = () => {
|
|
43
|
+
reset(el);
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
const cleanup = attachPointerFollow(el, { onMove, onLeave });
|
|
47
|
+
stateMap.set(el, { cleanup });
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
function destroy(el) {
|
|
51
|
+
const state = stateMap.get(el);
|
|
52
|
+
if (state) {
|
|
53
|
+
state.cleanup();
|
|
54
|
+
stateMap.delete(el);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
el.classList.remove(CSS_CLASS);
|
|
58
|
+
el.style.removeProperty('--readdy-anim-card-tilt-x');
|
|
59
|
+
el.style.removeProperty('--readdy-anim-card-tilt-y');
|
|
60
|
+
el.style.removeProperty('--readdy-anim-card-scale');
|
|
61
|
+
el.style.removeProperty('--readdy-anim-card-tilt-perspective');
|
|
62
|
+
el.style.removeProperty('--readdy-anim-card-tilt-duration');
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export { ANIMATION_ID, destroy, init };
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @readdy/anim/shared/constants.js
|
|
3
|
+
*
|
|
4
|
+
* 共享常量 —— 动效 ID 前缀、class 前缀、ID 构建器
|
|
5
|
+
* 解决 issues #2:动效 ID 前缀不一致
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
/** 动效 ID 前缀,统一格式 */
|
|
9
|
+
const ANIM_ID_PREFIX = 'readdy-anim-';
|
|
10
|
+
|
|
11
|
+
/** CSS class 前缀 */
|
|
12
|
+
const ANIM_CLASS_PREFIX = 'readdy-anim-';
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* 构建动效 CSS class
|
|
16
|
+
* @param {string} name - class 后缀,如 'text-type'
|
|
17
|
+
* @returns {string} 完整 class,如 'readdy-anim-text-type'
|
|
18
|
+
*/
|
|
19
|
+
function buildAnimClass(name) {
|
|
20
|
+
return ANIM_CLASS_PREFIX + name
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* 构建动效相关 DOM id
|
|
25
|
+
* 目前与 class 前缀保持一致,便于 SVG filter / portal 节点等共享同一命名空间。
|
|
26
|
+
*
|
|
27
|
+
* @param {string} name - id 后缀,如 'bubble-goo'
|
|
28
|
+
* @returns {string} 完整 id,如 'readdy-anim-bubble-goo'
|
|
29
|
+
*/
|
|
30
|
+
function buildAnimDomId(name) {
|
|
31
|
+
return ANIM_CLASS_PREFIX + name
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* 构建动效规范 ID
|
|
36
|
+
* 统一接受动效 slug,例如:
|
|
37
|
+
* - buildAnimId('letter-bounce') => 'readdy-anim-letter-bounce'
|
|
38
|
+
* - buildAnimId('bubble-button') => 'readdy-anim-bubble-button'
|
|
39
|
+
*
|
|
40
|
+
* @param {string} name - 动效 slug
|
|
41
|
+
* @returns {string} 规范 ID
|
|
42
|
+
*/
|
|
43
|
+
function buildAnimId(name) {
|
|
44
|
+
const slug = String(name).trim();
|
|
45
|
+
|
|
46
|
+
if (!slug) {
|
|
47
|
+
throw new Error('buildAnimId(name) requires a non-empty animation slug')
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
if (slug.includes('/')) {
|
|
51
|
+
throw new Error(`buildAnimId(name) only accepts animation slugs, received path-like value: ${slug}`)
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
const normalizedSlug = slug
|
|
55
|
+
.replace(/[^a-zA-Z0-9]+/g, '-')
|
|
56
|
+
.replace(/^-+|-+$/g, '')
|
|
57
|
+
.toLowerCase();
|
|
58
|
+
|
|
59
|
+
if (!normalizedSlug) {
|
|
60
|
+
throw new Error(`buildAnimId(name) could not derive a valid animation slug from: ${slug}`)
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
return ANIM_ID_PREFIX + normalizedSlug
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export { buildAnimClass as a, buildAnimId as b, buildAnimDomId as c };
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @readdy/anim/shared/constants.js
|
|
3
|
+
*
|
|
4
|
+
* 共享常量 —— 动效 ID 前缀、class 前缀、ID 构建器
|
|
5
|
+
* 解决 issues #2:动效 ID 前缀不一致
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
/** 动效 ID 前缀,统一格式 */
|
|
9
|
+
const ANIM_ID_PREFIX = 'readdy-anim-';
|
|
10
|
+
|
|
11
|
+
/** CSS class 前缀 */
|
|
12
|
+
const ANIM_CLASS_PREFIX = 'readdy-anim-';
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* 构建动效 CSS class
|
|
16
|
+
* @param {string} name - class 后缀,如 'text-type'
|
|
17
|
+
* @returns {string} 完整 class,如 'readdy-anim-text-type'
|
|
18
|
+
*/
|
|
19
|
+
function buildAnimClass(name) {
|
|
20
|
+
return ANIM_CLASS_PREFIX + name
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* 构建动效相关 DOM id
|
|
25
|
+
* 目前与 class 前缀保持一致,便于 SVG filter / portal 节点等共享同一命名空间。
|
|
26
|
+
*
|
|
27
|
+
* @param {string} name - id 后缀,如 'bubble-goo'
|
|
28
|
+
* @returns {string} 完整 id,如 'readdy-anim-bubble-goo'
|
|
29
|
+
*/
|
|
30
|
+
function buildAnimDomId(name) {
|
|
31
|
+
return ANIM_CLASS_PREFIX + name
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* 构建动效规范 ID
|
|
36
|
+
* 统一接受动效 slug,例如:
|
|
37
|
+
* - buildAnimId('letter-bounce') => 'readdy-anim-letter-bounce'
|
|
38
|
+
* - buildAnimId('bubble-button') => 'readdy-anim-bubble-button'
|
|
39
|
+
*
|
|
40
|
+
* @param {string} name - 动效 slug
|
|
41
|
+
* @returns {string} 规范 ID
|
|
42
|
+
*/
|
|
43
|
+
function buildAnimId(name) {
|
|
44
|
+
const slug = String(name).trim();
|
|
45
|
+
|
|
46
|
+
if (!slug) {
|
|
47
|
+
throw new Error('buildAnimId(name) requires a non-empty animation slug')
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
if (slug.includes('/')) {
|
|
51
|
+
throw new Error(`buildAnimId(name) only accepts animation slugs, received path-like value: ${slug}`)
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
const normalizedSlug = slug
|
|
55
|
+
.replace(/[^a-zA-Z0-9]+/g, '-')
|
|
56
|
+
.replace(/^-+|-+$/g, '')
|
|
57
|
+
.toLowerCase();
|
|
58
|
+
|
|
59
|
+
if (!normalizedSlug) {
|
|
60
|
+
throw new Error(`buildAnimId(name) could not derive a valid animation slug from: ${slug}`)
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
return ANIM_ID_PREFIX + normalizedSlug
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export { buildAnimClass as a, buildAnimId as b, buildAnimDomId as c };
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
function getPointerMetrics(target, event) {
|
|
2
|
+
const rect =
|
|
3
|
+
target && typeof target.getBoundingClientRect === 'function'
|
|
4
|
+
? target.getBoundingClientRect()
|
|
5
|
+
: target;
|
|
6
|
+
const centerX = rect.left + rect.width / 2;
|
|
7
|
+
const centerY = rect.top + rect.height / 2;
|
|
8
|
+
const deltaX = event.clientX - centerX;
|
|
9
|
+
const deltaY = event.clientY - centerY;
|
|
10
|
+
|
|
11
|
+
return {
|
|
12
|
+
rect,
|
|
13
|
+
deltaX,
|
|
14
|
+
deltaY,
|
|
15
|
+
relativeX: rect.width ? deltaX / rect.width : 0,
|
|
16
|
+
relativeY: rect.height ? deltaY / rect.height : 0,
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function attachPointerFollow(el, handlers) {
|
|
21
|
+
const { onMove, onLeave, onEnter } = handlers;
|
|
22
|
+
const requestFrame =
|
|
23
|
+
window.requestAnimationFrame?.bind(window) ?? ((callback) => window.setTimeout(callback, 16));
|
|
24
|
+
const cancelFrame =
|
|
25
|
+
window.cancelAnimationFrame?.bind(window) ?? ((frameId) => window.clearTimeout(frameId));
|
|
26
|
+
|
|
27
|
+
let frameId = null;
|
|
28
|
+
let lastEvent = null;
|
|
29
|
+
let activeRect = null;
|
|
30
|
+
|
|
31
|
+
const context = {
|
|
32
|
+
get rect() {
|
|
33
|
+
return activeRect
|
|
34
|
+
},
|
|
35
|
+
refreshRect() {
|
|
36
|
+
activeRect = el.getBoundingClientRect();
|
|
37
|
+
return activeRect
|
|
38
|
+
},
|
|
39
|
+
getMetrics(event) {
|
|
40
|
+
return getPointerMetrics(activeRect ?? context.refreshRect(), event)
|
|
41
|
+
},
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
const flushMove = () => {
|
|
45
|
+
frameId = null;
|
|
46
|
+
if (!lastEvent) {
|
|
47
|
+
return
|
|
48
|
+
}
|
|
49
|
+
if (!activeRect) {
|
|
50
|
+
context.refreshRect();
|
|
51
|
+
}
|
|
52
|
+
onMove(lastEvent, context);
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
const handleEnter = (event) => {
|
|
56
|
+
context.refreshRect();
|
|
57
|
+
onEnter?.(event, context);
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
const handleMove = (event) => {
|
|
61
|
+
lastEvent = event;
|
|
62
|
+
if (frameId !== null) {
|
|
63
|
+
return
|
|
64
|
+
}
|
|
65
|
+
frameId = requestFrame(flushMove);
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
const handleLeave = (event) => {
|
|
69
|
+
if (frameId !== null) {
|
|
70
|
+
cancelFrame(frameId);
|
|
71
|
+
frameId = null;
|
|
72
|
+
}
|
|
73
|
+
lastEvent = null;
|
|
74
|
+
activeRect = null;
|
|
75
|
+
onLeave?.(event, context);
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
el.addEventListener('pointerenter', handleEnter);
|
|
79
|
+
el.addEventListener('pointermove', handleMove);
|
|
80
|
+
el.addEventListener('pointerleave', handleLeave);
|
|
81
|
+
|
|
82
|
+
return () => {
|
|
83
|
+
if (frameId !== null) {
|
|
84
|
+
cancelFrame(frameId);
|
|
85
|
+
frameId = null;
|
|
86
|
+
}
|
|
87
|
+
el.removeEventListener('pointerenter', handleEnter);
|
|
88
|
+
el.removeEventListener('pointermove', handleMove);
|
|
89
|
+
el.removeEventListener('pointerleave', handleLeave);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
export { attachPointerFollow as a, getPointerMetrics as g };
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
function getPointerMetrics(target, event) {
|
|
2
|
+
const rect =
|
|
3
|
+
target && typeof target.getBoundingClientRect === 'function'
|
|
4
|
+
? target.getBoundingClientRect()
|
|
5
|
+
: target;
|
|
6
|
+
const centerX = rect.left + rect.width / 2;
|
|
7
|
+
const centerY = rect.top + rect.height / 2;
|
|
8
|
+
const deltaX = event.clientX - centerX;
|
|
9
|
+
const deltaY = event.clientY - centerY;
|
|
10
|
+
|
|
11
|
+
return {
|
|
12
|
+
rect,
|
|
13
|
+
deltaX,
|
|
14
|
+
deltaY,
|
|
15
|
+
relativeX: rect.width ? deltaX / rect.width : 0,
|
|
16
|
+
relativeY: rect.height ? deltaY / rect.height : 0,
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function attachPointerFollow(el, handlers) {
|
|
21
|
+
const { onMove, onLeave, onEnter } = handlers;
|
|
22
|
+
const requestFrame =
|
|
23
|
+
window.requestAnimationFrame?.bind(window) ?? ((callback) => window.setTimeout(callback, 16));
|
|
24
|
+
const cancelFrame =
|
|
25
|
+
window.cancelAnimationFrame?.bind(window) ?? ((frameId) => window.clearTimeout(frameId));
|
|
26
|
+
|
|
27
|
+
let frameId = null;
|
|
28
|
+
let lastEvent = null;
|
|
29
|
+
let activeRect = null;
|
|
30
|
+
|
|
31
|
+
const context = {
|
|
32
|
+
get rect() {
|
|
33
|
+
return activeRect
|
|
34
|
+
},
|
|
35
|
+
refreshRect() {
|
|
36
|
+
activeRect = el.getBoundingClientRect();
|
|
37
|
+
return activeRect
|
|
38
|
+
},
|
|
39
|
+
getMetrics(event) {
|
|
40
|
+
return getPointerMetrics(activeRect ?? context.refreshRect(), event)
|
|
41
|
+
},
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
const flushMove = () => {
|
|
45
|
+
frameId = null;
|
|
46
|
+
if (!lastEvent) {
|
|
47
|
+
return
|
|
48
|
+
}
|
|
49
|
+
if (!activeRect) {
|
|
50
|
+
context.refreshRect();
|
|
51
|
+
}
|
|
52
|
+
onMove(lastEvent, context);
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
const handleEnter = (event) => {
|
|
56
|
+
context.refreshRect();
|
|
57
|
+
onEnter?.(event, context);
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
const handleMove = (event) => {
|
|
61
|
+
lastEvent = event;
|
|
62
|
+
if (frameId !== null) {
|
|
63
|
+
return
|
|
64
|
+
}
|
|
65
|
+
frameId = requestFrame(flushMove);
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
const handleLeave = (event) => {
|
|
69
|
+
if (frameId !== null) {
|
|
70
|
+
cancelFrame(frameId);
|
|
71
|
+
frameId = null;
|
|
72
|
+
}
|
|
73
|
+
lastEvent = null;
|
|
74
|
+
activeRect = null;
|
|
75
|
+
onLeave?.(event, context);
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
el.addEventListener('pointerenter', handleEnter);
|
|
79
|
+
el.addEventListener('pointermove', handleMove);
|
|
80
|
+
el.addEventListener('pointerleave', handleLeave);
|
|
81
|
+
|
|
82
|
+
return () => {
|
|
83
|
+
if (frameId !== null) {
|
|
84
|
+
cancelFrame(frameId);
|
|
85
|
+
frameId = null;
|
|
86
|
+
}
|
|
87
|
+
el.removeEventListener('pointerenter', handleEnter);
|
|
88
|
+
el.removeEventListener('pointermove', handleMove);
|
|
89
|
+
el.removeEventListener('pointerleave', handleLeave);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
export { attachPointerFollow as a, getPointerMetrics as g };
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @readdy/anim/shared/reduced-motion.js
|
|
3
|
+
*
|
|
4
|
+
* 无障碍工具 —— 检测 prefers-reduced-motion
|
|
5
|
+
* 所有 React 组件和 init 函数统一使用此函数
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* 检测用户是否偏好减少动画
|
|
10
|
+
* @returns {boolean} true 表示用户偏好减少动画
|
|
11
|
+
*/
|
|
12
|
+
function prefersReducedMotion() {
|
|
13
|
+
return typeof window !== 'undefined' &&
|
|
14
|
+
window.matchMedia('(prefers-reduced-motion: reduce)').matches
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export { prefersReducedMotion as p };
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @readdy/anim/shared/reduced-motion.js
|
|
3
|
+
*
|
|
4
|
+
* 无障碍工具 —— 检测 prefers-reduced-motion
|
|
5
|
+
* 所有 React 组件和 init 函数统一使用此函数
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* 检测用户是否偏好减少动画
|
|
10
|
+
* @returns {boolean} true 表示用户偏好减少动画
|
|
11
|
+
*/
|
|
12
|
+
function prefersReducedMotion() {
|
|
13
|
+
return typeof window !== 'undefined' &&
|
|
14
|
+
window.matchMedia('(prefers-reduced-motion: reduce)').matches
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export { prefersReducedMotion as p };
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
function hasUsableBackgroundImage(node) {
|
|
2
|
+
const style = window.getComputedStyle(node);
|
|
3
|
+
return Boolean(style.backgroundImage && style.backgroundImage !== 'none')
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
function resolveCardMediaElement(el, mediaClass) {
|
|
7
|
+
const byClass = el.querySelector(`.${mediaClass}`);
|
|
8
|
+
if (byClass instanceof HTMLElement) {
|
|
9
|
+
return byClass
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
const image = el.querySelector('img');
|
|
13
|
+
if (image instanceof HTMLImageElement) {
|
|
14
|
+
let candidate = image.parentElement;
|
|
15
|
+
while (candidate && candidate !== el) {
|
|
16
|
+
const style = window.getComputedStyle(candidate);
|
|
17
|
+
if (
|
|
18
|
+
style.overflow === 'hidden' ||
|
|
19
|
+
style.position !== 'static' ||
|
|
20
|
+
candidate.childElementCount === 1 ||
|
|
21
|
+
hasUsableBackgroundImage(candidate)
|
|
22
|
+
) {
|
|
23
|
+
return candidate
|
|
24
|
+
}
|
|
25
|
+
candidate = candidate.parentElement;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const backgroundCandidate = Array.from(el.querySelectorAll('*')).find((node) => {
|
|
30
|
+
if (!(node instanceof HTMLElement)) {
|
|
31
|
+
return false
|
|
32
|
+
}
|
|
33
|
+
return hasUsableBackgroundImage(node)
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
if (backgroundCandidate instanceof HTMLElement) {
|
|
37
|
+
return backgroundCandidate
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
return el.firstElementChild instanceof HTMLElement ? el.firstElementChild : el
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export { resolveCardMediaElement as r };
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
function hasUsableBackgroundImage(node) {
|
|
2
|
+
const style = window.getComputedStyle(node);
|
|
3
|
+
return Boolean(style.backgroundImage && style.backgroundImage !== 'none')
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
function resolveCardMediaElement(el, mediaClass) {
|
|
7
|
+
const byClass = el.querySelector(`.${mediaClass}`);
|
|
8
|
+
if (byClass instanceof HTMLElement) {
|
|
9
|
+
return byClass
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
const image = el.querySelector('img');
|
|
13
|
+
if (image instanceof HTMLImageElement) {
|
|
14
|
+
let candidate = image.parentElement;
|
|
15
|
+
while (candidate && candidate !== el) {
|
|
16
|
+
const style = window.getComputedStyle(candidate);
|
|
17
|
+
if (
|
|
18
|
+
style.overflow === 'hidden' ||
|
|
19
|
+
style.position !== 'static' ||
|
|
20
|
+
candidate.childElementCount === 1 ||
|
|
21
|
+
hasUsableBackgroundImage(candidate)
|
|
22
|
+
) {
|
|
23
|
+
return candidate
|
|
24
|
+
}
|
|
25
|
+
candidate = candidate.parentElement;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const backgroundCandidate = Array.from(el.querySelectorAll('*')).find((node) => {
|
|
30
|
+
if (!(node instanceof HTMLElement)) {
|
|
31
|
+
return false
|
|
32
|
+
}
|
|
33
|
+
return hasUsableBackgroundImage(node)
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
if (backgroundCandidate instanceof HTMLElement) {
|
|
37
|
+
return backgroundCandidate
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
return el.firstElementChild instanceof HTMLElement ? el.firstElementChild : el
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export { resolveCardMediaElement as r };
|