Cubetti.vue 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. <template>
  2. <div id="cubetti" ref="cubetti" />
  3. </template>
  4. <style lang="pcss" scoped>
  5. @media screen(sm) {
  6. #cubetti {
  7. position: absolute;
  8. width: 200px !important;
  9. height: 200px !important;
  10. top: -55px !important;
  11. left: 0px !important;
  12. }
  13. }
  14. #cubetti {
  15. position: absolute;
  16. width: 120px;
  17. height: 120px;
  18. overflow: visible;
  19. top: -24px;
  20. left: -22px;
  21. }
  22. </style>
  23. <script lang="ts" setup>
  24. import { AmbientLight } from 'three/src/lights/AmbientLight';
  25. import { DirectionalLight } from 'three/src/lights/DirectionalLight';
  26. import { BoxGeometry } from 'three/src/geometries/BoxGeometry';
  27. import { Mesh } from 'three/src/objects/Mesh';
  28. import { MeshStandardMaterial } from 'three/src/materials/MeshStandardMaterial';
  29. import { PerspectiveCamera } from 'three/src/cameras/PerspectiveCamera';
  30. import { Scene } from 'three/src/scenes/Scene';
  31. import { Vector3 } from 'three/src/math/Vector3';
  32. import { WebGLRenderer } from 'three/src/renderers/WebGLRenderer';
  33. import anime from 'animejs';
  34. import { randInt } from 'three/src/math/MathUtils';
  35. const scene = new Scene()
  36. const camera = new PerspectiveCamera(80, 1, 0.1, 1000)
  37. const renderer = new WebGLRenderer({ antialias: true, alpha: true })
  38. renderer.setPixelRatio(window.devicePixelRatio);
  39. const directionalLight = new DirectionalLight(0x808080)
  40. const ambientLight = new AmbientLight(0x808080*1.75)
  41. const geometry = new BoxGeometry(1, 1, 1)
  42. const blueMaterial = new MeshStandardMaterial({ color: 'dodgerblue' })
  43. const greenMaterial = new MeshStandardMaterial({ color: 'greenyellow' })
  44. const orangeMaterial = new MeshStandardMaterial({ color: 'orange' })
  45. const blueCube = new Mesh(geometry, blueMaterial)
  46. blueCube.position.set(-1, 0, 1)
  47. const greenCube = new Mesh(geometry, greenMaterial)
  48. greenCube.position.set(1, 0, 1)
  49. const orangeCube = new Mesh(geometry, orangeMaterial)
  50. orangeCube.position.set(0, 0, -1)
  51. const cubeGroup = new Scene()
  52. cubeGroup.add(blueCube, greenCube, orangeCube)
  53. const cubettiAnims = [
  54. { // group spin
  55. targets: [cubeGroup.rotation],
  56. keyframes: [
  57. { y: 2 * Math.PI, duration: 1000 },
  58. ],
  59. easing: 'easeOutCubic',
  60. duration: 1000,
  61. complete: playRandomAnimation,
  62. },
  63. { // floating cubes
  64. targets: [orangeCube.position, blueCube.position, greenCube.position],
  65. keyframes: [
  66. { y: -0.5, duration: 500/3 },
  67. { y: 0.5, duration: 707/3 },
  68. { y: 0.0, duration: 500/3 },
  69. ],
  70. easing: 'easeInOutSine',
  71. delay: anime.stagger(500/3),
  72. complete: playRandomAnimation,
  73. },
  74. { // rotating cubes
  75. targets: [orangeCube.rotation, blueCube.rotation, greenCube.rotation],
  76. x: randInt(0, 1) * 2 * Math.PI, y: randInt(0, 1) * 2 * Math.PI, z: randInt(0, 1) * 2 * Math.PI, duration: 1000,
  77. easing: 'easeOutSine',
  78. delay: anime.stagger(500/3),
  79. complete: playRandomAnimation
  80. }
  81. ]
  82. const cubetti = ref()
  83. function playRandomAnimation() {
  84. setTimeout(() => {
  85. anime(cubettiAnims[randInt(0, cubettiAnims.length-1)])
  86. }, randInt(1000, 8000))
  87. }
  88. const animate = () => {
  89. requestAnimationFrame(animate)
  90. renderer.render(scene, camera)
  91. }
  92. const resizeCanvas = () => {
  93. if (window.innerWidth < 640) {
  94. renderer.setSize(120, 120);
  95. } else {
  96. renderer.setSize(200, 200);
  97. }
  98. }
  99. onMounted(() => {
  100. scene.add(camera)
  101. scene.add(ambientLight, directionalLight)
  102. scene.add(cubeGroup)
  103. // renderer.setSize(200, 200)
  104. resizeCanvas();
  105. camera.position.copy((new Vector3(-2, 1.5, 2)).multiplyScalar(1.2))
  106. camera.lookAt(0, 0, 0)
  107. scene.background = null
  108. cubetti.value.appendChild(renderer.domElement)
  109. window.addEventListener('resize', resizeCanvas);
  110. playRandomAnimation()
  111. animate()
  112. })
  113. onUnmounted(() => {
  114. window.removeEventListener('resize', resizeCanvas);
  115. })
  116. </script>