怎么用three.js react实现3d文字悬浮效果-亚博电竞手机版

怎么用three.js react实现3d文字悬浮效果

本篇内容介绍了“怎么用three.js react实现3d文字悬浮效果”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!

    背景

    three.js journey课程示例中,提供了一个使用three.js内置方法实现的3d文字悬浮效果的例子,本文使用react three.js技术栈,参照示例实现类似的效果。本文中涉及到的知识点主要包括:css网格背景、meshnormalmaterial法向材质、fontloader字体加载器、textgeometry文本缓冲几何体、torusbuffergeometry圆环缓冲几何体、conebuffergeometry圆锥缓冲几何体、octahedronbuffergeometry八面缓冲几何体、three.js后期渲染、glitchpass通道、element.requestfullscreendocument.exitfullscreen等。

    效果

    实现效果如banner图所示,页面主体由位于中心的文字网格模型以及四周的圆环面、圆锥以及八面体构成。随着鼠标在页面上移动或点击,模型也随之移动。页面右上角提供了2个按钮,可以切换页面背景色和切换故障风格后期特效。双击屏幕可以进入或退出全屏。

    在线预览:https://3d-dragonir.vercel.app/#/floating

    或https://dragonir.github.io/3d/#/floating

    已适配:

    • pc端

    • 移动端

    实现

    资源引入

    首先引入开发所需要的模块资源,其中fontloader用于加载字体文件,textgeometry用于创建3d字体网格,effectcomposerrenderpassglitchpass用于后期特效渲染。

    import*asthreefrom"three";import{fontloader}from"three/examples/jsm/loaders/fontloader";import{textgeometry}from'three/examples/jsm/geometries/textgeometry';import{effectcomposer}from'three/examples/jsm/postprocessing/effectcomposer.js';import{renderpass}from'three/examples/jsm/postprocessing/renderpass.js';import{glitchpass}from'three/examples/jsm/postprocessing/glitchpass.js';

    dom结构

    页面dom结构非常简单,容器#canvas用于场景渲染,.color_pick用于切换页面背景颜色,.pass_button用于切换故障风格后期渲染。

    特效{this.state.renderglithpass?'开':'关'}

    设置状态

    backgroundcolor表示当前页面背景色,renderglithpass表示是否开启后期状态。自测发现在ios safari浏览器中,故障风格后期渲染会导致模型产生穿模问题,因此使用该参数控制手机端默认关闭后期效果、pc端默认开启。

    state={backgroundcolor:'#164cca',renderglithpass:!(window.navigator.useragent.tolowercase().indexof('mobile')>0)}

    网格背景

    使用纯css属性linear-gradient实现网格背景来美化页面。

    background-image:linear-gradient(rgba(3,192,60,.3)1px,transparent1px),linear-gradient(90deg,rgba(3,192,60,.3)1px,transparent1px);background-size:1em1em;

    场景初始化

    初始化渲染容器、场景、摄像机,摄像机的位置可根据自身所需调整。render开启alpha并设置.setclearalpha(0)可将背景色设置为透明。

    canvas=document.getelementbyid('canvas');renderer=newthree.webglrenderer({antialias:true,alpha:true});renderer.setpixelratio(math.min(2,window.devicepixelratio));renderer.setsize(window.innerwidth,window.innerheight);renderer.setclearalpha(0);canvas.appendchild(renderer.domelement);scene=newthree.scene();camera=newthree.perspectivecamera(70,window.innerwidth/window.innerheight,.1,10000);camera.position.set(-2*10000,0,780);

    创建材质

    本文中所有网格模型都将使用同一种材质meshnormalmaterial,应用它的特性,可以使网格模型产生彩色渐变。全局创建一次,后续开发不需要重复创建,有利于页面性能提升。

    constmaterial=newthree.meshnormalmaterial();

    meshnormalmaterial 法向材质

    是一种把法向量映射到rgb颜色的材质,可以通过观察模型表面渐变颜色是否连续来检测模型表面是否平整

    构造函数

    meshnormalmaterial(parameters:object)

    parameters:可选,用于定义材质外观的对象,具有一个或多个属性。

    特殊属性

    创建文字模型

    使用fontloader加载fontface字体json文件,并用textgeometry创建文字几何体模型。

    constloader=newfontloader();loader.load('./fonts/helvetiker_regular.typeface.json',font=>{textmesh.geometry=newtextgeometry('@dragonir\nfantastic\nthree.js\nartwork',{font:font,size:100,height:40,curvesegments:12,bevelenabled:true,bevelthickness:30,bevelsize:8,beveloffset:1,bevelsegments:12});textmesh.material=material;scene.add(textmesh);});

    fontloader 字体加载器

    使用json格式中加载字体的一个类,返回font, 返回值是表示字体的shape类型的数组,其内部使用fileloader来加载文件。

    构造函数

    fontloader(manager:loadingmanager)

    方法:

    .loadurl中进行加载,并将被加载的texture传递给onload

    .parsejson格式进行解析,并返回一个font

    textgeometry 文本几何体

    用于将文本生成单一几何体的类,它是由一串给定的文本,以及由加载的font字体和该几何体extrudegeometry父类中的设置所组成的参数构造的。

    构造函数

    textgeometry(text:string,parameters:object)

    text:将要显示的文本。

    parameters

    可以使用facetype.js在线转换three.js支持的字体。

    创建几何体模型

    使用其他3种内置几何体模型圆环、圆锥和八面体来装饰页面。装饰几何体的数量比较多,为了有效提升页面性能,需要注意以下两点:

    //批量创建模型方法generaterandommesh=(geometry,material,count)=>{for(leti=0;i

    torusbuffergeometry 圆环缓冲几何体

    用于生成圆环几何体的类。

    构造函数

    torusbuffergeometry(radius:float,tube:float,radialsegments:integer,tubularsegments:integer,arc:float)

    conebuffergeometry 圆锥缓冲几何体

    用于生成圆锥几何体的类。

    构造函数

    conebuffergeometry(radius:float,height:float,radialsegments:integer,heightsegments:integer,openended:boolean,thetastart:float,thetalength:float)

    octahedronbuffergeometry 八面缓冲几何体

    用于创建八面体的类。

    构造函数

    octahedronbuffergeometry(radius:float,detail:integer)

    鼠标事件监听

    通过对鼠标移动坐标和模型坐标的相互转换来添加鼠标移动和触摸移动事件的监听方法。

    constmousefx={windowhalfx:window.innerwidth/2,windowhalfy:window.innerheight/2,coordinates:(coordx,coordy)=>{mousex=(coordx-mousefx.windowhalfx)*5;mousey=(coordy-mousefx.windowhalfy)*5;},onmousemove:e=>{mousefx.coordinates(e.clientx,e.clienty)},ontouchmove:e=>{mousefx.coordinates(e.changedtouches[0].clientx,e.changedtouches[0].clienty)}};document.addeventlistener('mousemove',mousefx.onmousemove,false);document.addeventlistener('touchmove',mousefx.ontouchmove,false);

    背景色切换

    使用一个input[type='color']标签来实现背景色切换。

    handleinputchange=e=>{this.setstate({backgroundcolor:e.target.value});}

    后期渲染

    为了更具有冲击感的视觉效果,我添加了一个故障风格后期渲染特效,并使用一个按钮开关来控制开启和关闭该特效。

    composer=neweffectcomposer(renderer);composer.addpass(newrenderpass(scene,camera));glitchpass=newglitchpass();composer.addpass(glitchpass);

    handlerenderchange=()=>{this.setstate({renderglithpass:!this.state.renderglithpass});}

    后期渲染

    three.js后期渲染处理,是通过叠加渲染通道达到预期视觉效果的过程。实现流程如下:

    glitchpass 故障风格通道

    glitchpass通道产生模拟故障风格效果,它只有一个可选配置参数:

    gowild该属性接收一个布尔值,指定是否持续产生电磁风暴效果。

    three.js提供了很多后期处理的通道,可以直接使用。同时提供了shaderpass通道,它支持使用自定义shader,可以创建高级的自定义后期处理通道。

    动画

    requestanimationframe中更新场景、相机、和后期渲染通道。

    functionanimate(){requestanimationframe(animate);camera.position.x =(mousex-camera.position.x)*0.05;camera.position.y =(mousey*-1-camera.position.y)*0.05;camera.lookat(scene.position);//给场景中的立方体网格和字体网格添加自转动画constt=date.now()*0.001;constrx=math.sin(t*0.7)*0.5;constry=math.sin(t*0.3)*0.5;constrz=math.sin(t*0.2)*0.5;group.rotation.x=rx;group.rotation.y=ry;group.rotation.z=rz;textmesh.rotation.x=rx;textmesh.rotation.y=ry;textmesh.rotation.z=rx;renderer.render(scene,camera);//更新后期渲染通道composer.render();}

    缩放适配

    renderercomposer大小要同时调整。

    window.addeventlistener('resize',()=>{camera.aspect=window.innerwidth/window.innerheight;camera.updateprojectionmatrix();renderer.setsize(window.innerwidth,window.innerheight);composer.setsize(window.innerwidth,window.innerheight);},false);

    双击全屏

    监听页面鼠标双击dblclick事件,通过调用requestfullscreenexitfullscreen进入或退出全屏状态。

    window.addeventlistener('dblclick',()=>{letfullscreenelement=document.fullscreenelement||document.webkitfullscreenelement;if(!fullscreenelement){if(canvas.requestfullscreen){canvas.requestfullscreen();}elseif(canvas.webkitrequestfullscreen){canvas.webkitrequestfullscreen();}console.log('进入全屏')}else{if(document.exitfullscreen){document.exitfullscreen();}elseif(document.webkitexitfullscreen){document.webkitexitfullscreen();}console.log('退出全屏')}})

    element.requestfullscreen

    element.requestfullscreen方法用于发出异步请求使元素进入全屏模式。调用此api并不能保证元素一定能够进入全屏模式。如果元素被允许进入全屏幕模式,返回的promiseresolve,并且该元素会收到一个fullscreenchange事件,通知它已经进入全屏模式。如果全屏请求被拒绝,返回的promise会变成rejected并且该元素会收到一个fullscreenerror事件。如果该元素已经从原来的文档中分离,那么该文档将会收到这些事件。

    语法

    varpromise=element.requestfullscreen(options);

    options:可选,一个fullscreenoptions对象提供切换到全屏模式的控制选项。

    这个方法只能在用户交互或者设备方向改变的时候调用,否则将会失败。fullscreenoptions目前唯一的选项是navigationui,这控制了是否在元素处于全屏模式时显示导航条ui。默认值是auto,表明这将由浏览器来决定是否显示导航条。

    document.exitfullscreen

    document.exitfullscreen方法用于让当前文档退出全屏模式。调用这个方法会让文档回退到上一个调用element.requestfullscreen方法进入全屏模式之前的状态。

    语法

    document.exitfullscreen();

    “怎么用three.js react实现3d文字悬浮效果”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注恰卡编程网网站,小编将为大家输出更多高质量的实用文章!

    展开全文
    内容来源于互联网和用户投稿,文章中一旦含有亚博电竞手机版的联系方式务必识别真假,本站仅做信息展示不承担任何相关责任,如有侵权或涉及法律问题请联系亚博电竞手机版删除

    最新文章

    网站地图