最近需要一個類似輪播的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>
我的效果