HEX
Server: Apache/2.4.6 (CentOS) OpenSSL/1.0.2k-fips PHP/7.4.30
System: Linux iZj6c1151k3ad370bosnmsZ 3.10.0-1160.76.1.el7.x86_64 #1 SMP Wed Aug 10 16:21:17 UTC 2022 x86_64
User: root (0)
PHP: 7.4.30
Disabled: NONE
Upload Files
File: /var/www/html/www.winghung.com/demo_v7/box.php
<?php
    error_reporting(E_ALL);
    ini_set('display_errors', 1);
    require_once('../wp-load.php'); 
    session_start();
    date_default_timezone_set("Asia/Hong_Kong"); 
    global $wpdb, $sitepress;
    if(isset($_GET['hash']) && $_GET['hash']!=""){
        $result = $wpdb->get_results("SELECT * FROM `custom_upload_files` WHERE hash = '".$_GET['hash']."' LIMIT 1");
        $file = $result[0]->file;
    } else {
        $file = "pattern.jpg";
    }
?>
<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>Box</title>
		<style>
			body { margin: 0; }
		</style>
	</head>
	<body>
        <script type="importmap">
        {
            "imports": {
            "three": "https://unpkg.com/three@0.130.0/build/three.module.js"
            }
        }
        </script>
        <script async src="https://unpkg.com/es-module-shims@1.3.6/dist/es-module-shims.js"></script>
        <script type="module">
            import * as THREE from 'https://cdn.skypack.dev/three@0.130.0';
            import { OrbitControls } from 'https://unpkg.com/three@0.130.0/examples/jsm/controls/OrbitControls.js';
            
            var setting = {
                'type':'<?php echo $_GET['type'];?>',
                'dimension': {
                    'length':<?php echo $_GET['length'];?>,
                    'width':<?php echo $_GET['height'];?>,
                    'height':<?php echo $_GET['width'];?>
                },
                'iphone': {
                    'length':7.2,
                    'width':0.7,
                    'height':14.7
                },                
                'position': {
                    'posX':<?php echo 0-($_GET['length']/2)-(5/2);?>,
                    'posY':0,
                    'posZ':0
                },            
                'background':{
                    'color':0x000000,
                    'opacity':0.01
                },
                'camera':{
                    'posX':0,
                    'posY':<?php echo max($_GET['length'], $_GET['height'], $_GET['width'])*2;?>,
                    'posZ':0
                },
                'light':{
                    'color':0xffffff,
                    'posX':0,
                    'posY':10,
                    'posZ':-20
                },
                'material':[
                    {'color':0xe3fefe, 'opacity':'1.0', 'transparent':false},
                    {'color':0x000000, 'opacity':'1.0', 'transparent':false},
                ],
                'outline':[
                    {'color':0xcccccc, 'opacity':'1.0', 'transparent':false},
                    {'color':0xdddddd, 'opacity':'1.0', 'transparent':false},
                    {'color':0xe3fefe, 'opacity':'1.0', 'transparent':false},
                ]
            }

            const scene = new THREE.Scene();
            const loader = new THREE.CubeTextureLoader();
            const texture = loader.load([
            'https://r105.threejsfundamentals.org/threejs/resources/images/cubemaps/computer-history-museum/pos-x.jpg',
            'https://r105.threejsfundamentals.org/threejs/resources/images/cubemaps/computer-history-museum/neg-x.jpg',
            'https://r105.threejsfundamentals.org/threejs/resources/images/cubemaps/computer-history-museum/pos-y.jpg',
            'https://r105.threejsfundamentals.org/threejs/resources/images/cubemaps/computer-history-museum/neg-y.jpg',
            'https://r105.threejsfundamentals.org/threejs/resources/images/cubemaps/computer-history-museum/pos-z.jpg',
            'https://r105.threejsfundamentals.org/threejs/resources/images/cubemaps/computer-history-museum/neg-z.jpg',
            ]);
            scene.background = texture;



            const camera = new THREE.PerspectiveCamera(75, window.innerWidth/window.innerHeight, 0.1, 1000);
            camera.position.set(setting.camera.posX, setting.camera.posY, setting.camera.posZ); // 相機位置
            camera.lookAt(scene.position); // 相機焦點

            // 建立光源
            const pointLight = new THREE.PointLight(0xffffff);
            pointLight.position.set(setting.position.posX,30,0);
            //scene.add(pointLight);            
        
            const spotLight = new THREE.SpotLight( 0xffffff );
            spotLight.position.set( setting.position.posX,40,0 );
            //scene.add( spotLight );

            const ambientLight = new THREE.AmbientLight('#ffffff');
            scene.add(ambientLight);            

            // 建立光源
            /*
            var pointLight = new THREE.PointLight(0xffffff);
            pointLight.position.set(setting.light.posX, setting.light.posY, setting.light.posZ);
            scene.add(pointLight);
            */

            const renderer = new THREE.WebGLRenderer({ alpha: true });
            renderer.setSize(window.innerWidth, window.innerHeight);
            renderer.setClearColor(setting.background.color, setting.background.opacity); //預設背景顏色
            renderer.shadowMap.enable = true; //陰影效果   

            document.body.appendChild(renderer.domElement);

            const controls = new OrbitControls(camera, renderer.domElement);
            const textureLoader = new THREE.TextureLoader();
            const image = 'upload/<?php echo $file;?>';
            
            const group = new THREE.Group();
            const phoneGroup = new THREE.Group();
            const boxGroup = new THREE.Group();
            const coverGroup = new THREE.Group();

            const boxGeometry = new THREE.BoxGeometry(setting.dimension.length, setting.dimension.width, setting.dimension.height);
            const boxTexture = textureLoader.load(image);
              
            // box side material
            var sidePlaneMat = new THREE.MeshPhongMaterial({
                <?php if ($file!="") { ?>
                map: new THREE.TextureLoader().load(image, tex => {   
                    
                    <?php if ($_GET['hash']=="") { ?>
                        const ratio = boxGeometry.parameters.height/boxGeometry.parameters.depth;
                        tex.wrapS = tex.wrapT = THREE.RepeatWrapping;
                        tex.offset.set( 0, 0 );
                        tex.repeat.set( 1, ratio);
                    <?php } ?>
                    /*
                    var repeatX, repeatY;
                    repeatX = boxGeometry.parameters.height * tex.image.width/ (boxGeometry.parameters.depth * tex.image.height);                    
                    //
                    if (repeatX > 1) { // checked correct
                        //fill the width and adjust the height accordingly
                        repeatX = 1;
                        repeatY =  boxGeometry.parameters.height * tex.image.width / (boxGeometry.parameters.depth * tex.image.height );
                        tex.repeat.set(repeatX, repeatY);
                        tex.offset.y= (repeatY - 1) / 2 * -1;
                    } else { // checked correct
                        //fill the height and adjust the width accordingly
                        repeatX = boxGeometry.parameters.depth * tex.image.height/ (boxGeometry.parameters.height * tex.image.width);
                        repeatY = 1;
                        tex.repeat.set(repeatX, repeatY);
                        tex.offset.x = (repeatX - 1) / 2 * -1;
                    } 
                    */                  
                }),
                <?php } ?>
                color: setting.material[0].color,
                opacity: setting.material[0].opacity, 
                transparent: setting.material[0].transparent, 
				side: THREE.FrontSide
            });
            
            // box bottom material
            var bottomPlaneMat = new THREE.MeshPhongMaterial({
                <?php if ($file!="") { ?>
                map: new THREE.TextureLoader().load(image, tex => { 

                    <?php if ($_GET['hash']=="") { ?>
                        const ratio = boxGeometry.parameters.depth/boxGeometry.parameters.width;
                        tex.wrapS = tex.wrapT = THREE.RepeatWrapping;
                        tex.offset.set( 0, 0 );
                        tex.repeat.set( 1, ratio);
                    <?php } ?>
                    /*                 
                    var repeatX, repeatY;
                    repeatX = boxGeometry.parameters.depth * tex.image.width/ (boxGeometry.parameters.width * tex.image.height);                    
                    //
                    if (repeatX > 1) { // checked correct
                        //fill the width and adjust the height accordingly
                        repeatX = 1;
                        repeatY =  boxGeometry.parameters.depth * tex.image.width / (boxGeometry.parameters.width * tex.image.height );
                        tex.repeat.set(repeatX, repeatY);
                        tex.offset.y= (repeatY - 1) / 2 * -1;
                    } else { // checked correct
                        //fill the height and adjust the width accordingly
                        repeatX = boxGeometry.parameters.width * tex.image.height/ (boxGeometry.parameters.depth * tex.image.width);
                        repeatY = 1;
                        tex.repeat.set(repeatX, repeatY);
                        tex.offset.x = (repeatX - 1) / 2 * -1;
                    }
                    */

                }),
                <?php } ?>
                color: setting.material[0].color,
                opacity: setting.material[0].opacity, 
                transparent: setting.material[0].transparent, 
				side: THREE.FrontSide
            });
            
            // box front material
            var frontPlaneMat = new THREE.MeshPhongMaterial({
                <?php if ($file!="") { ?>
                map: new THREE.TextureLoader().load(image, tex => {

                    <?php if ($_GET['hash']=="") { ?>
                        const ratio = boxGeometry.parameters.height/boxGeometry.parameters.width;
                        tex.wrapS = tex.wrapT = THREE.RepeatWrapping;
                        tex.offset.set( 0, 0 );
                        tex.repeat.set( 1, ratio);
                    <?php } ?>
                    /*
                    var repeatX, repeatY;
                    repeatX = boxGeometry.parameters.height * tex.image.width/ (boxGeometry.parameters.width * tex.image.height);                    
                    //
                    if (repeatX > 1) { // checked correct
                        //fill the width and adjust the height accordingly
                        repeatX = 1;
                        repeatY =  boxGeometry.parameters.height * tex.image.width / (boxGeometry.parameters.width * tex.image.height );
                        tex.repeat.set(repeatX, repeatY);
                        tex.offset.y= (repeatY - 1) / 2 * -1;
                    } else { // checked correct
                        //fill the height and adjust the width accordingly
                        repeatX = boxGeometry.parameters.width * tex.image.height/ (boxGeometry.parameters.height * tex.image.width);
                        repeatY = 1;
                        tex.repeat.set(repeatX, repeatY);
                        tex.offset.x = (repeatX - 1) / 2 * -1;
                    }
                    */
                }),
                <?php } ?>
                color: setting.material[0].color,
                opacity: setting.material[0].opacity, 
                transparent: setting.material[0].transparent, 
				side: THREE.FrontSide
            });            
            
            var boxMaterial = [
                sidePlaneMat, // left
                sidePlaneMat, // right
                new THREE.MeshBasicMaterial( { transparent: true, opacity: 0, wireframe: true, side: THREE.DoubleSide} ), // top
                bottomPlaneMat, // bottom
                frontPlaneMat, // front
                frontPlaneMat // back	
            ];            
            
            const box = new THREE.Mesh(boxGeometry, boxMaterial);
            box.position.set(setting.position.posX, setting.position.posY, setting.position.posZ);
            //scene.add(box);
            boxGroup.add(box);

            // draw outline
            const boxEdges = new THREE.EdgesGeometry( boxGeometry );            
            const boxLine = new THREE.LineSegments( boxEdges, new THREE.LineBasicMaterial( { color: setting.outline[0].color } ) );
            boxLine.scale.multiplyScalar(0.995);
            boxLine.position.set(setting.position.posX, setting.position.posY, setting.position.posZ);
            boxGroup.add(boxLine);            


            // draw bottom inner plane
            const bottomCardBackGeometry = new THREE.PlaneGeometry(setting.dimension.length, setting.dimension.height);
            const bottomCardBackMaterial = new THREE.MeshBasicMaterial( {color: setting.outline[2].color, side: THREE.BackSide} );

            const bottomCardBackPlane = new THREE.Mesh( bottomCardBackGeometry, bottomCardBackMaterial );
            bottomCardBackPlane.position.set(setting.position.posX, setting.position.posY-setting.dimension.width/2, setting.position.posZ);
            bottomCardBackPlane.rotation.x = Math.PI / 2;
            boxGroup.add(bottomCardBackPlane);  
            
            // draw front face inner plane
            const frontCardBackGeometry = new THREE.PlaneGeometry(setting.dimension.length, setting.dimension.width);
            const frontCardBackMaterial = new THREE.MeshBasicMaterial( {color: setting.outline[2].color, side: THREE.BackSide} );

            const frontCardBackPlane = new THREE.Mesh( frontCardBackGeometry, frontCardBackMaterial );
            frontCardBackPlane.position.set(setting.position.posX, setting.position.posY, setting.position.posZ+setting.dimension.height/2);
            //sideCardBackPlane.rotation.x = Math.PI / 2;
            boxGroup.add(frontCardBackPlane);             

            // draw back face inner plane
            const backCardBackGeometry = new THREE.PlaneGeometry(setting.dimension.length, setting.dimension.width);
            const backCardBackMaterial = new THREE.MeshBasicMaterial( {color: setting.outline[2].color, side: THREE.FrontSide} );

            const backCardBackPlane = new THREE.Mesh( backCardBackGeometry, backCardBackMaterial );
            backCardBackPlane.position.set(setting.position.posX, setting.position.posY, setting.position.posZ-setting.dimension.height/2);
            //sideCardBackPlane.rotation.x = Math.PI / 2;
            boxGroup.add(backCardBackPlane);   

            // draw left face inenr plane
            const leftCardBackGeometry = new THREE.PlaneGeometry(setting.dimension.height, setting.dimension.width);
            const leftCardBackMaterial = new THREE.MeshBasicMaterial( {color: setting.outline[2].color, side: THREE.FrontSide} );

            const leftCardBackPlane = new THREE.Mesh( leftCardBackGeometry, leftCardBackMaterial );
            leftCardBackPlane.position.set(setting.position.posX-setting.dimension.length/2, setting.position.posY, setting.position.posZ);
            leftCardBackPlane.rotation.y = Math.PI / 2;
            boxGroup.add(leftCardBackPlane);   

            // draw right face inenr plane
            const rightCardBackGeometry = new THREE.PlaneGeometry(setting.dimension.height-0.02, setting.dimension.width-0.02);
            const rightCardBackMaterial = new THREE.MeshBasicMaterial( {color: setting.outline[2].color, side: THREE.BackSide} );

            const rightCardBackPlane = new THREE.Mesh( rightCardBackGeometry, rightCardBackMaterial );
            rightCardBackPlane.position.set(setting.position.posX+setting.dimension.length/2, setting.position.posY, setting.position.posZ);
            rightCardBackPlane.rotation.y = Math.PI / 2;
            boxGroup.add(rightCardBackPlane);               


            if(setting.type=="fold"){
                // draw top main cover (front face)
                const topCoverFrontMainGeometry = new THREE.PlaneGeometry(setting.dimension.length, setting.dimension.height);
                const topCoverFrontMainMaterial = new THREE.MeshBasicMaterial({                    
                    color: setting.material[0].color, side: THREE.FrontSide
                });
                const topCoverFrontMainPlane = new THREE.Mesh( topCoverFrontMainGeometry, topCoverFrontMainMaterial );
                topCoverFrontMainPlane.position.set(setting.position.posX, setting.position.posY+setting.dimension.width/2+setting.dimension.height/2, setting.position.posZ-setting.dimension.height/2);
                boxGroup.add(topCoverFrontMainPlane);

                 // draw top main cover (back face)                
                const topCoverBackMainMaterial = new THREE.MeshBasicMaterial( {
                    <?php if ($file!="") { ?>
                    map: new THREE.TextureLoader().load(image, tex => {

                        <?php if ($_GET['hash']=="") { ?>
                            const ratio = topCoverFrontMainGeometry.parameters.width/topCoverFrontMainGeometry.parameters.height;
                            tex.wrapS = tex.wrapT = THREE.RepeatWrapping;
                            tex.offset.set( 0, 0 );
                            tex.repeat.set( 1, ratio);
                        <?php } ?>
                        /*
                        var repeatX, repeatY;
                        repeatX = boxGeometry.parameters.height * tex.image.width/ (boxGeometry.parameters.width * tex.image.height);                    
                        //
                        if (repeatX > 1) { // checked correct
                            //fill the width and adjust the height accordingly
                            repeatX = 1;
                            repeatY =  boxGeometry.parameters.height * tex.image.width / (boxGeometry.parameters.width * tex.image.height );
                            tex.repeat.set(repeatX, repeatY);
                            tex.offset.y= (repeatY - 1) / 2 * -1;
                        } else { // checked correct
                            //fill the height and adjust the width accordingly
                            repeatX = boxGeometry.parameters.width * tex.image.height/ (boxGeometry.parameters.height * tex.image.width);
                            repeatY = 1;
                            tex.repeat.set(repeatX, repeatY);
                            tex.offset.x = (repeatX - 1) / 2 * -1;
                        }
                        */
                    }),
                    <?php } ?>                    
                    color: setting.material[0].color, side: THREE.BackSide
                } );
                const topCoverBackMainPlane = new THREE.Mesh( topCoverFrontMainGeometry, topCoverBackMainMaterial );
                topCoverBackMainPlane.position.set(setting.position.posX, setting.position.posY+setting.dimension.width/2+setting.dimension.height/2, setting.position.posZ-setting.dimension.height/2);
                boxGroup.add(topCoverBackMainPlane);
                
                // draw top main cover outline
                const topCoverMainEdges = new THREE.EdgesGeometry( topCoverFrontMainGeometry );            
                const topCoverMainLine = new THREE.LineSegments( topCoverMainEdges, new THREE.LineBasicMaterial( { color: setting.outline[0].color } ) );
                topCoverMainLine.scale.multiplyScalar(0.995);
                topCoverMainLine.position.set(setting.position.posX, setting.position.posY+setting.dimension.width/2+setting.dimension.height/2, setting.position.posZ-setting.dimension.height/2);
                boxGroup.add(topCoverMainLine);   
                
                // draw top second cover
                const topCoverSecondGeometry = new THREE.PlaneGeometry(setting.dimension.length, 1.5);
                const topCoverSecondMaterial = new THREE.MeshBasicMaterial( {color: setting.material[0].color, side: THREE.DoubleSide} );

                const topCoverSecondPlane = new THREE.Mesh( topCoverSecondGeometry, topCoverSecondMaterial );
                topCoverSecondPlane.position.set(setting.position.posX, setting.position.posY+setting.dimension.width/2+setting.dimension.height, setting.position.posZ-setting.dimension.height/2+0.75);
                topCoverSecondPlane.rotation.x = Math.PI / 2;
                boxGroup.add(topCoverSecondPlane);    
                
                // draw top second cover outline
                const topCoverSecondEdges = new THREE.EdgesGeometry( topCoverSecondGeometry );            
                const topCoverSecondLine = new THREE.LineSegments( topCoverSecondEdges, new THREE.LineBasicMaterial( { color: setting.outline[0].color } ) );
                topCoverSecondLine.scale.multiplyScalar(0.995);
                topCoverSecondLine.position.set(setting.position.posX, setting.position.posY+setting.dimension.width/2+setting.dimension.height, setting.position.posZ-setting.dimension.height/2+0.75);
                topCoverSecondLine.rotation.x = Math.PI / 2;
                boxGroup.add(topCoverSecondLine);  

                // draw left cover
                const leftCoverMainGeometry = new THREE.PlaneGeometry(setting.dimension.length/2, setting.dimension.height);
                const leftCoverFrontMainMaterial = new THREE.MeshBasicMaterial( {
                    <?php if ($file!="") { ?>
                    map: new THREE.TextureLoader().load(image, tex => {

                        <?php if ($_GET['hash']=="") { ?>
                            const ratio = leftCoverMainGeometry.parameters.width/topCoverFrontMainGeometry.parameters.height;
                            tex.wrapS = tex.wrapT = THREE.RepeatWrapping;
                            tex.offset.set( 0, 0 );
                            tex.repeat.set( 1, ratio);
                        <?php } ?>
                        /*
                        var repeatX, repeatY;
                        repeatX = boxGeometry.parameters.height * tex.image.width/ (boxGeometry.parameters.width * tex.image.height);                    
                        //
                        if (repeatX > 1) { // checked correct
                            //fill the width and adjust the height accordingly
                            repeatX = 1;
                            repeatY =  boxGeometry.parameters.height * tex.image.width / (boxGeometry.parameters.width * tex.image.height );
                            tex.repeat.set(repeatX, repeatY);
                            tex.offset.y= (repeatY - 1) / 2 * -1;
                        } else { // checked correct
                            //fill the height and adjust the width accordingly
                            repeatX = boxGeometry.parameters.width * tex.image.height/ (boxGeometry.parameters.height * tex.image.width);
                            repeatY = 1;
                            tex.repeat.set(repeatX, repeatY);
                            tex.offset.x = (repeatX - 1) / 2 * -1;
                        }
                        */
                    }),
                    <?php } ?>                          
                    color: setting.material[0].color, side: THREE.FrontSide
                } );
                const leftCoverBackMainMaterial = new THREE.MeshBasicMaterial( {color: setting.material[0].color, side: THREE.BackSide} );

                const leftCoverFrontMainPlane = new THREE.Mesh( leftCoverMainGeometry, leftCoverFrontMainMaterial );
                leftCoverFrontMainPlane.position.set(setting.position.posX-setting.dimension.length/2-setting.dimension.length/4, setting.position.posY+setting.dimension.width/2, setting.position.posZ);
                leftCoverFrontMainPlane.rotation.x = Math.PI / 2;
                boxGroup.add(leftCoverFrontMainPlane);  

                const leftCoverBackMainPlane = new THREE.Mesh( leftCoverMainGeometry, leftCoverBackMainMaterial );
                leftCoverBackMainPlane.position.set(setting.position.posX-setting.dimension.length/2-setting.dimension.length/4, setting.position.posY+setting.dimension.width/2, setting.position.posZ);
                leftCoverBackMainPlane.rotation.x = Math.PI / 2;
                boxGroup.add(leftCoverBackMainPlane);                  


                // draw left cover outline
                const leftCoverMainEdges = new THREE.EdgesGeometry( leftCoverMainGeometry );            
                const leftCoverMainLine = new THREE.LineSegments( leftCoverMainEdges, new THREE.LineBasicMaterial( { color: setting.outline[0].color } ) );
                leftCoverMainLine.scale.multiplyScalar(0.995);
                leftCoverMainLine.position.set(setting.position.posX-setting.dimension.length/2-setting.dimension.length/4, setting.position.posY+setting.dimension.width/2, setting.position.posZ);
                leftCoverMainLine.rotation.x = Math.PI / 2;
                boxGroup.add(leftCoverMainLine);   


                // draw right cover
                const rightCoverMainGeometry = new THREE.PlaneGeometry(setting.dimension.length/2, setting.dimension.height);
                const rightCoverFrontMainMaterial = new THREE.MeshBasicMaterial( {
                    <?php if ($file!="") { ?>
                    map: new THREE.TextureLoader().load(image, tex => {

                        <?php if ($_GET['hash']=="") { ?>
                            const ratio = rightCoverMainGeometry.parameters.width/topCoverFrontMainGeometry.parameters.height;
                            tex.wrapS = tex.wrapT = THREE.RepeatWrapping;
                            tex.offset.set( 0, 0 );
                            tex.repeat.set( 1, ratio);
                        <?php } ?>
                        /*
                        var repeatX, repeatY;
                        repeatX = boxGeometry.parameters.height * tex.image.width/ (boxGeometry.parameters.width * tex.image.height);                    
                        //
                        if (repeatX > 1) { // checked correct
                            //fill the width and adjust the height accordingly
                            repeatX = 1;
                            repeatY =  boxGeometry.parameters.height * tex.image.width / (boxGeometry.parameters.width * tex.image.height );
                            tex.repeat.set(repeatX, repeatY);
                            tex.offset.y= (repeatY - 1) / 2 * -1;
                        } else { // checked correct
                            //fill the height and adjust the width accordingly
                            repeatX = boxGeometry.parameters.width * tex.image.height/ (boxGeometry.parameters.height * tex.image.width);
                            repeatY = 1;
                            tex.repeat.set(repeatX, repeatY);
                            tex.offset.x = (repeatX - 1) / 2 * -1;
                        }
                        */
                    }),
                    <?php } ?>
                    color: setting.material[0].color, side: THREE.FrontSide
                } );
                const rightCoverBackMainMaterial = new THREE.MeshBasicMaterial( {color: setting.material[0].color, side: THREE.BackSide} );

                const rightCoverFrontMainPlane = new THREE.Mesh( rightCoverMainGeometry, rightCoverFrontMainMaterial );
                rightCoverFrontMainPlane.position.set(setting.position.posX+setting.dimension.length/2+setting.dimension.length/4, setting.position.posY+setting.dimension.width/2, setting.position.posZ);
                rightCoverFrontMainPlane.rotation.x = Math.PI / 2;
                boxGroup.add(rightCoverFrontMainPlane);  

                const rightCoverBackMainPlane = new THREE.Mesh( rightCoverMainGeometry, rightCoverBackMainMaterial );
                rightCoverBackMainPlane.position.set(setting.position.posX+setting.dimension.length/2+setting.dimension.length/4, setting.position.posY+setting.dimension.width/2, setting.position.posZ);
                rightCoverBackMainPlane.rotation.x = Math.PI / 2;
                boxGroup.add(rightCoverBackMainPlane);                  

                // draw right cover outline
                const rightCoverMainEdges = new THREE.EdgesGeometry( rightCoverMainGeometry );            
                const rightCoverMainLine = new THREE.LineSegments( rightCoverMainEdges, new THREE.LineBasicMaterial( { color: setting.outline[1].color } ) );
                rightCoverMainLine.scale.multiplyScalar(0.995);
                rightCoverMainLine.position.set(setting.position.posX+setting.dimension.length/2+setting.dimension.length/4, setting.position.posY+setting.dimension.width/2, setting.position.posZ);
                rightCoverMainLine.rotation.x = Math.PI / 2;
                boxGroup.add(rightCoverMainLine);  
            }

            group.add(boxGroup);

            
            if(setting.type=="two"){

                const cover = boxGroup.clone();
                cover.position.set(setting.position.posX-setting.dimension.length*2 , setting.position.posY, setting.position.posZ);
                cover.rotation.z = Math.PI;
                //scene.add(box);
                coverGroup.add(cover);

                /*
                const coverEdges = new THREE.EdgesGeometry( boxGeometry );            
                const coverLine = new THREE.LineSegments( coverEdges, new THREE.LineBasicMaterial( { color: setting.outline[0].color } ) );
                coverLine.scale.multiplyScalar(0.995);
                coverLine.position.set(setting.position.posX-setting.dimension.length-5 , setting.position.posY, setting.position.posZ);
                coverGroup.add(coverLine);  
                */

                group.add(coverGroup);  

            }

            const phoneGeometry = new THREE.BoxGeometry(setting.iphone.length, setting.iphone.width, setting.iphone.height);
            const phoneTexture = textureLoader.load("asset/iphone.png");

            var phoneMaterial = [
                new THREE.MeshBasicMaterial({
                    color: setting.material[1].color,
                    opacity: setting.material[1].opacity, 
                    transparent: setting.material[1].transparent, 
                }),
                new THREE.MeshBasicMaterial({
                    color: setting.material[1].color,
                    opacity: setting.material[1].opacity, 
                    transparent: setting.material[1].transparent,
                }),
                new THREE.MeshBasicMaterial({
                   
                    map: phoneTexture,
                }),
                new THREE.MeshBasicMaterial({
                    color: setting.material[1].color,
                    opacity: setting.material[1].opacity, 
                    transparent: setting.material[1].transparent,
                }),                
                new THREE.MeshBasicMaterial({
                    color: setting.material[1].color,
                    opacity: setting.material[1].opacity, 
                    transparent: setting.material[1].transparent, 
                }),                
                new THREE.MeshBasicMaterial({
                    color: setting.material[1].color,
                    opacity: setting.material[1].opacity, 
                    transparent: setting.material[1].transparent,  
                }),
				
            ];
         
            const phone = new THREE.Mesh(phoneGeometry, phoneMaterial);
            phone.position.set(setting.iphone.length/2+setting.dimension.length/2, setting.position.posY, setting.position.posZ);
            phoneGroup.add(phone);
            group.add(phoneGroup);
            scene.add(group);

            /* box helper 
            const boxHelper = new THREE.BoxHelper( box, setting.outline[0].color );
            scene.add(boxHelper);
            */

            /* grid helper 
            const size = 100;
            const divisions = 100;
            const gridHelper = new THREE.GridHelper( size, divisions );
            scene.add( gridHelper );
            */

            /* spotlight helper
            const spotLightHelper = new THREE.SpotLightHelper( spotLight );
            scene.add( spotLightHelper );
            */

            /* pointlight helper
            const sphereSize = 30;
            const pointLightHelper = new THREE.PointLightHelper( pointLight, sphereSize );
            scene.add( pointLightHelper );   
            */

            /* axes helper 
            const axesHelper = new THREE.AxesHelper( 100 );
            scene.add( axesHelper );
            */

            /* camera helper
            const camerhelper = new THREE.CameraHelper( camera );
            scene.add( camerhelper );    
            */


            //camera.position.z = 5;

            function animate(){
                //sphere.rotation.x += 0.01;
                //sphere.rotation.y += 0.01;

                //box.rotation.x += 0.01;
                //box.rotation.y += 0.01;

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

            // 監聽螢幕寬高來做簡單 RWD 設定
            window.addEventListener('resize', function() {
                console.log("run");
                camera.aspect = window.innerWidth / window.innerHeight;
                camera.updateProjectionMatrix();
                renderer.setSize(window.innerWidth, window.innerHeight);
            })            

            animate();


        </script>
	</body>
</html>