Форум программистов, компьютерный форум, киберфорум
Наши страницы
JavaScript: HTML5 Canvas
Войти
Регистрация
Восстановить пароль
 
 
Бейсик рулит
1 / 1 / 1
Регистрация: 17.03.2016
Сообщений: 82
#1

Создание 3D объектов - HTML5 Canvas

10.04.2018, 10:23. Просмотров 436. Ответов 20
Метки нет (Все метки)

Какую литературу почитать, туториалы посмотреть, чтобы с нуля разобраться в 3d на javascript?
http://www.cyberforum.ru/javascript-canvas/thread1891942.html
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
10.04.2018, 10:23
Я подобрал для вас темы с готовыми решениями и ответами на вопрос Создание 3D объектов (HTML5 Canvas):

Создание объектов JS
Наткнулся на создание объекта с помощью конструктора (function): var new_obj...

Создание объектов
Здравствуйте, вот никак не могу создать собственные объекты. <html> <head>...

Создание объектов
Всем здравствуйте. Народ, помогите. Элементарный код из трёх строчек у меня не...

Создание нескольких объектов
Вот у меня есть код: var Timer = { // timer container timerContainer:...

Создание классов и их объектов
Нашёл много всякого про наследование в javascript, а вот про самые что ни...

20
j2FunOnly
Модератор
748 / 733 / 439
Регистрация: 05.06.2015
Сообщений: 1,735
10.04.2018, 14:21 #2
http://www.cyberforum.ru/javascript/thread1308561.html#post9727061
http://www.cyberforum.ru/javascript/...l#post10248593
0
8Observer8
2037 / 1330 / 216
Регистрация: 05.10.2013
Сообщений: 4,219
Записей в блоге: 56
11.04.2018, 11:51 #3
Лучший ответ Сообщение было отмечено Бейсик рулит как решение

Решение

WebGL. Программирование трехмерной графики
https://www.ozon.ru/context/detail/id/31239396/

Либо подключить библиотеки для 3D графики: three.js или babylon.js

По чистому WebGL и библиотекам-обёрткам над WebGL (то есть three.js и babylon.js) есть книги и видео туториалы. В основном на английском. Их можно найти в поиске на amazon или на youtube

Добавлено через 14 часов 6 минут
Изучать WebGL это, конечно, хорошо, это полезно даже если используешь библиотеки, но это долгий путь. Гораздо проще и быстрее освоить либо библиотеку Three.js, либо Babylon.js

Начать можно с официальных вводных туториалов, где расписаны основы, как создать первый 3D объект в браузере на JavaScript. Правда, эти туториалы на английском. Можно использовать https://translate.yandex.com/

Официальный вводный туториал по Three.js: Getting Started with Three.js

Я для удобства перенёс пример в песочницу --> запустить в песочнице

index.html
PHPHTML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
<!DOCTYPE html>
<html lang="en">
 
<head>
    <meta charset="UTF-8">
    <title>Three.js - Getting Started</title>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/89/three.min.js"></script>
 
    <style>
        body {
            margin: 0;
        }
 
        canvas {
            width: 100%;
            height: 100%
        }
    </style>
</head>
 
<body>
    <script>
        var scene = new THREE.Scene();
        var camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
 
        var renderer = new THREE.WebGLRenderer();
        renderer.setSize(window.innerWidth, window.innerHeight);
        document.body.appendChild(renderer.domElement);
 
        var geometry = new THREE.BoxGeometry(1, 1, 1);
        var material = new THREE.MeshBasicMaterial({ color: 0x00ff00 });
        var cube = new THREE.Mesh(geometry, material);
        scene.add(cube);
 
        camera.position.z = 5;
 
        var animate = function ()
        {
            requestAnimationFrame(animate);
 
            cube.rotation.x += 0.1;
            cube.rotation.y += 0.1;
 
            renderer.render(scene, camera);
        };
 
        animate();
    </script>
</body>
 
</html>
Официальный вводный туториал по Babylon.js: Getting Started with Babylon.js

Запустить в песочнице

PHPHTML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
<!DOCTYPE html>
<html lang="en">
 
<head>
    <meta charset="UTF-8">
    <title>Babylon.js - Getting Started</title>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/babylonjs/2.5.0/babylon.js"></script>
 
    <style>
        html,
        body {
            overflow: hidden;
            width: 100%;
            height: 100%;
            margin: 0;
            padding: 0;
        }
 
        #renderCanvas {
            width: 100%;
            height: 100%;
            touch-action: none;
        }
    </style>
</head>
 
<body>
    <canvas id="renderCanvas"></canvas>
 
    <script>
        window.addEventListener('DOMContentLoaded', function ()
        {
            // get the canvas DOM element
            var canvas = document.getElementById('renderCanvas');
 
            // load the 3D engine
            var engine = new BABYLON.Engine(canvas, true);
 
            // createScene function that creates and return the scene
            var createScene = function ()
            {
                // create a basic BJS Scene object
                var scene = new BABYLON.Scene(engine);
 
                // create a FreeCamera, and set its position to (x:0, y:5, z:-10)
                var camera = new BABYLON.FreeCamera('camera1', new BABYLON.Vector3(0, 5, -10), scene);
 
                // target the camera to scene origin
                camera.setTarget(BABYLON.Vector3.Zero());
 
                // attach the camera to the canvas
                camera.attachControl(canvas, false);
 
                // create a basic light, aiming 0,1,0 - meaning, to the sky
                var light = new BABYLON.HemisphericLight('light1', new BABYLON.Vector3(0, 1, 0), scene);
 
                // create a built-in "sphere" shape; its constructor takes 5 params: name, width, depth, subdivisions, scene
                var sphere = BABYLON.Mesh.CreateSphere('sphere1', 16, 2, scene);
 
                // move the sphere upward 1/2 of its height
                sphere.position.y = 1;
 
                // create a built-in "ground" shape; its constructor takes the same 5 params as the sphere's one
                var ground = BABYLON.Mesh.CreateGround('ground1', 6, 6, 2, scene);
 
                // return the created scene
                return scene;
            }
 
            // call the createScene function
            var scene = createScene();
 
            // run the render loop
            engine.runRenderLoop(function ()
            {
                scene.render();
            });
 
            // the canvas/window resize event handler
            window.addEventListener('resize', function ()            
            {
                engine.resize();
            });
        });
    </script>
</body>
 
