Created
March 13, 2017 06:32
-
-
Save joeynimu/ac5d68097b1b51db063236ed2f79fb55 to your computer and use it in GitHub Desktop.
A Mousy module; moves element on mouse move.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var MousyModule = function () { | |
function MousyModule(opt) { | |
classCallCheck(this, MousyModule); | |
opt = opt || {}; | |
this.name = 'mousy'; | |
this.rotation = opt.rotation || 10.0; | |
this.parallax = { | |
enabled: true, | |
distance: 10, | |
scale: 1.1 | |
}; | |
} | |
createClass(MousyModule, [{ | |
key: 'run', | |
value: function run() { | |
$(document).ready(this.attach.bind(this)); | |
} | |
}, { | |
key: 'attach', | |
value: function attach() { | |
var _this = this; | |
if (window.ismobile) return; | |
this.$elements = $('.mousy'); | |
this.$elements.mouseenter(function (e) { | |
return _this.enters(e); | |
}); | |
this.$elements.mousemove(function (e) { | |
return _this.moved(e); | |
}); // faster than bind? maybe | |
this.$elements.mouseleave(function (e) { | |
return _this.exit(e); | |
}); // faster than bind? maybe | |
this.$elements.each(function (i, el) { | |
el.mousy = { | |
state: { | |
norm: { x: 0, y: 0 }, // normal vector, axis to rotate on | |
degree: 1 // how much should we rotate, based on distance to mid point => mid point equals zero degree | |
}, | |
over: false, // check current mouse state | |
manipulatee: $(el).children('.mousy-target').get(0), // to be manipulated | |
animations: new AnimationStack(), // enter and exit animations | |
parallax: $(el).find('.mousy-parallax').toArray() | |
}; | |
for (var i = 0; i < el.mousy.parallax.length; i++) { | |
$(el.mousy.parallax[i]).css('transform', 'scale(' + _this.parallax.scale + ')'); | |
} | |
}); | |
} | |
}, { | |
key: 'enters', | |
value: function enters(e) { | |
var _this2 = this; | |
var target = e.currentTarget, | |
mousy = target.mousy; | |
if (mousy.over || !window.hasfocus) // mouse is already over element | |
return; | |
mousy.animations.terminateAll(); // stop all running animations | |
mousy.over = true; | |
this.updateNormal(e); | |
animateByInterpolation(mousy.manipulatee, 600, { | |
easing: Easing.cubicBezier(0.175, 0.885, 0.32, 1.275), | |
tags: ['enter'], | |
interpolate: function interpolate(x) { | |
_this2.rotate(mousy, x); // el contains normX and normY | |
} | |
}).addToStack(mousy.animations).go(); | |
} | |
// event handler: mouseleave | |
}, { | |
key: 'exit', | |
value: function exit(e) { | |
var _this3 = this; | |
var target = e.currentTarget, | |
mousy = target.mousy; | |
if (!mousy.over || !window.hasfocus) return; | |
mousy.animations.terminateAll(); // stop all running animations | |
mousy.over = false; | |
animateByInterpolation(mousy.manipulatee, 600, { | |
easing: Easing.cubicBezier(0.175, 0.885, 0.32, 1.275), | |
tags: ['exit'], | |
interpolate: function interpolate(x) { | |
_this3.rotate(mousy, 1.0 - x); | |
} | |
}).addToStack(mousy.animations).go(); | |
} | |
// event handler: mousemove | |
}, { | |
key: 'moved', | |
value: function moved(e) { | |
var target = e.currentTarget, | |
mousy = target.mousy; | |
if (!window.hasfocus || !mousy.over) return; | |
this.updateNormal(e); | |
if (mousy.animations.length < 1) { | |
this.rotate(mousy, 1.0); | |
} | |
} | |
}, { | |
key: 'updateNormal', | |
value: function updateNormal(e) { | |
var target = e.currentTarget, | |
mousy = target.mousy, | |
state = mousy.state; | |
var parentOffset = $(target).parent().offset(); | |
var parentWidth = $(target).parent().outerWidth(); | |
var parentHeight = $(target).parent().outerHeight(); | |
var relX = e.pageX - parentOffset.left; | |
var relY = e.pageY - parentOffset.top; | |
var X = Math.max(Math.min(2 * relX / parentWidth - 1.0, 1.0), -1.0); | |
var Y = Math.max(Math.min(2 * relY / parentHeight - 1.0, 1.0), -1.0); | |
state.norm.x = -Y; // calc normal vector, on which to rotate on | |
state.norm.y = X; | |
state.degree = Math.sqrt(X * X + Y * Y); | |
} | |
// helper: sets to transform of norm.normX and norm.normY and sets rotation to 10deg * ratio | |
}, { | |
key: 'rotate', | |
value: function rotate(m) { | |
var ratio = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 1.0; | |
// set manipulatee transform | |
m.manipulatee.style.transform = 'perspective(1500px) rotate3d(' + m.state.norm.x + ',' + m.state.norm.y + ', 0, ' + this.rotation * m.state.degree * ratio + 'deg)'; | |
// translate parralax items | |
for (var i = 0, dist = this.parallax.distance, scale = this.parallax.scale; i < m.parallax.length && this.parallax.enabled; i++) { | |
m.parallax[i].style.transform = 'translate3d(' + ratio * dist * -m.state.norm.y + 'px, ' + ratio * dist * m.state.norm.x + 'px, 0px) scale(' + scale + ')'; | |
} | |
} | |
}]); | |
return MousyModule; | |
}(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment