https://blog.csdn.net/qq563969790/article/details/76584976

网上资料大部分是通过引入外部font库进行文字效果的载入,但是在实际运行的时候发现非常占用资源。于是不得不想另一种方法。

于是想到了three.js中的粒子系统。这当中有个很gay的骚操作是下面这个函数。

var particleMaterial = new THREE.SpriteCanvasMaterial( {
     
                color: 0x000000,
                program: function ( context ) {
     
                    context.beginPath();
                    context.font="bold 20px Arial";
                    context.fillStyle="#058";
                    context.transform(-1,0,0,1,0,0);
                    context.rotate(Math.PI);
                    context.fillText( wordFont , 0, 0 );
     
                }

上面的函数当中,可以传入一个canvas对象。恩,对。如果你想载入文字,写到canvas里就够啦,你还可以画小h图哦。

附上源代码:

ps:代码中最后的注释部分是外部加载字体的方式。有知道的大神请告诉我这么loader为啥贼卡。还有为什么context中文字fillText初始是镜像倒转的?又费了一点劲给它倒腾回来。可能涉及到坐标的原因,同样希望大神告知。

<!DOCTYPE html>
    <html lang="en">
    <head>
        <title>three.js measute_length</title>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
        <style>
            body {
                font-family: Arial;
               
                margin: 0px;
                overflow: hidden;
            }
        </style>
    </head>
    <body>
     
    <script src="js/three.js"></script>
     
    <script src="js/Projector.js"></script>
    <script src="js/CanvasRenderer.js"></script>
     
    <script src="js/OrbitControls.js"></script>
     
    <script src="js/stats.min.js"></script>
     
    <script>
     
        var container, stats;
        var camera, scene, renderer;
        var particleMaterial;
     
        var raycaster;
        var mouse;
     
        var objects = [];
        var points = [];
     
        init();
        animate();
     
        function init() {
     
            container = document.createElement( 'div' );
            document.body.appendChild( container );
     
            camera = new THREE.PerspectiveCamera( 70, window.innerWidth / window.innerHeight, 1, 10000 );
            camera.position.set( 0, 400, 700 );
     
            scene = new THREE.Scene();
     
            var geometry = new THREE.BoxGeometry( 100, 100, 100 );
     
            for ( var i = 0; i < 10; i ++ ) {
     
                var object = new THREE.Mesh( geometry, new THREE.MeshBasicMaterial( { color: Math.random() * 0xffffff, opacity: 0.5 } ) );
                object.position.x = Math.random() * 800 - 400;
                object.position.y = Math.random() * 800 - 400;
                object.position.z = Math.random() * 800 - 400;
     
                object.scale.x = Math.random() * 2 + 1;
                object.scale.y = Math.random() * 2 + 1;
                object.scale.z = Math.random() * 2 + 1;
     
                object.rotation.x = Math.random() * 2 * Math.PI;
                object.rotation.y = Math.random() * 2 * Math.PI;
                object.rotation.z = Math.random() * 2 * Math.PI;
     
                scene.add( object );
     
                objects.push( object );
     
            }
     
            var PI2 = Math.PI * 2;
            particleMaterial = new THREE.SpriteCanvasMaterial( {
     
                color: 0x000000,
                program: function ( context ) {
     
                    context.beginPath();
                    context.arc( 0, 0, 0.5, 0, PI2, true );
                    context.fill();
     
                }
     
            } );
     
            raycaster = new THREE.Raycaster();
            mouse = new THREE.Vector2();
     
            renderer = new THREE.CanvasRenderer();
            renderer.setClearColor( 0xf0f0f0 );
            renderer.setPixelRatio( window.devicePixelRatio );
            renderer.setSize( window.innerWidth, window.innerHeight );
            container.appendChild( renderer.domElement );
     
            stats = new Stats();
            container.appendChild( stats.dom );
     
            document.addEventListener( 'mousedown', onDocumentMouseDown, false );
            document.addEventListener( 'touchstart', onDocumentTouchStart, false );
     
            window.addEventListener( 'resize', onWindowResize, false );
            var controls = new THREE.OrbitControls(camera);  //camera control
            controls.addEventListener('change', render);
     
        }
     
        function onWindowResize() {
     
            camera.aspect = window.innerWidth / window.innerHeight;
            camera.updateProjectionMatrix();
     
            renderer.setSize( window.innerWidth, window.innerHeight );
     
        }
     
        function onDocumentTouchStart( event ) {
     
            event.preventDefault();
     
            event.clientX = event.touches[0].clientX;
            event.clientY = event.touches[0].clientY;
            onDocumentMouseDown( event );
     
        }
     
        function onDocumentMouseDown( event ) {
     
            event.preventDefault();
     
            mouse.x = ( event.clientX / renderer.domElement.clientWidth ) * 2 - 1;
            mouse.y = - ( event.clientY / renderer.domElement.clientHeight ) * 2 + 1;
     
            raycaster.setFromCamera( mouse, camera );
     
            //射线原理拾取目标
            var intersects = raycaster.intersectObjects( objects );
     
            if ( intersects.length > 0 ) {
     
                //创建粒子,便于标识点击位置
                var particle = new THREE.Sprite( particleMaterial );
                particle.position.copy( intersects[ 0 ].point );
                particle.scale.x = particle.scale.y = 1;
                scene.add( particle );
     
                //保存选中点
                points.push( intersects[ 0 ].point );
     
                if( points.length >1 ) {
     
                    var p2 = points[points.length-1];
                    var p1 = points[points.length-2];
     
                    //动画的形式画线
                    drawLine( p1, p2);
                }
     
            }
     
        }
     
        function animate() {
     
            requestAnimationFrame( animate );
     
            render();
            stats.update();
     
        }
     
        function render() {
     
            renderer.render( scene, camera );
     
        }
     
        function drawLine( p1, p2) {
     
            var directionVector = new THREE.Vector3();
            var p3 = new THREE.Vector3();
            directionVector.x = p2.x - p1.x;
            directionVector.y = p2.y - p1.y;
            directionVector.z = p2.z - p1.z;
     
            var length = Math.sqrt( directionVector.x * directionVector.x
                + directionVector.y * directionVector.y
                + directionVector.z * directionVector.z);
     
            var text = Math.round( length ) + "m";
     
     
            var flag = 1;
            var id = setInterval(function () {
                if (flag == 11) {
                    clearInterval(id);
                    flag = 1;
                } else {
     
                    var geometry = new THREE.Geometry();
                    var material = new THREE.LineBasicMaterial( { opacity:1,color:0x000000 } );
     
                    geometry.vertices.push(p1);
     
                    p3.x = p1.x + (directionVector.x/10) * flag;
                    p3.y = p1.y + (directionVector.y/10) * flag;
                    p3.z = p1.z + (directionVector.z/10) * flag;
     
                    geometry.vertices.push(p1);
                    geometry.vertices.push(p3);
     
                    var geo = new THREE.Line(geometry, material);
     
                    scene.add(geo);
     
                    flag++;
                }
     
            }, 10);
     
            initText( text, p2 );
     
        }
     
    //    var font;
    //    var loader = new THREE.FontLoader();
    //    loader.load('js/optimer_bold.typeface.json',function(response) {
    //         font = response;
     
    //    });
        function initText( wordFont, p1){
     
            var particleMaterial = new THREE.SpriteCanvasMaterial( {
     
                color: 0x000000,
                program: function ( context ) {
     
                    context.beginPath();
                    context.font="bold 20px Arial";
                    context.fillStyle="#058";
                    context.transform(-1,0,0,1,0,0);
                    context.rotate(Math.PI);
                    context.fillText( wordFont , 0, 0 );
     
                }
     
            } );
     
            var particle = new THREE.Sprite( particleMaterial );
            particle.position.copy( p1 );
            particle.rotation.x = Math.PI/2;
    //      particle.lookAt( camera );
            scene.add( particle );
     
    //            var textGeometry = new THREE.TextGeometry(wordFont,{
    //                "font": font,
    //                "size" : 10,
    //                "height" : 0,
    //                "color" : 0x000000
    //            })
    //
    //            var text = new THREE.Mesh( textGeometry, new THREE.MeshBasicMaterial( { color: 0x000000 } ) );
    //
    //
    //            text.position.x = p1.x + 2;
    //            text.position.y = p1.y + 2;
    //            text.position.z = p1.z + 2;
    //            text.lookAt(camera.position);
    //            scene.add(text);
     
        }
     
    </script>
     
    </body>
    </html>

效果如下:

用到threejs的 精灵材料(SpriteMaterial)

https://threejs.org/docs/index.html#api/zh/materials/SpriteMaterial

下面的属性可以帮助我们实现文字在屏幕上大小不随像机位置变化而放缩!

.sizeAttenuation : Boolean ----标识文字是否自动放缩(false为屏幕尺寸自动放缩)

精灵的大小是否会被相机深度衰减。(仅限透视摄像头。)默认为true

关于three.js中添加文字的方式[转]的更多相关文章

  1. html css <input> javaScript .数据类型 JS中的函数编写方式 BOM总结 DOM总结

    Day27  html css div 块标签. 特点: 独占一行,有高度和宽度 span 行元素. 特点:在同一行显示,当前行满了自动去下一行显示. 不识别高度和宽度 1.1.1.1 2.输入域标签 ...

  2. 基础篇:1.JavaScript运行在html中,引用有几种方式?—— 6.js中常用的输出方式?

    书接上文,上文提到若干条JavaScript的基础性知识,大部分都是一些概念性的东西,本着认真严谨的态度,我们要认真对待,有些条目的问题是某个知识点的周边延伸,为节约篇幅,就一起整理了,如有描述不对的 ...

  3. WPF 在绘图控件(Shape)中添加文字 [2018.7.15]

    原文:WPF 在绘图控件(Shape)中添加文字 [2018.7.15] Q:使用Shape的子类Ellipse画一个圆,如何在圆中添加文字? A:Shape类中不包含Text属性.可使用Shape类 ...

  4. OSG项目经验2<在场景中添加文字面版>

    添加文字版需要用到osg的三个名字空间:                         osgText::Text,这个类用来添加文字和设置文字的一些属性:                     ...

  5. FFmpeg 向视频中添加文字

    原文地址:http://www.cnblogs.com/wanggang123/p/6707985.html FFmpeg支持添加文字功能,具体如何将文字叠加到视频中的每一张图片,FFmpeg调用了文 ...

  6. Ffmpeg 视频教程 向视频中添加文字

    Ffmpeg支持添加文字功能,具体如何将文字叠加到视频中的每一张图片,FFmpeg调用了文字库FreeSerif.ttf.当我们 用到ffmpeg 添加文字功能时 我们需要先下载改文字库,下载地址是h ...

  7. C# Excel 中设置文字对齐方式、方向和换行

    在Excel表格中输入文字时,我们常常需要调整文字对齐方式或者对文字进行换行.本文将介绍如何通过编程的方式设置文字对齐方式,改变文字方向以及对文字进行换行. //创建Workbook对象 Workbo ...

  8. 一道面试题关于js中添加动态属性

    js中数据类型包含基本数据类型和引用类型,基本类型包括:string.null.undefined.number.boolean.引用类型即是对象比如:array  .function以及自定义对象等 ...

  9. bootstrap table 生成的表格里动态添加HTML元素按钮,JS中添加点击事件,点击没反应---解决办法

    bootstraptable中onExpandRow属性---js  方法添加的 html代码,然后给这代码里面的 元素 添加 事件,却获取不该元素.(称之为未来元素),由于是未来的 所以现在没有这个 ...

随机推荐

  1. 分享一些 Java 无关基础方面的书籍

    个人认为看书有两个点好处: 1. 能出版出来的书一定是经过反复思考,雕琢和审核的,因此从专业性的角度来说,一本好书的价值超其他资料 2. 对着书上的代码自己敲的时候方便 “看完书之后再次提升自我的最好 ...

  2. JQUery利用Uploadify插件实现文件异步上传(十一)

    一:简介: Uploadify是JQuery的一个上传插件,实现的效果非常好,带进度显示 ,且Ajax异步,能一次性上传多个文件,功能强大,使用简单 1.支持单文件或多文件上传,可控制并发上传的文件数 ...

  3. System.getenv()和System.getProperty() 的区别

    1.System.getenv() 方法是获取指定的环境变量的值.它有两种方法,一种是接收参数为任意字符串,当存在指定环境变量时即返回环境变量的值,否则返回null.另外一种是不接受参数,那么返回的是 ...

  4. AOJ 2200 Mr. Rito Post Office (floyd+DP)

    题意: 快递到了:你是某个岛国(ACM-ICPC Japan)上的一个苦逼程序员,你有一个当邮递员的好基友利腾桑遇到麻烦了:全岛有一些镇子通过水路和旱路相连,走水路必须要用船,在X处下船了船就停在X处 ...

  5. asp.net core 微信H5支付(扫码支付,H5支付,公众号支付,app支付)之2

    上一篇说到微信扫码支付,今天来分享下微信H5支付,适用场景为手机端非微信浏览器调用微信H5支付惊醒网站支付业务处理.申请开通微信H5支付工作不多做介绍,直接上代码. 首先是微信支付业务类(WxPayS ...

  6. ORA-01427: 单行子查询返回多个行

    有人问题我一个问题,情况如下:他要用根据divide_act_channel_day的new_amount字段去更新divide_stat的new_amount字段.两张表关联的条件:day=log_ ...

  7. 6-5 巡逻机器人 uva1600

    一开始按照标准bfs来写  标记为二维数组 后来按照三维数组写过了    ps大部分bfs都不会是二维数组搞定!!! 其中有一个bug弄了半个小时... 一开始我是先判断!vis[x][y][v.c] ...

  8. 【Java】 剑指offer(68) 树中两个结点的最低公共祖先

      本文参考自<剑指offer>一书,代码采用Java语言. 更多:<剑指Offer>Java实现合集   题目 输入两个树结点,求它们的最低公共祖先. 思路 该题首先要和面试 ...

  9. Machine Learning 学习笔记2 - linear regression with one variable(单变量线性回归)

    一.Model representation(模型表示) 1.1 训练集 由训练样例(training example)组成的集合就是训练集(training set), 如下图所示, 其中(x,y) ...

  10. 《Android进阶之光》--注解与依赖注入框架

    No1: 标准注解: 1)@Override:覆写 2)@Deprecated:过时 3)@SuppressWarnings:取消警告 4)@SafeVarargs:申明使用了可变长度参数的方法 No ...