Threejs 의 OBJLoader(.obj 모델링 파일 가능) 를 이용하여 3D로 모델링 파일 로드를 할 수 있습니다.


여기에 텍스쳐를 입혀서 모델링을 좀더 꾸며 보겠습니다.


Material 이란? 오브젝트에 적용할 수 있는 색상? 페인트? 같은 개념입니다.

Texture란? 3D 모델에 입힐 이미지 파일 입니다. Texture를 사용하려면 중간에 Material 매개체가 필요합니다.


※ 참고: 해당 소스를 구동시 Local에서 실행하게 되면 Cross Origin 오류가 발생하니 크롬 확장 프로그램인 Web Server for Chrome를 받아서


해당 소스를 다운받은 크롬 확장 프로그램으로 서버를 돌려서 확인 하거나 Web Server에 소스를 업로드하여 구동하시기 바랍니다.


무료 모델링 소스는 https://free3d.com/3d-models/animals 에서 받아서 다른 모델링도 적용할 수 있습니다.



obj-mtl-loader.zip

↑↑↑↑↑↑↑↑↑↑

소스파일 다운로드 입니다.


<!DOCTYPE html>
<html>

<head>
    <meta charset=utf-8>
    <title>My first three.js app</title>
    <style>
        body {
            margin: 0;
        }

        canvas {
            width: 100%;
            height: 100%
        }
    </style>
</head>

<body>
    <!-- Three js -->
    <script src="https://threejs.org/build/three.min.js"></script>

    <!-- WebGL 지원유무 https://github.com/mrdoob/three.js/blob/master/examples/js/WebGL.js 참고 -->
    <script src="./libs/WebGL.js"></script>

    <!-- OrbitControls.js allow the camera to orbit around a target 마우스와 카메라를 상호작용하게 합니다. -->
    <script src="https://threejs.org/examples/js/controls/OrbitControls.js"></script>

    <!-- OBJ Loader를 사용하기 위해 추가. https://github.com/mrdoob/three.js/blob/master/examples/js/loaders/OBJLoader.js 와 동일 소스 -->
    <script src="./libs/OBJLoader.js"></script>

    <!-- OBJ Loader에 Material을 씌우기 위한 라이브러리 추가. https://github.com/mrdoob/three.js/blob/master/examples/js/loaders/MTLLoader.js 와 동일 소스 -->
    <script src="./libs/MTLLoader.js"></script>

    <script>
        window.onload = function (e) {

            let scene = new THREE.Scene();
            let light;
            let camera;
            let objLoader; // OBJLoader 객체를 넣을 변수를 선언합니다.
            let mtlLoader; // MTLLoader 객체를 넣을 변수를 선언합니다.

            initThree();
            addDirectionalLight();
            loadMTLLoader();

            /**
             * DirectionalLight를 추가하는 함수
             *
             * @method addDirectionalLight
             */
            function addDirectionalLight() {
                let light1 = new THREE.DirectionalLight(0xffffff, 1);
                light1.position.set(-100, 0, 100);
                let light2 = new THREE.DirectionalLight(0xffffff, 1);
                light2.position.set(100, 0, 100);
                let light3 = new THREE.DirectionalLight(0xffffff, 1);
                light3.position.set(100, 0, -100);
                scene.add(light1);
                scene.add(light2);
                scene.add(light3);
            }

            /**
             * Material 파일을 로드하는 함수
             *
             * @method loadMTLLoader
             */
            function loadMTLLoader() {
                mtlLoader = new THREE.MTLLoader();

                // MTLLoader Material 파일을 사용할 전역 경로를 설정합니다.
                mtlLoader.setPath('./resources/Umbreon/');

                // 로드할 Material 파일 명을 입력합니다.
                mtlLoader.load('UmbreonHighPoly.mtl', function (materials) {
                    // 로드 완료되었을때 호출하는 함수
                    materials.preload();

                    loadOBJLoader(materials);
                }, function (xhr) {
                    // 로드되는 동안 호출되는 함수
                    console.log('MTLLoader: ', xhr.loaded / xhr.total * 100, '% loaded');
                }, function (error) {
                    // 로드가 실패했을때 호출하는 함수
                    console.error('MTLLoader 로드 중 오류가 발생하였습니다.', error);
                    alert('MTLLoader 로드 중 오류가 발생하였습니다.');
                });
            }

            /**
             * .obj 파일의 모델을 로드하는 함수
             *
             * @method loadObjLoader
             * @param {Object} materials MTLLoader에서 로드한 Materials 값
             */
            function loadOBJLoader(materials) {
                loader = new THREE.OBJLoader();

                // MTLLoader에서 로드한 materials 파일을 설정합니다.
                loader.setMaterials(materials);

                // OBJLoader OBJ 파일을 사용할 전역 경로를 설정합니다.
                loader.setPath('./resources/Umbreon/');

                // 로드할 OBJ 파일 명을 입력합니다.
                loader.load('UmbreonHighPoly.obj', function (object) {
                    // 모델 로드가 완료되었을때 호출되는 함수
                    object.position.x = 0;
                    object.position.y = 0;
                    object.position.z = 0;
                    scene.add(object);
                }, function (xhr) {
                    // 모델이 로드되는 동안 호출되는 함수
                    console.log('OBJLoader: ', xhr.loaded / xhr.total * 100, '% loaded');
                }, function (error) {
                    // 모델 로드가 실패했을 때 호출하는 함수
                    alert('모델을 로드 중 오류가 발생하였습니다.');
                });
            }

            /**
             * Threejs 초기화 함수
             *
             * @method initThree
             */
            function initThree() {
                // 브라우저가 WebGL을 지원하는지 체크
                if (WEBGL.isWebGLAvailable()) {
                    console.log('이 브라우저는 WEBGL을 지원합니다.');
                } else {
                    console.log('이 브라우저는 WEBGL을 지원하지 않습니다.');
                }

                camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);

                let renderer = new THREE.WebGLRenderer({
                    antialias: true
                });
                renderer.setSize(window.innerWidth, window.innerHeight);
                renderer.setClearColor(0xffffff, 1); // 전체적인 배경색 수정
                renderer.shadowMap.enabled = true;
                renderer.shadowMap.type = THREE.PCFSoftShadowMap;
                document.body.appendChild(renderer.domElement);

                let axes = new THREE.AxisHelper(10);
                scene.add(axes);

                camera.position.x = 1;
                camera.position.y = 3;
                camera.position.z = 3;

                controls = new THREE.OrbitControls(camera);
                controls.rotateSpeed = 1.0;
                controls.zoomSpeed = 1.2;
                controls.panSpeed = 0.8;
                controls.minDistance = 3;
                controls.maxDistance = 10;

                function animate() {
                    requestAnimationFrame(animate);

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

                animate();
            }
        }
    </script>
