123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146 |
- <template>
- <figure id="cubetti" ref="cubetti" />
- </template>
- <style lang="pcss" scoped>
- @reference '../assets/css/main.css';
- @media screen and (width >= theme(breakpoint.sm)) {
- #cubetti {
- position: absolute;
- width: 200px !important;
- height: 200px !important;
- top: -55px !important;
- left: 0px !important;
- }
- }
- #cubetti {
- position: absolute;
- width: 120px;
- height: 120px;
- overflow: visible;
- top: -24px;
- left: -22px;
- }
- </style>
- <script lang="ts" setup>
- import {
- AmbientLight,
- DirectionalLight,
- BoxGeometry,
- Mesh,
- MeshStandardMaterial,
- PerspectiveCamera,
- Scene,
- Vector3,
- WebGLRenderer,
- MathUtils,
- LinearToneMapping,
- } from 'three';
- import { animate, stagger } from 'animejs';
- const scene = new Scene()
- const camera = new PerspectiveCamera(80, 1, 0.1, 1000)
- const renderer = new WebGLRenderer({ antialias: true, alpha: true })
- renderer.setPixelRatio(window.devicePixelRatio);
- renderer.toneMapping = LinearToneMapping
- renderer.toneMappingExposure = 2.5
- const directionalLight = new DirectionalLight(0xffffff)
- const ambientLight = new AmbientLight(0xffffff)
- const geometry = new BoxGeometry(1, 1, 1)
- const blueMaterial = new MeshStandardMaterial({ color: 'dodgerblue' })
- const greenMaterial = new MeshStandardMaterial({ color: 'greenyellow' })
- const orangeMaterial = new MeshStandardMaterial({ color: 'orange' })
- const blueCube = new Mesh(geometry, blueMaterial)
- blueCube.position.set(-1, 0, 1)
- const greenCube = new Mesh(geometry, greenMaterial)
- greenCube.position.set(1, 0, 1)
- const orangeCube = new Mesh(geometry, orangeMaterial)
- orangeCube.position.set(0, 0, -1)
- const cubeGroup = new Scene()
- cubeGroup.add(blueCube, greenCube, orangeCube)
- const cubettiAnims = [
- { // group spin
- targets: [cubeGroup.rotation],
- params: {
- keyframes: [
- { y: 2 * Math.PI, duration: 1000 },
- ],
- easing: 'easeOutCubic',
- duration: 1000,
- onComplete: playRandomAnimation,
- }
- },
- { // floating cubes
- targets: [orangeCube.position, blueCube.position, greenCube.position],
- params: {
- keyframes: [
- { y: -0.5, duration: 500/3 },
- { y: 0.5, duration: 707/3 },
- { y: 0.0, duration: 500/3 },
- ],
- easing: 'easeInOutSine',
- delay: stagger(500/3),
- onComplete: playRandomAnimation,
- }
- },
- { // rotating cubes
- targets: [orangeCube.rotation, blueCube.rotation, greenCube.rotation],
- params: {
- x: MathUtils.randInt(0, 1) * 2 * Math.PI, y: MathUtils.randInt(0, 1) * 2 * Math.PI, z: MathUtils.randInt(0, 1) * 2 * Math.PI, duration: 1000,
- easing: 'easeOutSine',
- delay: stagger(500/3),
- onComplete: playRandomAnimation
- }
- }
- ]
-
- const cubetti = ref()
- function playRandomAnimation() {
- setTimeout(() => {
- const n = MathUtils.randInt(0, cubettiAnims.length-1)
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
- const a = cubettiAnims[n] as any;
- animate(a.targets, a.params)
- }, MathUtils.randInt(1000, 8000))
- }
- const runAnimation = () => {
- renderer.render(scene, camera)
- requestAnimationFrame(runAnimation)
- }
- const resizeCanvas = () => {
- if (window.innerWidth < 640) {
- renderer.setSize(120, 120);
- } else {
- renderer.setSize(200, 200);
- }
- }
- onMounted(() => {
- scene.add(camera)
- scene.add(ambientLight, directionalLight)
- scene.add(cubeGroup)
- // renderer.setSize(200, 200)
- resizeCanvas();
- camera.position.copy((new Vector3(-2, 1.5, 2)).multiplyScalar(1.2))
- camera.lookAt(0, 0, 0)
- scene.background = null
- cubetti.value.appendChild(renderer.domElement)
- window.addEventListener('resize', resizeCanvas);
- playRandomAnimation()
- runAnimation()
- })
- onUnmounted(() => {
- window.removeEventListener('resize', resizeCanvas);
- })
- </script>
|