三维变幻字母(3D Fluctuating Letters)

时光怂恿深爱的人放手 提交于 2020-02-05 11:33:41

三维变幻字母(3D Fluctuating Letters)

示例

在这里插入图片描述

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();
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!