文字翻转效果

利用绝对定位、3D 变换和 JS 实现翻转文字
在这里插入图片描述

<template>
  <div class="rotating-text">
    <p>CSS Animation is</p>
    <p>
      <span
        v-for="(item, i) in list"
        :ref="
          (el) => { 
            if (el) words[i] = el;
          }
        "
        :key="i"
        :class="['word', item[0]]"
        >{{ item[1] }}.</span
      >
    </p>
  </div>
</template>

<script setup>
import { ref, onMounted } from 'vue';

const words = ref([]);

const list = [
  ['alizarin', 'awesome'],
  ['wisteria', 'beautiful'],
  ['peter-river', 'creative'],
  ['emerald', 'fabulous'],
  ['sun-flower', 'interesting'],
];

onMounted(() => {
  words.value.forEach((word) => {
    let letters = word.textContent.split('');
    word.textContent = '';
    letters.forEach((letter) => {
      let span = document.createElement('span');
      span.textContent = letter;
      span.className = 'letter';
      word.append(span);
    });
  });

  let currentWordIndex = 0;
  let maxWordIndex = words.value.length - 1;
  words.value[currentWordIndex].style.opacity = '1';

  let rotateText = () => {
    let currentWord = words.value[currentWordIndex];
    let nextWord = currentWordIndex === maxWordIndex ? words.value[0] : words.value[currentWordIndex + 1];
    // console.log('currentWord.children',currentWord.children);
    // rotate out letters of current word
    Array.from(currentWord.children).forEach((letter, i) => {
      setTimeout(() => {
        letter.className = 'letter out';
      }, i * 80);
    });
    // reveal and rotate in letters of next word
    nextWord.style.opacity = '1';
    Array.from(nextWord.children).forEach((letter, i) => {
      letter.className = 'letter behind';
      setTimeout(() => {
        letter.className = 'letter in';
      }, 340 + i * 80);
    });
    currentWordIndex = currentWordIndex === maxWordIndex ? 0 : currentWordIndex + 1;
  };

  rotateText();
  setInterval(rotateText, 4000);
});
</script>

<style scoped lang="less">
.rotating-text {
  font-weight: 600;
  font-size: 36px;
  color: #444;
  margin: 300px;

  p {
    display: inline-flex;
    margin: 0;
    vertical-align: top;

    &:first-child {
      margin-right: 10px;
    }

    .word {
      position: absolute;
      display: flex;
      opacity: 0;
    }
  }
}

// palette: https://flatuicolors.com/palette/defo
.alizarin {
  color: #e74c3c;
}

.wisteria {
  color: #8e44ad;
}

.peter-river {
  color: #3498db;
}

.emerald {
  color: #2ecc71;
}

.sun-flower {
  color: #f1c40f;
}
</style>

<style lang="less">
.dark {
  .rotating-text {
    color: #ccc;
  }
}
.letter {
  transform-origin: center center 25px;

  &.out {
    transform: rotateX(90deg);
    transition: 0.32s cubic-bezier(0.6, 0, 0.7, 0.2);
  }
  &.in {
    transition: 0.38s ease;
  }
  &.behind {
    transform: rotateX(-90deg);
  }
}
</style>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值