2014-12-17 4 views
9

Я пытаюсь добиться следующего эффекта с помощью CSS3 и JavaScript, когда мы перемещаем мышь к центру DIV (эффект MouseOver)CSS3D формирования матрицы

enter image description here

Я создал небольшую библиотеку, которая принимает 3 аргумента элемент, sourcePoints, пункты назначения и возвращает матрицу css3D и элемент обновления. вот мой код 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

Я вызываю метод TransformElement для каждого из 9 DIV с надлежащим источником и назначения координат. Но он работает не так, как ожидалось. Пожалуйста, предложите возможное решение. можем ли мы сделать это с использованием трёх.js в любом случае (просто вопрос может быть его глупой идеей)?

ОБНОВЛЕНИЕ: Можем ли мы сделать это с помощью рендеринга CSS3D и Three.js.

Идея состоит в том, чтобы создать плоскость и разрезать ее в сетке 3x3 и на каждой мышке над каждой плоскостью плоскости мы можем масштабировать этот div вверх и с уважением, мы должны масштабировать другие div в соответствии с текущим div? Является ли это возможным?

+2

Вы можете загрузить его в JSFiddle или аналогичный для нас, чтобы узнать, как он работает в данный момент? –

+0

@JamesHunt: Я обновил вопрос со ссылкой на скрипку. Пожалуйста, проверьте. – Dramorian

ответ

2

Я не пытался использовать вашу библиотеку, но вот мое решение вашей проблемы: http://codepen.io/bali_balo/pen/87b980a2acf722b1c9feb35f3fcb1c65/ (Я использовал Haml и SCSS, вы можете видеть скомпилированный код, щелкнув маленький глаз в верхнем правом углу каждой панели)

Я использовал this article, чтобы написать этот код.

Вначале вычисляются 9 матриц (соответствующих зависающей плитки и всех окружающих), используя numericjs и fomulas, доступные в предыдущей статье. Затем при наведении мыши эти матрицы применяются к соответствующим фрагментам. Вот код, чтобы получить матрицу, зная расположение 4 точек преобразования до и после преобразования:

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

Обратите внимание, что, как упоминалось в моем коде, если вы хотите анимировать переходы, вы не можете просто использовать CSS (так как он просто переводит каждый номер матрицы, но это редко дает соответствующий результат). Вы можете попробовать сделать это с помощью javascript, но он может быть немного медленным (я не тестировал его), потому что вы не могли кэшировать матрицы и должны были вычислять их в каждом кадре.

+0

Спасибо Бали. Я уже решил это :) http://stackoverflow.com/questions/27604916/mouseover-css3d-effect-with-javascript Я использовал те же статьи, что и ваши. – Dramorian

+0

@ Dramorian О, хорошо, хорошо! –