smoke.vue 2.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. <template>
  2. <div>
  3. <div class="smoke-container">
  4. <span>SS</span>
  5. </div>
  6. <div class="smoke-container" style="animation-delay: 1s;">
  7. <span>SS</span>
  8. </div>
  9. <div class="smoke-container" style="animation-delay: 2s;">
  10. <span>SS</span>
  11. </div>
  12. <div class="smoke-container" style="animation-delay: 3s;">
  13. <span>SS</span>
  14. </div>
  15. <div class="smoke-container" style="animation-delay: 4s;">
  16. <span>SS</span>
  17. </div>
  18. <div class="smoke-container" style="animation-delay: 5s;">
  19. <span>SS</span>
  20. </div>
  21. <div class="smoke-container" style="animation-delay: 6s;">
  22. <span>SS</span>
  23. </div>
  24. <svg width="0">
  25. <filter id="smoke-filter">
  26. <feTurbulence id="turbulence" type="fractalNoise" baseFrequency=".03" numOctaves="100" />
  27. <feDisplacementMap in="SourceGraphic" scale="30" />
  28. </filter>
  29. </svg>
  30. </div>
  31. </template>
  32. <script setup>
  33. import { onMounted } from 'vue';
  34. onMounted(() => {
  35. const filter = document.querySelector("#turbulence");
  36. let frames = 0;
  37. let rad = Math.PI / 180;
  38. let bf, bfx, bfy;
  39. let d = 1;
  40. function freqAnimation() {
  41. frames += d * 1;
  42. // if (frames > 360) {
  43. // frames = 0;
  44. // }
  45. bfx = 0.03;
  46. bfy = 0.03;
  47. bfx += 0.005 * Math.cos(frames * rad);
  48. bfy += 0.005 * Math.sin(frames * rad);
  49. bf = [bfx, bfy].join(' ');
  50. console.log(frames, bfx, bfy)
  51. filter.setAttributeNS(null, "baseFrequency", bf);
  52. window.requestAnimationFrame(freqAnimation);
  53. }
  54. // window.requestAnimationFrame(freqAnimation);
  55. })
  56. </script>
  57. <style lang="less">
  58. .smoke-container {
  59. position: absolute;
  60. width: 24px;
  61. margin: auto;
  62. filter: url('#smoke-filter');
  63. animation: ani-smoke 6s linear infinite forwards;
  64. span {
  65. font-size: 24px;
  66. font-weight: 700;
  67. color: #000;
  68. filter: blur(10px);
  69. }
  70. @keyframes ani-smoke {
  71. 0% {
  72. transform: translateY(0) rotate(-80deg);
  73. opacity: 1;
  74. }
  75. 70% {
  76. opacity: 1;
  77. }
  78. 100% {
  79. transform: translateY(-400%) rotate(-80deg);
  80. opacity: 0;
  81. }
  82. }
  83. }
  84. </style>