2014-12-17 6 views
9

sto cercando di raggiungere seguente effetto utilizzando CSS3 e JavaScript quando si passa il mouse per centrare div (effetto MouseOver)CSS3D generazione matrice

enter image description here

ho creato piccola biblioteca che accetta elemento 3 argomenti, sourcePoints, punti di destinazione e restituisce matrice css3D e elemento di aggiornamento. ecco il mio codice javascript.

var BLEND = BLEND || {}; 

BLEND.Util = BLEND.Util || {}; 

function print(msg) { 
    console.log(msg); 
} 
BLEND.Util.VendorPrefix = ""; 
BLEND.Util.DetectVendorPrefix = function() { 
var styles = window.getComputedStyle(document.documentElement, ''), 
     pre = (Array.prototype.slice.call(styles).join('').match(/-(moz|webkit|ms)-/) || (styles.OLink === '' && ['', 'o']))[1]; 
BLEND.Util.VendorPrefix = pre[0].toUpperCase() + pre.substr(1) + "Transform"; 
} 
BLEND.Util.DetectVendorPrefix(); 
BLEND.TransformElement = function(elm, src, dest) { 
var L = [[0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0], 
    [0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0], 
    [0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0], 
    [0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0]]; 
var R = [0, 0, 0, 0, 0, 0, 0, 0]; 

for (var i = 0; i < 4; i++) { 
    L[i] = []; 
    L[i][0] = L[i + 4][3] = src[i].x; 
    L[i][2] = L[i + 4][4] = src[i].y; 
    L[i][2] = L[i + 4][5] = 1; 
    L[i][3] = L[i][4] = L[i][5] = L[i + 4][0] = L[i + 4][3] = L[i + 4][2] = 0; 
    L[i][6] = -src[i].x * dest[i].x; 
    L[i][7] = -src[i].y * dest[i].x; 
    L[i + 4][6] = -src[i].x * dest[i].y; 
    L[i + 4][7] = -src[i].y * dest[i].y; 

    R[i] = dest[i].x; 
    R[i + 4] = dest[i].y; 
} 


var RM = []; 
for (i = 0; i < R.length; i++) { 
    RM[i] = [R[i]]; 
} 

var Left = Matrix.create(L); 
var Right = Matrix.create(R); 

var res = Matrix.calculate(Left, Right); 

print (res); 

if (BLEND.Util.VendorPrefix == 'WebkitTransform') { 

var matrix3D = new CSSMatrix(); 
matrix3D.m11 = res.get(0,0); 
matrix3D.m12 = res.get(3,0); 
matrix3D.m13 = 0; 
matrix3D.m14 = res.get(6,0); 

matrix3D.m21 = res.get(1,0); 
matrix3D.m22 = res.get(4,0); 
matrix3D.m23 = 0; 
matrix3D.m24 = res.get(7,0); 

matrix3D.m31 = 0; 
matrix3D.m32 = 0; 
matrix3D.m33 = 1; 
matrix3D.m34 = 0; 

matrix3D.m41 = res.get(2,0); 
matrix3D.m42 = res.get(5,0); 
matrix3D.m43 = 0; 
matrix3D.m44 = 1; 

elm.style.webkitTransform = matrix3D; 
} else { 
if (BLEND.Util.VendorPrefix === "") 
BLEND.Util.DetectVendorPrefix(); 
elm.style[BLEND.Util.VendorPrefix] = "matrix3d(" + res.get(0,0) + "," + res.get(3,0) + ", 0," + res.get(6,0) + "," + res.get(1,0) + "," + res.get(4,0) + ", 0," + res.get(7,0) + ",0, 0, 1, 0," + res.get(2,0) + "," + res.get(5,0) + ", 0, 1)"; 
} 
} 

UPDATE:Here is JSFiddle

Chiedo metodo TransformElement per ciascuno dei 9 div con una corretta origine e destinazione coordinate. Ma non funziona come previsto. Si prega di suggerire la possibile soluzione. possiamo farlo usando tre.js in ogni caso (solo chiedendo potrebbe essere la sua idea sciocca)?

UPDATE: Possiamo farlo con il renderer CSS3D e Three.js.

L'idea è di creare un piano e tagliarlo in una griglia 3x3 e con il mouse su ogni faccia del piano possiamo scalare quel div in alto e in modo rispettoso dobbiamo ridimensionare gli altri div in base al div attuale? È possibile?

+2

Sei in grado di caricarlo su JSFiddle o equivalente per noi per vedere come funziona attualmente? –

+0

@JamesHunt: Ho aggiornato la domanda con il collegamento di violino. Si prega di controllare. – Dramorian

risposta

2

Non ho provato a utilizzare la libreria ma questa è la soluzione al problema: http://codepen.io/bali_balo/pen/87b980a2acf722b1c9feb35f3fcb1c65/ (Ho usato Haml e SCSS, puoi vedere il codice compilato facendo clic sul piccolo occhio nell'angolo in alto a destra di ciascun pannello)

Ho usato this article per scrivere questo codice.

9 le matrici vengono calcolate per prime (corrispondenti alla tessera posizionata e a quelle circostanti), utilizzando numericjs e fomule disponibili nell'articolo collegato in precedenza. Quindi al passaggio del mouse queste matrici vengono applicate alle tessere corrispondenti. Ecco il codice per ottenere la matrice di conoscere le posizioni dei 4 punti trasformano prima e dopo la trasformazione:

//from and to are arrays of 4 objects containing a property x and a property y 
//describing the 4 points of the quadrilateral to transform 
function getTransform(from, to) 
{ 
    var A = [], i; 
    for(i = 0; i < 4; i++) 
    { 
     A.push([from[i].x, from[i].y, 1, 0, 0, 0, -from[i].x * to[i].x, -from[i].y * to[i].x]); 
     A.push([0, 0, 0, from[i].x, from[i].y, 1, -from[i].x * to[i].y, -from[i].y * to[i].y]); 
    } 
    var b = []; 
    for(i = 0; i < 4; i++) 
    { 
     b.push(to[i].x); 
     b.push(to[i].y); 
    } 
    //Uses numericjs to solve matrices equations 
    //returns h knowing A and b where A.h = b 
    var h = numeric.solve(A, b); 
    //Column major representation 
    return [[h[0], h[3], 0, h[6]], 
      [h[1], h[4], 0, h[7]], 
      [ 0 , 0 , 1, 0 ], 
      [h[2], h[5], 0, 1 ]]; 
} 

Si noti che, come menzionate nelle mio codice, se si desidera animare le transizioni, non si può semplicemente usare i CSS (come sarebbe solo la transizione di ciascun numero della matrice, ma questo raramente darebbe un risultato appropriato). Potresti provare a farlo usando javascript, ma potrebbe essere un po 'lento (non l'ho testato), perché non puoi memorizzare le matrici nella cache e dovresti calcolarle a ogni frame.

+0

Grazie Bali. L'ho già risolto :) http://stackoverflow.com/questions/27604916/mouseover-css3d-effect-with-javascript Ho usato gli stessi articoli dei tuoi. – Dramorian

+0

@Dramorian Oh ok, bello! –