├── 素材火帮助.txt
├── .idea
├── .name
├── vcs.xml
├── Ge1doot.js超酷3D立体照片墙.iml
├── modules.xml
└── misc.xml
├── imgs
└── o.png
├── js
├── ge1doot.js
└── imageTransform3D.js
└── index.html
/素材火帮助.txt:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/.idea/.name:
--------------------------------------------------------------------------------
1 | Ge1doot.js超酷3D立体照片墙
--------------------------------------------------------------------------------
/imgs/o.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/overmind1980/3d_pic_Using_Ge1doot.js/master/imgs/o.png
--------------------------------------------------------------------------------
/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/Ge1doot.js超酷3D立体照片墙.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/js/ge1doot.js:
--------------------------------------------------------------------------------
1 | ////////////////////////////////////////////////////////////
2 | // ============= micro HTML5 library =====================
3 | // @author Gerard Ferrandez / http://www.dhteumeuleu.com/
4 | // last update: May 27, 2013
5 | // Released under the MIT license
6 | // http://www.dhteumeuleu.com/LICENSE.html
7 | ////////////////////////////////////////////////////////////
8 |
9 | // ===== ge1doot global =====
10 |
11 | var ge1doot = ge1doot || {
12 | json: null,
13 | screen: null,
14 | pointer: null,
15 | camera: null,
16 | loadJS: function (url, callback, data) {
17 | if (typeof url == "string") url = [url];
18 | var load = function (src) {
19 | var script = document.createElement("script");
20 | if (callback) {
21 | if (script.readyState){
22 | script.onreadystatechange = function () {
23 | if (script.readyState == "loaded" || script.readyState == "complete"){
24 | script.onreadystatechange = null;
25 | if (--n === 0) callback(data || false);
26 | }
27 | }
28 | } else {
29 | script.onload = function() {
30 | if (--n === 0) callback(data || false);
31 | }
32 | }
33 | }
34 | script.src = src;
35 | document.getElementsByTagName("head")[0].appendChild(script);
36 | }
37 | for (var i = 0, n = url.length; i < n; i++) load(url[i]);
38 | }
39 | }
40 |
41 | // ===== html/canvas container =====
42 |
43 | ge1doot.Screen = function (setup) {
44 | ge1doot.screen = this;
45 | this.elem = document.getElementById(setup.container) || setup.container;
46 | this.ctx = this.elem.tagName == "CANVAS" ? this.elem.getContext("2d") : false;
47 | this.style = this.elem.style;
48 | this.left = 0;
49 | this.top = 0;
50 | this.width = 0;
51 | this.height = 0;
52 | this.cursor = "default";
53 | this.setup = setup;
54 | this.resize = function () {
55 | var o = this.elem;
56 | this.width = o.offsetWidth;
57 | this.height = o.offsetHeight;
58 | for (this.left = 0, this.top = 0; o != null; o = o.offsetParent) {
59 | this.left += o.offsetLeft;
60 | this.top += o.offsetTop;
61 | }
62 | if (this.ctx) {
63 | this.elem.width = this.width;
64 | this.elem.height = this.height;
65 | }
66 | this.setup.resize && this.setup.resize();
67 | }
68 | this.setCursor = function (type) {
69 | if (type !== this.cursor && 'ontouchstart' in window === false) {
70 | this.cursor = type;
71 | this.style.cursor = type;
72 | }
73 | }
74 | window.addEventListener('resize', function () {
75 | ge1doot.screen.resize();
76 | }, false);
77 | !this.setup.resize && this.resize();
78 | }
79 |
80 | // ==== unified touch events handler ====
81 |
82 | ge1doot.Pointer = function (setup) {
83 | ge1doot.pointer = this;
84 | var self = this;
85 | var body = document.body;
86 | var html = document.documentElement;
87 | this.setup = setup;
88 | this.screen = ge1doot.screen;
89 | this.elem = this.screen.elem;
90 | this.X = 0;
91 | this.Y = 0;
92 | this.Xi = 0;
93 | this.Yi = 0;
94 | this.bXi = 0;
95 | this.bYi = 0;
96 | this.Xr = 0;
97 | this.Yr = 0;
98 | this.startX = 0;
99 | this.startY = 0;
100 | this.scale = 0;
101 | this.wheelDelta = 0;
102 | this.isDraging = false;
103 | this.hasMoved = false;
104 | this.isDown = false;
105 | this.evt = false;
106 | var sX = 0;
107 | var sY = 0;
108 | // prevent default behavior
109 | if (setup.tap) this.elem.onclick = function () { return false; }
110 | if (!setup.documentMove) {
111 | document.ontouchmove = function(e) { e.preventDefault(); }
112 | }
113 | document.addEventListener("MSHoldVisual", function(e) { e.preventDefault(); }, false);
114 | if (typeof this.elem.style.msTouchAction != 'undefined') this.elem.style.msTouchAction = "none";
115 |
116 | this.pointerDown = function (e) {
117 | if (!this.isDown) {
118 | if (this.elem.setCapture) this.elem.setCapture();
119 | this.isDraging = false;
120 | this.hasMoved = false;
121 | this.isDown = true;
122 | this.evt = e;
123 | this.Xr = (e.clientX !== undefined ? e.clientX : e.touches[0].clientX);
124 | this.Yr = (e.clientY !== undefined ? e.clientY : e.touches[0].clientY);
125 | this.X = sX = this.Xr - this.screen.left;
126 | this.Y = sY = this.Yr - this.screen.top + ((html && html.scrollTop) || body.scrollTop);
127 | this.setup.down && this.setup.down(e);
128 | }
129 | }
130 | this.pointerMove = function(e) {
131 | this.Xr = (e.clientX !== undefined ? e.clientX : e.touches[0].clientX);
132 | this.Yr = (e.clientY !== undefined ? e.clientY : e.touches[0].clientY);
133 | this.X = this.Xr - this.screen.left;
134 | this.Y = this.Yr - this.screen.top + ((html && html.scrollTop) || body.scrollTop);
135 | if (this.isDown) {
136 | this.Xi = this.bXi + (this.X - sX);
137 | this.Yi = this.bYi - (this.Y - sY);
138 | }
139 | if (Math.abs(this.X - sX) > 11 || Math.abs(this.Y - sY) > 11) {
140 | this.hasMoved = true;
141 | if (this.isDown) {
142 | if (!this.isDraging) {
143 | this.startX = sX;
144 | this.startY = sY;
145 | this.setup.startDrag && this.setup.startDrag(e);
146 | this.isDraging = true;
147 | } else {
148 | this.setup.drag && this.setup.drag(e);
149 | }
150 | } else {
151 | sX = this.X;
152 | sY = this.Y;
153 | }
154 | }
155 | this.setup.move && this.setup.move(e);
156 | }
157 | this.pointerUp = function(e) {
158 | this.bXi = this.Xi;
159 | this.bYi = this.Yi;
160 | if (!this.hasMoved) {
161 | this.X = sX;
162 | this.Y = sY;
163 | this.setup.tap && this.setup.tap(this.evt);
164 | } else {
165 | this.setup.up && this.setup.up(this.evt);
166 | }
167 | this.isDraging = false;
168 | this.isDown = false;
169 | this.hasMoved = false;
170 | this.setup.up && this.setup.up(this.evt);
171 | if (this.elem.releaseCapture) this.elem.releaseCapture();
172 | this.evt = false;
173 | }
174 | this.pointerCancel = function(e) {
175 | if (this.elem.releaseCapture) this.elem.releaseCapture();
176 | this.isDraging = false;
177 | this.hasMoved = false;
178 | this.isDown = false;
179 | this.bXi = this.Xi;
180 | this.bYi = this.Yi;
181 | sX = 0;
182 | sY = 0;
183 | }
184 | if ('ontouchstart' in window) {
185 | this.elem.ontouchstart = function (e) { self.pointerDown(e); return false; }
186 | this.elem.ontouchmove = function (e) { self.pointerMove(e); return false; }
187 | this.elem.ontouchend = function (e) { self.pointerUp(e); return false; }
188 | this.elem.ontouchcancel = function (e) { self.pointerCancel(e); return false;}
189 | }
190 | document.addEventListener("mousedown", function (e) {
191 | if (
192 | e.target === self.elem ||
193 | (e.target.parentNode && e.target.parentNode === self.elem) ||
194 | (e.target.parentNode.parentNode && e.target.parentNode.parentNode === self.elem)
195 | ) {
196 | if (typeof e.stopPropagation != "undefined") {
197 | e.stopPropagation();
198 | } else {
199 | e.cancelBubble = true;
200 | }
201 | e.preventDefault();
202 | self.pointerDown(e);
203 | }
204 | }, false);
205 | document.addEventListener("mousemove", function (e) { self.pointerMove(e); }, false);
206 | document.addEventListener("mouseup", function (e) {
207 | self.pointerUp(e);
208 | }, false);
209 | document.addEventListener('gesturechange', function(e) {
210 | e.preventDefault();
211 | if (e.scale > 1) self.scale = 0.1; else if (e.scale < 1) self.scale = -0.1; else self.scale = 0;
212 | self.setup.scale && self.setup.scale(e);
213 | return false;
214 | }, false);
215 | if (window.navigator.msPointerEnabled) {
216 | var nContact = 0;
217 | var myGesture = new MSGesture();
218 | myGesture.target = this.elem;
219 | this.elem.addEventListener("MSPointerDown", function(e) {
220 | if (e.pointerType == e.MSPOINTER_TYPE_TOUCH) {
221 | myGesture.addPointer(e.pointerId);
222 | nContact++;
223 | }
224 | }, false);
225 | this.elem.addEventListener("MSPointerOut", function(e) {
226 | if (e.pointerType == e.MSPOINTER_TYPE_TOUCH) {
227 | nContact--;
228 | }
229 | }, false);
230 | this.elem.addEventListener("MSGestureHold", function(e) {
231 | e.preventDefault();
232 | }, false);
233 | this.elem.addEventListener("MSGestureChange", function(e) {
234 | if (nContact > 1) {
235 | if (e.preventDefault) e.preventDefault();
236 | self.scale = e.velocityExpansion;
237 | self.setup.scale && self.setup.scale(e);
238 | }
239 | return false;
240 | }, false);
241 | }
242 | if (window.addEventListener) this.elem.addEventListener('DOMMouseScroll', function(e) {
243 | if (e.preventDefault) e.preventDefault();
244 | self.wheelDelta = e.detail * 10;
245 | self.setup.wheel && self.setup.wheel(e);
246 | return false;
247 | }, false);
248 | this.elem.onmousewheel = function () {
249 | self.wheelDelta = -event.wheelDelta * .25;
250 | self.setup.wheel && self.setup.wheel(event);
251 | return false;
252 | }
253 | }
254 | // ===== request animation frame =====
255 |
256 | window.requestAnimFrame = (function(){
257 | return window.requestAnimationFrame ||
258 | window.webkitRequestAnimationFrame ||
259 | window.mozRequestAnimationFrame ||
260 | window.oRequestAnimationFrame ||
261 | window.msRequestAnimationFrame ||
262 | function( run ){
263 | window.setTimeout(run, 16);
264 | };
265 | })();
266 |
--------------------------------------------------------------------------------
/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Ge1doot.js三维立体相册切换
6 |
7 |
28 |
29 |
30 |
371 |
372 |
373 |
374 |
375 |
376 |
377 |
378 |
379 |
380 |
--------------------------------------------------------------------------------
/js/imageTransform3D.js:
--------------------------------------------------------------------------------
1 | ////////////////////////////////////////////////////////////
2 | // ==== HTML5 CANVAS transform Image ====
3 | // full 3D version
4 | // @author Gerard Ferrandez / http://www.dhteumeuleu.com/
5 | // last update: Dec 8, 2012
6 | // Released under the MIT license
7 | // http://www.dhteumeuleu.com/LICENSE.html
8 | ////////////////////////////////////////////////////////////
9 |
10 | "use strict";
11 |
12 | var ge1doot = ge1doot || {};
13 | ge1doot.transform3D = {};
14 |
15 | /* ==== draw Poly ==== */
16 | ge1doot.transform3D.drawPoly = function () {
17 | this.ctx.beginPath();
18 | this.ctx.moveTo(this.points[0].X, this.points[0].Y);
19 | this.ctx.lineTo(this.points[1].X, this.points[1].Y);
20 | this.ctx.lineTo(this.points[2].X, this.points[2].Y);
21 | this.ctx.lineTo(this.points[3].X, this.points[3].Y);
22 | this.ctx.closePath();
23 | }
24 | /* =============== camera constructor ================= */
25 | ge1doot.transform3D.Camera = function (setup, func) {
26 | ge1doot.camera = this;
27 | this.x = 0;
28 | this.y = 0;
29 | this.z = 0;
30 | this.rx = 0;
31 | this.ry = 0;
32 | this.rz = 0;
33 | this.focalLength = setup.focalLength || 500;
34 | this.easeTranslation = setup.easeTranslation || 0.1;
35 | this.easeRotation = setup.easeRotation || 0.025;
36 | this.enableRx = setup.disableRx ? false : true;
37 | this.enableRy = setup.disableRy ? false : true;
38 | this.enableRz = setup.disableRz ? false : true;
39 | this.cmov = false;
40 | this.cosX = 1;
41 | this.sinX = 0;
42 | this.cosY = 1;
43 | this.sinY = 0;
44 | this.cosZ = 1;
45 | this.sinZ = 0;
46 | this.target = {
47 | over: false,
48 | elem: false,
49 | x: 0,
50 | y: 0,
51 | z: 0,
52 | rx: 0,
53 | ry: 0,
54 | rz: 0
55 | };
56 | // ---- def custom move ----
57 | if (func && func.move) this.cmov = func.move;
58 | }
59 | /* ==== easing ==== */
60 | ge1doot.transform3D.Camera.prototype.ease = function (target, value) {
61 | while (Math.abs(target - value) > Math.PI) {
62 | if (target < value) value -= 2 * Math.PI;
63 | else value += 2 * Math.PI;
64 | }
65 | return (target - value) * this.easeRotation;
66 | }
67 | /* ==== move / rotate camera ==== */
68 | ge1doot.transform3D.Camera.prototype.move = function () {
69 | // ---- run custom function ----
70 | this.cmov && this.cmov();
71 | // ---- translations ----
72 | this.x += (this.target.x - this.x) * this.easeTranslation;
73 | this.y += (this.target.y - this.y) * this.easeTranslation;
74 | this.z += (this.target.z - this.z) * this.easeTranslation;
75 | // ---- rotation rx ----
76 | if (this.enableRx) {
77 | this.rx += this.ease(this.target.rx, this.rx);
78 | this.cosX = Math.cos(this.rx);
79 | this.sinX = Math.sin(this.rx);
80 | }
81 | // ---- rotation ry ----
82 | if (this.enableRy) {
83 | this.ry += this.ease(this.target.ry, this.ry);
84 | this.cosY = Math.cos(this.ry);
85 | this.sinY = Math.sin(this.ry);
86 | }
87 | // ---- rotation rz ----
88 | if (this.enableRz) {
89 | this.rz += this.ease(this.target.rz, this.rz);
90 | this.cosZ = Math.cos(this.rz);
91 | this.sinZ = Math.sin(this.rz);
92 | }
93 | }
94 | /* =============== point constructor ================= */
95 | ge1doot.transform3D.Point = function (x, y, z, tx, ty) {
96 | this.x = x;
97 | this.y = y;
98 | this.z = z;
99 | this.tx = tx || 0;
100 | this.ty = ty || 0;
101 | this.visible = false;
102 | this.scale = 0;
103 | this.X = 0;
104 | this.Y = 0;
105 | this.Z = 0;
106 | this.next = true;
107 | }
108 | /* ==== perspective projection ==== */
109 | ge1doot.transform3D.Point.prototype.projection = function () {
110 | var sw = this.scr.width >> 1;
111 | var sh = this.scr.height >> 1;
112 | // ---- 3D coordinates ----
113 | var nx = this.x - this.camera.x;
114 | var ny = this.y - this.camera.y;
115 | var nz = this.z - this.camera.z;
116 | // ---- 3D rotation and projection ----
117 | if (this.camera.enableRz) {
118 | var u = this.camera.sinZ * ny + this.camera.cosZ * nx;
119 | var t = this.camera.cosZ * ny - this.camera.sinZ * nx;
120 | } else {
121 | var u = nx;
122 | var t = ny;
123 | }
124 | var s = this.camera.cosY * nz + this.camera.sinY * u;
125 | this.Z = this.camera.cosX * s - this.camera.sinX * t;
126 | this.scale = this.camera.focalLength / Math.max(1, this.Z);
127 | this.X = sw + (this.camera.cosY * u - this.camera.sinY * nz) * this.scale;
128 | this.Y = -(this.camera.y >> 1) + sh - (this.camera.sinX * s + this.camera.cosX * t) * this.scale;
129 | // ---- visibility test ----
130 | this.visible = (
131 | this.X > -sw * 0.5 && this.X < sw * 2.5
132 | ) && (
133 | this.Y > -sh * 0.5 && this.Y < sh * 2.5
134 | );
135 | // ----return next (fast loop) ----
136 | return this.next;
137 | }
138 | /* ==== triangle constructor ==== */
139 | ge1doot.transform3D.Triangle = function (parent, p0, p1, p2) {
140 | this.ctx = parent.ctx;
141 | this.texture = parent.texture;
142 | this.p0 = p0;
143 | this.p1 = p1;
144 | this.p2 = p2;
145 | this.d = p0.tx * (p2.ty - p1.ty) - p1.tx * p2.ty + p2.tx * p1.ty + (p1.tx - p2.tx) * p0.ty;
146 | this.pmy = p1.ty - p2.ty;
147 | this.pmx = p1.tx - p2.tx;
148 | this.pxy = p2.tx * p1.ty - p1.tx * p2.ty;
149 | if (parent.t) parent.t.next = true;
150 | }
151 | /* ==== draw triangle ==== */
152 | ge1doot.transform3D.Triangle.prototype.draw = function () {
153 | if (this.p0.visible || this.p1.visible || this.p2.visible) {
154 | var dx, dy, d;
155 | // ---- centroid ----
156 | var xc = (this.p0.X + this.p1.X + this.p2.X) / 3;
157 | var yc = (this.p0.Y + this.p1.Y + this.p2.Y) / 3;
158 | // ---- clipping ----
159 | this.ctx.save();
160 | this.ctx.beginPath();
161 | dx = xc - this.p0.X;
162 | dy = yc - this.p0.Y;
163 | d = Math.max(Math.abs(dx), Math.abs(dy));
164 | this.ctx.moveTo(this.p0.X - 2 * (dx / d), this.p0.Y - 2 * (dy / d));
165 | dx = xc - this.p1.X;
166 | dy = yc - this.p1.Y;
167 | d = Math.max(Math.abs(dx), Math.abs(dy));
168 | this.ctx.lineTo(this.p1.X - 2 * (dx / d), this.p1.Y - 2 * (dy / d));
169 | dx = xc - this.p2.X;
170 | dy = yc - this.p2.Y;
171 | d = Math.max(Math.abs(dx), Math.abs(dy));
172 | this.ctx.lineTo(this.p2.X - 2 * (dx / d), this.p2.Y - 2 * (dy / d));
173 | this.ctx.closePath();
174 | this.ctx.clip();
175 | // ---- transform ----
176 | var t0 = this.p2.X - this.p1.X,
177 | t1 = this.p1.Y - this.p2.Y,
178 | t2 = this.p2.ty * this.p1.X,
179 | t3 = this.p1.tx * this.p2.X,
180 | t4 = this.p2.ty * this.p1.Y,
181 | t5 = this.p1.ty * this.p2.X,
182 | t6 = this.p1.ty * this.p2.Y,
183 | t7 = this.p2.tx * this.p1.X,
184 | t8 = this.p1.tx * this.p2.Y,
185 | t9 = this.p2.tx * this.p1.Y;
186 | this.ctx.transform(
187 | -(this.p0.ty * t0 - t5 + t2 + this.pmy * this.p0.X) / this.d, // m11
188 | (t6 + this.p0.ty * t1 - t4 - this.pmy * this.p0.Y) / this.d, // m12
189 | (this.p0.tx * t0 - t3 + t7 + this.pmx * this.p0.X) / this.d, // m21
190 | -(t8 + this.p0.tx * t1 - t9 - this.pmx * this.p0.Y) / this.d, // m22
191 | (this.p0.tx * (t2 - t5) + this.p0.ty * (t3 - t7) + this.pxy * this.p0.X) / this.d, // dx
192 | (this.p0.tx * (t4 - t6) + this.p0.ty * (t8 - t9) + this.pxy * this.p0.Y) / this.d // dy
193 | );
194 | // ---- draw ----
195 | this.ctx.drawImage(this.texture, 0, 0);
196 | this.ctx.restore();
197 | }
198 | return this.next;
199 | }
200 | /* ===================== image constructor ========================== */
201 | ge1doot.transform3D.Image = function (parent, imgSrc, lev, callback) {
202 | this.parent = parent;
203 | this.points = [];
204 | this.triangles = [];
205 | this.ctx = ge1doot.screen.ctx;
206 | this.pointer = ge1doot.pointer;
207 | this.texture = new Image();
208 | this.texture.src = imgSrc;
209 | this.isLoading = true;
210 | this.callback = callback;
211 | this.textureWidth = 0;
212 | this.textureHeight = 0;
213 | this.level = lev || 1;
214 | this.visible = false;
215 | this.t = false;
216 | if (!ge1doot.transform3D.Point.prototype.scr) {
217 | ge1doot.transform3D.Point.prototype.scr = ge1doot.screen;
218 | ge1doot.transform3D.Point.prototype.camera = ge1doot.camera;
219 | }
220 | }
221 | /* ==== drawPoly prototype ==== */
222 | ge1doot.transform3D.Image.prototype.drawPoly = ge1doot.transform3D.drawPoly;
223 | /* ==== change tessellation level prototype ==== */
224 | ge1doot.transform3D.Image.prototype.setLevel = function (level) {
225 | this.points.length = 0;
226 | this.triangles.length = 0;
227 | this.level = level;
228 | this.loading();
229 | }
230 | /* ==== loading prototype ==== */
231 | ge1doot.transform3D.Image.prototype.loading = function () {
232 | if (this.texture.complete) {
233 | var dir = [0,1,1,0,0,0,1,1];
234 | this.isLoading = false;
235 | // ---- image size ----
236 | this.textureWidth = this.texture.width;
237 | this.textureHeight = this.texture.height;
238 | // ---- isLoaded callback ---
239 | this.callback && this.callback.isLoaded && this.callback.isLoaded(this);
240 | // ---- texture position ----
241 | for (var i = -1, p; p = this.points[++i];) {
242 | p.tx = this.textureWidth * dir[i];
243 | p.ty = this.textureHeight * dir[i+4];
244 | }
245 | // ---- triangularization ----
246 | this.triangulate(this.points[0], this.points[1], this.points[2], this.level);
247 | this.triangulate(this.points[0], this.points[2], this.points[3], this.level);
248 | // ---- last point ----
249 | this.points[this.points.length - 1].next = false;
250 | }
251 | }
252 | /* ==== vector bisection function ==== */
253 | ge1doot.transform3D.Image.prototype.subdivise = function (p0, p1) {
254 | return {
255 | x: (p1.x + p0.x) * 0.5,
256 | y: (p1.y + p0.y) * 0.5,
257 | z: (p1.z + p0.z) * 0.5,
258 | tx: (p1.tx + p0.tx) * 0.5,
259 | ty: (p1.ty + p0.ty) * 0.5
260 | };
261 | }
262 | /* ==== triangulation ==== */
263 | ge1doot.transform3D.Image.prototype.triangulate = function (p0, p1, p2, level) {
264 | level--;
265 | if (level === 0) {
266 | // final triangle
267 | this.t = new ge1doot.transform3D.Triangle(this, p0, p1, p2);
268 | this.triangles.push(this.t);
269 | } else {
270 | // ---- subdivision ----
271 | var p01 = this.subdivise(p0, p1);
272 | var p12 = this.subdivise(p1, p2);
273 | var p20 = this.subdivise(p2, p0);
274 | // ---- insert new points ----
275 | this.points.push(p01 = new ge1doot.transform3D.Point(p01.x, p01.y, p01.z, p01.tx, p01.ty));
276 | this.points.push(p12 = new ge1doot.transform3D.Point(p12.x, p12.y, p12.z, p12.tx, p12.ty));
277 | this.points.push(p20 = new ge1doot.transform3D.Point(p20.x, p20.y, p20.z, p20.tx, p20.ty));
278 | // ---- recursive triangulation ----
279 | this.triangulate(p0, p01, p20, level);
280 | this.triangulate(p01, p1, p12, level);
281 | this.triangulate(p20, p12, p2, level);
282 | this.triangulate(p01, p12, p20, level);
283 | }
284 | }
285 | /* ==== transform prototype ==== */
286 | ge1doot.transform3D.Image.prototype.transform3D = function (backfaceTest) {
287 | if (this.isLoading) {
288 | // ---- image is loading ----
289 | this.loading();
290 | return false;
291 | } else {
292 | // ---- project points ----
293 | for (
294 | var i = 0;
295 | this.points[i++].projection();
296 | );
297 | if (backfaceTest) {
298 | var p0 = this.points[0];
299 | var p1 = this.points[1];
300 | var p2 = this.points[2];
301 | return (
302 | ((p1.Y - p0.Y) / (p1.X - p0.X) -
303 | (p2.Y - p0.Y) / (p2.X - p0.X) < 0) ^
304 | (p0.X <= p1.X == p0.X > p2.X)
305 | );
306 | } else return true;
307 | }
308 | }
309 | /* ==== draw prototype ==== */
310 | ge1doot.transform3D.Image.prototype.draw = function () {
311 | if (!this.isLoading) {
312 | // ---- draw triangles ----
313 | for (
314 | var i = 0;
315 | this.triangles[i++].draw();
316 | );
317 | }
318 | }
319 | /* ==== isPointerInside prototype ==== */
320 | ge1doot.transform3D.Image.prototype.isPointerInside = function (x, y) {
321 | this.drawPoly(this.points);
322 | return this.ctx.isPointInPath(x, y);
323 | }
--------------------------------------------------------------------------------