在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
本文内容主要介绍,通过使用React+three.js技术栈,加载3D模型、添加3D文字、增加动画、点击交互等,配合样式设计,实现充满设计感的 🤢`酸性风格页面。 背景近期学习了 基础知识
酸性设计
总之, 实现效果在线预览:https://tricell.fun 实现3D模型场景初始化
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera(70, window.innerWidth / window.innerHeight, 0.1, 1000); // 设置相机位置 camera.position.set(600, 20, -200); // 相机聚焦到屏幕中央 camera.lookAt(new THREE.Vector3(0, 0, 0));
添加 light = new THREE.HemisphereLight(0xffffff, 0x444444); light.position.set(0, 20, 0); scene.add(light); light = new THREE.DirectionalLight(0xffffff); light.position.set(0, 20, 10); light.castShadow = true; scene.add(light); 添加 var ambiColor = '#0C0C0C'; var ambientLight = new THREE.AmbientLight(ambiColor); scene.add(ambientLight); 添加辅助工具(可选)
var grid = new THREE.GridHelper(1000, 100, 0x000000, 0x000000); grid.material.opacity = 0.1; grid.material.transparent = true; grid.position.set(0, -240, 0); scene.add(grid);
通过相机控件 controls = new THREE.OrbitControls(camera, renderer.domElement); controls.target.set(0, 0, 0); controls.update();
stats = new Stats(); container.appendChild(stats.dom); 加载模型本文示例用到的 加载 需要单独引入 // var loader = new THREE.FBXLoader(); var loader = new THREE.OBJLoader(); loader.load(model, function (object) { object.traverse(function (child) { if (child.isMesh) { child.castShadow = true; child.receiveShadow = true; } }); object.rotation.y = Math.PI / 2; object.position.set(0, -200, 0); object.scale.set(0.32, 0.32, 0.32); model = object; scene.add(object); }); 加载 gltf 模型需要单独引入 var loader = new THREE.GLTFLoader(); loader.load(model, function (object) { object.scene.traverse(function (child) { if (child.isMesh) { child.castShadow = true; child.receiveShadow = true; } }); object.scene.rotation.y = Math.PI / 2; object.scene.position.set(0, -240, 0); object.scene.scale.set(0.33, 0.33, 0.33); model = object.scene; scene.add(object.scene); }); 添加网格、加载完成模型之后的效果如下图所示。 添加转盘动画通过 function animate () { requestAnimationFrame(animate); // 随着页面重绘不断改变场景的rotation.y来实现旋转 scene.rotation.y -= 0.015; renderer.render(scene, camera); } 添加点击交互在
代码实现的基本步骤是:获取鼠标在屏幕的坐标 //声明raycaster和mouse变量 var raycaster = new THREE.Raycaster(); var mouse = new THREE.Vector2(); onMouseClick = event => { // 将鼠标点击位置的屏幕坐标转成threejs中的标准坐标,以屏幕中心为原点,值的范围为-1到1. mouse.x = (event.clientX / window.innerWidth) * 2 - 1; mouse.y = - (event.clientY / window.innerHeight) * 2 + 1; // 通过鼠标点的位置和当前相机的矩阵计算出raycaster raycaster.setFromCamera(mouse, camera); // 获取raycaster直线和所有模型相交的数组集合 let intersects = raycaster.intersectObjects(scene.children); if (intersects.length > 0) { alert('HELLO WORLD') // 可以通过遍历实现点击不同mesh触发不同交互,如: let selectedObj = intersects[0].object; if (selectedObj.name === 'car') { alert('汽车🚗') } } } window.addEventListener('click', onMouseClick, false); 添加3D文字使用
var loader = new THREE.FontLoader(); loader.load('gentilis_regular.typeface.json', function (font) { var textGeo = new THREE.TextGeometry('HELLO WORLD', { font: font, size: .8, height: .8, curveSegments: .05, bevelThickness: .05, bevelSize: .05, bevelEnabled: true }); var textMaterial = new THREE.MeshPhongMaterial({ color: 0x03c03c }); var mesh = new THREE.Mesh(textGeo, textMaterial); mesh.position.set(0, 3.8, 0); scene.add(mesh); }); 优化现在模型加载已经基本完成了,但是 安装
将obj模型复制到以下目录中
执行转码指令
如图出现类似上述内容,转码完成,对比转化前后的文件体积,本例中
完整代码 var model = require('@/assets/models/kas.gltf'); var container, stats, controls; var camera, scene, renderer, light, model; class Kas extends React.Component { render () { return ( <div id="kas"></div> ) } componentDidMount () { this.initThree(); } initThree () { init(); animate(); function init () { container = document.getElementById('kas'); scene = new THREE.Scene(); scene.fog = new THREE.Fog(0xa0a0a0, 200, 1000); // 透视相机:视场、长宽比、近面、远面 camera = new THREE.PerspectiveCamera(70, window.innerWidth / window.innerHeight, 0.1, 1000); camera.position.set(600, 20, -200); camera.lookAt(new THREE.Vector3(0, 0, 0)); // 半球光源:创建室外效果更加自然的光源 light = new THREE.HemisphereLight(0xffffff, 0x444444); light.position.set(0, 20, 0); scene.add(light); light = new THREE.DirectionalLight(0xffffff); light.position.set(0, 20, 10); light.castShadow = true; scene.add(light); // 环境光 var ambiColor = '#0C0C0C'; var ambientLight = new THREE.AmbientLight(ambiColor); scene.add(ambientLight); // 网格 var grid = new THREE.GridHelper(1000, 100, 0x000000, 0x000000); grid.material.opacity = 0.1; grid.material.transparent = true; grid.position.set(0, -240, 0); scene.add(grid); // 加载gltf模型 var loader = new THREE.GLTFLoader(); loader.load(model, function (object) { object.scene.traverse(function (child) { if (child.isMesh) { child.castShadow = true; child.receiveShadow = true; } }); object.scene.rotation.y = Math.PI / 2; object.scene.position.set(0, -240, 0); object.scene.scale.set(0.33, 0.33, 0.33); model = object.scene; scene.add(object.scene); }); renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true }); renderer.setPixelRatio(window.devicePixelRatio); renderer.setSize(window.innerWidth, window.innerHeight); renderer.setClearAlpha(0); renderer.shadowMap.enabled = true; container.appendChild(renderer.domElement); window.addEventListener('resize', () => { camera.aspect = window.innerWidth / window.innerHeight; camera.updateProjectionMatrix(); renderer.setSize(window.innerWidth, window.innerHeight); }, false); stats = new Stats(); container.appendChild(stats.dom); } function animate () { var clock = new THREE.Clock() requestAnimationFrame(animate); var delta = clock.getDelta(); scene.rotation.y -= 0.015; renderer.render(scene, camera); stats.update(); } // 增加点击事件 //声明raycaster和mouse变量 var raycaster = new THREE.Raycaster(); var mouse = new THREE.Vector2(); function onMouseClick(event) { // 通过鼠标点击位置计算出raycaster所需要点的位置,以屏幕中心为原点,值的范围为-1到1. mouse.x = (event.clientX / window.innerWidth) * 2 - 1; mouse.y = - (event.clientY / window.innerHeight) * 2 + 1; // 通过鼠标点的位置和当前相机的矩阵计算出raycaster raycaster.setFromCamera(mouse, camera); // 获取raycaster直线和所有模型相交的数组集合 var intersects = raycaster.intersectObjects(scene.children); if (intersects.length > 0) { alert('HELLO WORLD') } } window.addEventListener('click', onMouseClick, false); } } 其他设计元素本文主要介绍 流体背景
金属、霓虹、故障效果等酸性效果字体可以阅读我的另一篇文章《仅用CSS几步实现赛博朋克2077风格视觉效果》,也可以使用设计生成,由于时间关系,本文项目中的金属效果文字以及本文banner头图中的文字都是使用在线艺术字体生成网站生成的,感兴趣的同学可以自行尝试设计。 未来进一步优化
最后给大家推荐几个非常惊艳的 github首页: kodeclubs:低面数 球鞋展示: 沙雕dance:沙雕动物舞者。 Zenly软件: 参考资料 three.js: https://threejs.org obj2gltf: https://github.com/CesiumGS/obj2gltf 200多页免费3d模型 https://www.turbosquid.com 免费3D雕像: https://threedscans.com 免费3D模型:https://free3d.com 艺术字体在线生成:https://cooltext.com 什么是酸性设计:https://www.shejipi.com/361258.html 作者:dragonir 本文地址:https://www.cnblogs.com/dragonir/p/15350537.html 到此这篇关于使用three.js实现炫酷的酸性风格3D页面的文章就介绍到这了,更多相关three.js酸性风格3D页面内容请搜索极客世界以前的文章或继续浏览下面的相关文章希望大家以后多多支持极客世界! |
请发表评论