|
<!DOCTYPE html> |
|
<html> |
|
<head> |
|
<meta charset="utf-8"> |
|
<title></title> |
|
<style> |
|
/*.scene {perspective:250;} |
|
.scene, .camera {width:100vw; height:100vh;}*/ |
|
/*.camera, .camera * {transform-style:preserve-3d;}*/ |
|
.camera { |
|
/*transform:rotateX(20deg) scale(1.1); background:rgba(255,255,255,.5);*/ |
|
} |
|
|
|
div { |
|
display: inline-block; |
|
background: rgba(255,0,0,.5); |
|
width: 100px;height:50px; |
|
box-shadow: 0 0 0 1px pink inset; |
|
} |
|
|
|
#a { |
|
position:relative; margin-left:50px;margin-top:100px; |
|
transform:translate(200px, 150px) rotate(-10deg) translateZ(50px); transform-origin:center; |
|
} |
|
#b { |
|
margin-left:100px; |
|
transform:translate(100px, 50px) rotate(-10deg) translateZ(50px) rotateX(-20deg); transform-origin:center; |
|
} |
|
#c { |
|
/*transform:translateY(100px);*/ |
|
} |
|
#d { |
|
margin-top:10px; |
|
} |
|
#e { |
|
transform:translateY(100px); |
|
} |
|
#f { |
|
position:absolute;left:100px;top:100px; |
|
transform:translate(-50px, 50px) rotate(5deg); transform-origin:right top; |
|
} |
|
#g { |
|
position:fixed;left:100px;top:50px; |
|
transform:scale(2) translate(-60px, 30px) rotate(20deg); transform-origin:right top; |
|
} |
|
</style> |
|
</head> |
|
<body style="margin:0;"> |
|
<!--<div class="scene"><div class="camera">--> |
|
<div id="a"> |
|
relative;A;(50,100);t(200,150)r(10)tz(50);center |
|
<div id="b"> |
|
static;B;(100,50);t(100,50)r(-10)tz(50)rx(-20);center |
|
<div id="c"> |
|
static;C;(0,0);;center |
|
<div id="d"> |
|
static;D;(0,0);;center |
|
<div id="e"> |
|
static;E;(0,0);;center |
|
<div id="f"> |
|
absolute;F;(100,100);t(-50,50)r(5);right top |
|
<div id="g"> |
|
fixed;G(100,50);s(2)t(-60,30)r(20);right top |
|
</div> |
|
</div> |
|
</div> |
|
</div> |
|
</div> |
|
</div> |
|
</div> |
|
<!--</div></div>--> |
|
|
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.7.0/underscore.js"></script> |
|
<script src="https://code.jquery.com/jquery-2.1.3.js"></script> |
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r70/three.js"></script> |
|
<script src="domvertices.js"></script> |
|
<script> |
|
function trace(v) { |
|
for (k in v) { // |
|
$('<b>').css({ |
|
display:'block',width:'0px',height:'0px', boxShadow:'0 0 0 3px lime', |
|
position:'absolute',left:'0px',top:'0px', transform:'translate3d(' + v[k].x + 'px,' + v[k].y + 'px, ' + v[k].z + 'px)' |
|
}).appendTo('body'); // !important so <b> is subjected to perspective |
|
} |
|
} |
|
|
|
function normalizeMatrix (matrixString) { |
|
var c = matrixString.split(/\s*[(),]\s*/).slice(1,-1); |
|
var matrix; |
|
|
|
if (c.length === 6) { |
|
// 'matrix()' (3x2) |
|
matrix = new THREE.Matrix4().set( |
|
c[0], +c[2], 0, +c[4], |
|
+c[1], +c[3], 0, +c[5], |
|
0, 0, 1, 0, |
|
0, 0, 0, 1 |
|
); |
|
} else if (c.length === 16) { |
|
// matrix3d() (4x4) |
|
matrix = new THREE.Matrix4().set( |
|
+c[0], +c[4], +c[8], +c[12], |
|
+c[1], +c[5], +c[9], +c[13], |
|
+c[2], +c[6], +c[10], +c[14], |
|
+c[3], +c[7], +c[11], +c[15] |
|
); |
|
} else { |
|
// handle 'none' or invalid values. |
|
matrix = new THREE.Matrix4().identity(); |
|
} |
|
|
|
return matrix; |
|
} |
|
|
|
function m(el, o) { |
|
var computedStyle = getComputedStyle(el, null); |
|
var transformOrigin = computedStyle.transformOrigin.split(' ').map(function (el) {return parseFloat(el, 10);}); |
|
|
|
var P01 = new THREE.Matrix4().makeTranslation(o.offset[0], o.offset[1], 0); |
|
var P12 = new THREE.Matrix4().makeTranslation(transformOrigin[0], transformOrigin[1], 0); |
|
var P23 = normalizeMatrix(computedStyle.transform); |
|
var P21 = new THREE.Matrix4().getInverse(P12); |
|
|
|
var P03 = new THREE.Matrix4().identity() |
|
.multiply(P01) // (1): translate position |
|
.multiply(P12) // (2): translate transform-origin |
|
.multiply(P23) // (3): transform |
|
.multiply(P21) // (4): inverse of (2) |
|
; |
|
|
|
return P03; |
|
} |
|
|
|
function v(el) { |
|
var w = el.offsetWidth; |
|
var h = el.offsetHeight; |
|
var v = { |
|
a: new THREE.Vector3().set(0, 0, 0), // top left corner |
|
b: new THREE.Vector3().set(w, 0, 0), // top right corner |
|
c: new THREE.Vector3().set(w, h, 0), // bottom right corner |
|
d: new THREE.Vector3().set(0, h, 0) // bottom left corner |
|
}; |
|
|
|
return v; |
|
} |
|
|
|
// a |
|
|
|
var a = document.querySelector('#a'); |
|
var ma = m(a, { |
|
offset: [50, 100] |
|
}); |
|
var va = v(a); |
|
//trace(va); |
|
|
|
/*va.a = va.a.applyMatrix4(ma); |
|
va.b = va.b.applyMatrix4(ma); |
|
va.c = va.c.applyMatrix4(ma); |
|
va.d = va.d.applyMatrix4(ma); |
|
trace(va);*/ |
|
|
|
// b |
|
|
|
var b = document.querySelector('#b'); |
|
var mb = m(b, { |
|
offset: [100, 32] |
|
}); |
|
var vb = v(b); |
|
//trace(vb); |
|
|
|
/*vb.a = vb.a.applyMatrix4(mb); |
|
vb.b = vb.b.applyMatrix4(mb); |
|
vb.c = vb.c.applyMatrix4(mb); |
|
vb.d = vb.d.applyMatrix4(mb); |
|
trace(vb); |
|
|
|
vb.a = vb.a.applyMatrix4(ma); |
|
vb.b = vb.b.applyMatrix4(ma); |
|
vb.c = vb.c.applyMatrix4(ma); |
|
vb.d = vb.d.applyMatrix4(ma); |
|
trace(vb);*/ |
|
|
|
// c |
|
|
|
var c = document.querySelector('#c'); |
|
var mc = m(c, { |
|
offset: [0, 32] |
|
}); |
|
var vc = v(c); |
|
|
|
/*vc.a = vc.a.applyMatrix4(mc); |
|
vc.b = vc.b.applyMatrix4(mc); |
|
vc.c = vc.c.applyMatrix4(mc); |
|
vc.d = vc.d.applyMatrix4(mc); |
|
trace(vc); |
|
|
|
vc.a = vc.a.applyMatrix4(mb); |
|
vc.b = vc.b.applyMatrix4(mb); |
|
vc.c = vc.c.applyMatrix4(mb); |
|
vc.d = vc.d.applyMatrix4(mb); |
|
trace(vc); |
|
|
|
vc.a = vc.a.applyMatrix4(ma); |
|
vc.b = vc.b.applyMatrix4(ma); |
|
vc.c = vc.c.applyMatrix4(ma); |
|
vc.d = vc.d.applyMatrix4(ma); |
|
trace(vc);*/ |
|
|
|
// d |
|
|
|
var d = document.querySelector('#d'); |
|
var md = m(d, { |
|
offset: [0, 42] |
|
}); |
|
var vd = v(d); |
|
|
|
/*vd.a = vd.a.applyMatrix4(md); |
|
vd.b = vd.b.applyMatrix4(md); |
|
vd.c = vd.c.applyMatrix4(md); |
|
vd.d = vd.d.applyMatrix4(md); |
|
trace(vd); |
|
|
|
vd.a = vd.a.applyMatrix4(mc); |
|
vd.b = vd.b.applyMatrix4(mc); |
|
vd.c = vd.c.applyMatrix4(mc); |
|
vd.d = vd.d.applyMatrix4(mc); |
|
trace(vd); |
|
|
|
vd.a = vd.a.applyMatrix4(mb); |
|
vd.b = vd.b.applyMatrix4(mb); |
|
vd.c = vd.c.applyMatrix4(mb); |
|
vd.d = vd.d.applyMatrix4(mb); |
|
trace(vd); |
|
|
|
vd.a = vd.a.applyMatrix4(ma); |
|
vd.b = vd.b.applyMatrix4(ma); |
|
vd.c = vd.c.applyMatrix4(ma); |
|
vd.d = vd.d.applyMatrix4(ma); |
|
trace(vd);*/ |
|
|
|
// e |
|
|
|
var e = document.querySelector('#e'); |
|
var me = m(e, { |
|
offset: [0, 32] |
|
}); |
|
var ve = v(e); |
|
|
|
/*ve.a = ve.a.applyMatrix4(me); |
|
ve.b = ve.b.applyMatrix4(me); |
|
ve.c = ve.c.applyMatrix4(me); |
|
ve.d = ve.d.applyMatrix4(me); |
|
trace(ve); |
|
|
|
ve.a = ve.a.applyMatrix4(md); |
|
ve.b = ve.b.applyMatrix4(md); |
|
ve.c = ve.c.applyMatrix4(md); |
|
ve.d = ve.d.applyMatrix4(md); |
|
trace(ve); |
|
|
|
ve.a = ve.a.applyMatrix4(mc); |
|
ve.b = ve.b.applyMatrix4(mc); |
|
ve.c = ve.c.applyMatrix4(mc); |
|
ve.d = ve.d.applyMatrix4(mc); |
|
trace(ve); |
|
|
|
ve.a = ve.a.applyMatrix4(mb); |
|
ve.b = ve.b.applyMatrix4(mb); |
|
ve.c = ve.c.applyMatrix4(mb); |
|
ve.d = ve.d.applyMatrix4(mb); |
|
trace(ve); |
|
|
|
ve.a = ve.a.applyMatrix4(ma); |
|
ve.b = ve.b.applyMatrix4(ma); |
|
ve.c = ve.c.applyMatrix4(ma); |
|
ve.d = ve.d.applyMatrix4(ma); |
|
trace(ve);*/ |
|
|
|
// f |
|
|
|
var f = document.querySelector('#f'); |
|
var mf = m(f, { |
|
offset: [100, 100] |
|
}); |
|
var vf = v(f); |
|
|
|
/*vf.a = vf.a.applyMatrix4(mf); |
|
vf.b = vf.b.applyMatrix4(mf); |
|
vf.c = vf.c.applyMatrix4(mf); |
|
vf.d = vf.d.applyMatrix4(mf); |
|
trace(vf); |
|
|
|
vf.a = vf.a.applyMatrix4(me); |
|
vf.b = vf.b.applyMatrix4(me); |
|
vf.c = vf.c.applyMatrix4(me); |
|
vf.d = vf.d.applyMatrix4(me); |
|
trace(vf); |
|
|
|
vf.a = vf.a.applyMatrix4(md); |
|
vf.b = vf.b.applyMatrix4(md); |
|
vf.c = vf.c.applyMatrix4(md); |
|
vf.d = vf.d.applyMatrix4(md); |
|
trace(vf); |
|
|
|
vf.a = vf.a.applyMatrix4(mc); |
|
vf.b = vf.b.applyMatrix4(mc); |
|
vf.c = vf.c.applyMatrix4(mc); |
|
vf.d = vf.d.applyMatrix4(mc); |
|
trace(vf); |
|
|
|
vf.a = vf.a.applyMatrix4(mb); |
|
vf.b = vf.b.applyMatrix4(mb); |
|
vf.c = vf.c.applyMatrix4(mb); |
|
vf.d = vf.d.applyMatrix4(mb); |
|
trace(vf); |
|
|
|
vf.a = vf.a.applyMatrix4(ma); |
|
vf.b = vf.b.applyMatrix4(ma); |
|
vf.c = vf.c.applyMatrix4(ma); |
|
vf.d = vf.d.applyMatrix4(ma); |
|
trace(vf);*/ |
|
|
|
// g |
|
|
|
var g = document.querySelector('#g'); |
|
var mg = m(g, { |
|
offset: [100, 50] |
|
}); |
|
var vg = v(g); |
|
|
|
vg.a = vg.a.applyMatrix4(mg); |
|
vg.b = vg.b.applyMatrix4(mg); |
|
vg.c = vg.c.applyMatrix4(mg); |
|
vg.d = vg.d.applyMatrix4(mg); |
|
trace(vg); |
|
|
|
vg.a = vg.a.applyMatrix4(mf); |
|
vg.b = vg.b.applyMatrix4(mf); |
|
vg.c = vg.c.applyMatrix4(mf); |
|
vg.d = vg.d.applyMatrix4(mf); |
|
trace(vg); |
|
|
|
vg.a = vg.a.applyMatrix4(me); |
|
vg.b = vg.b.applyMatrix4(me); |
|
vg.c = vg.c.applyMatrix4(me); |
|
vg.d = vg.d.applyMatrix4(me); |
|
trace(vg); |
|
|
|
vg.a = vg.a.applyMatrix4(md); |
|
vg.b = vg.b.applyMatrix4(md); |
|
vg.c = vg.c.applyMatrix4(md); |
|
vg.d = vg.d.applyMatrix4(md); |
|
trace(vg); |
|
|
|
vg.a = vg.a.applyMatrix4(mc); |
|
vg.b = vg.b.applyMatrix4(mc); |
|
vg.c = vg.c.applyMatrix4(mc); |
|
vg.d = vg.d.applyMatrix4(mc); |
|
trace(vg); |
|
|
|
vg.a = vg.a.applyMatrix4(mb); |
|
vg.b = vg.b.applyMatrix4(mb); |
|
vg.c = vg.c.applyMatrix4(mb); |
|
vg.d = vg.d.applyMatrix4(mb); |
|
trace(vg); |
|
|
|
vg.a = vg.a.applyMatrix4(ma); |
|
vg.b = vg.b.applyMatrix4(ma); |
|
vg.c = vg.c.applyMatrix4(ma); |
|
vg.d = vg.d.applyMatrix4(ma); |
|
trace(vg); |
|
|
|
|
|
</script> |
|
</body> |
|
</html> |
read later: https://stackoverflow.com/questions/28518722/apply-perspective-matrix-order