Three.js 扇形圓形

最近需要一個類似輪播的3d效果,6個輪播,每頁圖片280*300,記錄下案例demo

當前版本104

直接下載官網案例:https://github.com/mrdoob/three.js/

參考學習案例:https://techbrood.com/threejs/examples/#webgl_geometry_shapes

我的代碼:

<!DOCTYPE html>
<html lang="en">
<head>
	<title>three.js webgl - geometry - shapes</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: Monospace;
			background-color: #f0f0f0;
			margin: 0px;
			overflow: hidden;
		}
	</style>
</head>
<body>
	
	<script src="../build/three.js"></script>
	<script src="js/libs/stats.min.js"></script>
	
	<script>
		
		var container, stats;
		
		var camera, scene, renderer;
		
		var group;
		
		var targetRotation = 0;
		var targetRotationY = 0;
		var targetRotationOnMouseDown = 0;
		var targetRotationOnMouseDownY = 0;
		
		var mouseX = 0;
		var mouseXOnMouseDown = 0;
		
		var mouseY = 0;
		var mouseYOnMouseDown = 0;
		var windowHalfY= window.innerHeight / 2;
		var windowHalfX = window.innerWidth / 2;
		
		init();
		animate();
		
		function init() {
			
			container = document.createElement( 'div' );
			document.body.appendChild( container );
			
		
			
			scene = new THREE.Scene();
			scene.background = new THREE.Color( 0x071f6f );
			
			camera = new THREE.PerspectiveCamera( 50, window.innerWidth / window.innerHeight, 1, 5000 );
			camera.position.set( 0, 0, 1000 );
			scene.add( camera );
			
			var light = new THREE.PointLight( 0xffffff, 0.8 );
			camera.add( light );
			
			group = new THREE.Group();
			group.position.y = 50;
			scene.add( group );
			
			var loader = new THREE.TextureLoader();
			/**
			 * 	@作用 添加特殊材質
			 */
			var texture = loader.load( "textures/UV_Grid_Sm.jpg" );//特殊材質
			
			// it's necessary to apply these settings in order to correctly display the texture on a shape geometry
			
			texture.wrapS = texture.wrapT = THREE.RepeatWrapping;
			texture.repeat.set( 0.008, 0.008 );
			

			function addShapeDRN( shape, extrudeSettings, color, x, y, z, rx, ry, rz, s ) {
				
				// flat shape with texture
				// note: default UVs generated by ShapeBufferGeometry are simply the x- and y-coordinates of the vertices
				/**
				 * ShapeBufferGeometry形狀緩衝幾何體
				 */
				
				var geometry = new THREE.ShapeBufferGeometry( shape );
				/**
				 * 網格(Mesh)
				 * MaterialPhong網格材質(MeshPhongMaterial)
				 一種用於具有鏡面高光的光澤表面的材質。
				 * **/
				var mesh = new THREE.Mesh( geometry, new THREE.MeshPhongMaterial( { side: THREE.DoubleSide, map: texture } ) );
				mesh.position.set( x, y, z - 175 );
				mesh.rotation.set( rx, ry, rz );
				mesh.scale.set( s, s, s );
				group.add( mesh );
				

				// extruded shape擠壓成形
				/**
				 * ExtrudeBufferGeometry
				 * 擠壓緩衝幾何體
				 * 從一個形狀路徑中,擠壓出一個BufferGeometry。
				 * */
				/**
				 * 網格(Mesh)
				 * MaterialPhong網格材質(MeshPhongMaterial)
				 一種用於具有鏡面高光的光澤表面的材質。
				 * **/
				var geometry = new THREE.ExtrudeBufferGeometry( shape, extrudeSettings );
				var material =new THREE.MeshPhongMaterial( { color: color ,opacity:0.8,transparent:true } )
				var mesh = new THREE.Mesh( geometry,material );
				mesh.position.set( x, y, z - 75 );
				mesh.rotation.set( rx, ry, rz );
				mesh.scale.set( s, s, s );
				group.add( mesh );
				var mesh2=mesh.clone();
				mesh2.rotateZ(Math.PI*2/6)
				group.add( mesh2 );
				var mesh3=mesh2.clone();
				mesh3.rotateZ(Math.PI*2/6)
				group.add( mesh3 );
				var mesh4=mesh3.clone();
				mesh4.rotateZ(Math.PI*2/6)
				group.add( mesh4 );
				var mesh5=mesh4.clone();
				mesh5.rotateZ(Math.PI*2/6)
				group.add( mesh5 );
				var mesh6=mesh5.clone();
				mesh6.rotateZ(Math.PI*2/6)
				group.add( mesh6 );
				
			}
			// Arc circle圓弧drn
			/**
			 * absarc ( x : Float, y : Float, radius : Float, startAngle : Float, endAngle : Float, clockwise : Float ) : null
			 * x, y -- 弧線的絕對中心。
			 * radius -- 弧線的半徑。
			 * startAngle -- 起始角,以弧度來表示。
			 *endAngle -- 終止角,以弧度來表示。
			 *clockwise -- 以順時針方向創建(掃過)弧線。默認值爲false。
			 * @type {Shape}
			 */
			/**
			 *.arc ( x : Float, y : Float, radius : Float, startAngle : Float, endAngle : Float, clockwise : Float ) : null
			 x, y -- 弧線的中心來自上次調用後的偏移量。
			 radius -- 弧線的半徑。
			 startAngle -- 起始角,以弧度來表示。
			 endAngle -- 終止角,以弧度來表示。
			 clockwise -- 以順時針方向創建(掃過)弧線。默認值爲false。
			 */
			var arcShapeDrn01 = new THREE.Shape();
			//  需要長:280,高300 平分6分,60度,中間有間隙取50度,  通過公式,爲L=n× π× r/180,L=α× r。其中n是圓心角度數,r是半徑,L是圓心角弧長得 r=320,n=50,弧度=280,
			arcShapeDrn01.moveTo( 310, 0 );
			arcShapeDrn01.lineTo( 320, 0 );
			arcShapeDrn01.absarc( 0, 0, 320, 0, Math.PI * 2/6/6*5, false );
			arcShapeDrn01.absarc( 0, 0, 310,Math.PI * 2/6/6*5,0, true );
			var arcShapeDrn02=arcShapeDrn01
			
	
			
			/**
			 *curveSegments — int,曲線上點的數量,默認值是12。
			 steps — int,用於沿着擠出樣條的深度細分的點的數量,默認值爲1。
			 depth — float,擠出的形狀的深度,默認值爲100。
			 bevelEnabled — bool,對擠出的形狀應用是否斜角,默認值爲true。
			 bevelThickness — float,設置原始形狀上斜角的厚度。默認值爲6。
			 bevelSize — float。斜角與原始形狀輪廓之間的延伸距離,默認值爲bevelThickness-2。
			 bevelSegments — int。斜角的分段層數,默認值爲3。
			 extrudePath — THREE.CurvePath對象。一條沿着被擠出形狀的三維樣條線。
			 UVGenerator — Object。提供了UV生成器函數的對象。
			 */
			var extrudeSettings = { depth: 300, bevelEnabled: false, bevelSegments: 9, steps: 2, bevelSize: 0, bevelThickness: 0 };
			
	
			addShapeDRN( arcShapeDrn02, extrudeSettings, 0x6188d2, 0, 0, 0, 0, 0, 0, 1 );

			
			renderer = new THREE.WebGLRenderer( { antialias: true } );
			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 );
			document.addEventListener( 'touchmove', onDocumentTouchMove, false );
			window.addEventListener( 'resize', onWindowResize, false );
			
		}
		
		function onWindowResize() {
			camera.aspect = window.innerWidth / window.innerHeight;
			camera.updateProjectionMatrix();
			renderer.setSize( window.innerWidth, window.innerHeight );
		}
		function onDocumentMouseDown( event ) {
			event.preventDefault();
			document.addEventListener( 'mousemove', onDocumentMouseMove, false );
			document.addEventListener( 'mouseup', onDocumentMouseUp, false );
			document.addEventListener( 'mouseout', onDocumentMouseOut, false );
			mouseXOnMouseDown = event.clientX - windowHalfX;
			mouseYOnMouseDown = event.clientY - windowHalfY;
			targetRotationOnMouseDown = targetRotation;
			targetRotationOnMouseDownY = targetRotationY;
			
		}
		
		function onDocumentMouseMove( event ) {
			mouseX = event.clientX - windowHalfX;
			mouseY = event.clientY - windowHalfY;
			targetRotation = targetRotationOnMouseDown + ( mouseX - mouseXOnMouseDown ) * 0.02;
			targetRotationY = targetRotationOnMouseDownY + ( mouseY - mouseYOnMouseDown ) * 0.02;
		}
		function onDocumentMouseUp() {
			document.removeEventListener( 'mousemove', onDocumentMouseMove, false );
			document.removeEventListener( 'mouseup', onDocumentMouseUp, false );
			document.removeEventListener( 'mouseout', onDocumentMouseOut, false );
		}
		function onDocumentMouseOut() {
			document.removeEventListener( 'mousemove', onDocumentMouseMove, false );
			document.removeEventListener( 'mouseup', onDocumentMouseUp, false );
			document.removeEventListener( 'mouseout', onDocumentMouseOut, false );
		}
		
		function onDocumentTouchStart( event ) {
			
			if ( event.touches.length == 1 ) {
				
				event.preventDefault();
				
				mouseXOnMouseDown = event.touches[ 0 ].pageX - windowHalfX;
				mouseYOnMouseDown = event.touches[ 0 ].pageY - windowHalfY;
				targetRotationOnMouseDown = targetRotation;
				targetRotationOnMouseDownY = targetRotationY;
				
			}
			
		}
		
		function onDocumentTouchMove( event ) {
			
			if ( event.touches.length == 1 ) {
				
				event.preventDefault();
				
				mouseX = event.touches[ 0 ].pageX - windowHalfX;
				mouseY = event.touches[ 0 ].pageY - windowHalfY;
				targetRotation = targetRotationOnMouseDown + ( mouseX - mouseXOnMouseDown ) * 0.05;
				targetRotationY = targetRotationOnMouseDownY + ( mouseY - mouseYOnMouseDown ) * 0.05;
				
			}
			
		}
		
		//
		
		function animate() {
			
			requestAnimationFrame( animate );
			
			render();
			stats.update();
			
		}
		
		function render() {
			
			group.rotation.z += ( targetRotation - group.rotation.z ) * 0.05;
			group.rotation.x += ( targetRotationY - group.rotation.x ) * 0.05;
			renderer.render( scene, camera );
			
		}
	
	</script>

</body>
</html>

我的效果

 

發佈了46 篇原創文章 · 獲贊 44 · 訪問量 6萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章