Hone logo
Hone
Problems

Vue.js Animated Greeting Message

Create a Vue.js component that displays a greeting message which animates into view when the component is mounted. This challenge focuses on basic Vue animation techniques, which are crucial for building more dynamic and engaging user interfaces.

Problem Description

Your task is to build a Vue.js component named AnimatedGreeting. This component should:

  1. Display a Greeting: Render a simple text message, for example, "Hello, Vue Animation!".
  2. Animate In: When the AnimatedGreeting component is mounted to the DOM, the greeting message should animate into visibility. You should use Vue's built-in <transition> component for this.
  3. Choose an Animation: Select a basic CSS transition (e.g., fade-in, slide-in) to apply to the message. You can either use Vue's default transition classes or define your own custom CSS classes.
  4. TypeScript: Implement the Vue component using TypeScript.

Key Requirements:

  • The animation should occur automatically on component mount.
  • The animation should be a single, straightforward transition (not a complex sequence).
  • The component should be a single-file Vue component (.vue file) using the <script setup lang="ts"> syntax.

Expected Behavior:

When the AnimatedGreeting component is added to the application's DOM, the greeting text should gradually appear or slide in over a short duration (e.g., 0.5 to 1 second).

Edge Cases:

  • Component Unmount: While not the primary focus, ensure the component doesn't cause errors if unmounted abruptly (though the animation in is the main requirement).
  • Initial State: The message should not be visible or should be in its starting, non-animated state before the animation begins.

Examples

Example 1: Fade-In Animation

<template>
  <div class="greeting-container">
    <transition name="fade">
      <h1 v-if="showGreeting" class="greeting-text">Hello, Vue Animation!</h1>
    </transition>
  </div>
</template>

<script setup lang="ts">
import { ref, onMounted } from 'vue';

const showGreeting = ref(false);

onMounted(() => {
  // Trigger the animation by making the element visible after mount
  showGreeting.value = true;
});
</script>

<style>
.fade-enter-active, .fade-leave-active {
  transition: opacity 0.5s ease;
}
.fade-enter-from, .fade-leave-to {
  opacity: 0;
}
.fade-enter-to, .fade-leave-from {
  opacity: 1;
}
.greeting-container {
  display: flex;
  justify-content: center;
  align-items: center;
  min-height: 100vh; /* For demonstration purposes */
}
.greeting-text {
  font-size: 2em;
  color: #333;
}
</style>

Explanation:

The showGreeting reactive variable is initially false. In onMounted, it's set to true. The <transition name="fade"> component wraps the <h1> element, which is conditionally rendered based on showGreeting. Vue automatically applies the fade-enter-active, fade-enter-from, and fade-enter-to classes to animate the opacity property from 0 to 1 over 0.5 seconds when showGreeting becomes true.

Example 2: Slide-In Animation

(This example demonstrates a different type of animation. You can choose one or the other.)

<template>
  <div class="greeting-container">
    <transition name="slide">
      <h1 v-if="showGreeting" class="greeting-text">Hello, Vue Animation!</h1>
    </transition>
  </div>
</template>

<script setup lang="ts">
import { ref, onMounted } from 'vue';

const showGreeting = ref(false);

onMounted(() => {
  showGreeting.value = true;
});
</script>

<style>
.slide-enter-active {
  transition: transform 0.8s ease-out;
}
.slide-enter-from {
  transform: translateX(-100%); /* Start off-screen to the left */
  opacity: 0;
}
.slide-enter-to {
  transform: translateX(0); /* End at its normal position */
  opacity: 1;
}
.greeting-container {
  display: flex;
  justify-content: center;
  align-items: center;
  min-height: 100vh; /* For demonstration purposes */
}
.greeting-text {
  font-size: 2em;
  color: #333;
}
</style>

Explanation:

Similar to Example 1, but the transition targets the transform and opacity properties. The slide-enter-from class positions the element 100% off-screen to the left and makes it invisible. The slide-enter-to class brings it back to its natural position with full opacity. The slide-enter-active class applies the transition for 0.8 seconds.

Constraints

  • The solution must be a Vue 3 single-file component using the <script setup lang="ts"> syntax.
  • The animation should be triggered automatically on component mount.
  • Only use basic CSS transitions or Vue's default transition classes. No JavaScript animation libraries (e.g., GSAP) are allowed for this specific challenge.
  • The greeting message text can be hardcoded within the component for this problem.

Notes

  • You can use the v-if directive in conjunction with the <transition> component to control the element's presence in the DOM and trigger animations.
  • Remember that <transition> needs a single direct child element to animate.
  • Experiment with different CSS properties for animation (e.g., opacity, transform, height, width).
  • The onMounted lifecycle hook is the perfect place to initiate actions after the component has been added to the DOM.
  • Vue's <transition> component provides default class names (e.g., v-enter-active, v-enter-from) if you don't specify a name attribute, but using a name attribute like fade or slide creates more specific class names (e.g., fade-enter-active) which is generally recommended for better organization.
Loading editor...
typescript