</body>

</html>


Threejs 의 OBJLoader(.obj 모델링 파일 가능) 를 이용하여 3D로 모델링된 고양이를 로드를 할 수 있습니다.


해당 소스를 구동시 Local에서 실행하게 되면 Cross Origin 오류가 발생하니 크롬 확장 프로그램인 Web Server for Chrome를 받아서


해당 소스를 다운받은 크롬 확장 프로그램으로 서버를 돌려서 확인 하거나 Web Server에 소스를 업로드하여 구동하시기 바랍니다.


무료 모델링 소스는 https://free3d.com/3d-models/animals 에서 받아서 다른 모델링도 적용할 수 있습니다.



obj-loader-cat.zip

↑↑↑↑↑↑↑↑↑↑

소스 다운로드 파일 입니다.


<!DOCTYPE html>
<html>

<head>
    <meta charset=utf-8>
    <title>My first three.js app</title>
    <style>
        body {
            margin: 0;
        }

        canvas {
            width: 100%;
            height: 100%
        }
    </style>
</head>

<body>
    <!-- Three js -->
    <script src="https://threejs.org/build/three.min.js"></script>

    <!-- WebGL 지원유무 https://github.com/mrdoob/three.js/blob/master/examples/js/WebGL.js 참고 -->
    <script src="./WebGL.js"></script>

    <!-- OrbitControls.js allow the camera to orbit around a target 마우스와 카메라를 상호작용하게 합니다. -->
    <script src="https://threejs.org/examples/js/controls/OrbitControls.js"></script>

    <!-- OBJ Loader를 사용하기 위해 추가. https://github.com/mrdoob/three.js/blob/master/
examples/js/loaders/OBJLoader.js 와 동일 소스 -->
    <script src="./objloader.js"></script>

    <script>
        window.onload = function (e) {

            let scene = new THREE.Scene();
            let light;
            let camera;
            let loader; // OBJLoader 객체를 넣을 변수를 선언합니다.

            initThree();
            addDirectionalLight();
            loadObjLoader();

            /**
             * DirectionalLight를 추가하는 함수
             *
             * @method addDirectionalLight
             */
            function addDirectionalLight() {

                light = new THREE.DirectionalLight(0xffffff, 1);
                light.castShadow = true;
                light.position.x = 5;
                light.position.y = 5;
                light.position.z = 5;
                scene.add(light);
            }

            /**
             * .obj 파일의 모델을 로드하는 함수
             *
             * @method loadObjLoader
             */
            function loadObjLoader() {
                loader = new THREE.OBJLoader();
                loader.load('./cat.obj', function (object) {
                    // 모델 로드가 완료되었을때 호출되는 함수
                    scene.add(object);
                }, function (xhr) {
                    // 모델이 로드되는 동안 호출되는 함수
                    console.log(xhr.loaded / xhr.total * 100, '% loaded');
                }, function (error) {
                    // 모델 로드가 실패했을 때 호출하는 함수
                    alert('모델을 로드 중 오류가 발생하였습니다.');
                });
            }

            /**
             * Threejs 초기화 함수
             *
             * @method initThree
             */
            function initThree() {
                // 브라우저가 WebGL을 지원하는지 체크
                if (WEBGL.isWebGLAvailable()) {
                    console.log('이 브라우저는 WEBGL을 지원합니다.');
                } else {
                    console.log('이 브라우저는 WEBGL을 지원하지 않습니다.');
                }

                camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);

                let renderer = new THREE.WebGLRenderer({
                    antialias: true
                });
                renderer.setSize(window.innerWidth, window.innerHeight);
                renderer.shadowMap.enabled = true;
                renderer.shadowMap.type = THREE.PCFSoftShadowMap;
                document.body.appendChild(renderer.domElement);

                let axes = new THREE.AxisHelper(10);
                scene.add(axes);

                camera.position.x = 2;
                camera.position.y = 1;
                camera.position.z = 1;

                controls = new THREE.OrbitControls(camera);
                controls.rotateSpeed = 1.0;
                controls.zoomSpeed = 1.2;
                controls.panSpeed = 0.8;
                controls.minDistance = 5;
                controls.maxDistance = 100;

                function animate() {
                    requestAnimationFrame(animate);

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

                animate();
            }
        }
    </script>
</body>

</html>


기존에 만들었던 씬에 Light와 PlaneGeometry를 추가했습니다.

light.zip

↑↑↑↑↑

소스 파일 입니다.



각 Light 에 대한 자세한 설명은 아래 URL에서 확인해 주시기 바랍니다.


https://threejs.org/docs/#api/en/lights/AmbientLight - 모든 오브젝트를 전역으로 빛을 비춰줍니다. 이 빛은 그림자가 생기지 않습니다.

https://threejs.org/docs/#api/en/lights/DirectionalLight - 특정 방향으로 빛을 방출합니다.(예시. 태양) 이 빛은 그림자가 생길 수 있습니다.

https://threejs.org/docs/#api/en/lights/HemisphereLight - 하늘색? 지상색? 장면 바로 위에서 광원을 방출합니다. 이 빛은 그림자가 생기지 않습니다.

https://threejs.org/docs/#api/en/lights/PointLight - 한 방향으로 빛을 방출합니다.(예시. 전구)

https://threejs.org/docs/#api/en/lights/RectAreaLight - 직사각형 평면에 균일하게 빛을 방출합니다.

https://threejs.org/docs/#api/en/lights/SpotLight - 원뿔 모양에 따라 빛의 방출 합니다. 이 빛은 그림자가 생길 수 있습니다.





<!DOCTYPE html>
<html>

<head>
    <meta charset=utf-8>
    <title>My first three.js app</title>
    <style>
        body {
            margin: 0;
        }

        canvas {
            width: 100%;
            height: 100%
        }
    </style>
</head>

<body>
    <div>
        <button id="am-light">AmbientLight</button>
        <button id="dic-light">DirectionalLight</button>
        <p>Light를 클릭하여 조명을 추가해 주세요.</p>
    </div>
    <!-- Three js -->
    <script src="https://threejs.org/build/three.min.js"></script>

    <!-- WebGL 지원유무 https://github.com/mrdoob/three.js/blob/master/examples/js/WebGL.js 참고 -->
    <script src="./WebGL.js"></script>

    <!-- OrbitControls.js allow the camera to orbit around a target 마우스와 카메라를 상호작용하게 합니다. -->
    <script src="https://threejs.org/examples/js/controls/OrbitControls.js"></script>

    <script>
        window.onload = function (e) {

            let scene = new THREE.Scene();
            let light;
            let camera;

            initThree();

            // AmbientLight 조명 추가 클릭 이벤트
            document.getElementById('am-light').onclick = () => {
                removeLight();
                addAmbientLight();
            }

            // DirectionalLight 조명 추가 클릭 이벤트
            document.getElementById('dic-light').onclick = () => {
                removeLight();
                addDirectionalLight();
            }

            /**
             * AmbientLight를 추가하는 함수
             *
             * @method addAmbientLight
             */
            function addAmbientLight() {
                /**
                 * AmbientLight는 Scene의 모든 오브젝트를 전역으로 빛을 비춰줍니다.
                 * 그러므로 빛의 방향이 없어 그림자는 존재하지 않습니다.
                 *
                 * AmbientLight(color : Integer, intensity : Float)
                 * color: optional, 조명 색상 값(RGB 값을 사용), 기본값은 0xffffff 입니다.
                 * intensity: optional, 조명의 밝기 수차, 기본값은 1 입니다.(값이 낮아 질 수록 어두워 집니다.)
                 */
                light = new THREE.AmbientLight(0xffffff, 0.2);
                scene.add(light);

                setShadowCamera();
            }

            /**
             * DirectionalLight를 추가하는 함수
             *
             * @method addDirectionalLight
             */
            function addDirectionalLight() {
                /**
                 * 특정 방향으로 빛을 방출합니다. 태양을 생각하면 쉬울거 같습니다.
                 * 그리고 이 조명은 그림자를 생기게 합니다.
                 *
                 * DirectionalLight(color : Integer, intensity : Float)
                 * color: optional, 빛의 색상, 기본값은 0xffffff(흰색) 입니다.
                 * intensity: optional, 빛의 강도, 기본값은 1 입니다.
                 */
                light = new THREE.DirectionalLight(0xffffff, 0.5);
                light.castShadow = true; // true 이면 광원이 그림자를 생성합니다. 기본값은 false 입니다.
                scene.add(light);

                setShadowCamera();
            }

            /**
             * 카메라에 조명 헬퍼를 생성하는 함수
             *
             * @method setShadowCamera
             */
            function setShadowCamera() {
                let helper = new THREE.CameraHelper(light.shadow.camera);
                scene.add(helper);
            }

            function removeLight() {
                scene.remove(light);
                light = null;
            }

            /**
             * Threejs 초기화 함수
             *
             * @method initThree
             */
            function initThree() {
                // 브라우저가 WebGL을 지원하는지 체크
                if (WEBGL.isWebGLAvailable()) {
                    console.log('이 브라우저는 WEBGL을 지원합니다.');
                } else {
                    console.log('이 브라우저는 WEBGL을 지원하지 않습니다.');
                }

                camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);

                /**
                 * Anti Aliasing이란? 픽셀로 이루어진 화면은 우둘투둘하게 계단효과가 나타나게 되는데
                 * 이것을 부드럽게 만드는 옵션 입니다.
                 * 참고: http://www.itworld.co.kr/news/97807
                 */
                let renderer = new THREE.WebGLRenderer({
                    antialias: true
                });
                renderer.setSize(window.innerWidth, window.innerHeight);
                renderer.shadowMap.enabled = true;
                renderer.shadowMap.type = THREE.PCFSoftShadowMap;
                document.body.appendChild(renderer.domElement);

                let geometry = new THREE.BoxGeometry(1, 1, 1);

                /**
                 * scene 화면상에 XYZ(Red: X, Green: Y, Blue: Z) 축을 보여줍니다.
                 *
                 * AxisHelper(size : Number)
                 * size: optional 축의 크기, 기본값은 1입니다.
                 */
                let axes = new THREE.AxisHelper(10);
                scene.add(axes);

                /**
                 * 반사 하이라이트가 있는 표면(반짝이는 표현)으로 생성합니다.
                 * MeshBasicMaterial일 경우에는 그림자가 생기지 않습니다.
                 */
                let material = new THREE.MeshPhongMaterial({ color: 0x00ff00 });
                let cube = new THREE.Mesh(geometry, material);
                cube.position.set(0, 0.5, 0);
                scene.add(cube);

                /**
                 * 평면 지오메트리를 생성합니다.
                 *
                 * PlaneGeometry(width : Float, height : Float, widthSegments : Integer, heightSegments : Integer)
                 * width: X 축 방향의 폭, 기본값은 1 입니다.
                 * height: Y 축 높이, 기본값은 1 입니다.
                 * widthSegments: optional, 면의 너비에 따라 분할된 면수, 기본값은 1 입니다.
                 * heightSegments: optional, 축면의 높이에 따라 분할된 면수,기본값은 1 입니다.
                 */
                let planeGeomtry = new THREE.PlaneGeometry(10, 10, 1, 1);
                let planeMaterial = new THREE.MeshPhongMaterial({ color: 0xCCCCCC });
                let plane = new THREE.Mesh(planeGeomtry, planeMaterial);
                plane.rotation.x = -0.5 * Math.PI; // 평면지오메트리를 바닥에 일치하게 돌린다.
                scene.add(plane);

                camera.position.x = 0;
                camera.position.y = 10;
                camera.position.z = 5;

                controls = new THREE.OrbitControls(camera);
                controls.rotateSpeed = 1.0;
                controls.zoomSpeed = 1.2;
                controls.panSpeed = 0.8;
                controls.minDistance = 5;
                controls.maxDistance = 100;

                function animate() {
                    requestAnimationFrame(animate);

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

                animate();
            }
        }
    </script>
</body>

</html>




카메라를 마우스 드래그 & 휠을 이용하여 카메라를 로테이션하고 줌을 하는방법입니다.


자세한건 아래의 소스에 주석을 적어놨습니다.


추가된것이 OrbitControls.js 입니다. 그리고 OrbitControls.js 사용할때 panSpeed를 제어하는 부분이 있는데


이 부분은 아직 이해하지 못했습니다.


mouse_camera.zip

전체 소스 파일 입니다.


<!DOCTYPE html>
<html>

<head>
    <meta charset=utf-8>
    <title>My first three.js app</title>
    <style>
        body {
            margin: 0;
        }

        canvas {
            width: 100%;
            height: 100%
        }
    </style>
</head>

<body>
    <!-- Three js -->
    <script src="https://threejs.org/build/three.min.js"></script>

    <!-- WebGL 지원유무 https://github.com/mrdoob/three.js/blob/master/examples/js/WebGL.js 참고 -->
    <script src="./WebGL.js"></script>

    <!-- OrbitControls.js allow the camera to orbit around a target 마우스와 카메라를 상호작용하게 합니다. -->
    <script src="https://threejs.org/examples/js/controls/OrbitControls.js"></script>

    <script>
        // 브라우저가 WebGL을 지원하는지 체크
        if (WEBGL.isWebGLAvailable()) {
            console.log('이 브라우저는 WEBGL을 지원합니다.');
        } else {
            console.log('이 브라우저는 WEBGL을 지원하지 않습니다.');
        }

        let scene = new THREE.Scene();
        let camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);

        let renderer = new THREE.WebGLRenderer();
        renderer.setSize(window.innerWidth, window.innerHeight);
        document.body.appendChild(renderer.domElement);

        let geometry = new THREE.BoxGeometry(1, 1, 1);
        let material = new THREE.MeshBasicMaterial({ color: 0x00ff00 });
        let cube = new THREE.Mesh(geometry, material);
        scene.add(cube);

        camera.position.z = 5;

        // 카메라와 마우스 상호작용을 위해 OrbitControls를 설정합니다.
        controls = new THREE.OrbitControls(camera);
        controls.rotateSpeed = 1.0; // 마우스로 카메라를 회전시킬 속도입니다. 기본값(Float)은 1입니다.
        controls.zoomSpeed = 1.2; // 마우스 휠로 카메라를 줌 시키는 속도 입니다. 기본값(Float)은 1입니다.
        controls.panSpeed = 0.8; // 패닝 속도 입니다. 기본값(Float)은 1입니다.
        controls.minDistance = 5; // 마우스 휠로 카메라 거리 조작시 최소 값. 기본값(Float)은 0 입니다.
        controls.maxDistance = 100; // 마우스 휠로 카메라 거리 조작시 최대 값. 기본값(Float)은 무제한 입니다.

        function animate() {
            requestAnimationFrame(animate);

            renderer.render(scene, camera);
            controls.update(); // 마우스로인해 변경된 카메라값을 업데이트 합니다.
        }

        animate();
    </script>
</body>

</html>


Threejs 공식 문서에 나와있는 기본 듀토리얼 소스입니다.

아래의 소스를 실제 브라우저에서 실행하게 되면 박스가 뱅글뱅글 도는 모습을 볼 수 있습니다.

첨부파일로 해당 소스를 첨부하였습니다.

<!DOCTYPE html>
<html>
    <head>
        <meta charset=utf-8>
        <title>My first three.js app</title>
        <style>
            body { margin: 0; }
            canvas { width: 100%; height: 100% }
        </style>
    </head>
    <body>
        <!-- Three js -->
        <script src="https://threejs.org/build/three.min.js"></script>

        <!-- WebGL 지원유무 https://github.com/mrdoob/three.js/blob/master/examples/js/WebGL.js 참고 -->
        <script src="./WebGL.js"></script>

        <script>
            // 브라우저가 WebGL을 지원하는지 체크
            if ( WEBGL.isWebGLAvailable() ) {
                console.log('이 브라우저는 WEBGL을 지원합니다.');
            } else {
                console.log('이 브라우저는 WEBGL을 지원하지 않습니다.');
            }

// 화면을 표현하려면 기본적으로 scene, camera, renderer 3가지가 필요합니다.
let scene = new THREE.Scene();

            /**
             * 카메라
             *
             * PerspectiveCamera(fov: Number, aspect: Number, near: Number, far: Number)
             * fov: 시야각 즉 3D 게임에서 한 화면에 어느 정도의 각도에서 보여줄지 설정
             * aspect: 화면 비율 즉 넓이를 높이로 나눈값
             * near: 렌더링이 수행되는 가까운점
             * far: 랜더링이 수행되는 가장 먼점
             */
let camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 1000 );
            
            /**
             * 랜더링
             *
             * WebGLRenderer(parameters : Object)
             */
let renderer = new THREE.WebGLRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );

            /**
             * 박스 지오메트리
             * 지오메트리란? 바탕으로 컴퓨터 화면에 탄생된 가상의 오브젝트를 만들 수 있게 되었는데 이 가상의 오프젝트 지칭
             *
             * BoxGeometry(width : Float, height : Float, depth : Float, widthSegments : Integer,
            * heightSegments : Integer, depthSegments : Integer)
             * width: x 축의 값
             * height: y 축의 값
             * depth : z 축의 값
             * widthSegments: optional, x축의 너비에 따라 분할 된 면의 수
             * heightSegments: optional, y축의 높이에 따라 분할 된 면의 수
             * depthSegments : optional, z축의 깊이에 따라 분할 된 면의 수
             */
            var geometry = new THREE.BoxGeometry( 1, 1, 1 );

            /**
             * 조명에 영향을 받지 않는 기본 머티리얼
             * 머티리얼이란? 3D 모델에 적용할 텍스쳐의 다양한 속성을 설정하는 역활
             *
             * MeshBasicMaterial(parameters : Object)
             */
            var material = new THREE.MeshBasicMaterial( { color: 0x00ff00 } );

            /**
             * 모델의 기초 구조 메쉬(그물망, 철망)
             *
             * Mesh( geometry : Geometry, material : Material )
             * geometry: optional, 지오메트리 값
             * material: optional, 머티리얼 값
             */
            let cube = new THREE.Mesh( geometry, material );
            scene.add( cube );

            camera.position.z = 5;
            
            // 해당 장면을 랜더링하기 위한 애니메이션은 필수
            function animate() {
                requestAnimationFrame( animate );
                
                // 큐브를 x, y 0.1 방향만큼씩 회전시킨다.
                //cube.rotation.x += 0.1;
                //cube.rotation.y += 0.1;

                renderer.render( scene, camera );
            }
            
            animate();
        </script>
    </body>
</html>


# NPM 설치 목록

1. 설치한 패키지 버전 확인: npm show [패키지명] version

2. npm install -g cordova

3. npm install -g ionic 


# ionic 프로젝트 생성

1. ionic start [프로젝트명] [프로젝트템플릿명]

 (프로젝트템플릿명: blank, tabs, sidemenu, tutorial, githul-URL 등이 있습니다.)

2. ionic4 beta로 만들것인지 물어보는데 N 이라고 답하면 됩니다.

3. ionic cordova platform add android, ionic cordova platform add ios, ionic cordova platform add browser

 (플랫폼 추가)

4. ionic build ios, ionic build android

 (플랫폼 빌드)

5. ionic serve --lab

 (브라우저에서 안드로이드, IOS 를 동시에 볼 수 있습니다. 

 그리고 소스내용을 수정하면 자동 리프레시가 됩니다.)

6. ionic cordova run android --device 실제 안드로이드 디바이스에서 실행

 ionic cordova run browser 브라우저에서 실행

 ionic cordova emulate [<platform>] 예물레이터에서 실행

(실행 관련 옵션: https://ionicframework.com/docs/cli/cordova/run/)


# 페이지 추가: ionic에서 사용하는 페이지 추가

1. ionic g page [pageName]


# 서비스 생성

1. ionic g provider [providerName]

 => 프로바이더를 만들어서 사용하면 싱글톤 패턴이기 때문에 변수가 static 적용되어 사용됩니다.


# 컴포넌트 생성: 공통으로 사용하는 뷰 및 기능

1. ionic g component [componentName]


# 플러그인 Docs

1. HTTP 플러그인: https://ionicframework.com/docs/native/http/


# app.module.ts

1. declarations: 이 모듈에서 사용하는 뷰 클래스를 정의한다. Angular에는 컴포넌트, 디렉티브, 파이프 세 종류의 뷰 클래스가 있다.

2. imports: export로 공개된 클래스를 다른 컴포넌트 템플릿의 this 모듈에 선언해서 사용할 때 사용한다.

3. bootstrap: 루트 컴포넌트라고 하는 메인 어플리케이션의 뷰를 선언한다. bootstrap 항목은 루트 모듈에만 존재한다.

4. entryComponents: 라우터 구성에서 참조되는 컴포넌트

5. providers: 전역에서 사용되는 서비스를 해당 객체에서 사용할 수 있도록 생성하고 지정한다. 프로바이더는 앱의 모든 곳에서 접근할 수 있다.


# Ionic Tips

1. navbar에서 뒤로가기 버튼 숨기는 방법: <ion-navbar hideBackButton> 처럼 hideBackButton을 추가하면 된다.

2. When to Use Providers / Services / Injectables in Ionic : https://www.joshmorony.com/when-to-use-providersservicesinjectables-in-ionic/

3. 스플래시 및 아이콘 변경 방법: http://kamang-it.tistory.com/entry/Ionic-04%EC%95%84%EC%9D%B4%EC%BD%98%EA%B3%BC-%EC%8A%A4%ED%94%8C%EB%9E%98%EC%8B%9C-%EC%83%9D%EC%84%B1

4. 하드웨어 백버튼 관련: https://www.codementor.io/syseverton/ionic-3-solving-the-hardware-back-button-avoiding-to-close-the-app-k23a6wu4e

5. ionic cordodva run android --device시 기기와 타이임아웃이 자주 발생할때 기기 찾는 시간을 늘린다.

https://forum.ionicframework.com/t/error-device-communication-timed-out/40118/3

6. 패키지명과 앱 이름 변경시 플랫폼을 전부 삭제후 변경해야 변경이 적용됩니다.

7. build 혹은 run 시 cordova Could not find any matches for com.android.tools.build:gradle:2.3.+ as no versions of com.android.tools.build:gradle are available. 오류가 발생하면

platforms > android > app > build.gradle 에 buildscript 안에 mavenCentral() 를 추가합니다.

8. FCM Plugin 추가 후 android studio 툴에서 gradle 빌드시 이와 같은 오류가 날수 있습니다.

오류 발생원인은 repositories에서 2.3 이상의 버전을 찾을 수 없기 때문입니다. 그래서 repositories에 mavenCentroal()를 추가합니다.

Could not find any matches for com.android.tools.build:gradle:2.3.+ as no versions of com.android.tools.build:gradle are available.

이럴 경우

test-FCMPlugin.gradle 에서 오류가 날 경우 이와 깉이 buildscript를 변경한다.

buildscript {

    repositories {

        jcenter()

        mavenLocal()

        mavenCentral()

        maven {

          url 'https://maven.google.com'

        }

    }

    dependencies {

        classpath 'com.android.tools.build:gradle:2.3.+'

        classpath 'com.google.gms:google-services:3.1.+'

    }

}


# 설치한 플러그인

1. npm install --save @ionic-native/camera @ionic-native/file @ionic-native/file-path @ionic-native/transfer

2. ionic cordova plugin add cordova-plugin-camera --save : ios 일 경우 https://github.com/apache/cordova-plugin-camera 에서 퍼미션허용해줘야 합니다.

3. ionic cordova plugin add cordova-plugin-file --save

4. ionic cordova plugin add cordova-plugin-file-transfer --save

5. ionic cordova plugin add cordova-plugin-filepath --save

6. npm install whatwg-fetch --save : fetch polyfill: Html의 Fetch API의 Polyfill NPM

7. ionic cordova plugin add cordova-plugin-fcm-with-dependecy-updated: FCM 플러그인

8. npm install --save @ionic-native/fcm: FCM NPM

9. ionic cordova plugin add cordova-sqlite-storage: 스토리지 플러그인

10. npm install --save @ionic/storage: 스토리지 NPM

11. ionic cordova plugin add cordova-plugin-file-opener2

12. npm install --save @ionic-native/file-opener

13. ionic cordova plugin add cordova-plugin-screen-orientation

14. npm install --save @ionic-native/screen-orientation


# Visual Studio Code Plugin

1. angular language service

2. angular v4 typescript snippets

3. TSlint


# FCM

1. FCM 테스트 사이트: https://cordova-plugin-fcm.appspot.com/

2. 백그라운드 일때 노티피케이션 눌렀을때 작동을 시키려면 위 사이트에서 테스트 할때

Custom data parameters안에 키: click_action, 값: FCM_PLUGIN_ACTIVITY 를 넣어줘야 합니다.

Node Webkit 줄여서 nwjs 를 사용하면서 자바, 파이썬, C/C++ 같은 네이티브 함수/메소드가 필요할 때가 있습니다.


이를 사용하기 위해서는 node-gyp를 사용해야 합니다.


하지만 nwjs 에서 node-gyp를 개량한 nw-gyp라는것이 존재합니다.

(nwjs git url: https://github.com/nwjs/nw-gyp)

(nwjs 공식설명: http://docs.nwjs.io/en/latest/For%20Users/Advanced/Use%20Native%20Node%20Modules/#node-pre-gyp)


이것을 이용해서 네이티브 함수/메소드를 사용할 수 있습니다.


윈도우 기준 및 파이썬 기준으로 설명하겠습니다.


1. nw-gyp는 파이썬 2.7 버전을 지원을 하여 3.x 버전은 지원하지 않습니다. 그래서 파이썬 2.7 버전을 설치합니다.


2. 파이썬 2.7 버전을 설치가 완료되었으면 npm install --global --production windows-build-tools 을 설치합니다.


이때 CMD 콘솔창은 관리자 권한으로 실행을 해야 설치가 됩니다.


3. 설치가완료되면 npm install -g nw-gyp 을 설치합니다.


4. 만약 파이썬 버전이 여러개가 설치되어 있는경우 nw-gyp --python /path/to/python2.7 명령어를 통해 해당 파이썬 버전을 선택할 수 있습니다.


5. 그 후 내가 만든 프로젝트로 이동 후 nw-gyp configure --target=<0.3.2 or other nw version> 명령어를 통해 nwjs 버전을 설정합니다.


6. 그리고 Visual C ++ 빌드 도구 2015 설정을 위해 nw-gyp configure --msvs_version=2015 명령어를 실행합니다.


7. 그리고 빌드된 파일을 가지고 binding.gyp JSON파일을 만들어서 package.json 파일과 동일한 위치에 만듭니다.

내용은 아래와 같습니다.



{

  "targets": [

    {

      "target_name": "binding",

      "sources": [ "src/binding.cc" ]

    }

  ]

}



8. nw-gyp build 명령어로 src/ 안에 있는 파일을 빌드합니다.


9. 완료되었습니다.

(Hello World 예제: https://github.com/nodejs/node/tree/master/test/addons/hello-world)


여기 까지인데 저도 5번까지하고 다른 모듈을 사용하느라 그 후의 작업은 진행하지 못했습니다.


추후 해보고 다시 수정해서 올리겠습니다.

SPA 페이지가 아닌 페이지에서 페이지가 로딩되는 동안 의도치 않게 머스태그({{}}) 라든지


보여지지말아야할 요소(v-if, v-show 등등...)가 보인다는 등의 상황이 오게 됩니다.


이럴 때 사용 하는 것이 v-cloak 입니다.




자세한 내용은 http://vuetips.com/v-cloak-directive-hides-html-on-startup 에서 확인해 주시기 바랍니다.

+ Recent posts