前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >three.js 带更新文字的旋转地球

three.js 带更新文字的旋转地球

原创
作者头像
tianyawhl
修改2019-04-23 09:47:41
9.7K0
修改2019-04-23 09:47:41
举报
文章被收录于专栏:前端之攻略前端之攻略

查看旋转地球效果

主要用到几个知识点

(1)显示文字是使用了three.js 的精灵(Sprite),精灵的文字方向始终面向相机,文字是在canvas中画的,精灵的材质就是加载的带有文字的canvas

代码语言:javascript
复制
	function showText(){
	  const canvas = document.getElementById("canvas");
	  const ctx = canvas.getContext("2d");
	  ctx.canvas.width =256;
	  const x =0;
	  const y=32;
	  ctx.fillStyle = "red";
	  ctx.font = "30px arial";
	  ctx.textAlign = "left";
	  ctx.textBaseline = "middle";
	  ctx.fillText(text,x,y)
	}
	
代码语言:javascript
复制
	var sprite
	function showSprite(){
	  showText()
	  const canvasTexture = new THREE.CanvasTexture(
	    document.querySelector("#canvas")
	  )
	 
	  const spritMaterial = new THREE.SpriteMaterial({
	    map:canvasTexture
	  })
	  sprite = new THREE.Sprite(spritMaterial)
	  sprite.position.set(-280,0,0);
	  //精灵的默认大小很小估计是[1,1,1]
	  sprite.scale.set(0.64*256,0.64*64,1);
	  scene.add(sprite)
	}

(2)文字更新的方法是为canvas的文字重新赋值,并在动画中移除上次加载的精灵,否则精灵会重叠

代码语言:javascript
复制
scene.remove(sprite)

也可以更新sprite的material属性

代码语言:javascript
复制
    function animate() {
	    text="new text";
	    showText()
		  //scene.remove(sprite)
		  const canvasTexture = new THREE.CanvasTexture(
		    	document.querySelector("#canvas")
		   )
		  sprite.material.map = canvasTexture;
		  //sprite.material.map.needsUpdate = true;默认为true
    }

(3)窗口变化时自适应

代码语言:javascript
复制
	window.addEventListener("resize", onWindowResize, false);
	
	function onWindowResize() {   
	    width = document.getElementById('canvas-frame').clientWidth;
        height = document.getElementById('canvas-frame').clientHeight;
	    camera.aspect = width / height;   
	    camera.updateProjectionMatrix();    
	    renderer.setSize(width, height);
	}

完整代码

代码语言:javascript
复制
<!DOCTYPE html>
<html>

<head>
    <meta charset="UTF-8">
    <title>旋转地球</title>
    <script src="assets/plus/threejs/three.min.js"></script>
    <script src="assets/plus/threejs/js/controls/OrbitControls.js"></script>
    <script src="assets/plus/threejs/js/libs/stats.min.js"></script>
    <style type="text/css">
        body {
            margin: 0px;
        }

        div#canvas-frame {
            border: none;
            cursor: pointer;
            width: 80%;
			margin:0 auto;
            height:100vh;
            background-color: #EEEEEE;
        }

        img {
            width: 0px;
            height: 0px;
            opacity: 0;
        }
    </style>
</head>

<body>
    <canvas id="canvas" width="64" height="64" style="display:none;"></canvas>
    <!-- 存放canvas的容器 -->
    <div id="canvas-frame"></div>
</body>

