結構如下
<template>
<main class="min-h-screen grid place-items-center">
<section class="w-full max-w-[560px] space-y-6 sm:space-y-8 text-center">
<!-- 顯示時間 -->
<div class="mx-auto w-full max-w-[340px] sm:max-w-[420px]">
<div class="mb-3 grid place-items-center">
<div class="px-3.5 py-1.5 rounded-full bg-white/70 backdrop-blur-sm">
<div class="text-3xl md:text-4xl font-semibold">
{{ fmt() }}
</div>
</div>
</div>
<!-- 呼吸球 + 進度圈 -->
<div class="relative">
<ThreeBreathingSphere />
<div class="progress-ring" :style="{ '--progress': (progress*360) + 'deg' }"></div>
</div>
</div>
<!-- 停止 -->
<button @click="handleStop" class="stop-btn">STOP</button>
</section>
</main>
</template>
結構如下
// 場景初始化
const initScene = () => {
scene = new THREE.Scene()
camera = new THREE.PerspectiveCamera(32, 1, 0.1, 100)
camera.position.set(0, 0, 9)
const sphereGeo = new THREE.SphereGeometry(2.4, 128, 128)
const sphereMat = new THREE.MeshPhysicalMaterial({
color: new THREE.Color(0.2, 0.5, 1.0),
roughness: 0.01,
metalness: 0.05,
transmission: 0.99,
thickness: 1.2,
clearcoat: 1.0,
clearcoatRoughness: 0.01,
ior: 1.6,
reflectivity: 0.95,
iridescence: 0.9,
iridescenceIOR: 1.6
})
mainSphere = new THREE.Mesh(sphereGeo, sphereMat)
scene.add(mainSphere)
}
// 動畫
const animate = () => {
requestAnimationFrame(animate)
const t = Date.now() * 0.001
const breath = Math.sin(t * 0.5) * 0.1 + 1.0
mainSphere.scale.set(breath, breath, breath) // 呼吸
mainSphere.rotation.x = t * 0.1
mainSphere.rotation.y = t * 0.15
renderer.render(scene, camera)
}
展示畫面如下,還有一些地方要修改(像是裡面的球在放大時、沒有完整顯示)