| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195 |
- define(function(require, exports, module) {
- "use strict";
- var Util = require('../util');
- var Animate = require('../animate');
- var MAX_BOUNCE_DISTANCE = 40;
- var MIN_BAR_SCROLLED_SIZE = 10;
- var MIN_BAR_SIZE = 50;
- var transform = Util.prefixStyle("transform");
- var transformStr = Util.vendor ? ["-", Util.vendor, "-transform"].join("") : "transform";
- var transition = Util.prefixStyle("transition");
- var borderRadius = Util.prefixStyle("borderRadius");
- var transitionDuration = Util.prefixStyle("transitionDuration");
- var ScrollBar = function(cfg) {
- this.userConfig = Util.mix({
- MIN_BAR_SCROLLED_SIZE:MIN_BAR_SCROLLED_SIZE,
- MIN_BAR_SIZE:MIN_BAR_SIZE,
- MAX_BOUNCE_DISTANCE:MAX_BOUNCE_DISTANCE,
- spacing:5
- }, cfg);
- this.init(cfg.xscroll);
- }
- Util.mix(ScrollBar.prototype, {
- init: function(xscroll) {
- var self = this;
- self.xscroll = xscroll;
- self.type = self.userConfig.type;
- self.isY = self.type == "y" ? true : false;
- self.scrollTopOrLeft = self.isY ? "scrollTop" : "scrollLeft";
- },
- destroy: function() {
- var self = this;
- Util.remove(self.scrollbar);
- self.xscroll.off("scroll", self._scrollHandler, self);
- self.xscroll.off("scrollend", self._scrollEndHandler, self);
- },
- render: function() {
- var self = this;
- var xscroll = self.xscroll;
- var boundry = xscroll.boundry;
- var indicatorInsets = self.xscroll.userConfig.indicatorInsets;
- var translateZ = xscroll.userConfig.gpuAcceleration ? " translateZ(0) " : "";
- var transform = translateZ ? transformStr + ":" + translateZ + ";" : "";
- var commonCss = "opacity:0;position:absolute;z-index:999;overflow:hidden;-webkit-border-radius:3px;-moz-border-radius:3px;-o-border-radius:3px;" + transform;
- indicatorInsets._xright = indicatorInsets.right + indicatorInsets.spacing;
- indicatorInsets._xbottom = indicatorInsets.bottom + indicatorInsets.spacing;
- var css = self.isY ?
- Util.substitute("width:{width}px;bottom:{_xbottom}px;top:{top}px;right:{right}px;", indicatorInsets) + commonCss :
- Util.substitute("height:{width}px;left:{left}px;right:{_xright}px;bottom:{bottom}px;",indicatorInsets) + commonCss;
-
- if(!self.scrollbar){
- self.scrollbar = document.createElement("div");
- self.indicate = document.createElement("div");
- xscroll.renderTo.appendChild(self.scrollbar);
- self.scrollbar.appendChild(self.indicate);
- }
- self.scrollbar.style.cssText = css;
- var size = self.isY ? "width:100%;" : "height:100%;";
- self.indicate.style.cssText = size + "position:absolute;background:rgba(0,0,0,0.3);-webkit-border-radius:3px;-moz-border-radius:3px;-o-border-radius:3px;"
- self._update();
- self.hide(0);
- self._bindEvt();
- },
- _update: function(pos, duration, easing, callback) {
- var self = this;
- var pos = undefined === pos ? (self.isY ? self.xscroll.getScrollTop() : self.xscroll.getScrollLeft()) : pos;
- var barInfo = self.computeScrollBar(pos);
- var size = self.isY ? "height" : "width";
- self.indicate.style[size] = Math.round(barInfo.size) + "px";
- if (duration && easing) {
- self.scrollTo(barInfo.pos, duration, easing, callback);
- } else {
- self.moveTo(barInfo.pos);
- }
- },
- //compute the position and size of the scrollbar
- computeScrollBar: function(pos) {
- var self = this;
- var type = self.isY ? "y" : "x";
- var spacing = self.userConfig.spacing;
- var xscroll = self.xscroll;
- var boundry = xscroll.boundry;
- var userConfig = self.userConfig;
- var pos = self.isY ? Math.round(pos) + boundry._xtop : Math.round(pos) + boundry._xleft;
- var MIN_BAR_SCROLLED_SIZE = userConfig.MIN_BAR_SCROLLED_SIZE;
- var MIN_BAR_SIZE = userConfig.MIN_BAR_SIZE;
- var MAX_BOUNCE_DISTANCE = userConfig.MAX_BOUNCE_DISTANCE;
- self.containerSize = self.isY ? xscroll.containerHeight + boundry._xtop + boundry._xbottom : self.xscroll.containerWidth + boundry._xright + boundry._xleft;
- self.size = self.isY ? boundry.cfg.height : boundry.cfg.width;
- self.indicateSize = self.isY ? boundry.cfg.height - spacing * 2 : boundry.cfg.width - spacing * 2;
- var indicateSize = self.indicateSize;
- var containerSize = self.containerSize;
- var barPos = indicateSize * pos / containerSize;
- var barSize = Math.round(indicateSize * self.size / containerSize);
- var overTop = self.isY ? xscroll.getBoundryOutTop() : xscroll.getBoundryOutLeft();
- var overBottom = self.isY ? xscroll.getBoundryOutBottom() : xscroll.getBoundryOutRight();
- var barShiftSize = MIN_BAR_SIZE - barSize > 0 ? MIN_BAR_SIZE - barSize : 0;
- barSize = barSize < MIN_BAR_SIZE ? MIN_BAR_SIZE : barSize;
- barPos = (indicateSize - barShiftSize) * pos / containerSize;
- if (overTop >= 0) {
- var pct = overTop / MAX_BOUNCE_DISTANCE;
- pct = pct > 1 ? 1 : pct;
- barPos = - pct * (barSize - MIN_BAR_SCROLLED_SIZE)
- }
- if (overBottom >= 0) {
- var pct = overBottom / MAX_BOUNCE_DISTANCE;
- pct = pct > 1 ? 1 : pct;
- barPos = pct * (barSize - MIN_BAR_SCROLLED_SIZE) + indicateSize - barSize;
- }
- self.barPos = Math.round(barPos);
- return {
- size: Math.round(barSize),
- pos: self.barPos
- };
- },
- scrollTo: function(pos, duration, easing, callback) {
- var self = this;
- self.show();
- var translateZ = self.xscroll.userConfig.gpuAcceleration ? " translateZ(0) " : "";
- var config = {
- css: {
- transform: self.isY ? "translateY(" + pos + "px)" + translateZ : "translateX(" + pos + "px)" + translateZ
- },
- duration: duration,
- easing: easing,
- useTransition: self.xscroll.userConfig.useTransition,
- end: callback
- };
- self.__timer = self.__timer || new Animate(self.indicate, config);
- //run
- self.__timer.stop();
- self.__timer.reset(config);
- self.__timer.run();
- },
- moveTo: function(pos) {
- var self = this;
- self.show();
- var translateZ = self.xscroll.userConfig.gpuAcceleration ? " translateZ(0) " : "";
- self.isY ? self.indicate.style[transform] = "translateY(" + pos + "px) " + translateZ : self.indicate.style[transform] = "translateX(" + pos + "px) " + translateZ
- self.indicate.style[transition] = "";
- },
- _scrollHandler: function(e) {
- var self = this;
- self._update(e[self.scrollTopOrLeft]);
- return self;
- },
- isBoundryOut: function() {
- var self = this;
- return !self.isY ? (self.xscroll.isBoundryOutLeft() || self.xscroll.isBoundryOutRight()) : (self.xscroll.isBoundryOutTop() || self.xscroll.isBoundryOutBottom());
- },
- _scrollEndHandler: function(e) {
- var self = this;
- if (!self.isBoundryOut()) {
- self._update(e[self.scrollTopOrLeft]);
- self.hide();
- }
- return self;
- },
- _bindEvt: function() {
- var self = this;
- if (self.__isEvtBind) return;
- self.__isEvtBind = true;
- self.xscroll.on("scroll", self._scrollHandler, self);
- self.xscroll.on("scrollend", self._scrollEndHandler, self);
- },
- reset: function() {
- var self = this;
- self.pos = 0;
- self._update();
- },
- hide: function(duration, easing, delay) {
- var self = this;
- var duration = duration >= 0 ? duration : 300;
- var easing = easing || "ease-out";
- var delay = delay >= 0 ? delay : 100;
- self.scrollbar.style.opacity = 0;
- self.scrollbar.style[transition] = ["opacity ", duration, "ms ", " ease-out ", delay, "ms"].join("");
- },
- show: function() {
- var self = this;
- self.scrollbar.style.opacity = 1;
- self.scrollbar.style[transition] = "";
- }
- });
- if (typeof module == 'object' && module.exports) {
- module.exports = ScrollBar;
- }
- /** ignored by jsdoc **/
- else {
- return ScrollBar;
- }
- });
|