| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258 |
- define(function(require, exports, module) {
- "use strict";
- var Util = require('../util'),
- Base = require('../base');
- // reduced scale rate
- var SCALE_RATE = 0.7;
- var SCALE_TO_DURATION = 300;
- /**
- * A scalable plugin for xscroll.
- * @constructor
- * @param {object} cfg
- * @param {number} cfg.minScale min value for scale
- * @param {number} cfg.maxScale max value for scale
- * @param {number} cfg.duration duration for scale animation
- * @extends {Base}
- */
- var Scale = function(cfg) {
- Scale.superclass.constructor.call(this, cfg);
- this.userConfig = Util.mix({
- minScale: 1,
- maxScale: 2,
- duration: SCALE_TO_DURATION
- }, cfg);
- }
- Util.extend(Scale, Base, {
- /**
- * a pluginId
- * @memberOf Scale
- * @type {string}
- */
- pluginId: "scale",
- /**
- * plugin initializer
- * @memberOf Scale
- * @override Scale
- * @return {Infinite}
- */
- pluginInitializer: function(xscroll) {
- var self = this;
- self.scale = 1;
- self.xscroll = xscroll.render();
- self.initialContainerWidth = xscroll.containerWidth;
- self.initialContainerHeight = xscroll.containerHeight;
- self.minScale = self.userConfig.minScale || Math.max(xscroll.width / xscroll.containerWidth, xscroll.height / xscroll.containerHeight);
- self.maxScale = self.userConfig.maxScale || 1;
- self._bindEvt();
- return self;
- },
- /**
- * detroy the plugin
- * @memberOf Scale
- * @override Base
- * @return {Scale}
- */
- pluginDestructor: function() {
- var self = this;
- var xscroll = self.xscroll;
- xscroll.off("doubletap", self._doubleTapHandler, self);
- xscroll.off("pinchstart", self._pinchStartHandler, self);
- xscroll.off("pinchmove", self._pinchHandler, self);
- xscroll.off("pinchend pinchcancel", self._pinchEndHandler, self);
- return self;
- },
- _doubleTapHandler: function(e) {
- var self = this;
- var xscroll = self.xscroll;
- var minScale = self.userConfig.minScale;
- var maxScale = self.userConfig.maxScale;
- var duration = self.userConfig.duration;
- self.originX = (e.center.x - xscroll.x) / xscroll.containerWidth;
- self.originY = (e.center.y - xscroll.y) / xscroll.containerHeight;
- xscroll.scale > self.minScale ? self.scaleTo(minScale, self.originX, self.originY, duration) : self.scaleTo(maxScale, self.originX, self.originY, duration);
- return self;
- },
- _pinchStartHandler: function(e) {
- var self = this;
- var xscroll = self.xscroll;
- //disable pan gesture
- self.disablePan();
- xscroll.stop();
- self.isScaling = false;
- self.scale = xscroll.scale;
- self.originX = (e.center.x - xscroll.x) / xscroll.containerWidth;
- self.originY = (e.center.y - xscroll.y) / xscroll.containerHeight;
- },
- _pinchHandler: function(e) {
- var self = this;
- var scale = self.scale;
- var xscroll = self.xscroll;
- var originX = self.originX;
- var originY = self.originY;
- var __scale = scale * e.scale;
- if (__scale <= self.userConfig.minScale) {
- // s = 1/2 * a * 2^(s/a)
- __scale = 0.5 * self.userConfig.minScale * Math.pow(2, __scale / self.userConfig.minScale);
- }
- if (__scale >= self.userConfig.maxScale) {
- // s = 2 * a * 1/2^(a/s)
- __scale = 2 * self.userConfig.maxScale * Math.pow(0.5, self.userConfig.maxScale / __scale);
- }
- self._scale(__scale, originX, originY);
- self.xscroll.translate(xscroll.x, xscroll.y, __scale, 'e.scale', e.scale);
- },
- disablePan: function() {
- this.xscroll.mc.get("pan").set({
- enable: false
- });
- return this;
- },
- enablePan: function() {
- this.xscroll.mc.get("pan").set({
- enable: true
- });
- return this;
- },
- _pinchEndHandler: function(e) {
- var self = this;
- var originX = self.originX;
- var originY = self.originY;
- var xscroll = self.xscroll;
- if (xscroll.scale < self.minScale) {
- self.scaleTo(self.minScale, originX, originY, SCALE_TO_DURATION, "ease-out", self.enablePan);
- } else if (xscroll.scale > self.maxScale) {
- self.scaleTo(self.maxScale, originX, originY, SCALE_TO_DURATION, "ease-out", self.enablePan);
- } else {
- self.enablePan();
- }
- },
- _bindEvt: function() {
- var self = this;
- var xscroll = self.xscroll;
- xscroll.on("doubletap", self._doubleTapHandler, self);
- xscroll.on("pinchstart", self._pinchStartHandler, self);
- xscroll.on("pinchmove", self._pinchHandler, self);
- xscroll.on("pinchend pinchcancel", self._pinchEndHandler, self);
- return self;
- },
- _scale: function(scale, originX, originY) {
- var self = this;
- var xscroll = self.xscroll;
- var boundry = self.xscroll.boundry;
- if (xscroll.scale == scale || !scale) return;
- if (!self.isScaling) {
- self.scaleBegin = xscroll.scale;
- self.isScaling = true;
- self.scaleBeginX = xscroll.x;
- self.scaleBeginY = xscroll.y;
- }
- if (originX) {
- self.originX = originX;
- }
- if (originY) {
- self.originY = originY;
- }
- var containerWidth = scale * self.initialContainerWidth;
- var containerHeight = scale * self.initialContainerHeight;
- xscroll.containerWidth = Math.round(containerWidth > xscroll.width ? containerWidth : xscroll.width);
- xscroll.containerHeight = Math.round(containerHeight > xscroll.height ? containerHeight : xscroll.height);
- xscroll.scale = scale;
- var x = originX * (self.initialContainerWidth * self.scaleBegin - xscroll.containerWidth) + self.scaleBeginX;
- var y = originY * (self.initialContainerHeight * self.scaleBegin - xscroll.containerHeight) + self.scaleBeginY;
- if (x > boundry.left) {
- x = boundry.left;
- }
- if (y > boundry.top) {
- y = boundry.top;
- }
- if (x < boundry.right - xscroll.containerWidth) {
- x = boundry.right - xscroll.containerWidth;
- }
- if (y < boundry.bottom - xscroll.containerHeight) {
- y = boundry.bottom - xscroll.containerHeight;
- }
- xscroll.x = x;
- xscroll.y = y;
- },
- /**
- * scale with an animation
- * @memberOf Scale
- * @param {number} scale
- * @param {number} originX 0~1
- * @param {number} originY 0~1
- * @param {number} duration
- * @param {string} easing
- * @param {function} callback
- */
- scaleTo: function(scale, originX, originY, duration, easing, callback) {
- var self = this;
- var xscroll = self.xscroll;
- //unscalable
- if (xscroll.scale == scale || !scale) return;
- var duration = duration || SCALE_TO_DURATION;
- var easing = easing || "ease-out";
- self.scaleStart = xscroll.scale || 1;
- // transitionStr = [transformStr, " ", duration , "s ", easing, " 0s"].join("");
- self._scale(scale, originX, originY);
- xscroll._animate("x", "translateX(" + xscroll.x + "px) scale(" + scale + ")", duration, easing, function(e) {
- callback && callback.call(self, e);
- });
- xscroll._animate("y", "translateY(" + xscroll.y + "px)", duration, easing, function(e) {
- callback && callback.call(self, e);
- });
- xscroll.__timers.x.timer.off("run", self.scaleHandler, self);
- xscroll.__timers.x.timer.off("stop", self.scaleendHandler, self);
- self.scaleHandler = function(e) {
- var _scale = (scale - self.scaleStart) * e.percent + self.scaleStart;
- //trigger scroll event
- self.trigger("scale", {
- scale: _scale,
- origin: {
- x: originX,
- y: originY
- }
- });
- };
- self.scaleendHandler = function(e) {
- self.isScaling = false;
- //enable pan gesture
- self.enablePan();
- self.trigger("scaleend", {
- type: "scaleend",
- scale: self.scale,
- origin: {
- x: originX,
- y: originY
- }
- })
- }
-
- xscroll.__timers.x.timer.on("run", self.scaleHandler, self);
- xscroll.__timers.x.timer.on("stop", self.scaleendHandler, self);
- self.trigger("scaleanimate", {
- type:"scaleanimate",
- scale: xscroll.scale,
- duration: duration,
- easing: easing,
- offset: {
- x: xscroll.x,
- y: xscroll.y
- },
- origin: {
- x: originX,
- y: originY
- }
- });
- }
- });
- if (typeof module == 'object' && module.exports) {
- module.exports = Scale;
- }
- /** ignored by jsdoc **/
- else if (window.XScroll && window.XScroll.Plugins) {
- return XScroll.Plugins.Scale = Scale;
- }
- });
|