geração de matriz CSS3D

9

Estou tentando alcançar o efeito a seguir usando css3 e javascript quando movemos o mouse para o centro div (efeito MouseOver)

Eucrieiumapequenabibliotecaqueaceita3elementosdeargumentos,sourcePoints,pontosdedestinoeretornaamatrizcss3Deoelementodeatualização.aquiestáomeucódigojavascript.

varBLEND=BLEND||{};BLEND.Util=BLEND.Util||{};functionprint(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)";
 } 
}

ATUALIZAÇÃO: Aqui está o JSFiddle

Estou chamando o método TransformElement para cada um dos 9 div com as coordenadas de origem e destino apropriadas. Mas não está funcionando como esperado. Por favor, sugira a possível solução. podemos fazê-lo usando three.js de qualquer maneira (apenas perguntar pode ser a sua ideia boba)?

ATUALIZAÇÃO: Podemos fazer isso com o renderizador CSS3D e o Three.js.

A idéia é criar plano e fatiá-lo em grade 3x3 e ao passar o mouse sobre cada face do plano podemos dimensionar essa parte superior da div e respeitosamente temos que dimensionar outras div de acordo com a div atual? É possível?

    
por Dramorian 17.12.2014 в 12:50
fonte

1 resposta

2

Eu não tentei usar sua biblioteca, mas esta é a minha solução para o seu problema: link (usei Haml e SCSS, você pode ver o código compilado clicando no pequeno olho no canto superior direito de cada painel)

Eu usei este artigo para escrever este código.

9 matrizes são computadas primeiro (correspondendo ao bloco pairado e a todas as adjacências), usando numericjs e fórmulas disponíveis no artigo vinculado antes. Então, ao passar o mouse, essas matrizes são aplicadas aos blocos correspondentes. Aqui está o código para obter a matriz de transformação conhecendo os locais de 4 pontos antes e depois da transformação:

//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  ]];
}

Note que, como mencionado no meu código, se você deseja animar as transições, você não pode simplesmente usar CSS (já que isso apenas faria a transição de cada número da matriz, mas isso raramente daria um resultado apropriado). Você poderia tentar fazê-lo usando javascript, mas pode ser um pouco lento (eu não testei), porque você não poderia armazenar em cache matrizes e teria que computá-las em cada frame.

    
por Bali Balo 30.12.2014 / 00:31
fonte