[ThreeJs学习笔记] 精灵与canvas结合动态生成伪三维文字

精灵与canvas结合动态生成伪三维文字

介绍

由于三维文字太过占用内存,但是项目中又需要,参考在CSDN各路大佬的相关代码,研究出了另一种创建三维文字的方法,这种方法可以创建伪三维文字

####创建过程如下

1.使用canvas画布,并在画布上写入自己想要创建的三维文字

  let canvas = document.createElement('canvas');
          canvas.width = 256 ;
          canvas.height = 256 ;
          //画布建议使用正方形,长宽像素值使用2的次方数
        let ctx = canvas.getContext('2d');
        ctx.fillStyle = "rgb(58,255,250)";//设定画布颜色
        ctx.font = "bolder 24px Arial ";//设定字体属性,和css语法一致
        ctx.fillText("示例文字",0,60);//添加文字,并设置文字的位置
        ctx.globalAlpha =1;//设定canvas透明

2.将canvas生成的图片,作为 three.js的材质,使用new THREE.Texture(canvas)来读取该材质

  //将画布生成的图片作为贴图给精灵使用,并将精灵创建在设定好的位置
        let texture = new THREE.Texture(canvas);
        texture.needsUpdate = true; //告诉threejs材质需要更新
        let spriteMaterial = new THREE.PointsMaterial({ 
          map:texture, //贴图
          sizeAttenuation:true,  //开启尺寸衰减
          size:300, //衰减尺寸
          transparent:true, //允许透明
          opacity:1, //设置不透明度
        });

3.创建精灵,将该材质赋予给创建的精灵

 //创建点3D对象
  let geometry = new THREE.BufferGeometry();
        let vertices = [0,0,0];
        geometry.addAttribute('position',new THREE.Float32BufferAttribute(vertices,3));
        let sprite = new THREE.Points(geometry,spriteMaterial);//将材质赋给点实体

4.调整好精灵的位置

sprite.position.set( 100,150, 0);

5.将该点添加到场景中

scene.add(sprite);

##效果图
[ThreeJs学习笔记] 精灵与canvas结合动态生成伪三维文字
该文字不会因为旋转,移动而改变大小和方向,始终会面向屏幕,如果使用orbit的中键缩放,会影响该文字的大小

##示例代码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="../three.js-master/build/three.js"></script>
    <script src="../three.js-master/examples/js/controls/OrbitControls.js"></script>
    <script src="../three.js-master/examples/js/libs/dat.gui.min.js"></script>
    <style>

    </style>
</head>
<body>
<script>
    //声明全局的场景, 相机,渲染器,灯光
    var scene,camera,renderer,light;
    function init() {
        //创建场景
        scene = new THREE.Scene();

        //创建相机
        camera = new THREE.PerspectiveCamera(75,window.innerWidth/window.innerHeight,0.1,2000);
        //将相机移动到Z轴等于15的位置(将相机拉近15个距离)
        camera.position.z = 50;

        //创建灯光
        light = new THREE.PointLight(0xffffff,1);
        //将灯光添加到相机中
        camera.add(light);
        //将相机添加进场景
        scene.add(camera);

        //创建渲染器,                       设定背景透明
        renderer = new THREE.WebGLRenderer({alpha:true});
        //设定渲染器大小
        renderer.setSize(window.innerWidth,window.innerHeight);
        //将渲染器放到<body></body>中
        document.body.appendChild(renderer.domElement);

    }

    //创建实体的方法
    function initMesh(){
        createText("示例文字",{
            px:0,py:0,pz:0
        });
    }


    /**
     * 创建三维空间二维文字,每一行的文字不要超过16个,超过16个将不会显示出来
     * @param message 文本内容
     * @param sets 二维文字属性设置对象,其中包含有下列属性
     * {
     *    px:文字x位置
     *    py:文字y位置
     *    pz:文字z位置
     * }
     */
    function createText(message,sets){
        //使用画布动态生成带有文字的图片
        let canvas = document.createElement('canvas');
        canvas.width = 256 ;
        canvas.height = 256 ;
        let ctx = canvas.getContext('2d');
        ctx.fillStyle = "rgb(58,255,250)";
        ctx.font = "bolder 24px Arial ";
        ctx.fillText(message,0,60);
        ctx.globalAlpha =1;

        //将画布生成的图片作为贴图给精灵使用,并将精灵创建在设定好的位置
        let texture = new THREE.Texture(canvas);
        texture.needsUpdate = true;
        let spriteMaterial = new THREE.PointsMaterial({
            map:texture,
            sizeAttenuation:true,
            size:300,
            transparent:true,
            opacity:1,
        });
        let geometry = new THREE.BufferGeometry();
        let vertices = [0,0,0];
        geometry.addAttribute('position',new THREE.Float32BufferAttribute(vertices,3));
        let sprite = new THREE.Points(geometry,spriteMaterial);
        if(sets!==undefined){
            sprite.position.set(sets.px ,sets.py,sets.pz);
        }else{
            sprite.position.set( 100,150, 0);
        }
        scene.add(sprite);
    }


    //使用工具,实现鼠标控制物体旋转缩放
    function initOrbit(){
        var orbit = new THREE.OrbitControls(camera,renderer.domElement);
       //orbit.enablePan = false;
        renderer.render(scene,camera);
    }

    //执行动作之后,将移动结果展现出来
    function animate(){
        renderer.render(scene,camera);
        requestAnimationFrame(animate);
    }


    //当窗口加载完成时,执行上述所有方法
    window.onload = function start(){
        init();
        initMesh();
        initOrbit();
        animate();
    }
</script>
</body>
</html>
上一篇:WebGL可视化3D绘图框架:Three.js 零基础上手实战


下一篇:threeJS射线拾取机制及案例