<script>

    document.addEventListener('DOMContentLoaded', function () {
        threeStart();
    })

	var text = "first text";
	function showText(){
	  const canvas = document.getElementById("canvas");
	  const ctx = canvas.getContext("2d");
	  ctx.canvas.width =256;
	  const x =0;
	  const y=32;
	  ctx.fillStyle = "red";
	  ctx.font = "30px arial";
	  ctx.textAlign = "left";
	  ctx.textBaseline = "middle";
	  ctx.fillText(text,x,y)
	}

    // 渲染器
    var renderer;
	var width, height;
    function initThree() {
        width = document.getElementById('canvas-frame').clientWidth;
        height = document.getElementById('canvas-frame').clientHeight;
        renderer = new THREE.WebGLRenderer({
            antialias: true,
            alpha: true,
            canvas: renderer
        });
        renderer.setSize(width, height);
        document.getElementById('canvas-frame').appendChild(renderer.domElement);
        renderer.setClearColor(0x000000, 1.0);
    }

    // 相机
    var camera;
    function initCamera() {
        // 透视相机 视角越大,看到的场景越大,那么中间的物体相对于整个场景来说,就越小了
        camera = new THREE.PerspectiveCamera(45, width / height, 1, 10000);
        camera.position.x = 0;
        camera.position.y = 0;
        camera.position.z = 700;
        //camera.lookAt({ x: 0, y: 0, z: 0 });
    }

    // 场景
    var scene;
    function initScene() {
        scene = new THREE.Scene();
    }

    // 光源
    var light;
    function initLight() {

        // 环境光
        light = new THREE.AmbientLight(0xFFFFFF);
        light.position.set(100, 100, 200);
        scene.add(light);

        // 平行光
        // 位置不同,方向光作用于物体的面也不同,看到的物体各个面的颜色也不一样
        // light = new THREE.DirectionalLight(0xffffbb, 1);
        // light.position.set(-1, 1, 1);
        // scene.add(light);
    }

    // 地球
    var earthMesh;
    function initEarth() {
        var earthGeo = new THREE.SphereGeometry(200, 100, 100);
        var earthMater = new THREE.MeshPhongMaterial({
            map: new THREE.TextureLoader().load('./assets/earth.jpg'),
            //side: THREE.DoubleSide
        });
        earthMesh = new THREE.Mesh(earthGeo, earthMater);
        scene.add(earthMesh);
    }

    // 云
    var cloudsMesh;
    function initClouds() {
        var cloudsGeo = new THREE.SphereGeometry(201, 100, 100);
        var cloudsMater = new THREE.MeshPhongMaterial({
            alphaMap: new THREE.TextureLoader().load('./assets/clouds.jpg'),
            transparent: true,
            opacity: 0.2
        });
        cloudsMesh = new THREE.Mesh(cloudsGeo, cloudsMater);
        scene.add(cloudsMesh);
    }

    var controls;
    function threeStart() {
        initThree();
        //initStats();
        initCamera();
        initScene();
        initLight();
        initEarth();
        initClouds();
        // 载入控制器
        controls = new THREE.OrbitControls(camera, renderer.domElement);
		window.addEventListener("resize", onWindowResize, false);
        //renderer.clear();
        animate();
    }
	function onWindowResize() {   
	    width = document.getElementById('canvas-frame').clientWidth;
        height = document.getElementById('canvas-frame').clientHeight;
	    camera.aspect = width / height;   
	    camera.updateProjectionMatrix();    
	    renderer.setSize(width, height);
	}

	var sprite
	function showSprite(){
	  showText()
	  const canvasTexture = new THREE.CanvasTexture(
	    document.querySelector("#canvas")
	  )
	  //canvasTexture.needsUpdate = true; //注意这句不能少
	  const spritMaterial = new THREE.SpriteMaterial({
	    map:canvasTexture
	  })
	  sprite = new THREE.Sprite(spritMaterial)
	  sprite.position.set(-280,0,0);
	  //精灵的默认大小很小估计是[1,1,1]
	  sprite.scale.set(0.64*256,0.64*64,1);
	  scene.add(sprite)
	
	}

    function animate() {
	    text="new text";
		scene.remove(sprite)
		showSprite();
        controls.update();
        //stats.update();
        // 地球自转
        earthMesh.rotation.y -= 0.002;

        // 漂浮的云层
        cloudsMesh.rotation.y -= 0.005;
        cloudsMesh.rotation.z += 0.005;

        renderer.render(scene, camera);
        requestAnimationFrame(animate);
    }

</script>
</html>

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • (1)显示文字是使用了three.js 的精灵(Sprite),精灵的文字方向始终面向相机,文字是在canvas中画的,精灵的材质就是加载的带有文字的canvas
  • (2)文字更新的方法是为canvas的文字重新赋值,并在动画中移除上次加载的精灵,否则精灵会重叠
  • (3)窗口变化时自适应
相关产品与服务
容器服务
腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档