“使用 Three.js 的 WebGL 小实验。变形动画。”
HTML:
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r124/three.min.js"></script>
<script src="https://cdn.jsdelivr.net/particles.js/2.0.0/particles.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<canvas>
<video id="video" autoplay loop muted crossOrigin="anonymous" >
<source src="https://assets.codepen.io/9234665/cyberjourney+-+720WebShareName.mov" type="video/mp4">
</video>
<audio id="audio" autoplay loop crossOrigin="anonymous" >
<source src="https://assets.codepen.io/9234665/recording.m4a" />
</audio>
</canvas>
html,
body {
margin: 0;
padding: 0;
background: black;
overflow: hidden;
height: 100%;
animation:none;
}
JAVASCRIPT:
var renderer = new THREE.WebGLRenderer({
canvas: document.querySelector("canvas"),
powerPreference: "high-performance"
});
renderer.setSize(window.innerWidth, window.innerHeight);
var scene = new THREE.Scene();
//===================================================== Create a perpsective camera
var camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.001, 1000);
camera.position.z = 400;
//===================================================== resize
window.addEventListener("resize", function() {
renderer.setSize(window.innerWidth, window.innerHeight);
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
});
//===================================================== Array of points
var points = [
[68.5,185.5],
[160.6,3.3],
[68.5,185.5]
];
//===================================================== Convert the array of points into vertices
for (var i = 0; i < points.length; i++) {
var x = points[i][0];
var y = 0;
var z = points[i][1];
points[i] = new THREE.Vector3(x, y, z);
}
//===================================================== Create a path from the points
var path = new THREE.CatmullRomCurve3(points);
//===================================================== Create the tube geometry from the path
var sides = 70;
var geometry = new THREE.TubeGeometry( path, 500, .5, sides, true );
//===================================================== Basic material
const tex = new THREE.VideoTexture(video);
video.play();
const listener = new THREE.AudioListener(autoplay=true);
camera.add( listener );
// create a global audio source
const sound = new THREE.Audio( listener );
// load a sound and set it as the Audio object's buffer
const audioLoader = new THREE.AudioLoader();
audioLoader.load( 'sounds/ambient.ogg', function( buffer ) {
sound.setBuffer( buffer );
sound.setLoop( true );
sound.setVolume( 0.5 );
sound.play();
});
var material = new THREE.MeshBasicMaterial({
side : THREE.BackSide,
map: tex
});
material.map.wrapS = THREE.RepeatWrapping;
material.map.wrapT= THREE.RepeatWrapping;
material.map.repeat.set(20, 1)
//===================================================== Create a mesh
var tube = new THREE.Mesh( geometry, material );
tube.matrixAutoUpdate = false;//wont be moving so no need to update
scene.add( tube );
//===================================================== Create a point light in our scene
var light = new THREE.PointLight(new THREE.Color("white"),1, 100);
scene.add(light);
//===================================================== Animate
var startTime = performance.now(); // Record the start time
function animate() {
var currentTime = performance.now(); // Get the current time
var elapsedTime = (currentTime - startTime) / 1000; // Calculate elapsed time in seconds
percentage = (elapsedTime * 0.0005) % 1; // Use elapsed time to calculate percentage
var p1 = path.getPointAt(percentage);
var p2 = path.getPointAt((percentage + 0.03) % 1);
camera.position.set(p1.x, p1.y, p1.z);
camera.lookAt(p2);
light.position.set(p2.x, p2.y, p2.z);
// Increment the material map repeat.x value by 0.1
material.map.repeat.y += 0.001;
// Render the scene
renderer.render(scene, camera);
requestAnimationFrame(animate);
}
animate();
源码:
https://codepen.io/WilliamStaudenmeier/pen/qBLbJbx
体验:
https://codepen.io/WilliamStaudenmeier/full/qBLbJbx