Hone logo
Hone
Problems

Vue Animation Orchestrator

This challenge asks you to build a reusable animation system for Vue.js applications using TypeScript. A robust animation system is crucial for creating engaging and dynamic user interfaces, improving user experience by providing visual feedback and guiding attention.

Problem Description

Your task is to create a Vue component or set of composables that allows developers to easily define and trigger complex animations on DOM elements. This system should be declarative, reusable, and integrate seamlessly with Vue's reactivity system.

Key Requirements:

  1. Animation Definition: Allow defining animations through a structured configuration, specifying properties to animate, duration, easing functions, delays, and sequences.
  2. Triggering Animations: Provide methods or events to trigger animations programmatically or based on user interactions/component lifecycle.
  3. State Management: The system should internally manage the animation state (e.g., playing, paused, finished) and expose this information if needed.
  4. Element Targeting: Easily target specific DOM elements for animation, potentially using Vue refs.
  5. TypeScript Support: The entire system must be written in TypeScript, providing strong typing for animation configurations and API.
  6. Reusability: Design the system to be highly reusable across different Vue components and projects.
  7. Basic Animation Types: Support common CSS properties like opacity, transform (e.g., translateX, scale), and potentially color.

Expected Behavior:

When an animation is triggered, the targeted element should smoothly transition its properties over the specified duration and according to the defined easing function. Sequences should execute animations one after another, respecting delays.

Edge Cases to Consider:

  • Animations that are triggered multiple times before completion.
  • Dynamic changes to animation configurations while an animation is running.
  • Handling elements that are conditionally rendered.
  • Canceling ongoing animations.

Examples

Let's imagine a scenario where we want to animate a simple div to fade in and then scale up.

Example 1: Basic Fade-In and Scale Animation

  • Input (Conceptual Configuration): A component uses your animation system to animate a div. The animation configuration specifies:

    • properties: [{ property: 'opacity', to: 1, duration: 500 }, { property: 'transform', value: 'scale(1.2)', duration: 700, delay: 200 }]
    • trigger: 'onMount'
  • Expected Output (Visual): When the component mounts, the div will gradually become visible (opacity from 0 to 1) over 500ms. After a 200ms delay, it will also scale up to 1.2 times its original size over the next 700ms.

Example 2: Sequential Animation with Callback

  • Input (Conceptual Configuration): A button, when clicked, triggers an animation sequence:

    1. Move the div 100px to the right (translateX(100px)) over 400ms.
    2. Change background color to blue over 300ms.
    3. After the sequence completes, log "Animation finished!" to the console.
    • animations: [{ property: 'transform', value: 'translateX(100px)', duration: 400 }, { property: 'backgroundColor', to: 'blue', duration: 300 }]
    • trigger: 'onClick' (on a button)
    • onComplete: () => console.log('Animation finished!')
  • Expected Output (Visual & Console): Clicking the button will cause the div to move right. During the move, its background color will also change to blue. Once both animations are done, "Animation finished!" will appear in the console.

Constraints

  • Animation Properties: Focus on animating opacity, transform (specifically translateX, translateY, scale, rotate), and backgroundColor. You can extend this list if you have time.
  • Easing Functions: Support at least linear, ease-in, ease-out, and ease-in-out. Consider using a library like bezier-easing or implementing simple CSS transitions.
  • Performance: Animations should be performant, ideally utilizing CSS transforms and opacity for hardware acceleration. Avoid animating properties that trigger layout reflows excessively.
  • Vue Version: Compatible with Vue 3 and TypeScript.

Notes

  • Consider creating a composable function (e.g., useAnimation) that can be used within your Vue components.
  • Think about how to represent animation steps and sequences. An array of animation objects is a good starting point.
  • You'll need to manage the animation timeline and apply style changes at appropriate times. Web Animations API (WAAPI) could be an option, or you might opt for a more manual approach using requestAnimationFrame and CSS transitions/animations.
  • Proper handling of element references (using ref) will be key.
  • The goal is a flexible and developer-friendly API for animations in Vue.
Loading editor...
typescript