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 =newTHREE.Scene();const camera =newTHREE.PerspectiveCamera(75,
window.innerWidth / window.innerHeight,
nearDist,
farDist
);
camera.position.x = farDist *-2;
camera.position.z =450;const renderer =newTHREE.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 TYPOGRAPHYconst group =newTHREE.Group();const typoSize =120;for(let i =0; i <12; i++){const typoLoader =newTHREE.FontLoader();constcreateTypo= font =>{const textMesh =newTHREE.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 =newTHREE.TextBufferGeometry(word, typoProperties);// BufferAttribute allows for more efficient passing of data to the GPU
textMesh.material =newTHREE.MeshMatcapMaterial();
textMesh.material.color =newTHREE.Color(0xfc27a7);// HotPinkconst texture =newTHREE.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 EFFECTlet 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 GRAPHICconstrender=()=>{requestAnimationFrame(render);// Camera animation// Works with onMouseMove and onTouchMove functionsconst 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 animationconst 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();