MouseOver CSS3D эффект с помощью JavaScript
Я пытаюсь добиться эффекта MouseOver, как это.
Я могу сгенерировать матрицу css3d, необходимую для каждой плитки в соответствии с их положением.
Я достиг этого эффекта медленным движением мыши, но если я быстро перемещаюсь от одной плитки к другой, она не обновляется должным образом. это показывает разрыв между плитками. Каков наилучший способ обновить все координаты плиток / плиток при наведении курсора, чтобы получить постоянный эффект?
Вот мой код JS:
$('.box').each(function() {
$(this).css('height', '284px');
$(this).css('width', '284px');
});
generateGrid = function(w, h) {
var t = this;
this.p = [];
var d = 30;
var c = Math.floor($('.w').outerWidth() / 284 + 1);
var r = Math.ceil($('.w').outerHeight() / 284) + 1;
var vc = c * r;
for (i = 0; i < vc; i++) {
var l = {
x: Math.floor(i % c) * 284,
y: Math.floor(i / c) * 284
};
this.p.push(l);
}
var m = m || {};
m.Grid = function() {
this.elms = [];
this.init();
}, m.Grid.prototype = {
init: function() {
this.createTiles();
},
animateTile: function() {
var e = this;
for (i = 0; i < e.elms.length; i++) {
console.log(i);
e.elms[i].update();
}
requestAnimationFrame($.proxy(this.animateTile, this));
},
createTiles: function() {
var c = this;
for (i = 0; i < $('.box').length; i++) {
c.elms.push(new m.tile($('.box:eq(' + i + ')'), i));
}
c.animateTile();
}
}, m.tile = function(e, i, pt) {
this.el = e;
this.i = i;
var p = t.p;
this.elX = Math.floor(i % 4) * 284,
this.elY = Math.floor(i / 4) * 284,
this.p1 = p[i + Math.floor(i / 4)],
this.p2 = p[i + Math.floor(i / 4) + 1],
this.p3 = p[i + Math.floor(i / 4) + 6]
this.p4 = p[i + Math.floor(i / 4) + 5];
this.init();
}, m.tile.prototype = {
init: function() {
this.initEvents();
},
initEvents: function() {
var e = this;
var pts = t.p;
var p1 = pts[e.i + Math.floor(i / 4)],
p2 = pts[e.i + Math.floor(i / 4) + 1],
p3 = pts[e.i + Math.floor(i / 4) + 6],
p4 = pts[e.i + Math.floor(i / 4) + 5];
$(e.el).hover(function() {
TweenMax.killTweensOf(p1),
TweenMax.killTweensOf(p2),
TweenMax.killTweensOf(p3),
TweenMax.killTweensOf(p4),
TweenMax.to(p1, .3, {
x: p1.x - d,
y: p1.y - d,
ease: Back.easeOut
}),
TweenMax.to(p2, .3, {
x: p2.x + d,
y: p2.y - d,
ease: Back.easeOut
}),
TweenMax.to(p3, .3, {
x: p3.x + d,
y: p3.y + d,
ease: Back.easeOut
}),
TweenMax.to(p4, .3, {
x: p4.x - d,
y: p4.y + d,
ease: Back.easeOut
}),
TweenMax.to(e.el, .3, {
zIndex: 10,
ease: Back.easeOut
});
}, function() {
TweenMax.killTweensOf(p1),
TweenMax.killTweensOf(p2),
TweenMax.killTweensOf(p3),
TweenMax.killTweensOf(p4);
TweenMax.to(p1, .7, {
x: p1.x + d,
y: p1.y + d,
ease: Back.easeOut
}),
TweenMax.to(p2, .7, {
x: p2.x - d,
y: p2.y + d,
ease: Back.easeOut
}),
TweenMax.to(p3, .7, {
x: p3.x - d,
y: p3.y - d,
ease: Back.easeOut
}),
TweenMax.to(p4, .7, {
x: p4.x + d,
y: p4.y - d,
ease: Back.easeOut
}),
TweenMax.to(e.el, .7, {
zIndex: 0,
ease: Back.easeOut
});
});
},
update: function() {
var e = this;
var pts = t.p;
var p1 = pts[e.i + Math.floor(i / 4)],
p2 = pts[e.i + Math.floor(i / 4) + 1],
p3 = pts[e.i + Math.floor(i / 4) + 6],
p4 = pts[e.i + Math.floor(i / 4) + 5];
BLEND.TransformElement(
{
el: e.el[0],
src: [{x: 0, y: 0}, {x: w, y: 0}, {x: w, y: h}, {x: 0, y: h}],
dest: [
{x: p1.x - e.elX,
y: p1.y - e.elY},
{x: p2.x - e.elX,
y: p2.y - e.elY},
{x: p3.x - e.elX,
y: p3.y - e.elY},
{x: p4.x - e.elX,
y: p4.y - e.elY},
]
});
}
};
t.grid = new m.Grid();
};
generateGrid(284, 284);
BLEND.TransformElement (el, src, dest) в моем коде дает матрицу CSS3D, она работает нормально. Мне нужно обновить вершины правильно.
Вот мой HTML и CSS:
<style>
.box{
float: left;
background: #2b5349;
transform-origin: 0px 0px;
}
</style>
<div class="w" style=" margin-bottom:190px;display:inline-block;width: calc(284px * 4); margin:100px auto;">
<div class="box" style="background: red"></div>
<div class="box" style="background: #2b5349"></div>
<div class="box" style="background: green"></div>
<div class="box" style="background: blue"></div>
<div class="box" style="background: darkgoldenrod"></div>
<div class="box" style="background: fuchsia"></div>
<div class="box" style="background: lightpink"></div>
<div class="box" style="background: mediumspringgreen"></div>
<div class="box" style="background: burlywood"></div>
<div class="box" style="background: orange"></div>
<div class="box" style="background: gold"></div>
<div class="box" ></div>
</div>
Я делаю все это с самого начала без использования какого-либо внешнего плагина для этого конкретного эффекта. Пожалуйста, предложите какое-нибудь решение.
Я сохранил все вершины всех плиток и обновил их при наведении курсора. как только я наведу курсор мыши с одной плитки на другую, анимация сброса значений вершин с новой на исходную останавливается. Как я могу исправить проблему с обновлением вершин в mouseenter и mouseleave envent.
2 ответа
Я решил проблему. Проблема заключалась в том, что при обновлении мыши не обновлялось значение вершин до исходного. чтобы вернуть значение вершин в исходный вопрос, я должен сохранить дополнительное значение вершин, как это.
var l = {
x: Math.floor(i % c) * 284,
y: Math.floor(i / c) * 284,
x2: Math.floor(i % c) * 284,
y2: Math.floor(i / c) * 284,
};
При наведении курсора измените значение вершины следующим образом для каждой координаты.
TweenMax.to(p1, .3, {
x: p1.x2 + d,
y: p1.y2 - d,
ease: Back.easeOut
})
и при наведении мыши сбросить исходное положение
TweenMax.to(p2, .3, {
x: p2.x,
y: p2.y,
ease: Back.easeOut
})
У вас это работает для гибкого количества столбцов. В настоящее время это работает только на 4!