canvas交互动画html+ css+ js+ three. js
可以看一下别人的这个案例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="js/three.js"></script>
<style>
html,body{
margin: 0;
padding: 0;
width: 100%;
height: 100%;
}
#music-button{
position: absolute;
top: 20px;
left: 100px;
cursor: pointer;
}
#music-button img{
position: absolute;
left: 0;
top: 0;
width: 30px;
height: 30px;
}
</style>
</head>
<body>
<div id="bg-music">
<audio src="music/desk-bgm.e1c8e207.mp3" loop autoplay></audio>
</div>
<div id="music-button">
<img id = "music-off" src="img/audio-off.89ea1960.png" alt="">
<img id = "music-on" src="img/audio-on.5e57c737.png" alt="">
</div>
<script>
//创建场景
var scene = new THREE.Scene();
// 创建相机
var camera = new THREE.PerspectiveCamera( 60, window.innerWidth/window.innerHeight, 0.1, 1000 );
// 设置相机高度
camera.position.z = 5;
// 创建渲染器
var renderer = new THREE.WebGLRenderer();
// 设置渲染器大小
renderer.setSize( window.innerWidth, window.innerHeight );
// 设置背景颜色
renderer.setClearColor(0xaaaaaa, 1)
// 将渲染器加入html
document.body.appendChild( renderer.domElement );
//创建辅助轴模型
var axes = new THREE.AxesHelper(50);
// 将模型添加到场景
scene.add(axes)
// 创建矩形模型
var plane = new THREE.PlaneGeometry(117,72);
// 创建基础材质
var planeMaterial = new THREE.MeshBasicMaterial();
// 创建纹理对象
var textureloader = new THREE.TextureLoader();
// 加载纹理图片
var bg = textureloader.load("../img/77a3b856-6651-4956-85fa-8b05ad374dc5.jpg");
// 将纹理叠加到材质上
planeMaterial.map = bg
// 将材质叠加到模型上
var planeMesh = new THREE.Mesh(plane,planeMaterial);
// 移动模型
planeMesh.translateZ(-40);
// 将模型添加到场景
scene.add(planeMesh);
// 创建矩形模型
var pendantBox = new THREE.PlaneGeometry(15,11);
// 创建基础材质
var pendantMaterial = new THREE.MeshBasicMaterial();
// 创建纹理对象
var pendanttexture = new THREE.TextureLoader();
// 加载纹理图片
var pendanttextureload = pendanttexture.load("img/37b8e838-7b22-4f8d-b100-fe1464843236.png");
// 将纹理叠加到材质上
pendantMaterial.map = pendanttextureload;
//png图片透明部分开启
pendantMaterial.transparent = true;
pendantMaterial.opacity = 0;
// 将材质叠加到模型上
var pendantMesh = new THREE.Mesh(pendantBox,pendantMaterial);
// 移动模型
pendantMesh.translateX(4.8);
pendantMesh.translateY(0.7);
pendantMesh.translateZ(-25);
// 将模型添加到场景
scene.add(pendantMesh);
// 创建矩形模型
var pendantLightBox = new THREE.PlaneGeometry(15,11);
// 创建基础材质
var pendantLightMaterial = new THREE.MeshBasicMaterial();
// 创建纹理对象
var pendantLighttexture = new THREE.TextureLoader();
// 加载纹理图片
var pendantLighttextureload = pendantLighttexture.load("../img/1fe2462e-7aaa-4c13-ad10-7ff6fa973d31.png");
// 将纹理叠加到材质上
pendantLightMaterial.map = pendantLighttextureload;
//png图片透明部分开启
pendantLightMaterial.transparent = true;
// 混合模式设置为叠加
pendantLightMaterial.blending = THREE.AdditiveBlending;
// 透明度设置为0
pendantLightMaterial.opacity = 0;
// 将材质叠加到模型上
var pendantLightMesh = new THREE.Mesh(pendantLightBox,pendantLightMaterial);
pendantLightMesh.name = "pendantLight";
// 移动模型
pendantLightMesh.translateX(5.5);
pendantLightMesh.translateY(1.6);
pendantLightMesh.translateZ(-30);
// 旋转模型
pendantLightMesh.rotation.x = -0.4;
pendantLightMesh.rotation.y = 0.2;
// 缩放模型
pendantLightMesh.scale.set(0.0,0.0,0.0);
// 将模型添加到场景
scene.add(pendantLightMesh);
// 创建矩形模型
var arrowsBox = new THREE.PlaneGeometry(3,3);
//创建基础材质
var arrowsMaterial = new THREE.MeshBasicMaterial();
// 创建纹理对象
var arrowsTexture = new THREE.TextureLoader();
// 加载纹理图片
var arrowsTextureload = arrowsTexture.load("img/8527e88b-685a-46cd-aec8-4ab73403dce3.png");
// 将纹理叠加到材质上
arrowsMaterial.map = arrowsTextureload;
// png图片透明部分开启
arrowsMaterial.transparent = true;
// 将材质叠加到模型上
var arrowsMesh = new THREE.Mesh(arrowsBox,arrowsMaterial);
// 移动模型
arrowsMesh.translateX(4)
arrowsMesh.translateZ(-24)
// 将模型添加到场景
scene.add(arrowsMesh);
// 创建矩形模型
var textplane = new THREE.PlaneGeometry(9,1.8);
// 创建基础材质
var textplaneMaterial = new THREE.MeshBasicMaterial();
// 创建纹理对象
var texttexture = new THREE.TextureLoader();
// 加载纹理图片
var text = textureloader.load("img/4546fc0e-f6ac-4360-8bfd-626091a7f2e7.png");
// 将纹理叠加到材质上
textplaneMaterial.map = text;
// png图片透明部分开启
textplaneMaterial.transparent = true;
// 将材质叠加到模型上
var textMesh = new THREE.Mesh(textplane,textplaneMaterial);//纹理贴图网格模型
// 移动模型
textMesh.translateX(1);
textMesh.translateY(-2.5);
textMesh.translateZ(-1);//平移纹理贴图网格模型
// 将模型添加到场景
scene.add(textMesh);//纹理贴图网格模型添加到场景中
var lightplane = new THREE.PlaneGeometry(12,60);
var lightplaneMaterial = new THREE.MeshBasicMaterial();
var lighttexture = new THREE.TextureLoader();
var light = textureloader.load("img/b9047335-f041-4c4b-a7c3-449fd5d5ff7c.jpg");
lightplaneMaterial.map = light;
lightplaneMaterial.blending = THREE.AdditiveBlending;
lightplaneMaterial.transparent = true;
var lightMesh = new THREE.Mesh(lightplane,lightplaneMaterial);
lightMesh.translateX(-10);
lightMesh.translateY(10);
lightMesh.translateZ(-35);
lightMesh.rotation.z = -0.9;
scene.add(lightMesh);
var lightplane2 = new THREE.PlaneGeometry(12,60);
var lightplaneMaterial2 = new THREE.MeshBasicMaterial();
var lighttexture2 = new THREE.TextureLoader();
var light2 = textureloader.load("img/b9047335-f041-4c4b-a7c3-449fd5d5ff7c.jpg");
lightplaneMaterial2.map = light2;
lightplaneMaterial2.blending = THREE.AdditiveBlending;
lightplaneMaterial2.transparent = true;
var lightMesh2 = new THREE.Mesh(lightplane2,lightplaneMaterial2);
lightMesh2.translateX(6);
lightMesh2.translateY(10);
lightMesh2.translateZ(-34);
lightMesh2.rotation.z = -0.9;
scene.add(lightMesh2);
var lightplane2 = new THREE.PlaneGeometry(25,50);
var lightplaneMaterial2 = new THREE.MeshBasicMaterial();
var lighttexture2 = new THREE.TextureLoader();
var light2 = textureloader.load("img/b9047335-f041-4c4b-a7c3-449fd5d5ff7c.jpg");
lightplaneMaterial2.map = light2;
lightplaneMaterial2.blending = THREE.AdditiveBlending;
lightplaneMaterial2.transparent = true;
var lightMesh2 = new THREE.Mesh(lightplane2,lightplaneMaterial2);
lightMesh2.translateX(25);
lightMesh2.translateY(10);
lightMesh2.translateZ(-33);
lightMesh2.rotation.z = -0.8;
scene.add(lightMesh2);
// 创建关键帧
var inScaleTrack = new THREE.KeyframeTrack('pendantLight.scale', [0, 30], [0.5, 0.5, 0.5, 1, 1, 1]);
var inOpacityTrack = new THREE.KeyframeTrack('pendantLight.material.opacity', [0, 30], [0, 1]);
// 动画持续时间(帧)
var duration = 60;
// 创建剪辑对象
var clip = new THREE.AnimationClip("in", duration, [inScaleTrack,inOpacityTrack]);
// 创建混合器对象
var Mixer = new THREE.AnimationMixer(scene);
// 将剪辑对象放入混合器
var AnimationAction = Mixer.clipAction(clip);
// 设置动画播放速度,默认为1
AnimationAction.timeScale = 30;
// 设置动画循环,只执行一次
AnimationAction.loop = THREE.LoopOnce;
// 动画播放完成后停在最后一帧
AnimationAction.clampWhenFinished = true;
// 储存每个点每一帧移动的量
let moveArrX = [];
let moveArrY = [];
// 储存每个点移动的时间
let moveTime = [];
// 当前时间
let nowTime = 0;
// 每个光点生成时间
let joinTime = [];
// 添加光点模型z(z轴位置),sc(缩放大小),i(y轴范围)
function addDot(z,sc,i = 1){
// 绘制时的时间
joinTime.push(Date.now());
// 绘制的坐标
moveArrX.push(Math.random()*0.02-0.01);
moveArrY.push(Math.random()*0.02-0.01);
// 移动时间为10~20秒
moveTime.push(Math.round(Math.random()*10000+10000));
// 随机x轴为-50~50,y轴默认为-25~25
let randomX = Math.random()*100-50;
let randomY = Math.random()*50-25*i;
var dotPlane = new THREE.PlaneGeometry(1,1);
var dotPlaneMaterial = new THREE.MeshBasicMaterial();
var dotTexture = new THREE.TextureLoader();
var dotTextureload = dotTexture.load("img/d0d14aff-ecee-4449-806c-4a866163a7ce.jpg");
dotPlaneMaterial.map = dotTextureload;
dotPlaneMaterial.blending = THREE.AdditiveBlending;
dotPlaneMaterial.transparent = true;
var dotMesh = new THREE.Mesh(dotPlane,dotPlaneMaterial);
dotMesh.translateZ(z);
dotMesh.position.x = randomX*sc;
dotMesh.position.y = randomY*sc;
dotMesh.scale.set(sc,sc,sc);
group1.add(dotMesh);
}
// 创建一个组存放所有光点
let group1 = new THREE.Group();
// 循环创建最上层大光点
for(let i = 0;i<40;i++){
addDot(-39,1.3);
}
// 循环创建小光点
for(let j = 0;j<200;j++){
addDot(-29,0.3,0)
}
// 把组里所有模型添加到场景
scene.add(group1)
// 设置播放音量
var musicVolume = 1;
// 鼠标划过神之眼音效
function pendantMusic(){
// 创建audio标签
let audio = document.createElement("audio");
audio.src = "music/eye-mouseover.7d883e2b.mp3"
audio.autoplay = true;
// audio的音量
audio.volume = musicVolume;
document.body.appendChild(audio);
// 播放完成时移出标签
audio.addEventListener("ended",function(){
document.body.removeChild(audio);
})
}
let musicButton = document.querySelector("#music-button");
let musicOn = document.querySelector("#music-on");
let musicOff = document.querySelector("#music-off");
let bgMusic = document.querySelector("#bg-music audio");
// 把静音图标隐藏
musicOff.style.display = "none"
// 左上角音乐图标点击事件
function toggle(){
if(musicOff.style.display == "none"){
musicOff.style.display = "block"
musicOn.style.display = "none"
bgMusic.volume = 0;
musicVolume = 0;
}else{
bgMusic.volume = 1;
musicVolume = 1;
bgMusic.play();
musicOff.style.display = "none"
musicOn.style.display = "block"
}
}
musicButton.addEventListener("click",toggle);
// 鼠标移动事件
function mouseEvent(e){
camera.position.x = -(e.offsetX - window.innerWidth/2)/10000
camera.position.y = (e.offsetY - window.innerHeight/2)/4000
// 相机看向原点
camera.lookAt(scene.position);
// 鼠标在屏幕上的坐标
var Sx = e.clientX;
var Sy = e.clientY;
//屏幕坐标转标准设备坐标
var x = ( Sx / window.innerWidth ) * 2 - 1;
var y = -( Sy / window.innerHeight ) * 2 + 1;
var standardVector = new THREE.Vector3(x, y, 0.5);
//标准设备坐标转三维坐标
var worldVector = standardVector.unproject(camera);
//射线投射方向单位向量(worldVector坐标减相机位置坐标)
var ray = worldVector.sub(camera.position).normalize();
//创建射线投射器对象
var raycaster = new THREE.Raycaster(camera.position, ray);
//返回射线选中的对象
var intersects = raycaster.intersectObjects([pendantMesh]);
if (intersects.length > 0) {
if (animationstate) {
// 动画状态不可播放
animationstate = false;
// 取消暂停
AnimationAction.paused = false;
// 播放的速度
AnimationAction.timeScale = 120;
// 播放动画
AnimationAction.play();
// 修改鼠标光标
renderer.domElement.style.cursor = "pointer";
// 创建音效并播放
pendantMusic();
}
}else{
// 暂停播放
AnimationAction.paused = true;
// 播放速度
AnimationAction.timeScale = -50;
// 获取鼠标移出物体时在第几帧
var timing = AnimationAction.time;
// 从第几帧开始播放
AnimationAction.tiem = timing;
// 第几帧结束
clip.duration = 30;
// 取消暂停
AnimationAction.paused = false;
// 动画状态可播放
animationstate = true;
// 修改鼠标光标
renderer.domElement.style.cursor = "default";
}
}
document.body.addEventListener("mousemove",mouseEvent);
// 创建一个时钟对象Clock
var clock = new THREE.Clock();
// 创建箭头正弦角度
var angle = 0;
// 创建光点正弦角度
var angle2 = 0;
// 创建渲染函数
var render = function (){
// 渲染相机和场景
renderer.render(scene,camera)
// 刷新混合器
Mixer.update(clock.getDelta());
// 箭头上下移动
arrowsMesh.position.y = 9+Math.sin(angle)*0.5;
angle += 0.05;
// 遍历光点如果移动时间到了移除光点并重新创建一个随机光点
for(let i = 0;i<group1.children.length;i++){
nowTime = Date.now();
let item = group1.children[i]
item.position.x += moveArrX[i];
item.position.y += moveArrY[i];
if(nowTime - joinTime[i] < moveTime[i]){
if(item.position.z == -39){
item.material.opacity = 0.5 * ((Math.sin(angle2)+2.5)/3.5);
}else{
item.material.opacity = 0.5 * ((Math.sin(angle2)+4)/5);
}
}else{
item.material.opacity -= 0.0005;
}
if(item.material.opacity <= 0){
let itemArguments = [item.position.z,item.scale.x];
group1.remove(item);
moveArrX.splice(i,1);
moveArrY.splice(i,1);
moveTime.splice(i,1);
joinTime.splice(i,1);
addDot(...itemArguments);
}
}
angle2 +=0.03;
// 按当前设备帧数每秒回调多少次渲染,实现动画效果
requestAnimationFrame( render );
}
render()
</script>
</body>
</html>