示例
HTML
#canvas-wrapper(aria-label='One Up')
CSS
body {
height: 100vh;
background-color: #101010; // black
margin: 0;
padding: 0;
overflow: hidden;
}
JS
/*
* 3D ONE UP TYPO
* Made with ThreeJS - Enjoy!
* https://threejs.org/
*
* Experimenting with porcelain typography.
* Move the cursor to zoom in/out and float around the typo space.
* On mobile touch + drag screen to zoom in/out and float.
*
* #015 - #100DaysOfCode
* By ilithya | 2019
*/
const nearDist = 0.1;
const farDist = 7000;
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(
75,
window.innerWidth / window.innerHeight,
nearDist,
farDist
);
camera.position.x = farDist * -2;
camera.position.z = 450;
const renderer = new THREE.WebGLRenderer({antialias: true});
renderer.setClearColor("#101010"); // Backgrond Color - Black
renderer.setPixelRatio(window.devicePixelRatio); // For HiDPI devices to prevent bluring output canvas
renderer.setSize(window.innerWidth, window.innerHeight);
document.querySelector("#canvas-wrapper").appendChild(renderer.domElement);
// CREATE TYPOGRAPHY
const group = new THREE.Group();
const typoSize = 120;
for (let i = 0; i < 12; i++) {
const typoLoader = new THREE.FontLoader();
const createTypo = font => {
const textMesh = new THREE.Mesh();
const word = "ONE UP";
const typoProperties = {
font: font,
size: typoSize,
height: typoSize * 2,
curveSegments: 2,
bevelEnabled: true,
bevelThickness: 10,
bevelSize: 6,
bevelOffset: 1,
bevelSegments: 8
};
textMesh.geometry = new THREE.TextBufferGeometry(word, typoProperties); // BufferAttribute allows for more efficient passing of data to the GPU
textMesh.material = new THREE.MeshMatcapMaterial();
textMesh.material.color = new THREE.Color(0xfc27a7); // HotPink
const texture = new THREE.TextureLoader().load(
"https://threejs.org/examples/textures/matcaps/matcap-porcelain-white.jpg"
);
// Using RepeatWrapping the texture will simply repeat to infinity
texture.wrapS = THREE.RepeatWrapping; // Texture is wrapped horizontally and corresponds to U in UV mapping
texture.wrapT = THREE.RepeatWrapping; // Texture is wrapped vertically and corresponds to V in UV mapping
texture.repeat.set(4, 4); // Times the texture is repeated across the surface, in each direction U and V
textMesh.material.matcap = texture;
const dist = i * (typoSize * 1.05);
textMesh.position.x = dist;
textMesh.position.y = dist;
// Manually control when 3D transformations recalculation occurs for better performance
textMesh.matrixAutoUpdate = false;
textMesh.updateMatrix();
group.add(textMesh);
};
typoLoader.load(
"https://threejs.org/examples/fonts/helvetiker_bold.typeface.json",
createTypo
);
}
group.position.x = typoSize * -1.6;
group.position.y = typoSize * -1;
scene.add(group);
// CREATE PART OF THE MOUSE/TOUCH OVER EFFECT
let mouseX = 0;
let mouseY = 0;
const mouseFX = {
windowHalfX: window.innerWidth / 2,
windowHalfY: window.innerHeight / 2,
coordinates: function(coordX, coordY) {
mouseX = (coordX - mouseFX.windowHalfX) * 5;
mouseY = (coordY - mouseFX.windowHalfY) * 5;
},
onMouseMove: function(e) {
mouseFX.coordinates(e.clientX, e.clientY);
},
onTouchMove: function(e) {
mouseFX.coordinates(e.changedTouches[0].clientX, e.changedTouches[0].clientY);
}
};
document.addEventListener("mousemove", mouseFX.onMouseMove, false);
document.addEventListener("touchmove", mouseFX.onTouchMove, false);
// RENDER 3D GRAPHIC
const render = () => {
requestAnimationFrame(render);
// Camera animation
// Works with onMouseMove and onTouchMove functions
const ctiming = 0.04;
const pX = (mouseX - camera.position.x) * ctiming;
const pY = (mouseY * -1 - camera.position.y) * ctiming;
camera.position.x += pX;
camera.position.y += pY;
camera.position.z += pY;
camera.lookAt(scene.position); // Rotates the object to face a point in world space
// Floating animation
const radians = Date.now() * 0.0004;
const rot = Math.sin(radians) * 0.2;
group.rotation.x = rot;
group.rotation.y = rot;
renderer.render(scene, camera);
};
render();
来源:CSDN
作者:盈嘉小红砖(同公众号)
链接:https://blog.csdn.net/weixin_45544796/article/details/104178580