zoukankan      html  css  js  c++  java
  • Three.js创建运动立体几何体示例

    效果图

    安装

    npm install three
    

    帧率统计工具

    // 监听动画帧率
    
    var Stats = function () {
    
    	var mode = 0;
    
    	var container = document.createElement( 'div' );
    	container.style.cssText = 'position:fixed;top:0;left:0;cursor:pointer;opacity:0.9;z-index:10000';
    	container.addEventListener( 'click', function ( event ) {
    
    		event.preventDefault();
    		showPanel( ++ mode % container.children.length );
    
    	}, false );
    
    	//
    
    	function addPanel( panel ) {
    
    		container.appendChild( panel.dom );
    		return panel;
    
    	}
    
    	function showPanel( id ) {
    
    		for ( var i = 0; i < container.children.length; i ++ ) {
    
    			container.children[ i ].style.display = i === id ? 'block' : 'none';
    
    		}
    
    		mode = id;
    
    	}
    
    	//
    
    	var beginTime = ( performance || Date ).now(), prevTime = beginTime, frames = 0;
    
    	var fpsPanel = addPanel( new Stats.Panel( 'FPS', '#0ff', '#002' ) );
    	var msPanel = addPanel( new Stats.Panel( 'MS', '#0f0', '#020' ) );
    
    	if ( self.performance && self.performance.memory ) {
    
    		var memPanel = addPanel( new Stats.Panel( 'MB', '#f08', '#201' ) );
    
    	}
    
    	showPanel( 0 );
    
    	return {
    
    		REVISION: 16,
    
    		dom: container,
    
    		addPanel: addPanel,
    		showPanel: showPanel,
    
    		begin: function () {
    
    			beginTime = ( performance || Date ).now();
    
    		},
    
    		end: function () {
    
    			frames ++;
    
    			var time = ( performance || Date ).now();
    
    			msPanel.update( time - beginTime, 200 );
    
    			if ( time >= prevTime + 1000 ) {
    
    				fpsPanel.update( ( frames * 1000 ) / ( time - prevTime ), 100 );
    
    				prevTime = time;
    				frames = 0;
    
    				if ( memPanel ) {
    
    					var memory = performance.memory;
    					memPanel.update( memory.usedJSHeapSize / 1048576, memory.jsHeapSizeLimit / 1048576 );
    
    				}
    
    			}
    
    			return time;
    
    		},
    
    		update: function () {
    
    			beginTime = this.end();
    
    		},
    
    		// Backwards Compatibility
    
    		domElement: container,
    		setMode: showPanel
    
    	};
    
    };
    
    Stats.Panel = function ( name, fg, bg ) {
    
    	var min = Infinity, max = 0, round = Math.round;
    	var PR = round( window.devicePixelRatio || 1 );
    
    	var WIDTH = 80 * PR, HEIGHT = 48 * PR,
    			TEXT_X = 3 * PR, TEXT_Y = 2 * PR,
    			GRAPH_X = 3 * PR, GRAPH_Y = 15 * PR,
    			GRAPH_WIDTH = 74 * PR, GRAPH_HEIGHT = 30 * PR;
    
    	var canvas = document.createElement( 'canvas' );
    	canvas.width = WIDTH;
    	canvas.height = HEIGHT;
    	canvas.style.cssText = '80px;height:48px';
    
    	var context = canvas.getContext( '2d' );
    	context.font = 'bold ' + ( 9 * PR ) + 'px Helvetica,Arial,sans-serif';
    	context.textBaseline = 'top';
    
    	context.fillStyle = bg;
    	context.fillRect( 0, 0, WIDTH, HEIGHT );
    
    	context.fillStyle = fg;
    	context.fillText( name, TEXT_X, TEXT_Y );
    	context.fillRect( GRAPH_X, GRAPH_Y, GRAPH_WIDTH, GRAPH_HEIGHT );
    
    	context.fillStyle = bg;
    	context.globalAlpha = 0.9;
    	context.fillRect( GRAPH_X, GRAPH_Y, GRAPH_WIDTH, GRAPH_HEIGHT );
    
    	return {
    
    		dom: canvas,
    
    		update: function ( value, maxValue ) {
    
    			min = Math.min( min, value );
    			max = Math.max( max, value );
    
    			context.fillStyle = bg;
    			context.globalAlpha = 1;
    			context.fillRect( 0, 0, WIDTH, GRAPH_Y );
    			context.fillStyle = fg;
    			context.fillText( round( value ) + ' ' + name + ' (' + round( min ) + '-' + round( max ) + ')', TEXT_X, TEXT_Y );
    
    			context.drawImage( canvas, GRAPH_X + PR, GRAPH_Y, GRAPH_WIDTH - PR, GRAPH_HEIGHT, GRAPH_X, GRAPH_Y, GRAPH_WIDTH - PR, GRAPH_HEIGHT );
    
    			context.fillRect( GRAPH_X + GRAPH_WIDTH - PR, GRAPH_Y, PR, GRAPH_HEIGHT );
    
    			context.fillStyle = bg;
    			context.globalAlpha = 0.9;
    			context.fillRect( GRAPH_X + GRAPH_WIDTH - PR, GRAPH_Y, PR, round( ( 1 - ( value / maxValue ) ) * GRAPH_HEIGHT ) );
    
    		}
    
    	};
    
    };
    
    export { Stats as default };
    

    变量控制GUI

    创建一个小窗口,能够方便的控制变量
    
    安装 npm install --save dat.gui 
    

    demo

    <template>
        <div>
            <div id="Stats-output"></div>
            <div ref="ThreeBox"></div>
        </div>
    </template>
    
    <script>
    /* eslint-disable */
    import * as THREE from 'three';
    import Stats from '../assets/js/stats.js';
    import * as dat from 'dat.gui';
    
    var scene = new THREE.Scene(); // 场景,用来保存渲染的物体
    var camera = new THREE.PerspectiveCamera( 75, window.innerWidth/window.innerHeight, 0.1, 1000 ); // 相机,定义渲染的物体
    var mousecontrols = new THREE.OrbitControls(camera);
    
    var renderer = new THREE.WebGLRenderer(); // 渲染器,定义角度,WebGLRenderer表示使用显卡来渲染场景
    renderer.setClearColor(0xEEEEEE); // 设置背景颜色
    renderer.setSize( window.innerWidth, window.innerHeight ); // 设置背景大小
    renderer.shadowMap.enabled = true; // 开启阴影映射
    
    var axes= new THREE.AxesHelper(20); // 创建坐标轴
    scene.add(axes);
    
    var spotLight = new THREE.SpotLight(0xffffff); // 创建光源
    spotLight.position.set(-40, 60, -10);
    spotLight.castShadow = true; // 此光源开启阴影效果
    scene.add(spotLight);
    
    var planeGeometry = new THREE.PlaneGeometry(60,20,1,1);  // 创建平面,宽60高20
    var planeMaterial = new THREE.MeshLambertMaterial({color: 0xffffff}); // 设置平面的材质,MeshBasicMaterial材质不会对光源产生效果
    var plane = new THREE.Mesh(planeGeometry,planeMaterial); // 将平面放置到Mesh对象中
    plane.rotation.x = -0.5*Math.PI; 
    plane.position.x = 15;
    plane.position.y = 0;
    plane.position.z = 0;
    plane.receiveShadow = true; // 生成阴影
    scene.add(plane);
    
    var cubeGeometry = new THREE.CubeGeometry(4,4,4); // 创建立方体
    var cubeMaterial = new THREE.MeshLambertMaterial({color : 0xff0000}); // 可以添加,wireframe: true表示线框
    var cube= new THREE.Mesh(cubeGeometry, cubeMaterial );
    cube.position.x = -4;
    cube.position.y = 3;
    cube.position.z = 0;
    cube.castShadow = true; 
    scene.add(cube);
    
    var sphereGeometry = new THREE.SphereGeometry(4,20,20); // 创建球体
    var sphereMaterial = new THREE.MeshLambertMaterial({color: 0x7777ff});
    var sphere= new THREE.Mesh(sphereGeometry,sphereMaterial);
    sphere.position.x = 20;
    sphere.position.y = 4 ;
    sphere.position.z = 2 ;
    sphere.castShadow = true; 
    scene.add (sphere) ;
    
    camera.position.x = -30;
    camera.position.y = 40;
    camera.position.z = 30;
    
    camera.lookAt(scene.position); // 场景中心
    
    let step = 0;
    const gui = new dat.GUI(); // 创建gui工具,控制变量
    var controls= new function() {
        this.rotationSpeed = 0.02;
        this.bouncingSpeed = 0.03 ; 
    }
    gui.add(controls,'rotationSpeed', 0, 0.5); 
    gui.add(controls,'bouncingSpeed', 0, 0.5); 
    
    export default {
        mounted() {
            this.$refs.ThreeBox.appendChild( renderer.domElement );
            renderer.render(scene, camera );
            this.renderScene();
        },
        methods: {
            renderScene(){
                let stats = this.initStats(); // stats.js代码如下,用来监听动画帧率的
    
                stats.begin();
    
                cube.rotation.x += 0.02; // 旋转正方体
                cube.rotation.y += 0.02;
                cube.rotation.z += 0.02;
    
                step+=0.04; // 球运动的速度
                sphere.position.x = 20+(10*(Math.cos(step)));
                sphere.position.y = 2+(10*Math.abs(Math.sin(step)));
    
                renderer.render(scene, camera);
                stats.end();
    
                requestAnimationFrame(this.renderScene); // 重画场景,从而方便应用动画效果
            },
    
            initStats () {
                var stats= new Stats ();
                stats.showPanel( 1 );
                this.$refs.StatsBox.appendChild(stats.dom);
                return stats;
            }
        }
    }
    </script>
    
  • 相关阅读:
    Java_swing控件实例
    java_泛型 TreeSet 判断hashcode/length(升序排列)
    java_泛型(设置通配符下限)
    java_泛型(构造器)部分实例
    子类可以继承的同时实现接口
    继承类的线程写法
    匿名内部类的线程写法
    接口作为参数并用参数变量可以调用接口中的方法------------------需要多练习
    类可以作为参数类型,参数的变量还能调用作为参数类型的方法--------------需要多练习
    接口和类
  • 原文地址:https://www.cnblogs.com/ye-hcj/p/9789523.html
Copyright © 2011-2022 走看看