diff --git a/.changeset/cold-crews-fold.md b/.changeset/cold-crews-fold.md new file mode 100644 index 0000000..cb26242 --- /dev/null +++ b/.changeset/cold-crews-fold.md @@ -0,0 +1,5 @@ +--- +"slidev-addon-fancy-arrow": patch +--- + +Animate overlay contents diff --git a/components/FancyArrow.vue b/components/FancyArrow.vue index cb788dd..85ff83b 100644 --- a/components/FancyArrow.vue +++ b/components/FancyArrow.vue @@ -5,7 +5,11 @@ import { type SnapAnchorPoint, } from "./parse-option"; import { useEndpointResolution } from "./use-element-position"; -import { useRoughArrow, type AbsolutePosition } from "./use-rough-arrow"; +import { + useRoughArrow, + DEFAULT_ANIMATION_DURATION, + type AbsolutePosition, +} from "./use-rough-arrow"; const props = defineProps<{ from?: string; // Shorthand for (q1 and pos1) or (x1 and y1) @@ -80,6 +84,14 @@ const point2: Ref = useEndpointResolution( }, ); +const animationEnabled = computed(() => { + return ( + props.animated || + props.animationDuration != null || + props.animationDelay != null + ); +}); + const { arrowSvg, textPosition } = useRoughArrow({ point1, point2, @@ -90,19 +102,18 @@ const { arrowSvg, textPosition } = useRoughArrow({ headSize: props.headSize ? Number(props.headSize) : null, roughness: props.roughness ? Number(props.roughness) : undefined, seed: props.seed ? Number(props.seed) : undefined, - animation: - props.animated || props.animationDuration || props.animationDelay - ? { - duration: - props.animationDuration != null - ? Number(props.animationDuration) - : undefined, - delay: - props.animationDelay != null - ? Number(props.animationDelay) - : undefined, - } - : undefined, + animation: animationEnabled.value + ? { + duration: + props.animationDuration != null + ? Number(props.animationDuration) + : undefined, + delay: + props.animationDelay != null + ? Number(props.animationDelay) + : undefined, + } + : undefined, strokeAnimationKeyframeName: "rough-arrow-dash", fillAnimationKeyframeName: "rough-arrow-fill", }); @@ -131,6 +142,10 @@ const { arrowSvg, textPosition } = useRoughArrow({ left: `${textPosition.x}px`, top: `${textPosition.y}px`, transform: 'translate(-50%, -50%)', + visibility: animationEnabled ? 'hidden' : 'visible', + animation: animationEnabled + ? `rough-arrow-content ${props.animationDuration ?? DEFAULT_ANIMATION_DURATION}ms ease-out ${props.animationDelay ?? 0}ms forwards` + : 'none', }" > @@ -158,4 +173,16 @@ const { arrowSvg, textPosition } = useRoughArrow({ visibility: visible; } } + +@keyframes rough-arrow-content { + from { + visibility: hidden; + } + 99.99% { + visibility: hidden; + } + 100% { + visibility: visible; + } +} diff --git a/components/use-rough-arrow.ts b/components/use-rough-arrow.ts index 4ae658c..051c952 100644 --- a/components/use-rough-arrow.ts +++ b/components/use-rough-arrow.ts @@ -4,7 +4,7 @@ import { splitPath } from "./split-path"; type RoughSVG = ReturnType; -const DEFAULT_ANIMATION_DURATION = 800; // Same as https://github.com/rough-stuff/rough-notation/blob/668ba82ac89c903d6f59c9351b9b85855da9882c/src/model.ts#L3C14-L3C47 +export const DEFAULT_ANIMATION_DURATION = 800; // Same as https://github.com/rough-stuff/rough-notation/blob/668ba82ac89c903d6f59c9351b9b85855da9882c/src/model.ts#L3C14-L3C47 const createArrowHeadSvg = ( roughSvg: RoughSVG, diff --git a/slides.md b/slides.md index 4227241..97af47a 100644 --- a/slides.md +++ b/slides.md @@ -712,9 +712,13 @@ If no snap target or absolute position is specified, the arrow will automaticall -
+ + Animated + -```html +
+ +```html {*}{maxHeight: '100%'} Hello @@ -731,6 +735,10 @@ If no snap target or absolute position is specified, the arrow will automaticall Slidev logo + + + Animated + ```