Home > Back-end >  Typewriter animation using Vue Js
Typewriter animation using Vue Js

Time:01-01

I'm having an issue and I don't find the answer by myself. I'm trying to make the following code work. Actually it doesn't work in my Vue project.

const text = document.getElementById("text");

const phrases = [
  "I'm John Doe",
  "I'm student",
  "I'm developer",
];

let currentPhraseIndex = 0;
let currentCharacterIndex = 0;
let currentPhrase = "";
let isDeleting = false;

function loop() {
  const currentPhraseText = phrases[currentPhraseIndex];

  if (!isDeleting) {
    currentPhrase  = currentPhraseText[currentCharacterIndex];
    currentCharacterIndex  ;
  } else {
    currentPhrase = currentPhrase.slice(0, -1);
    currentCharacterIndex--;
  }

  text.innerHTML = currentPhrase;

  if (currentCharacterIndex === currentPhraseText.length) {
    isDeleting = true;
  }

  if (currentCharacterIndex === 0) {
    currentPhrase = "";
    isDeleting = false;
    currentPhraseIndex  ;
    if (currentPhraseIndex === phrases.length) {
      currentPhraseIndex = 0;
    }
  }

  const spedUp = Math.random() * (80 - 50)   50;
  const normalSpeed = Math.random() * (300 - 200)   200;
  const time = isDeleting ? spedUp : normalSpeed;
  setTimeout(loop, time);
}

loop();
<h2 id="text"></h2>

As you can see the code is actually working. Checkout the errors I have in my from my Vue Js project.

enter image description here

Do not hesitate, if you have any suggestions to improve my code according to Vue of course.

CodePudding user response:

Try to put variables in data property and function in methods, or i composition api make variables reactive:

const { ref, reactive, onMounted } = Vue
const app = Vue.createApp({
  setup() {
    const opt = reactive({
      currentPhraseIndex: 0, 
      currentCharacterIndex: 0, 
      currentPhrase: "", 
      isDeleting: false
    })
    const phrases = reactive([
      "I'm John Doe",
      "I'm student",
      "I'm developer"
    ])
    const text = ref('')
    const loop = () => {
      const currentPhraseText = phrases[opt.currentPhraseIndex];
      if (!opt.isDeleting) {
        opt.currentPhrase  = currentPhraseText[opt.currentCharacterIndex];
        opt.currentCharacterIndex  ;
      } else {
        opt.currentPhrase = opt.currentPhrase.slice(0, -1);
        opt.currentCharacterIndex--;
      }
      text.value = opt.currentPhrase;
      if (opt.currentCharacterIndex === currentPhraseText.length) {
        opt.isDeleting = true;
      }
      if (opt.currentCharacterIndex === 0) {
        opt.currentPhrase = "";
        opt.isDeleting = false;
        opt.currentPhraseIndex  ;
        if (opt.currentPhraseIndex === opt.phrases?.length) {
          opt.currentPhraseIndex = 0;
        }
      }
      const spedUp = Math.random() * (80 - 50)   50;
      const normalSpeed = Math.random() * (300 - 200)   200;
      const time = opt.isDeleting ? spedUp : normalSpeed;
      setTimeout(loop, time);
    }
    onMounted(() => {
      loop()
    })
    return {
      text
    }
  }
})
app.mount('#demo')
<script src="https://unpkg.com/vue@3/dist/vue.global.prod.js"></script>
<div id="demo">
  <h2>{{ text }}</h2>
</div>

CodePudding user response:

I found the way to make it work. The following code is updated and works using Vue.js 3.

<script setup>
import { ref } from "vue";

const phrases = [
  "I am John Doe.",
  "I am student.",
  "I am developer.",
];

const currentPhraseIndex = ref(0);
const currentCharacterIndex = ref(0);
const currentPhrase = ref("");
const isDeleting = ref(false);

function loop() {
  const currentPhraseText = phrases[currentPhraseIndex.value];

  if (!isDeleting.value) {
    currentPhrase.value  = currentPhraseText[currentCharacterIndex.value];
    currentCharacterIndex.value  ;
  } else {
    currentPhrase.value = currentPhrase.value.slice(0, -1);
    currentCharacterIndex.value--;
  }

  if (currentCharacterIndex.value === currentPhraseText.length) {
    isDeleting.value = true;
  }

  if (currentCharacterIndex.value === 0) {
    currentPhrase.value = "";
    isDeleting.value = false;
    currentPhraseIndex.value  ;
    if (currentPhraseIndex.value === phrases.length) {
      currentPhraseIndex.value = 0;
    }
  }

  const spedUp = Math.random() * (80 - 50)   50;
  const normalSpeed = Math.random() * (300 - 200)   200;
  const time = isDeleting.value ? spedUp : normalSpeed;
  setTimeout(loop, time);
}

loop();
</script>
<template>
    <div>
      <h1 id="title">{{ currentPhrase }}</h1>
    </div>
</template>

  • Related