</html>
3
clecar
9 / 9 / 3
Регистрация: 16.02.2018
Сообщений: 29
11.04.2018, 14:04 #4
8Observer8, Спасибо! Не занимался ещё этим в canvas, и представлял 3D как массив точек развёртки, оказывается всё значительно проще.
1
Бейсик рулит
1 / 1 / 1
Регистрация: 17.03.2016
Сообщений: 82
11.04.2018, 18:10  [ТС] #5
8Observer8, спасибо за ответ. И за примеры отдельное спасибо!
1
8Observer8
2037 / 1330 / 216
Регистрация: 05.10.2013
Сообщений: 4,219
Записей в блоге: 56
11.04.2018, 21:06 #6
Цитата Сообщение от Бейсик рулит Посмотреть сообщение
туториалы посмотреть
Я в основном смотрю на английском, чтобы за одно стараться тренировать восприятие на слух.

THREE.js Part 1: Intro
youtube


Introduction to WebGL 3D with HTML5 and Babylon.js
youtube


BabylonJS Game Engine Tutorial Series
youtube
1
Бейсик рулит
1 / 1 / 1
Регистрация: 17.03.2016
Сообщений: 82
13.04.2018, 09:10  [ТС] #7
Может быть у кого-то есть пример типа такого, только с более простой реализацией?
http://codecenter.awardspace.com/rotate_cube.html
0
8Observer8
2037 / 1330 / 216
Регистрация: 05.10.2013
Сообщений: 4,219
Записей в блоге: 56
13.04.2018, 09:42 #8
Цитата Сообщение от Бейсик рулит Посмотреть сообщение
Может быть у кого-то есть пример типа такого, только с более простой реализацией?
http://codecenter.awardspace.com/rotate_cube.html
Оригинальный пример. Посмотрел обзорно его реализацию. В нём каждый пиксель - это div с размером 1 пиксель. Вы тоже хотите делать на div, без <canvas> и библиотек типа, что я выше приводил? Только html, css и js можно использовать?
0
Бейсик рулит
1 / 1 / 1
Регистрация: 17.03.2016
Сообщений: 82
13.04.2018, 09:54  [ТС] #9
8Observer8, да нет, в принципе можно и с библиотеками. Не могу пока разобраться с вращением вручную. Книгу, которую Вы мне посоветовали - скачал, почитал, попробовал примеры. Там есть автоматическое вращение, типа как Вы мне прислали пример в песочнице ( очень хороший пример, еще раз спасибо!). А вот вращения фигуры с помощью мыши или с помощью ползунков, как я скинул пример выше, не нашел.
0
8Observer8
2037 / 1330 / 216
Регистрация: 05.10.2013
Сообщений: 4,219
Записей в блоге: 56
13.04.2018, 10:51 #10
Лучший ответ Сообщение было отмечено Бейсик рулит как решение

Решение

Цитата Сообщение от Бейсик рулит Посмотреть сообщение
А вот вращения фигуры с помощью мыши или с помощью ползунков, как я скинул пример выше, не нашел.
На Three.js для вращения мышкой нужно добавить две строчки кода. Ниже опишу - какие. Удобно работать через песочницу. Если зарегистрироваться, то можно нажать кнопку Fork, доработать пример, нажать кнопку Save, тогда можно скинуть ссылку обратно сюда на форум.

Возьмём тот пример из сообщения #3 на Three.js с кубиком. Остановим анимацию, удалением строк:
Javascript
1
2
            cube.rotation.x += 0.1;
            cube.rotation.y += 0.1;
Нужно через тег <script> подсоединить скрипт OrbitControls.js, который находится в папке controls: https://github.com/mrdoob/three.js/tree/dev/examples/js/controls

Я закинул скрипт OrbitControls.js на dropbox, чтобы можно было в песочнице использовать:
Javascript
1
<script src="https://dl.dropboxusercontent.com/s/eiw16qns7365m0w/OrbitControls.js"></script>
Для вращения мышкой нужно создать экземпляр класса OrbitControls:
Javascript
1
var controls = new THREE.OrbitControls(camera);
И добавить эту строку в в метод animate:
Javascript
1
controls.update();
Пробуйте вращать мышкой в живой демке

Я заменил материал куба на MeshStandardMaterial и добавил точечный источник света - PointLight. Точечный - это как от лампочки. Можно было бы добавить либо направленный источник - как солнце с параллельными лучами, а можно было, как от фонаря (или прожектора)

Добавил AmbientLight - это окружающий рассеянный свет, чтобы с другой стороны от лампочки кубик тоже немного освещался. Можете закомментировать сначала один источник света, потом другой, чтобы посмотреть какой будет эффект.

Код из песочницы:
PHPHTML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
<!DOCTYPE html>
<html lang="en">
 
<head>
    <meta charset="UTF-8">
 
    <title>Three.js - Getting Started</title>
 
    <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/89/three.min.js"></script>
    <script src="https://dl.dropboxusercontent.com/s/eiw16qns7365m0w/OrbitControls.js"></script>
 
    <style>
        body {
            margin: 0;
        }
        
        canvas {
            width: 100%;
            height: 100%
        }
    </style>
</head>
 
<body>
    <script>
        var scene = new THREE.Scene();
        var camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
 
        var renderer = new THREE.WebGLRenderer();
        renderer.setSize(window.innerWidth, window.innerHeight);
        document.body.appendChild(renderer.domElement);
 
        var light = new THREE.PointLight(0xffffff, 1, 50);
        light.position.set(3, 4, 2);
        scene.add(light);
 
        var ambientlight = new THREE.AmbientLight(0x404040); // soft white light
        scene.add(ambientlight);
 
        var geometry = new THREE.BoxGeometry(1, 1, 1);
        var material = new THREE.MeshStandardMaterial({
            color: 0x00ff00
        });
        var cube = new THREE.Mesh(geometry, material);
        scene.add(cube);
 
        camera.position.z = 3;
 
        var controls = new THREE.OrbitControls(camera);
 
        var animate = function() {
            requestAnimationFrame(animate);
 
            controls.update();
 
            renderer.render(scene, camera);
        };
 
        animate();
    </script>
</body>
 
</html>
1
8Observer8
2037 / 1330 / 216
Регистрация: 05.10.2013
Сообщений: 4,219
Записей в блоге: 56
13.04.2018, 13:40 #11
Если можете читать на английском, то приобретите книгу:
Learning Three.js – the JavaScript 3D Library for WebGL - 2nd Edition - Jos Dirksen

Исходники к книге: https://github.com/josdirksen/learning-threejs

Создание 3D объектов
1
8Observer8
2037 / 1330 / 216
Регистрация: 05.10.2013
Сообщений: 4,219
Записей в блоге: 56
13.04.2018, 15:44 #12
Цитата Сообщение от Бейсик рулит Посмотреть сообщение
Может быть у кого-то есть пример типа такого, только с более простой реализацией?
http://codecenter.awardspace.com/rotate_cube.html
Можно попробовать сделать точно такой же пример на Three.js. Для анимации хорошо подойдёт дополнительная библиотека Tween.js Использование этой библиотеки описано в книге сообщением выше "Learning Three.js" -> "Chapter 9: Animation and Moving" -> "Basic animations" -> "Animation with Tween.js"

На странице github библиотеки Tween.js есть пример: https://github.com/sole/tween.js
Javascript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
var coords = { x: 0, y: 0 };
var tween = new TWEEN.Tween(coords)
    .to({ x: 100, y: 100 }, 1000)
    .onUpdate(function() {
        console.log(this.x, this.y);
    })
    .start();
 
requestAnimationFrame(animate);
 
function animate(time) {
    requestAnimationFrame(animate);
    TWEEN.update(time);
}
Можете запустить этот код. Он будет выводить значения от 0 до 100 в течение одной секунды: демка в песочнице

Код из песочницы:

index.html
PHPHTML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
<!DOCTYPE html>
<html>
 
<head>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/tween.js/16.3.5/Tween.min.js"></script>
</head>
 
<body>
    <div id="output"></div>
    <script>
        var output = document.getElementById("output");
        output.innerHTML = "(x, y)" + "<br>";
 
        var coords = {
            x: 0,
            y: 0
        };
        var tween = new TWEEN.Tween(coords)
            .to({
                x: 100,
                y: 100
            }, 1000)
            .onUpdate(function() {
                //console.log(this.x, this.y);
                var x = Math.floor(this.x);
                var y = Math.floor(this.y);
                output.innerHTML += "(" + x + ", " + y + ")" + "<br>";
            })
            .start();
 
        requestAnimationFrame(animate);
 
        function animate(time) {
            requestAnimationFrame(animate);
            TWEEN.update(time);
        }
    </script>
</body>
 
</html>
1
8Observer8
2037 / 1330 / 216
Регистрация: 05.10.2013
Сообщений: 4,219
Записей в блоге: 56
15.04.2018, 20:17 #13
Цитата Сообщение от Бейсик рулит Посмотреть сообщение
Может быть у кого-то есть пример типа такого, только с более простой реализацией?
http://codecenter.awardspace.com/rotate_cube.html
Я реализовал, как в примере, вращение кубика вокруг оси Y против часовой и по часовой стрелки с помощью Tween.js. Если кто-нибудь хочет может реализовать вращение вокруг других осей, или что-то улучшить, или добавить в код.

>>> Демка <<<

Название: RotatedCube.gif
Просмотров: 45

Размер: 122.7 Кб

index.html
PHPHTML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
<!DOCTYPE html>
<html lang="en">
 
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
 
    <title>Rotated Cube</title>
 
    <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/89/three.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/tween.js/16.3.5/Tween.min.js"></script>
 
    <style>
        body {
            margin: 0;
        }
    </style>
</head>
 
<body>
    <ul>
        <li>
            <a href="#" onclick="aroundYAntiClockwise();">Around Y, anti-clockwise</a>
        </li>
        <li>
            <a href="#" onclick="aroundYClockwise();">Around Y, clockwise</a>
        </li>
    </ul>
    <script>
        var eRotation = Object.freeze({
            eYAntiClockwise: 0,
            eYClockwise: 1
        });
        var scene = new THREE.Scene();
        var canvasWidth = 500;
        var canvasHeight = 500;
        var inRotatingProcess = false;
 
        var renderer = new THREE.WebGLRenderer({ alpha: true });
        renderer.setSize(canvasWidth, canvasHeight);
        document.body.appendChild(renderer.domElement);
 
        var camera = new THREE.PerspectiveCamera(55, canvasWidth / canvasHeight, 0.1, 1000);
        camera.position.set(1.1, 1.1, 1.1);
        // camera.position.x = 3;
        // camera.position.y = 3;
        // camera.position.z = 3;
        camera.lookAt(new THREE.Vector3(0, 0, 0));
 
        var directionalLight = new THREE.DirectionalLight(0xffffff, 0.5);
        directionalLight.position.x = 1;
        directionalLight.position.y = 5;
        directionalLight.position.z = 2;
        scene.add(directionalLight);
 
        var ambientLight = new THREE.AmbientLight(0xdddddd);
        scene.add(ambientLight);
 
        var geometry = new THREE.BoxGeometry(1, 1, 1);
        var material = new THREE.MeshStandardMaterial({ color: 0x00ff00 });
        var cube = new THREE.Mesh(geometry, material);
        scene.add(cube);
 
        var tween = null;
 
        animate();
 
        function animate() {
            requestAnimationFrame(animate);
 
            // cube.rotation.x += 0.01;
            // cube.rotation.y += 0.01;
            if (tween !== undefined) {
                TWEEN.update();
            }
 
 
            renderer.render(scene, camera);
        };
 
        function runRotation(rotation) {
            var ry_start = 0, ry_end = 0;
            inRotatingProcess = true;
            switch (rotation) {
                case eRotation.eYAntiClockwise:
                    ry_start = THREE.Math.radToDeg(cube.rotation.y);
                    ry_end = ry_start + 90;
                    break;
                case eRotation.eYClockwise:
                    ry_start = THREE.Math.radToDeg(cube.rotation.y);
                    ry_end = ry_start - 90;
                    break;
            }
 
            tween = new TWEEN.Tween({ ry: ry_start })
            .to({ ry: ry_end }, 1000)
            .onUpdate(function() {
                cube.rotation.y = THREE.Math.degToRad(this.ry);
            })
            .onComplete(function() {
                inRotatingProcess = false;
            })
            .start();
        }
 
        function aroundYAntiClockwise() {
            if (inRotatingProcess) return;
            runRotation(eRotation.eYAntiClockwise);
        }
 
        function aroundYClockwise() {
            if (inRotatingProcess) return;
            runRotation(eRotation.eYClockwise);
        }
    </script>
</body>
 
</html>
2
8Observer8
2037 / 1330 / 216
Регистрация: 05.10.2013
Сообщений: 4,219
Записей в блоге: 56
16.04.2018, 21:41 #14
Добавил вращение вокруг всех трёх осей по часовой и против часовой стрелки.

>>> Демка в песочнице <<<

Код из песочницы:

PHPHTML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
<!DOCTYPE html>
<html lang="en">
 
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
 
    <title>Rotated Cube</title>
 
    <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/89/three.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/tween.js/16.3.5/Tween.min.js"></script>
 
    <style>
        body {
            margin: 0;
        }
 
        li {
            margin: 5px 50px;
        }
    </style>
</head>
 
<body>
    <ul>
        <li>
            <a href="#" onclick="aroundXAntiClockwise();">Around X, anti-clockwise</a>
        </li>
        <li>
            <a href="#" onclick="aroundXClockwise();">Around X, clockwise</a>
        </li>
        <hr width="300" noshade="" size="1" align="left">
        <li>
            <a href="#" onclick="aroundYAntiClockwise();">Around Y, anti-clockwise</a>
        </li>
        <li>
            <a href="#" onclick="aroundYClockwise();">Around Y, clockwise</a>
        </li>
        <hr width="300" noshade="" size="1" align="left">
        <li>
            <a href="#" onclick="aroundZAntiClockwise();">Around Z, anti-clockwise</a>
        </li>
        <li>
            <a href="#" onclick="aroundZClockwise();">Around Z, clockwise</a>
        </li>
    </ul>
    <script>
        var eRotation = Object.freeze({
            eXAntiClockwise: 0,
            eXClockwise: 1,
            eYAntiClockwise: 2,
            eYClockwise: 3,
            eZAntiClockwise: 4,
            eZClockwise: 5
        });
        var scene = new THREE.Scene();
        var canvasWidth = 500;
        var canvasHeight = 500;
        var inRotatingProcess = false;
 
        var renderer = new THREE.WebGLRenderer({ alpha: true });
        renderer.setSize(canvasWidth, canvasHeight);
        document.body.appendChild(renderer.domElement);
 
        var camera = new THREE.PerspectiveCamera(55, canvasWidth / canvasHeight, 0.1, 1000);
        camera.position.set(1.3, 1.3, 1.3);
        camera.lookAt(new THREE.Vector3(0, 0, 0));
 
        var directionalLight = new THREE.DirectionalLight(0xffffff, 0.5);
        directionalLight.position.x = 1;
        directionalLight.position.y = 5;
        directionalLight.position.z = 2;
        scene.add(directionalLight);
 
        var ambientLight = new THREE.AmbientLight(0xdddddd);
        scene.add(ambientLight);
 
        var geometry = new THREE.BoxGeometry(1, 1, 1);
        var material = new THREE.MeshStandardMaterial({ color: 0x00ff00 });
        var cube = new THREE.Mesh(geometry, material);
        cube.position.y = 0.3;
        scene.add(cube);
 
        var tween = null;
 
        animate();
 
        function animate() {
            requestAnimationFrame(animate);
 
            if (tween !== undefined) {
                TWEEN.update();
            }
 
            renderer.render(scene, camera);
        };
 
        function runRotation(rotation) {
            var rx_start = THREE.Math.radToDeg(cube.rotation.x);
            var rx_end = THREE.Math.radToDeg(cube.rotation.x);
            var ry_start = THREE.Math.radToDeg(cube.rotation.y);
            var ry_end = THREE.Math.radToDeg(cube.rotation.y);
            var rz_start = THREE.Math.radToDeg(cube.rotation.z);
            var rz_end = THREE.Math.radToDeg(cube.rotation.z);
            inRotatingProcess = true;
 
            switch (rotation) {
                case eRotation.eXAntiClockwise:
                    rx_end = rx_start + 90;
                    break;
                case eRotation.eXClockwise:
                    rx_end = rx_start - 90;
                    break;
                case eRotation.eYAntiClockwise:
                    ry_end = ry_start + 90;
                    break;
                case eRotation.eYClockwise:
                    ry_end = ry_start - 90;
                    break;
                case eRotation.eZAntiClockwise:
                    rz_end = rz_start + 90;
                    break;
                case eRotation.eZClockwise:
                    rz_end = rz_start - 90;
                    break;
            }
 
            tween = new TWEEN.Tween({ rx: rx_start, ry: ry_start, rz: rz_start })
                .to({ rx: rx_end, ry: ry_end, rz: rz_end }, 500)
                .onUpdate(function() {
                    cube.rotation.x = THREE.Math.degToRad(this.rx);
                    cube.rotation.y = THREE.Math.degToRad(this.ry);
                    cube.rotation.z = THREE.Math.degToRad(this.rz);
                })
                .onComplete(function() {
                    inRotatingProcess = false;
                })
                .start();
        }
 
        function aroundXAntiClockwise() {
            if (inRotatingProcess) return;
            runRotation(eRotation.eXAntiClockwise);
        }
 
        function aroundXClockwise() {
            if (inRotatingProcess) return;
            runRotation(eRotation.eXClockwise);
        }
 
        function aroundYAntiClockwise() {
            if (inRotatingProcess) return;
            runRotation(eRotation.eYAntiClockwise);
        }
 
        function aroundYClockwise() {
            if (inRotatingProcess) return;
            runRotation(eRotation.eYClockwise);
        }
 
        function aroundZAntiClockwise() {
            if (inRotatingProcess) return;
            runRotation(eRotation.eZAntiClockwise);
        }
 
        function aroundZClockwise() {
            if (inRotatingProcess) return;
            runRotation(eRotation.eZClockwise);
        }
    </script>
</body>
 
</html>
Добавлено через 10 часов 45 минут
Исправил ошибку в примере выше. Убрал var у переменной inRotatingProcess в функции:
Javascript
1
2
3
4
5
function runRotation(rotation) {
    // ...
    var inRotatingProcess = true;
    // ...
}
Эта переменная должна быть глобальной, чтобы на время анимации поворота заблокировать возможность поворота до его завершения.
2
8Observer8
2037 / 1330 / 216
Регистрация: 05.10.2013
Сообщений: 4,219
Записей в блоге: 56
17.04.2018, 14:06 #15
Цитата Сообщение от Бейсик рулит Посмотреть сообщение
Может быть у кого-то есть пример типа такого, только с более простой реализацией?
http://codecenter.awardspace.com/rotate_cube.html
Я раскрасил кубик так же, как в примере. Получился полный аналог. Сравните по быстродействию.

Для раскраски я использовал тутор: Tutorial 03: Adding color.
Для добавления текста - подсказку из официальной документации: Creating text
Оси добавил с помощью AxesHelper

>>> Демка в песочнице <<<

Название: RotatedCube.png
Просмотров: 35

Размер: 6.7 Кб

Код из песочницы:

PHPHTML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
<!DOCTYPE html>
<html lang="en">
 
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
 
    <title>Rotated Cube</title>
 
    <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/89/three.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/tween.js/16.3.5/Tween.min.js"></script>
 
    <style>
        html, body {
            margin: 0;
            background: #efefef;
        }
        
        li {
            margin: 5px 50px;
        }
 
        #x {
            font-size: 2em;
            position: absolute;
            top: 510px;
            width: 100%;
            left: 440px;
            z-index: 100;
            display: block;
        }
        
        #y {
            font-size: 2em;
            position: absolute;
            top: 200px;
            width: 100%;
            left: 255px;
            z-index: 100;
            display: block;
        }
 
        #z {
            font-size: 2em;
            position: absolute;
            top: 510px;
            width: 100%;
            left: 50px;
            z-index: 100;
            display: block;
        }
    </style>
</head>
 
<body>
    <div id="x">x</div>
    <div id="y">y</div>
    <div id="z">z</div>
    
    <ul>
        <li>
            <a href="#" onclick="aroundXAntiClockwise();">Around X, anti-clockwise</a>
        </li>
        <li>
            <a href="#" onclick="aroundXClockwise();">Around X, clockwise</a>
        </li>
        <hr width="300" noshade="" size="1" align="left">
        <li>
            <a href="#" onclick="aroundYAntiClockwise();">Around Y, anti-clockwise</a>
        </li>
        <li>
            <a href="#" onclick="aroundYClockwise();">Around Y, clockwise</a>
        </li>
        <hr width="300" noshade="" size="1" align="left">
        <li>
            <a href="#" onclick="aroundZAntiClockwise();">Around Z, anti-clockwise</a>
        </li>
        <li>
            <a href="#" onclick="aroundZClockwise();">Around Z, clockwise</a>
        </li>
    </ul>
    <script>
        var eRotation = Object.freeze({
            eXAntiClockwise: 0,
            eXClockwise: 1,
            eYAntiClockwise: 2,
            eYClockwise: 3,
            eZAntiClockwise: 4,
            eZClockwise: 5
        });
        var scene = new THREE.Scene();
        var canvasWidth = 500;
        var canvasHeight = 500;
        var inRotatingProcess = false;
 
        var renderer = new THREE.WebGLRenderer({
            alpha: true
        });
        renderer.setSize(canvasWidth, canvasHeight);
        document.body.appendChild(renderer.domElement);
 
        var camera = new THREE.PerspectiveCamera(55, canvasWidth / canvasHeight, 0.1, 1000);
        camera.position.set(1.3, 1.3, 1.3);
        camera.lookAt(new THREE.Vector3(0, 0, 0));
 
        var axesHelper = new THREE.AxesHelper(1);
        scene.add(axesHelper);
 
        var geometry = new THREE.BoxGeometry(1, 1, 1);
        // Yellow
        geometry.faces[0].vertexColors[0] = new THREE.Color(0xffff00);
        geometry.faces[0].vertexColors[1] = new THREE.Color(0xffff00); 
        geometry.faces[0].vertexColors[2] = new THREE.Color(0xffff00); 
        geometry.faces[1].vertexColors[0] = new THREE.Color(0xffff00);
        geometry.faces[1].vertexColors[1] = new THREE.Color(0xffff00); 
        geometry.faces[1].vertexColors[2] = new THREE.Color(0xffff00);
        // White 
        geometry.faces[2].vertexColors[0] = new THREE.Color(0xffffff);
        geometry.faces[2].vertexColors[1] = new THREE.Color(0xffffff); 
        geometry.faces[2].vertexColors[2] = new THREE.Color(0xffffff); 
        geometry.faces[3].vertexColors[0] = new THREE.Color(0xffffff);
        geometry.faces[3].vertexColors[1] = new THREE.Color(0xffffff); 
        geometry.faces[3].vertexColors[2] = new THREE.Color(0xffffff); 
        // Green
        geometry.faces[4].vertexColors[0] = new THREE.Color(0x008000);
        geometry.faces[4].vertexColors[1] = new THREE.Color(0x008000); 
        geometry.faces[4].vertexColors[2] = new THREE.Color(0x008000); 
        geometry.faces[5].vertexColors[0] = new THREE.Color(0x008000);
        geometry.faces[5].vertexColors[1] = new THREE.Color(0x008000); 
        geometry.faces[5].vertexColors[2] = new THREE.Color(0x008000);
        // Red 
        geometry.faces[6].vertexColors[0] = new THREE.Color(0xff0000);
        geometry.faces[6].vertexColors[1] = new THREE.Color(0xff0000); 
        geometry.faces[6].vertexColors[2] = new THREE.Color(0xff0000); 
        geometry.faces[7].vertexColors[0] = new THREE.Color(0xff0000);
        geometry.faces[7].vertexColors[1] = new THREE.Color(0xff0000); 
        geometry.faces[7].vertexColors[2] = new THREE.Color(0xff0000); 
        // Blue
        geometry.faces[8].vertexColors[0] = new THREE.Color(0x0000ff);
        geometry.faces[8].vertexColors[1] = new THREE.Color(0x0000ff); 
        geometry.faces[8].vertexColors[2] = new THREE.Color(0x0000ff); 
        geometry.faces[9].vertexColors[0] = new THREE.Color(0x0000ff);
        geometry.faces[9].vertexColors[1] = new THREE.Color(0x0000ff); 
        geometry.faces[9].vertexColors[2] = new THREE.Color(0x0000ff); 
        // Orange
        geometry.faces[10].vertexColors[0] = new THREE.Color(0xffa500);
        geometry.faces[10].vertexColors[1] = new THREE.Color(0xffa500); 
        geometry.faces[10].vertexColors[2] = new THREE.Color(0xffa500); 
        geometry.faces[11].vertexColors[0] = new THREE.Color(0xffa500);
        geometry.faces[11].vertexColors[1] = new THREE.Color(0xffa500); 
        geometry.faces[11].vertexColors[2] = new THREE.Color(0xffa500); 
        var material = new THREE.MeshBasicMaterial({
            vertexColors:THREE.VertexColors
        });
        var cube = new THREE.Mesh(geometry, material);
        cube.position.y = 0;
        scene.add(cube);
 
        var tween = null;
 
        animate();
 
        function animate() {
            requestAnimationFrame(animate);
 
            if (tween !== undefined) {
                TWEEN.update();
            }
 
            renderer.render(scene, camera);
        };
 
        function runRotation(rotation) {
            var rx_start = THREE.Math.radToDeg(cube.rotation.x);
            var rx_end = THREE.Math.radToDeg(cube.rotation.x);
            var ry_start = THREE.Math.radToDeg(cube.rotation.y);
            var ry_end = THREE.Math.radToDeg(cube.rotation.y);
            var rz_start = THREE.Math.radToDeg(cube.rotation.z);
            var rz_end = THREE.Math.radToDeg(cube.rotation.z);
            inRotatingProcess = true;
 
            switch (rotation) {
                case eRotation.eXAntiClockwise:
                    rx_end = rx_start + 90;
                    break;
                case eRotation.eXClockwise:
                    rx_end = rx_start - 90;
                    break;
                case eRotation.eYAntiClockwise:
                    ry_end = ry_start + 90;
                    break;
                case eRotation.eYClockwise:
                    ry_end = ry_start - 90;
                    break;
                case eRotation.eZAntiClockwise:
                    rz_end = rz_start + 90;
                    break;
                case eRotation.eZClockwise:
                    rz_end = rz_start - 90;
                    break;
            }
 
            tween = new TWEEN.Tween({
                    rx: rx_start,
                    ry: ry_start,
                    rz: rz_start
                })
                .to({
                    rx: rx_end,
                    ry: ry_end,
                    rz: rz_end
                }, 1000)
                .onUpdate(function() {
                    cube.rotation.x = THREE.Math.degToRad(this.rx);
                    cube.rotation.y = THREE.Math.degToRad(this.ry);
                    cube.rotation.z = THREE.Math.degToRad(this.rz);
                })
                .onComplete(function() {
                    inRotatingProcess = false;
                })
                .start();
        }
 
        function aroundXAntiClockwise() {
            if (inRotatingProcess) return;
            runRotation(eRotation.eXAntiClockwise);
        }
 
        function aroundXClockwise() {
            if (inRotatingProcess) return;
            runRotation(eRotation.eXClockwise);
        }
 
        function aroundYAntiClockwise() {
            if (inRotatingProcess) return;
            runRotation(eRotation.eYAntiClockwise);
        }
 
        function aroundYClockwise() {
            if (inRotatingProcess) return;
            runRotation(eRotation.eYClockwise);
        }
 
        function aroundZAntiClockwise() {
            if (inRotatingProcess) return;
            runRotation(eRotation.eZAntiClockwise);
        }
 
        function aroundZClockwise() {
            if (inRotatingProcess) return;
            runRotation(eRotation.eZClockwise);
        }
    </script>
</body>
 
</html>
1
8Observer8
2037 / 1330 / 216
Регистрация: 05.10.2013
Сообщений: 4,219
Записей в блоге: 56
17.04.2018, 21:41 #16
Мой код, из предыщущего сообщения, неправильно работал. В нём вращение происходило вокруг локальный осей кубика, а не вокруг мировых осей. Проблему исправил. Если хотите, можете потестировать демку

PHPHTML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
<!DOCTYPE html>
<html lang="en">
 
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
 
    <title>Rotated Cube</title>
 
    <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/89/three.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/tween.js/16.3.5/Tween.min.js"></script>
 
    <style>
        html,
        body {
            margin: 0;
            background: #efefef;
        }
        
        li {
            margin: 5px 50px;
        }
        
        #x {
            font-size: 2em;
            position: absolute;
            top: 510px;
            width: 100%;
            left: 440px;
            z-index: 100;
            display: block;
        }
        
        #y {
            font-size: 2em;
            position: absolute;
            top: 200px;
            width: 100%;
            left: 255px;
            z-index: 100;
            display: block;
        }
        
        #z {
            font-size: 2em;
            position: absolute;
            top: 510px;
            width: 100%;
            left: 50px;
            z-index: 100;
            display: block;
        }
    </style>
</head>
 
