mirror of
https://github.com/Lastorder-DC/rhymix.git
synced 2026-01-04 01:01:41 +09:00
126 lines
No EOL
4.3 KiB
JavaScript
126 lines
No EOL
4.3 KiB
JavaScript
/*
|
|
* Parallax-Scroll - v0.2.0
|
|
* jQuery plugin for background-attachment: scroll with friction, similar to the parallax scrolling effect on Spotify.
|
|
* http://parallax-scroll.aenism.com
|
|
*
|
|
* Made by Aen Tan
|
|
* Under MIT License
|
|
*/
|
|
;(function (root, factory) {
|
|
if (typeof define === "function" && define.amd) {
|
|
// AMD. Register as an anonymous module.
|
|
define(["jquery"], factory);
|
|
} else {
|
|
// Browser globals
|
|
factory(root.jQuery);
|
|
}
|
|
}(this, function ($) {
|
|
"use strict";
|
|
|
|
var ParallaxScroll,
|
|
defaults = {
|
|
friction: 0.5,
|
|
direction: "vertical"
|
|
},
|
|
$win = $(window),
|
|
lastTickTime = 0;
|
|
|
|
window.requestAnimationFrame = function (callback) {
|
|
var currTime = new Date().getTime();
|
|
var timeToCall = Math.max(0, 5 - (currTime - lastTickTime));
|
|
var id = window.setTimeout(function () {
|
|
callback(currTime + timeToCall);
|
|
}, timeToCall);
|
|
lastTickTime = currTime + timeToCall;
|
|
return id;
|
|
};
|
|
|
|
ParallaxScroll = function (background, options) {
|
|
return {
|
|
init: function () {
|
|
this.$background = $(background);
|
|
this.settings = $.extend({}, defaults, options);
|
|
this._initStyles();
|
|
this._bindEvents();
|
|
},
|
|
_initStyles: function () {
|
|
this.$background.css({
|
|
"background-attachment": "scroll"
|
|
});
|
|
},
|
|
_visibleInViewport: function () {
|
|
var vpHeight = $win.height();
|
|
var rec = this.$background.get(0).getBoundingClientRect();
|
|
return (rec.top < vpHeight && rec.bottom > 0) || (rec.bottom <= vpHeight && rec.top > vpHeight);
|
|
},
|
|
_bindEvents: function () {
|
|
var self = this;
|
|
$win.on("load scroll resize", function () {
|
|
self._requestTick();
|
|
});
|
|
},
|
|
_requestTick: function () {
|
|
var self = this;
|
|
if (!this.ticking) {
|
|
this.ticking = true;
|
|
requestAnimationFrame(function () {
|
|
self._updateBgPos();
|
|
});
|
|
}
|
|
},
|
|
_updateBgPos: function () {
|
|
if (this._visibleInViewport()) {
|
|
var winW = $win.width();
|
|
var winH = $win.height();
|
|
var imgW = this.$background.data("width");
|
|
var imgH = this.$background.data("height");
|
|
var imgA = imgW / imgH;
|
|
var bgW = this.$background.width();
|
|
var bgH = this.$background.height();
|
|
var bgA = bgW / bgH;
|
|
var revA = bgA < imgA;
|
|
var bgScale = bgW / imgW;
|
|
var bgScaledH = imgH * bgScale;
|
|
var bgScaledW = imgW * bgScale;
|
|
var bgOffsetTop = this.$background.offset().top;
|
|
var winScrollTop = $win.scrollTop();
|
|
var bgScrollTop = winScrollTop - bgOffsetTop;
|
|
var xDistToMove = winH + bgScaledH;
|
|
var yDistToMove = winW + bgScaledW;
|
|
var xf1 = bgScrollTop * (winH / xDistToMove);
|
|
var xf2 = bgScrollTop / winH;
|
|
var yf1 = bgScrollTop * (winW / yDistToMove);
|
|
var yf2 = bgScrollTop / winW;
|
|
var centerOffsetY = (winH - bgH) / 2;
|
|
centerOffsetY = revA ? centerOffsetY * xf2 : centerOffsetY;
|
|
var centerOffsetX = (winW - bgW) / 2;
|
|
centerOffsetX = revA ? centerOffsetX : centerOffsetX * yf2;
|
|
var bgFriction = revA? this.settings.friction * (bgA * 2) : this.settings.friction * bgA;
|
|
var bgSize;
|
|
var bgPos;
|
|
if (this.settings.direction === "horizontal") {
|
|
bgSize = revA ? winW + "px auto" : "auto " + winH + "px";
|
|
bgPos = (centerOffsetX - (yf1 * bgFriction)) + "px 50%";
|
|
} else {
|
|
bgSize = revA ? "auto " + winH + "px" : winW + "px auto";
|
|
bgPos = "50% " + ((xf1 * bgFriction) - centerOffsetY) + "px";
|
|
}
|
|
this.$background.css({
|
|
"background-size": bgSize,
|
|
"background-position": bgPos
|
|
});
|
|
}
|
|
this.ticking = false;
|
|
}
|
|
};
|
|
};
|
|
|
|
ParallaxScroll.defaults = defaults;
|
|
$.fn.parallaxScroll = function (options) {
|
|
return this.each(function () {
|
|
new ParallaxScroll(this, options).init();
|
|
});
|
|
};
|
|
|
|
return ParallaxScroll;
|
|
})); |