以下代码中的my moveMask函数对于具有类.layout-box
的每个HTML元素称为x次。
我很难想到一种重写代码的方法,以便每次调用事件监听器时它只运行一次函数。
我知道这可能不是一个简单的解决办法,但如果我能够了解我需要进入的方向,那么我真的很感激。
// Store SVG container element as variable
var layoutBox = document.querySelectorAll(".layout-box"),
xPos = 0,
yPos = 0,
elOver = true,
clicked = false,
rect,
coords,
split = document.querySelectorAll('.words h2, .words h3, .words p, .words li');
// GSAP tweens/functions that require access to coordinates
function moveMask(valueX, valueY) {
[].slice.call(layoutBox).forEach(function(el, i) {
console.log("test");
var img = el.querySelectorAll('.img');
// Mask move animation
var tlMove = new TimelineMax({
paused: true
});
tlMove.set(img, {
webkitClipPath: '40px at ' + valueX + 'px ' + valueY + 'px'
});
el.animationMaskMove = tlMove;
// Mask click animation
var tlClick = tlLeave = new TimelineMax({
paused: true
});
tlClick.to(img, 0.8, {
webkitClipPath: '500px at ' + valueX + 'px ' + valueY + 'px',
});
tlClick.to(img, 0.4, {
'-webkit-filter': 'grayscale(0%)',
filter: 'grayscale(0%)'
}, '-=0.8');
el.animationMaskClick = tlClick;
tlClick.progress(1).progress(0); // Forces an initial render of this tween so that it's cached for its 2nd usage
// Mask leave animation
var tlLeave = new TimelineMax({
paused: true
});
tlLeave.to(img, 0.2, {
webkitClipPath: '0 at ' + valueX + 'px ' + valueY + 'px',
'-webkit-filter': 'grayscale(100%)',
filter: 'grayscale(100%)'
});
el.animationMaskLeave = tlLeave;
tlLeave.progress(1).progress(0);
// Mask slow leave animation
var tlLeaveSlow = new TimelineMax({
paused: true
});
tlLeaveSlow.to(img, 0.6, {
ease: Bounce.easeOut,
webkitClipPath: '0 at ' + valueX + 'px ' + valueY + 'px',
'-webkit-filter': 'grayscale(100%)',
filter: 'grayscale(100%)'
});
el.animationMaskSlowLeave = tlLeaveSlow;
tlLeaveSlow.progress(1).progress(0);
});
}
// Force initial run with temporary coordinates (so tweens can be cached)
moveMask(-100, -100);
// GSAP tweens/functions that don't access to coordinates
[].slice.call(layoutBox).forEach(function(el, i) {
console.log("test2");
var svgContainer = el.querySelectorAll('.svg-container');
var svgContainerLeft = el.querySelectorAll('.left');
var svgContainerBottom = el.querySelectorAll('.bottom');
var img = el.querySelectorAll('.img');
var mask = el.querySelectorAll('.mask');
var text = el.querySelectorAll('.text');
var elSplit = el.querySelectorAll('.words');
// Container 3d push effect
var tlContainer3d = new TimelineMax({
paused: true
});
tlContainer3d.to(svgContainer, 0.3, {
x: "-=6px",
y: "+=6px"
});
el.animationContainer3d = tlContainer3d;
tlContainer3d.progress(1).progress(0);
// Container 3d push effect left
var tlContainer3dLeft = new TimelineMax({
paused: true
});
tlContainer3dLeft.to(svgContainerLeft, 0.3, {
width: "4px"
});
el.animationContainer3dLeft = tlContainer3dLeft;
tlContainer3dLeft.progress(1).progress(0);
// Container 3d push effect bottom
var tlContainer3dBottom = new TimelineMax({
paused: true
});
tlContainer3dBottom.to(svgContainerBottom, 0.3, {
height: "4px",
right: "+=6px"
});
el.animationContainer3dBottom = tlContainer3dBottom;
tlContainer3dBottom.progress(1).progress(0);
// Img move animation
var tlImgMove = new TimelineMax({
paused: true
});
tlImgMove.to(img, 0.3, {
scale: 1,
ease: Sine.easeOut,
'-webkit-filter': 'grayscale(0%)',
filter: 'grayscale(0%)'
}, 0.05);
el.animationImgMove = tlImgMove;
tlImgMove.progress(1).progress(0);
// Mask click text animation
var tlText = new TimelineMax({
paused: true
})
tlText.to(elSplit, .3, {
autoAlpha: 0
});
el.animationTextClick = tlText;
tlText.progress(1).progress(0);
});
// Loop through boxes and assign event listeners
for (var x = 0; x < layoutBox.length; x++) {
layoutBox[x].addEventListener("mousemove", function(e) {
if (elOver) { // Only run if mousedown hasn't been triggered
// Get coordinates of container
rect = this.getBoundingClientRect();
xPos = e.pageX - rect.left;
yPos = e.pageY - rect.top - window.scrollY;
// Add coordinates to array and pass in to moveMask function
coords = [xPos, yPos];
moveMask.apply(null, coords);
this.animationMaskMove.play();
}
});
layoutBox[x].addEventListener("mousedown", function(e) {
this.animationContainer3d.play();
this.animationContainer3dLeft.play();
this.animationContainer3dBottom.play();
this.animationMaskClick.play();
this.animationTextClick.play();
clicked = true;
elOver = false;
});
layoutBox[x].addEventListener("mouseleave", function(e) {
this.animationContainer3d.reverse();
this.animationContainer3dLeft.reverse();
this.animationContainer3dBottom.reverse();
this.animationTextClick.timeScale(1.25).reverse();
// If clicked then run slow animation
if (clicked) {
this.animationMaskSlowLeave.play();
} else {
this.animationMaskLeave.play();
}
clicked = false;
elOver = true;
});
}
编辑:
// Store SVG container element as variable
var layoutBox = document.querySelectorAll(".layout-box"),
elOver = true,
clicked = false,
xPos = 0,
yPos = 0,
rect,
coords;
// GSAP tweens/functions that require access to coordinates
function moveMask(el, valueX, valueY) {
console.log("test");
var img = el.querySelectorAll('.img');
// Mask move animation
var tlMove = new TimelineMax({
paused: true
});
tlMove.set(img, {
webkitClipPath: '40px at ' + valueX + 'px ' + valueY + 'px'
});
el.animationMaskMove = tlMove;
// Mask click animation
var tlClick = tlLeave = new TimelineMax({
paused: true
});
tlClick.to(img, 0.8, {
webkitClipPath: '500px at ' + valueX + 'px ' + valueY + 'px',
});
tlClick.to(img, 0.4, {
'-webkit-filter': 'grayscale(0%)',
filter: 'grayscale(0%)'
}, '-=0.8');
el.animationMaskClick = tlClick;
tlClick.progress(1).progress(0); // Forces an initial render of this tween so that it's cached for its 2nd usage
// Mask leave animation
var tlLeave = new TimelineMax({
paused: true
});
tlLeave.to(img, 0.2, {
webkitClipPath: '0 at ' + valueX + 'px ' + valueY + 'px',
'-webkit-filter': 'grayscale(100%)',
filter: 'grayscale(100%)'
});
el.animationMaskLeave = tlLeave;
tlLeave.progress(1).progress(0);
// Mask slow leave animation
var tlLeaveSlow = new TimelineMax({
paused: true
});
tlLeaveSlow.to(img, 0.6, {
ease: Bounce.easeOut,
webkitClipPath: '0 at ' + valueX + 'px ' + valueY + 'px',
'-webkit-filter': 'grayscale(100%)',
filter: 'grayscale(100%)'
});
el.animationMaskSlowLeave = tlLeaveSlow;
tlLeaveSlow.progress(1).progress(0);
}
// Force initial run with temporary coordinates (so tweens can be cached)
[].forEach.call(layoutBox, function(el, i) { moveMask(el, -100, -100) });
// GSAP tweens/functions that don't access to coordinates
[].forEach.call(layoutBox, function(el, i) {
console.log("test2");
var svgContainer = el.querySelectorAll('.svg-container');
var svgContainerLeft = el.querySelectorAll('.left');
var svgContainerBottom = el.querySelectorAll('.bottom');
var img = el.querySelectorAll('.img');
var mask = el.querySelectorAll('.mask');
var text = el.querySelectorAll('.text');
var elSplit = el.querySelectorAll('.words');
// Container 3d push effect
var tlContainer3d = new TimelineMax({
paused: true
});
tlContainer3d.to(svgContainer, 0.3, {
x: "-=6px",
y: "+=6px"
});
el.animationContainer3d = tlContainer3d;
tlContainer3d.progress(1).progress(0);
// Container 3d push effect left
var tlContainer3dLeft = new TimelineMax({
paused: true
});
tlContainer3dLeft.to(svgContainerLeft, 0.3, {
width: "4px"
});
el.animationContainer3dLeft = tlContainer3dLeft;
tlContainer3dLeft.progress(1).progress(0);
// Container 3d push effect bottom
var tlContainer3dBottom = new TimelineMax({
paused: true
});
tlContainer3dBottom.to(svgContainerBottom, 0.3, {
height: "4px",
right: "+=6px"
});
el.animationContainer3dBottom = tlContainer3dBottom;
tlContainer3dBottom.progress(1).progress(0);
// Img move animation
var tlImgMove = new TimelineMax({
paused: true
});
tlImgMove.to(img, 0.3, {
scale: 1,
ease: Sine.easeOut,
'-webkit-filter': 'grayscale(0%)',
filter: 'grayscale(0%)'
}, 0.05);
el.animationImgMove = tlImgMove;
tlImgMove.progress(1).progress(0);
// Mask click text animation
var tlText = new TimelineMax({
paused: true
})
tlText.to(elSplit, .3, {
autoAlpha: 0
});
el.animationTextClick = tlText;
tlText.progress(1).progress(0);
});
// Event listener functions
function myMouseMove(e) {
if (elOver) { // Only run if mousedown hasn't been triggered
// Get coordinates of container
rect = this.getBoundingClientRect();
xPos = e.pageX - rect.left;
yPos = e.pageY - rect.top - window.scrollY;
// Add coordinates to array and pass in to moveMask function
coords = [xPos, yPos];
moveMask.call(null, coords);
this.animationMaskMove.play();
}
}
function myMouseDown(e) {
this.animationContainer3d.play();
this.animationContainer3dLeft.play();
this.animationContainer3dBottom.play();
this.animationMaskClick.play();
this.animationTextClick.play();
clicked = true;
elOver = false;
};
function myMouseLeave(e) {
this.animationContainer3d.reverse();
this.animationContainer3dLeft.reverse();
this.animationContainer3dBottom.reverse();
this.animationTextClick.timeScale(1.25).reverse();
// If clicked then run slow animation
if (clicked) {
this.animationMaskSlowLeave.play();
} else {
this.animationMaskLeave.play();
}
clicked = false;
elOver = true;
};
// Loop through boxes and assign event listener
for (var x = 0; x < layoutBox.length; x++) {
layoutBox[x].addEventListener("mousemove", myMouseMove);
//layoutBox[x].addEventListener("mousedown", this, myMouseDown);
//layoutBox[x].addEventListener("mouseleave", this, myMouseLeave);
};