(function () { function Vector3() { this.x = 0; this.y = 0; this.z = 0; } Vector3.prototype.set = function (x, y, z) { this.x = x; this.y = y; this.z = z; return this; } Vector3.prototype.applyMatrix4 = function (m) { // See: https://github.com/mrdoob/three.js/blob/r92/src/math/Vector3.js#L278 var x = this.x; var y = this.y; var z = this.z; var w = 1 / ( m.m14 * x + m.m24 * y + m.m34 * z + m.m44 ); this.x = ( m.m11 * x + m.m21 * y + m.m31 * z + m.m41 ) * w; this.y = ( m.m12 * x + m.m22 * y + m.m32 * z + m.m42 ) * w; this.z = ( m.m13 * x + m.m23 * y + m.m33 * z + m.m43 ) * w; return this; } var CSSMatrix = window.CSSMatrix || window.WebKitCSSMatrix || window.MozCSSMatrix || window.MSCSSMatrix; function relAbsOrFixedPositionnedAncestor(el) { /*var parent = el.parentNode; var parentComputedStyle; while (parent && parent.nodeType === 1) { // walk up parentComputedStyle = getComputedStyle(parent, null); if (parentComputedStyle.position === 'relative' || parentComputedStyle.position === 'absolute' || parentComputedStyle.position === 'fixed') { break; // stop } parent = parent.parentNode; } if (parent === document) return document.body; // html is the last element before document return parent;*/ return el.offsetParent; } function domvertices(el, options) { options || (options = {}); options.root || (options.root = document.body.parentNode) // element by default // // a b //  +--------------+ //  | | //  | el | //  | | //  +--------------+ // d c // var w = el.offsetWidth; var h = el.offsetHeight; var v = { a: new Vector3().set(0, 0, 0), // top left corner b: new Vector3().set(w, 0, 0), // top right corner c: new Vector3().set(w, h, 0), // bottom right corner d: new Vector3().set(0, h, 0) // bottom left corner }; // // Walk the DOM up, and extract // var matrices = []; while (el.nodeType === 1 && el !== options.root) {(function () { var nextParent = el.parentNode; var computedStyle = getComputedStyle(el, null); // // P(0->1) : relative position (to parent) // var P01; (function () { var offsetLeft = el.offsetLeft; var offsetTop = el.offsetTop; var position = computedStyle.position; if (position === 'absolute' || position === 'fixed') { // nothing } else if (position === 'static' || position === 'relative') { var closestPositionedParent = relAbsOrFixedPositionnedAncestor(el); if (closestPositionedParent === el.parentNode) { // nothing } else { var parent = el.parentNode; if (parent && parent.nodeType === 1) { offsetLeft -= parent.offsetLeft; offsetTop -= parent.offsetTop; } } } //console.log(offsetLeft, offsetTop); x = offsetLeft + el.clientLeft; y = offsetTop + el.clientTop; if (el !== document.body) { x -= el.scrollLeft; y -= el.scrollTop; } P01 = new CSSMatrix().translate(x, y, 0); }).call(this); // // P(1->2) : transform-origin // var P12; (function () { var transformOrigin = computedStyle.transformOrigin || computedStyle.webkitTransformOrigin || computedStyle.MozTransformOrigin || computedStyle.msTransformOrigin; transformOrigin = transformOrigin.split(' '); var x = parseFloat(transformOrigin[0], 10); var y = parseFloat(transformOrigin[1], 10); P12 = new CSSMatrix().translate(x, y, 0); }).call(this); // // P(2->3) : transform // var P23; (function () { var transform = computedStyle.transform || computedStyle.webkitTransform || computedStyle.MozTransform || computedStyle.msTransform; P23 = new CSSMatrix(transform); }).call(this); // // P(0->3) = P(0->1) . P(1->2) . P(2->3) // var P21 = P12.inverse(); var P03 = new CSSMatrix(); P03 = P03.multiply(P01); // (1): translate position P03 = P03.multiply(P12); // (2): translate transform-origin P03 = P03.multiply(P23); // (3): transform P03 = P03.multiply(P21); // (4): inverse of (2) matrices.push(P03); el = nextParent; }())} // // Compute the global matrix (reverse order) // var globalMatrix = new CSSMatrix(); var l = matrices.length; while (l--) { globalMatrix = globalMatrix.multiply(matrices[l]); } v.matrix = globalMatrix; // save the global matrix to v v.a = v.a.applyMatrix4(globalMatrix); v.b = v.b.applyMatrix4(globalMatrix); v.c = v.c.applyMatrix4(globalMatrix); v.d = v.d.applyMatrix4(globalMatrix); return v; } // Exports this.domvertices = domvertices; if (typeof module !== "undefined" && module !== null) { module.exports = this.domvertices; } }).call(this);