<body>
    <div id="x">x</div>
    <div id="y">y</div>
    <div id="z">z</div>
 
    <ul>
        <li>
            <a href="#" onclick="aroundXAntiClockwise();">Around X, anti-clockwise</a>
        </li>
        <li>
            <a href="#" onclick="aroundXClockwise();">Around X, clockwise</a>
        </li>
        <hr width="300" noshade="" size="1" align="left">
        <li>
            <a href="#" onclick="aroundYAntiClockwise();">Around Y, anti-clockwise</a>
        </li>
        <li>
            <a href="#" onclick="aroundYClockwise();">Around Y, clockwise</a>
        </li>
        <hr width="300" noshade="" size="1" align="left">
        <li>
            <a href="#" onclick="aroundZAntiClockwise();">Around Z, anti-clockwise</a>
        </li>
        <li>
            <a href="#" onclick="aroundZClockwise();">Around Z, clockwise</a>
        </li>
    </ul>
    <script>
        // https://stackoverflow.com/questions/37903979/set-an-objects-absolute-rotation-around-the-world-axis
 
        var xWorldRot = 0,
            yWorldRot = 0,
            zWorldRot = 0;
 
        var prevX = 0,
            prevY = 0,
            prevZ = 0;
 
        var eRotation = Object.freeze({
            eXAntiClockwise: 0,
            eXClockwise: 1,
            eYAntiClockwise: 2,
            eYClockwise: 3,
            eZAntiClockwise: 4,
            eZClockwise: 5
        });
        var scene = new THREE.Scene();
        var canvasWidth = 500;
        var canvasHeight = 500;
        var inRotatingProcess = false;
 
        var renderer = new THREE.WebGLRenderer({
            alpha: true
        });
        renderer.setSize(canvasWidth, canvasHeight);
        document.body.appendChild(renderer.domElement);
 
        var camera = new THREE.PerspectiveCamera(55, canvasWidth / canvasHeight, 0.1, 1000);
        camera.position.set(1.3, 1.3, 1.3);
        camera.lookAt(new THREE.Vector3(0, 0, 0));
 
        var axesHelper = new THREE.AxesHelper(1);
        scene.add(axesHelper);
 
        var geometry = new THREE.BoxGeometry(1, 1, 1);
        // Yellow
        geometry.faces[0].vertexColors[0] = new THREE.Color(0xffff00);
        geometry.faces[0].vertexColors[1] = new THREE.Color(0xffff00);
        geometry.faces[0].vertexColors[2] = new THREE.Color(0xffff00);
        geometry.faces[1].vertexColors[0] = new THREE.Color(0xffff00);
        geometry.faces[1].vertexColors[1] = new THREE.Color(0xffff00);
        geometry.faces[1].vertexColors[2] = new THREE.Color(0xffff00);
        // White 
        geometry.faces[2].vertexColors[0] = new THREE.Color(0xffffff);
        geometry.faces[2].vertexColors[1] = new THREE.Color(0xffffff);
        geometry.faces[2].vertexColors[2] = new THREE.Color(0xffffff);
        geometry.faces[3].vertexColors[0] = new THREE.Color(0xffffff);
        geometry.faces[3].vertexColors[1] = new THREE.Color(0xffffff);
        geometry.faces[3].vertexColors[2] = new THREE.Color(0xffffff);
        // Green
        geometry.faces[4].vertexColors[0] = new THREE.Color(0x008000);
        geometry.faces[4].vertexColors[1] = new THREE.Color(0x008000);
        geometry.faces[4].vertexColors[2] = new THREE.Color(0x008000);
        geometry.faces[5].vertexColors[0] = new THREE.Color(0x008000);
        geometry.faces[5].vertexColors[1] = new THREE.Color(0x008000);
        geometry.faces[5].vertexColors[2] = new THREE.Color(0x008000);
        // Red 
        geometry.faces[6].vertexColors[0] = new THREE.Color(0xff0000);
        geometry.faces[6].vertexColors[1] = new THREE.Color(0xff0000);
        geometry.faces[6].vertexColors[2] = new THREE.Color(0xff0000);
        geometry.faces[7].vertexColors[0] = new THREE.Color(0xff0000);
        geometry.faces[7].vertexColors[1] = new THREE.Color(0xff0000);
        geometry.faces[7].vertexColors[2] = new THREE.Color(0xff0000);
        // Blue
        geometry.faces[8].vertexColors[0] = new THREE.Color(0x0000ff);
        geometry.faces[8].vertexColors[1] = new THREE.Color(0x0000ff);
        geometry.faces[8].vertexColors[2] = new THREE.Color(0x0000ff);
        geometry.faces[9].vertexColors[0] = new THREE.Color(0x0000ff);
        geometry.faces[9].vertexColors[1] = new THREE.Color(0x0000ff);
        geometry.faces[9].vertexColors[2] = new THREE.Color(0x0000ff);
        // Orange
        geometry.faces[10].vertexColors[0] = new THREE.Color(0xffa500);
        geometry.faces[10].vertexColors[1] = new THREE.Color(0xffa500);
        geometry.faces[10].vertexColors[2] = new THREE.Color(0xffa500);
        geometry.faces[11].vertexColors[0] = new THREE.Color(0xffa500);
        geometry.faces[11].vertexColors[1] = new THREE.Color(0xffa500);
        geometry.faces[11].vertexColors[2] = new THREE.Color(0xffa500);
        var material = new THREE.MeshBasicMaterial({
            vertexColors: THREE.VertexColors
        });
        var cube = new THREE.Mesh(geometry, material);
        scene.add(cube);
 
        // var pivotPoint = new THREE.Object3D();
        // scene.add(pivotPoint);
        // pivotPoint.add(cube);
 
        var tween = null;
 
        animate();
 
        function animate() {
            requestAnimationFrame(animate);
 
            if (tween !== undefined) {
                TWEEN.update();
            }
 
            renderer.render(scene, camera);
        };
 
        function runRotation(rotation) {
            rx_start = THREE.Math.radToDeg(prevX);
            ry_start = THREE.Math.radToDeg(prevY);
            rz_start = THREE.Math.radToDeg(prevZ);
            
            inRotatingProcess = true;
 
            switch (rotation) {
                case eRotation.eXAntiClockwise:
                    rx_end = rx_start + 90;
                    ry_end = ry_start;
                    rz_end = rz_start;
                    break;
                case eRotation.eXClockwise:
                    rx_end = rx_start - 90;
                    ry_end = ry_start;
                    rz_end = rz_start;
                    break;
                case eRotation.eYAntiClockwise:
                    rx_end = rx_start;
                    ry_end = ry_start + 90;
                    rz_end = rz_start;
                    break;
                case eRotation.eYClockwise:
                    rx_end = rx_start;
                    ry_end = ry_start - 90;
                    rz_end = rz_start;
                    break;
                case eRotation.eZAntiClockwise:
                    rx_end = rx_start;
                    ry_end = ry_start;
                    rz_end = rz_start + 90;
                    break;
                case eRotation.eZClockwise:
                    rx_end = rx_start;
                    ry_end = ry_start;
                    rz_end = rz_start - 90;
                    break;
            }
 
            tween = new TWEEN.Tween({
                    rx: rx_start,
                    ry: ry_start,
                    rz: rz_start
                })
                .to({
                    rx: rx_end,
                    ry: ry_end,
                    rz: rz_end
                }, 500)
                .onUpdate(function() {
                    doRotation(
                        THREE.Math.degToRad(this.rx),
                        THREE.Math.degToRad(this.ry),
                        THREE.Math.degToRad(this.rz));
                })
                .onComplete(function() {
                    inRotatingProcess = false;
                })
                .start();
        }
 
        function doRotation(x, y, z) {
            var inverse = new THREE.Matrix4().getInverse(cube.matrix);
 
            var rotation = cube.matrix;
            var worldXAxis = new THREE.Vector3(1, 0, 0).applyMatrix4(new THREE.Matrix4().getInverse(rotation));
            var rotationWorldX = new THREE.Matrix4().makeRotationAxis(worldXAxis, x - prevX);
            rotation.multiply(rotationWorldX);
            var worldYAxis = new THREE.Vector3(0, 1, 0).applyMatrix4(new THREE.Matrix4().getInverse(rotation));
            var rotationWorldY = new THREE.Matrix4().makeRotationAxis(worldYAxis, y - prevY);
            rotation.multiply(rotationWorldY);
            var worldZAxis = new THREE.Vector3(0, 0, 1).applyMatrix4(new THREE.Matrix4().getInverse(rotation));
            var rotationWorldZ = new THREE.Matrix4().makeRotationAxis(worldZAxis, z - prevZ);
            rotation.multiply(rotationWorldZ);
 
            prevX = x;
            prevY = y;
            prevZ = z;
 
            cube.matrixAutoUpdate = false;
            cube.matrix = rotation;
        }
 
        function aroundXAntiClockwise() {
            if (inRotatingProcess) return;
            runRotation(eRotation.eXAntiClockwise);
        }
 
        function aroundXClockwise() {
            if (inRotatingProcess) return;
            runRotation(eRotation.eXClockwise);
        }
 
        function aroundYAntiClockwise() {
            if (inRotatingProcess) return;
            runRotation(eRotation.eYAntiClockwise);
        }
 
        function aroundYClockwise() {
            if (inRotatingProcess) return;
            runRotation(eRotation.eYClockwise);
        }
 
        function aroundZAntiClockwise() {
            if (inRotatingProcess) return;
            runRotation(eRotation.eZAntiClockwise);
        }
 
        function aroundZClockwise() {
            if (inRotatingProcess) return;
            runRotation(eRotation.eZClockwise);
        }
    </script>
</body>
 
</html>
1
Бейсик рулит
1 / 1 / 1
Регистрация: 17.03.2016
Сообщений: 82
17.04.2018, 21:47  [ТС] #17
8Observer8, а в чем разница?
0
8Observer8
2037 / 1330 / 216
Регистрация: 05.10.2013
Сообщений: 4,219
Записей в блоге: 56
17.04.2018, 22:01 #18
Цитата Сообщение от Бейсик рулит Посмотреть сообщение
в чем разница?
Ссылка одна и та жа, но если скопировать код, то разница есть. У кубика (и у каждого объекта) есть своя система координат - локальная. А есть глобальная система координат или подругому её называют мировая. Разница между ними в том, что мировая - она одна. У неё оси, которые не повернёшь и не сдвинешь. Локальная система координат вращается и перемещается вместе с кубиком в мировой системе координат. Повернуть кубик вокруг какой-то оси в его локальной системе координат и вокруг оси в мировой системе координат - эффект будет разный. Попробуйте скопировать код из #16 и #17 и сравнить между собой. Только не по ссылке, а именно, код из сообщений.
2
8Observer8
2037 / 1330 / 216
Регистрация: 05.10.2013
Сообщений: 4,219
Записей в блоге: 56
18.04.2018, 12:19 #19
3D объекты иногда (или часто) удобно создавать вручную в бесплатном 3D-редакторе Blender. В нём можно создать дополнительные фейсы, назначить им материалы и цвета, то есть раскрасить объект, как захочется. К тому же можно создать объекты почти любой формы.

Для экспорта объектов из Blender в файл-json, который будет понятен импортёру в Three.js, нужно поставить на Blender плагин io_three, который ставится, как любой другой плагин в Blender.

Загружается объект таким кодом:
Javascript
1
2
3
4
5
6
        var loader = new THREE.JSONLoader();
        loader.load('assets/models/colored_box/colored_box.json',
            function(geometry, materials) {
                var box = new THREE.Mesh(geometry, materials);
                scene.add(box);
            });
Я немного изменил форму кубика, раскрасил его. Назвал его box, так как он уже не похож на обычный кубик. Вращать box можно с помощью мышки. Отредактировать объект (изменить форму и цвет) можно, открыв проект colored_box.blend (colored_box.zip) в Blender'е и экспортировать в json.

>>> Демка в песочнице <<<

Название: colored-box-from-blender.png
Просмотров: 19

Размер: 5.0 Кб

Код из песочницы
PHPHTML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
<!DOCTYPE html>
<html lang="en">
 
<head>
    <meta charset="UTF-8">
 
    <title>Colored box from Blender</title>
 
    <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/89/three.min.js"></script>
    <script src="https://dl.dropboxusercontent.com/s/eiw16qns7365m0w/OrbitControls.js"></script>
 
    <style>
        html,
        body {
            overflow: hidden;
            margin: 0;
        }
        
        canvas {
            width: 100%;
            height: 100%
        }
    </style>
</head>
 
<body>
    <script>
        var scene = new THREE.Scene();
        scene.background = new THREE.Color(0x59c8d4);
        var camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
 
        var renderer = new THREE.WebGLRenderer();
        renderer.setSize(window.innerWidth, window.innerHeight);
        document.body.appendChild(renderer.domElement);
 
        var dirlight = new THREE.DirectionalLight(0xffffff);
        dirlight.position.set(3, 4, 2);
        scene.add(dirlight);
 
        var light = new THREE.HemisphereLight(0xffffbb, 0xffffbb, 0.6);
        scene.add(light);
 
        var groundGeometry = new THREE.PlaneGeometry(20, 20, 20);
        var groundMaterial = new THREE.MeshPhongMaterial({
            color: 0x59d46c,
            side: THREE.DoubleSide
        });
        var ground = new THREE.Mesh(groundGeometry, groundMaterial);
        ground.rotation.x = THREE.Math.degToRad(-90);
        scene.add(ground);
 
        camera.position.set(2, 3, 4);
        var controls = new THREE.OrbitControls(camera);
 
        var loader = new THREE.JSONLoader();
        loader.load('https://dl.dropboxusercontent.com/s/u09km246xihb1db/colored_box.json',
            function(geometry, materials) {
                var box = new THREE.Mesh(geometry, materials);
                box.position.y = 1.01;
                scene.add(box);
            });
 
        window.addEventListener('resize', onWindowResize, false);
        animate();
 
        function animate() {
            requestAnimationFrame(animate);
 
            controls.update();
 
            renderer.render(scene, camera);
        };
 
        function onWindowResize() {
            camera.aspect = window.innerWidth / window.innerHeight;
            camera.updateProjectionMatrix();
 
            renderer.setSize(window.innerWidth, window.innerHeight);
        }
    </script>
</body>
 
</html>
2
8Observer8
2037 / 1330 / 216
Регистрация: 05.10.2013
Сообщений: 4,219
Записей в блоге: 56
18.04.2018, 12:26 #20
Так объект выглядит в Blender'е. Здесь видно, что созданны новые фейсы (один из них выделен), фейсам назначены разные материалы - разных цветов:

Название: colored-box-inside-blender.png
Просмотров: 19

Размер: 9.5 Кб
1
18.04.2018, 12:26
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
18.04.2018, 12:26
Привет! Вот еще темы с решениями:

Динамическое создание объектов JavaScript
Всем здрасьте. Подскажите, пожалуйста, кто может, какое можно придумать...

[ПОМОГИТЕ] Создание объектов на разных страницах
Привет всем. Прошу помощи. Мне нужно, чтобы при нажатии на кнопку, на одной...

Создание динамических объектов HTML+JavaScript
Смена семи цветов текста (красный , оранжевый , желтый , зеленый , голубой ,...

Ошибка при запуске ActiveX: 'Невозможно создание объекта сервером программирования объектов'
ситуация: есть мой ActiveX (написан на Visual Basic 6.0) работающий на...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru