1205 lines
57 KiB
JavaScript
1205 lines
57 KiB
JavaScript
/**
|
|
* Kendo UI v2016.1.226 (http://www.telerik.com/kendo-ui)
|
|
* Copyright 2016 Telerik AD. All rights reserved.
|
|
*
|
|
* Kendo UI commercial licenses may be obtained at
|
|
* http://www.telerik.com/purchase/license-agreement/kendo-ui-complete
|
|
* If you do not own a commercial license, this file shall be governed by the trial license terms.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/
|
|
(function (f, define) {
|
|
define('kendo.fx', ['kendo.core'], f);
|
|
}(function () {
|
|
var __meta__ = {
|
|
id: 'fx',
|
|
name: 'Effects',
|
|
category: 'framework',
|
|
description: 'Required for animation effects in all Kendo UI widgets.',
|
|
depends: ['core']
|
|
};
|
|
(function ($, undefined) {
|
|
var kendo = window.kendo, fx = kendo.effects, each = $.each, extend = $.extend, proxy = $.proxy, support = kendo.support, browser = support.browser, transforms = support.transforms, transitions = support.transitions, scaleProperties = {
|
|
scale: 0,
|
|
scalex: 0,
|
|
scaley: 0,
|
|
scale3d: 0
|
|
}, translateProperties = {
|
|
translate: 0,
|
|
translatex: 0,
|
|
translatey: 0,
|
|
translate3d: 0
|
|
}, hasZoom = typeof document.documentElement.style.zoom !== 'undefined' && !transforms, matrix3dRegExp = /matrix3?d?\s*\(.*,\s*([\d\.\-]+)\w*?,\s*([\d\.\-]+)\w*?,\s*([\d\.\-]+)\w*?,\s*([\d\.\-]+)\w*?/i, cssParamsRegExp = /^(-?[\d\.\-]+)?[\w\s]*,?\s*(-?[\d\.\-]+)?[\w\s]*/i, translateXRegExp = /translatex?$/i, oldEffectsRegExp = /(zoom|fade|expand)(\w+)/, singleEffectRegExp = /(zoom|fade|expand)/, unitRegExp = /[xy]$/i, transformProps = [
|
|
'perspective',
|
|
'rotate',
|
|
'rotatex',
|
|
'rotatey',
|
|
'rotatez',
|
|
'rotate3d',
|
|
'scale',
|
|
'scalex',
|
|
'scaley',
|
|
'scalez',
|
|
'scale3d',
|
|
'skew',
|
|
'skewx',
|
|
'skewy',
|
|
'translate',
|
|
'translatex',
|
|
'translatey',
|
|
'translatez',
|
|
'translate3d',
|
|
'matrix',
|
|
'matrix3d'
|
|
], transform2d = [
|
|
'rotate',
|
|
'scale',
|
|
'scalex',
|
|
'scaley',
|
|
'skew',
|
|
'skewx',
|
|
'skewy',
|
|
'translate',
|
|
'translatex',
|
|
'translatey',
|
|
'matrix'
|
|
], transform2units = {
|
|
'rotate': 'deg',
|
|
scale: '',
|
|
skew: 'px',
|
|
translate: 'px'
|
|
}, cssPrefix = transforms.css, round = Math.round, BLANK = '', PX = 'px', NONE = 'none', AUTO = 'auto', WIDTH = 'width', HEIGHT = 'height', HIDDEN = 'hidden', ORIGIN = 'origin', ABORT_ID = 'abortId', OVERFLOW = 'overflow', TRANSLATE = 'translate', POSITION = 'position', COMPLETE_CALLBACK = 'completeCallback', TRANSITION = cssPrefix + 'transition', TRANSFORM = cssPrefix + 'transform', BACKFACE = cssPrefix + 'backface-visibility', PERSPECTIVE = cssPrefix + 'perspective', DEFAULT_PERSPECTIVE = '1500px', TRANSFORM_PERSPECTIVE = 'perspective(' + DEFAULT_PERSPECTIVE + ')', directions = {
|
|
left: {
|
|
reverse: 'right',
|
|
property: 'left',
|
|
transition: 'translatex',
|
|
vertical: false,
|
|
modifier: -1
|
|
},
|
|
right: {
|
|
reverse: 'left',
|
|
property: 'left',
|
|
transition: 'translatex',
|
|
vertical: false,
|
|
modifier: 1
|
|
},
|
|
down: {
|
|
reverse: 'up',
|
|
property: 'top',
|
|
transition: 'translatey',
|
|
vertical: true,
|
|
modifier: 1
|
|
},
|
|
up: {
|
|
reverse: 'down',
|
|
property: 'top',
|
|
transition: 'translatey',
|
|
vertical: true,
|
|
modifier: -1
|
|
},
|
|
top: { reverse: 'bottom' },
|
|
bottom: { reverse: 'top' },
|
|
'in': {
|
|
reverse: 'out',
|
|
modifier: -1
|
|
},
|
|
out: {
|
|
reverse: 'in',
|
|
modifier: 1
|
|
},
|
|
vertical: { reverse: 'vertical' },
|
|
horizontal: { reverse: 'horizontal' }
|
|
};
|
|
kendo.directions = directions;
|
|
extend($.fn, {
|
|
kendoStop: function (clearQueue, gotoEnd) {
|
|
if (transitions) {
|
|
return fx.stopQueue(this, clearQueue || false, gotoEnd || false);
|
|
} else {
|
|
return this.stop(clearQueue, gotoEnd);
|
|
}
|
|
}
|
|
});
|
|
if (transforms && !transitions) {
|
|
each(transform2d, function (idx, value) {
|
|
$.fn[value] = function (val) {
|
|
if (typeof val == 'undefined') {
|
|
return animationProperty(this, value);
|
|
} else {
|
|
var that = $(this)[0], transformValue = value + '(' + val + transform2units[value.replace(unitRegExp, '')] + ')';
|
|
if (that.style.cssText.indexOf(TRANSFORM) == -1) {
|
|
$(this).css(TRANSFORM, transformValue);
|
|
} else {
|
|
that.style.cssText = that.style.cssText.replace(new RegExp(value + '\\(.*?\\)', 'i'), transformValue);
|
|
}
|
|
}
|
|
return this;
|
|
};
|
|
$.fx.step[value] = function (fx) {
|
|
$(fx.elem)[value](fx.now);
|
|
};
|
|
});
|
|
var curProxy = $.fx.prototype.cur;
|
|
$.fx.prototype.cur = function () {
|
|
if (transform2d.indexOf(this.prop) != -1) {
|
|
return parseFloat($(this.elem)[this.prop]());
|
|
}
|
|
return curProxy.apply(this, arguments);
|
|
};
|
|
}
|
|
kendo.toggleClass = function (element, classes, options, add) {
|
|
if (classes) {
|
|
classes = classes.split(' ');
|
|
if (transitions) {
|
|
options = extend({
|
|
exclusive: 'all',
|
|
duration: 400,
|
|
ease: 'ease-out'
|
|
}, options);
|
|
element.css(TRANSITION, options.exclusive + ' ' + options.duration + 'ms ' + options.ease);
|
|
setTimeout(function () {
|
|
element.css(TRANSITION, '').css(HEIGHT);
|
|
}, options.duration);
|
|
}
|
|
each(classes, function (idx, value) {
|
|
element.toggleClass(value, add);
|
|
});
|
|
}
|
|
return element;
|
|
};
|
|
kendo.parseEffects = function (input, mirror) {
|
|
var effects = {};
|
|
if (typeof input === 'string') {
|
|
each(input.split(' '), function (idx, value) {
|
|
var redirectedEffect = !singleEffectRegExp.test(value), resolved = value.replace(oldEffectsRegExp, function (match, $1, $2) {
|
|
return $1 + ':' + $2.toLowerCase();
|
|
}), effect = resolved.split(':'), direction = effect[1], effectBody = {};
|
|
if (effect.length > 1) {
|
|
effectBody.direction = mirror && redirectedEffect ? directions[direction].reverse : direction;
|
|
}
|
|
effects[effect[0]] = effectBody;
|
|
});
|
|
} else {
|
|
each(input, function (idx) {
|
|
var direction = this.direction;
|
|
if (direction && mirror && !singleEffectRegExp.test(idx)) {
|
|
this.direction = directions[direction].reverse;
|
|
}
|
|
effects[idx] = this;
|
|
});
|
|
}
|
|
return effects;
|
|
};
|
|
function parseInteger(value) {
|
|
return parseInt(value, 10);
|
|
}
|
|
function parseCSS(element, property) {
|
|
return parseInteger(element.css(property));
|
|
}
|
|
function keys(obj) {
|
|
var acc = [];
|
|
for (var propertyName in obj) {
|
|
acc.push(propertyName);
|
|
}
|
|
return acc;
|
|
}
|
|
function strip3DTransforms(properties) {
|
|
for (var key in properties) {
|
|
if (transformProps.indexOf(key) != -1 && transform2d.indexOf(key) == -1) {
|
|
delete properties[key];
|
|
}
|
|
}
|
|
return properties;
|
|
}
|
|
function normalizeCSS(element, properties) {
|
|
var transformation = [], cssValues = {}, lowerKey, key, value, isTransformed;
|
|
for (key in properties) {
|
|
lowerKey = key.toLowerCase();
|
|
isTransformed = transforms && transformProps.indexOf(lowerKey) != -1;
|
|
if (!support.hasHW3D && isTransformed && transform2d.indexOf(lowerKey) == -1) {
|
|
delete properties[key];
|
|
} else {
|
|
value = properties[key];
|
|
if (isTransformed) {
|
|
transformation.push(key + '(' + value + ')');
|
|
} else {
|
|
cssValues[key] = value;
|
|
}
|
|
}
|
|
}
|
|
if (transformation.length) {
|
|
cssValues[TRANSFORM] = transformation.join(' ');
|
|
}
|
|
return cssValues;
|
|
}
|
|
if (transitions) {
|
|
extend(fx, {
|
|
transition: function (element, properties, options) {
|
|
var css, delay = 0, oldKeys = element.data('keys') || [], timeoutID;
|
|
options = extend({
|
|
duration: 200,
|
|
ease: 'ease-out',
|
|
complete: null,
|
|
exclusive: 'all'
|
|
}, options);
|
|
var stopTransitionCalled = false;
|
|
var stopTransition = function () {
|
|
if (!stopTransitionCalled) {
|
|
stopTransitionCalled = true;
|
|
if (timeoutID) {
|
|
clearTimeout(timeoutID);
|
|
timeoutID = null;
|
|
}
|
|
element.removeData(ABORT_ID).dequeue().css(TRANSITION, '').css(TRANSITION);
|
|
options.complete.call(element);
|
|
}
|
|
};
|
|
options.duration = $.fx ? $.fx.speeds[options.duration] || options.duration : options.duration;
|
|
css = normalizeCSS(element, properties);
|
|
$.merge(oldKeys, keys(css));
|
|
element.data('keys', $.unique(oldKeys)).height();
|
|
element.css(TRANSITION, options.exclusive + ' ' + options.duration + 'ms ' + options.ease).css(TRANSITION);
|
|
element.css(css).css(TRANSFORM);
|
|
if (transitions.event) {
|
|
element.one(transitions.event, stopTransition);
|
|
if (options.duration !== 0) {
|
|
delay = 500;
|
|
}
|
|
}
|
|
timeoutID = setTimeout(stopTransition, options.duration + delay);
|
|
element.data(ABORT_ID, timeoutID);
|
|
element.data(COMPLETE_CALLBACK, stopTransition);
|
|
},
|
|
stopQueue: function (element, clearQueue, gotoEnd) {
|
|
var cssValues, taskKeys = element.data('keys'), retainPosition = !gotoEnd && taskKeys, completeCallback = element.data(COMPLETE_CALLBACK);
|
|
if (retainPosition) {
|
|
cssValues = kendo.getComputedStyles(element[0], taskKeys);
|
|
}
|
|
if (completeCallback) {
|
|
completeCallback();
|
|
}
|
|
if (retainPosition) {
|
|
element.css(cssValues);
|
|
}
|
|
return element.removeData('keys').stop(clearQueue);
|
|
}
|
|
});
|
|
}
|
|
function animationProperty(element, property) {
|
|
if (transforms) {
|
|
var transform = element.css(TRANSFORM);
|
|
if (transform == NONE) {
|
|
return property == 'scale' ? 1 : 0;
|
|
}
|
|
var match = transform.match(new RegExp(property + '\\s*\\(([\\d\\w\\.]+)')), computed = 0;
|
|
if (match) {
|
|
computed = parseInteger(match[1]);
|
|
} else {
|
|
match = transform.match(matrix3dRegExp) || [
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0
|
|
];
|
|
property = property.toLowerCase();
|
|
if (translateXRegExp.test(property)) {
|
|
computed = parseFloat(match[3] / match[2]);
|
|
} else if (property == 'translatey') {
|
|
computed = parseFloat(match[4] / match[2]);
|
|
} else if (property == 'scale') {
|
|
computed = parseFloat(match[2]);
|
|
} else if (property == 'rotate') {
|
|
computed = parseFloat(Math.atan2(match[2], match[1]));
|
|
}
|
|
}
|
|
return computed;
|
|
} else {
|
|
return parseFloat(element.css(property));
|
|
}
|
|
}
|
|
var EffectSet = kendo.Class.extend({
|
|
init: function (element, options) {
|
|
var that = this;
|
|
that.element = element;
|
|
that.effects = [];
|
|
that.options = options;
|
|
that.restore = [];
|
|
},
|
|
run: function (effects) {
|
|
var that = this, effect, idx, jdx, length = effects.length, element = that.element, options = that.options, deferred = $.Deferred(), start = {}, end = {}, target, children, childrenLength;
|
|
that.effects = effects;
|
|
deferred.then($.proxy(that, 'complete'));
|
|
element.data('animating', true);
|
|
for (idx = 0; idx < length; idx++) {
|
|
effect = effects[idx];
|
|
effect.setReverse(options.reverse);
|
|
effect.setOptions(options);
|
|
that.addRestoreProperties(effect.restore);
|
|
effect.prepare(start, end);
|
|
children = effect.children();
|
|
for (jdx = 0, childrenLength = children.length; jdx < childrenLength; jdx++) {
|
|
children[jdx].duration(options.duration).run();
|
|
}
|
|
}
|
|
for (var effectName in options.effects) {
|
|
extend(end, options.effects[effectName].properties);
|
|
}
|
|
if (!element.is(':visible')) {
|
|
extend(start, { display: element.data('olddisplay') || 'block' });
|
|
}
|
|
if (transforms && !options.reset) {
|
|
target = element.data('targetTransform');
|
|
if (target) {
|
|
start = extend(target, start);
|
|
}
|
|
}
|
|
start = normalizeCSS(element, start);
|
|
if (transforms && !transitions) {
|
|
start = strip3DTransforms(start);
|
|
}
|
|
element.css(start).css(TRANSFORM);
|
|
for (idx = 0; idx < length; idx++) {
|
|
effects[idx].setup();
|
|
}
|
|
if (options.init) {
|
|
options.init();
|
|
}
|
|
element.data('targetTransform', end);
|
|
fx.animate(element, end, extend({}, options, { complete: deferred.resolve }));
|
|
return deferred.promise();
|
|
},
|
|
stop: function () {
|
|
$(this.element).kendoStop(true, true);
|
|
},
|
|
addRestoreProperties: function (restore) {
|
|
var element = this.element, value, i = 0, length = restore.length;
|
|
for (; i < length; i++) {
|
|
value = restore[i];
|
|
this.restore.push(value);
|
|
if (!element.data(value)) {
|
|
element.data(value, element.css(value));
|
|
}
|
|
}
|
|
},
|
|
restoreCallback: function () {
|
|
var element = this.element;
|
|
for (var i = 0, length = this.restore.length; i < length; i++) {
|
|
var value = this.restore[i];
|
|
element.css(value, element.data(value));
|
|
}
|
|
},
|
|
complete: function () {
|
|
var that = this, idx = 0, element = that.element, options = that.options, effects = that.effects, length = effects.length;
|
|
element.removeData('animating').dequeue();
|
|
if (options.hide) {
|
|
element.data('olddisplay', element.css('display')).hide();
|
|
}
|
|
this.restoreCallback();
|
|
if (hasZoom && !transforms) {
|
|
setTimeout($.proxy(this, 'restoreCallback'), 0);
|
|
}
|
|
for (; idx < length; idx++) {
|
|
effects[idx].teardown();
|
|
}
|
|
if (options.completeCallback) {
|
|
options.completeCallback(element);
|
|
}
|
|
}
|
|
});
|
|
fx.promise = function (element, options) {
|
|
var effects = [], effectClass, effectSet = new EffectSet(element, options), parsedEffects = kendo.parseEffects(options.effects), effect;
|
|
options.effects = parsedEffects;
|
|
for (var effectName in parsedEffects) {
|
|
effectClass = fx[capitalize(effectName)];
|
|
if (effectClass) {
|
|
effect = new effectClass(element, parsedEffects[effectName].direction);
|
|
effects.push(effect);
|
|
}
|
|
}
|
|
if (effects[0]) {
|
|
effectSet.run(effects);
|
|
} else {
|
|
if (!element.is(':visible')) {
|
|
element.css({ display: element.data('olddisplay') || 'block' }).css('display');
|
|
}
|
|
if (options.init) {
|
|
options.init();
|
|
}
|
|
element.dequeue();
|
|
effectSet.complete();
|
|
}
|
|
};
|
|
extend(fx, {
|
|
animate: function (elements, properties, options) {
|
|
var useTransition = options.transition !== false;
|
|
delete options.transition;
|
|
if (transitions && 'transition' in fx && useTransition) {
|
|
fx.transition(elements, properties, options);
|
|
} else {
|
|
if (transforms) {
|
|
elements.animate(strip3DTransforms(properties), {
|
|
queue: false,
|
|
show: false,
|
|
hide: false,
|
|
duration: options.duration,
|
|
complete: options.complete
|
|
});
|
|
} else {
|
|
elements.each(function () {
|
|
var element = $(this), multiple = {};
|
|
each(transformProps, function (idx, value) {
|
|
var params, currentValue = properties ? properties[value] + ' ' : null;
|
|
if (currentValue) {
|
|
var single = properties;
|
|
if (value in scaleProperties && properties[value] !== undefined) {
|
|
params = currentValue.match(cssParamsRegExp);
|
|
if (transforms) {
|
|
extend(single, { scale: +params[0] });
|
|
}
|
|
} else {
|
|
if (value in translateProperties && properties[value] !== undefined) {
|
|
var position = element.css(POSITION), isFixed = position == 'absolute' || position == 'fixed';
|
|
if (!element.data(TRANSLATE)) {
|
|
if (isFixed) {
|
|
element.data(TRANSLATE, {
|
|
top: parseCSS(element, 'top') || 0,
|
|
left: parseCSS(element, 'left') || 0,
|
|
bottom: parseCSS(element, 'bottom'),
|
|
right: parseCSS(element, 'right')
|
|
});
|
|
} else {
|
|
element.data(TRANSLATE, {
|
|
top: parseCSS(element, 'marginTop') || 0,
|
|
left: parseCSS(element, 'marginLeft') || 0
|
|
});
|
|
}
|
|
}
|
|
var originalPosition = element.data(TRANSLATE);
|
|
params = currentValue.match(cssParamsRegExp);
|
|
if (params) {
|
|
var dX = value == TRANSLATE + 'y' ? +null : +params[1], dY = value == TRANSLATE + 'y' ? +params[1] : +params[2];
|
|
if (isFixed) {
|
|
if (!isNaN(originalPosition.right)) {
|
|
if (!isNaN(dX)) {
|
|
extend(single, { right: originalPosition.right - dX });
|
|
}
|
|
} else {
|
|
if (!isNaN(dX)) {
|
|
extend(single, { left: originalPosition.left + dX });
|
|
}
|
|
}
|
|
if (!isNaN(originalPosition.bottom)) {
|
|
if (!isNaN(dY)) {
|
|
extend(single, { bottom: originalPosition.bottom - dY });
|
|
}
|
|
} else {
|
|
if (!isNaN(dY)) {
|
|
extend(single, { top: originalPosition.top + dY });
|
|
}
|
|
}
|
|
} else {
|
|
if (!isNaN(dX)) {
|
|
extend(single, { marginLeft: originalPosition.left + dX });
|
|
}
|
|
if (!isNaN(dY)) {
|
|
extend(single, { marginTop: originalPosition.top + dY });
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (!transforms && value != 'scale' && value in single) {
|
|
delete single[value];
|
|
}
|
|
if (single) {
|
|
extend(multiple, single);
|
|
}
|
|
}
|
|
});
|
|
if (browser.msie) {
|
|
delete multiple.scale;
|
|
}
|
|
element.animate(multiple, {
|
|
queue: false,
|
|
show: false,
|
|
hide: false,
|
|
duration: options.duration,
|
|
complete: options.complete
|
|
});
|
|
});
|
|
}
|
|
}
|
|
}
|
|
});
|
|
fx.animatedPromise = fx.promise;
|
|
var Effect = kendo.Class.extend({
|
|
init: function (element, direction) {
|
|
var that = this;
|
|
that.element = element;
|
|
that._direction = direction;
|
|
that.options = {};
|
|
that._additionalEffects = [];
|
|
if (!that.restore) {
|
|
that.restore = [];
|
|
}
|
|
},
|
|
reverse: function () {
|
|
this._reverse = true;
|
|
return this.run();
|
|
},
|
|
play: function () {
|
|
this._reverse = false;
|
|
return this.run();
|
|
},
|
|
add: function (additional) {
|
|
this._additionalEffects.push(additional);
|
|
return this;
|
|
},
|
|
direction: function (value) {
|
|
this._direction = value;
|
|
return this;
|
|
},
|
|
duration: function (duration) {
|
|
this._duration = duration;
|
|
return this;
|
|
},
|
|
compositeRun: function () {
|
|
var that = this, effectSet = new EffectSet(that.element, {
|
|
reverse: that._reverse,
|
|
duration: that._duration
|
|
}), effects = that._additionalEffects.concat([that]);
|
|
return effectSet.run(effects);
|
|
},
|
|
run: function () {
|
|
if (this._additionalEffects && this._additionalEffects[0]) {
|
|
return this.compositeRun();
|
|
}
|
|
var that = this, element = that.element, idx = 0, restore = that.restore, length = restore.length, value, deferred = $.Deferred(), start = {}, end = {}, target, children = that.children(), childrenLength = children.length;
|
|
deferred.then($.proxy(that, '_complete'));
|
|
element.data('animating', true);
|
|
for (idx = 0; idx < length; idx++) {
|
|
value = restore[idx];
|
|
if (!element.data(value)) {
|
|
element.data(value, element.css(value));
|
|
}
|
|
}
|
|
for (idx = 0; idx < childrenLength; idx++) {
|
|
children[idx].duration(that._duration).run();
|
|
}
|
|
that.prepare(start, end);
|
|
if (!element.is(':visible')) {
|
|
extend(start, { display: element.data('olddisplay') || 'block' });
|
|
}
|
|
if (transforms) {
|
|
target = element.data('targetTransform');
|
|
if (target) {
|
|
start = extend(target, start);
|
|
}
|
|
}
|
|
start = normalizeCSS(element, start);
|
|
if (transforms && !transitions) {
|
|
start = strip3DTransforms(start);
|
|
}
|
|
element.css(start).css(TRANSFORM);
|
|
that.setup();
|
|
element.data('targetTransform', end);
|
|
fx.animate(element, end, {
|
|
duration: that._duration,
|
|
complete: deferred.resolve
|
|
});
|
|
return deferred.promise();
|
|
},
|
|
stop: function () {
|
|
var idx = 0, children = this.children(), childrenLength = children.length;
|
|
for (idx = 0; idx < childrenLength; idx++) {
|
|
children[idx].stop();
|
|
}
|
|
$(this.element).kendoStop(true, true);
|
|
return this;
|
|
},
|
|
restoreCallback: function () {
|
|
var element = this.element;
|
|
for (var i = 0, length = this.restore.length; i < length; i++) {
|
|
var value = this.restore[i];
|
|
element.css(value, element.data(value));
|
|
}
|
|
},
|
|
_complete: function () {
|
|
var that = this, element = that.element;
|
|
element.removeData('animating').dequeue();
|
|
that.restoreCallback();
|
|
if (that.shouldHide()) {
|
|
element.data('olddisplay', element.css('display')).hide();
|
|
}
|
|
if (hasZoom && !transforms) {
|
|
setTimeout($.proxy(that, 'restoreCallback'), 0);
|
|
}
|
|
that.teardown();
|
|
},
|
|
setOptions: function (options) {
|
|
extend(true, this.options, options);
|
|
},
|
|
children: function () {
|
|
return [];
|
|
},
|
|
shouldHide: $.noop,
|
|
setup: $.noop,
|
|
prepare: $.noop,
|
|
teardown: $.noop,
|
|
directions: [],
|
|
setReverse: function (reverse) {
|
|
this._reverse = reverse;
|
|
return this;
|
|
}
|
|
});
|
|
function capitalize(word) {
|
|
return word.charAt(0).toUpperCase() + word.substring(1);
|
|
}
|
|
function createEffect(name, definition) {
|
|
var effectClass = Effect.extend(definition), directions = effectClass.prototype.directions;
|
|
fx[capitalize(name)] = effectClass;
|
|
fx.Element.prototype[name] = function (direction, opt1, opt2, opt3) {
|
|
return new effectClass(this.element, direction, opt1, opt2, opt3);
|
|
};
|
|
each(directions, function (idx, theDirection) {
|
|
fx.Element.prototype[name + capitalize(theDirection)] = function (opt1, opt2, opt3) {
|
|
return new effectClass(this.element, theDirection, opt1, opt2, opt3);
|
|
};
|
|
});
|
|
}
|
|
var FOUR_DIRECTIONS = [
|
|
'left',
|
|
'right',
|
|
'up',
|
|
'down'
|
|
], IN_OUT = [
|
|
'in',
|
|
'out'
|
|
];
|
|
createEffect('slideIn', {
|
|
directions: FOUR_DIRECTIONS,
|
|
divisor: function (value) {
|
|
this.options.divisor = value;
|
|
return this;
|
|
},
|
|
prepare: function (start, end) {
|
|
var that = this, tmp, element = that.element, direction = directions[that._direction], offset = -direction.modifier * (direction.vertical ? element.outerHeight() : element.outerWidth()), startValue = offset / (that.options && that.options.divisor || 1) + PX, endValue = '0px';
|
|
if (that._reverse) {
|
|
tmp = start;
|
|
start = end;
|
|
end = tmp;
|
|
}
|
|
if (transforms) {
|
|
start[direction.transition] = startValue;
|
|
end[direction.transition] = endValue;
|
|
} else {
|
|
start[direction.property] = startValue;
|
|
end[direction.property] = endValue;
|
|
}
|
|
}
|
|
});
|
|
createEffect('tile', {
|
|
directions: FOUR_DIRECTIONS,
|
|
init: function (element, direction, previous) {
|
|
Effect.prototype.init.call(this, element, direction);
|
|
this.options = { previous: previous };
|
|
},
|
|
previousDivisor: function (value) {
|
|
this.options.previousDivisor = value;
|
|
return this;
|
|
},
|
|
children: function () {
|
|
var that = this, reverse = that._reverse, previous = that.options.previous, divisor = that.options.previousDivisor || 1, dir = that._direction;
|
|
var children = [kendo.fx(that.element).slideIn(dir).setReverse(reverse)];
|
|
if (previous) {
|
|
children.push(kendo.fx(previous).slideIn(directions[dir].reverse).divisor(divisor).setReverse(!reverse));
|
|
}
|
|
return children;
|
|
}
|
|
});
|
|
function createToggleEffect(name, property, defaultStart, defaultEnd) {
|
|
createEffect(name, {
|
|
directions: IN_OUT,
|
|
startValue: function (value) {
|
|
this._startValue = value;
|
|
return this;
|
|
},
|
|
endValue: function (value) {
|
|
this._endValue = value;
|
|
return this;
|
|
},
|
|
shouldHide: function () {
|
|
return this._shouldHide;
|
|
},
|
|
prepare: function (start, end) {
|
|
var that = this, startValue, endValue, out = this._direction === 'out', startDataValue = that.element.data(property), startDataValueIsSet = !(isNaN(startDataValue) || startDataValue == defaultStart);
|
|
if (startDataValueIsSet) {
|
|
startValue = startDataValue;
|
|
} else if (typeof this._startValue !== 'undefined') {
|
|
startValue = this._startValue;
|
|
} else {
|
|
startValue = out ? defaultStart : defaultEnd;
|
|
}
|
|
if (typeof this._endValue !== 'undefined') {
|
|
endValue = this._endValue;
|
|
} else {
|
|
endValue = out ? defaultEnd : defaultStart;
|
|
}
|
|
if (this._reverse) {
|
|
start[property] = endValue;
|
|
end[property] = startValue;
|
|
} else {
|
|
start[property] = startValue;
|
|
end[property] = endValue;
|
|
}
|
|
that._shouldHide = end[property] === defaultEnd;
|
|
}
|
|
});
|
|
}
|
|
createToggleEffect('fade', 'opacity', 1, 0);
|
|
createToggleEffect('zoom', 'scale', 1, 0.01);
|
|
createEffect('slideMargin', {
|
|
prepare: function (start, end) {
|
|
var that = this, element = that.element, options = that.options, origin = element.data(ORIGIN), offset = options.offset, margin, reverse = that._reverse;
|
|
if (!reverse && origin === null) {
|
|
element.data(ORIGIN, parseFloat(element.css('margin-' + options.axis)));
|
|
}
|
|
margin = element.data(ORIGIN) || 0;
|
|
end['margin-' + options.axis] = !reverse ? margin + offset : margin;
|
|
}
|
|
});
|
|
createEffect('slideTo', {
|
|
prepare: function (start, end) {
|
|
var that = this, element = that.element, options = that.options, offset = options.offset.split(','), reverse = that._reverse;
|
|
if (transforms) {
|
|
end.translatex = !reverse ? offset[0] : 0;
|
|
end.translatey = !reverse ? offset[1] : 0;
|
|
} else {
|
|
end.left = !reverse ? offset[0] : 0;
|
|
end.top = !reverse ? offset[1] : 0;
|
|
}
|
|
element.css('left');
|
|
}
|
|
});
|
|
createEffect('expand', {
|
|
directions: [
|
|
'horizontal',
|
|
'vertical'
|
|
],
|
|
restore: [OVERFLOW],
|
|
prepare: function (start, end) {
|
|
var that = this, element = that.element, options = that.options, reverse = that._reverse, property = that._direction === 'vertical' ? HEIGHT : WIDTH, setLength = element[0].style[property], oldLength = element.data(property), length = parseFloat(oldLength || setLength), realLength = round(element.css(property, AUTO)[property]());
|
|
start.overflow = HIDDEN;
|
|
length = options && options.reset ? realLength || length : length || realLength;
|
|
end[property] = (reverse ? 0 : length) + PX;
|
|
start[property] = (reverse ? length : 0) + PX;
|
|
if (oldLength === undefined) {
|
|
element.data(property, setLength);
|
|
}
|
|
},
|
|
shouldHide: function () {
|
|
return this._reverse;
|
|
},
|
|
teardown: function () {
|
|
var that = this, element = that.element, property = that._direction === 'vertical' ? HEIGHT : WIDTH, length = element.data(property);
|
|
if (length == AUTO || length === BLANK) {
|
|
setTimeout(function () {
|
|
element.css(property, AUTO).css(property);
|
|
}, 0);
|
|
}
|
|
}
|
|
});
|
|
var TRANSFER_START_STATE = {
|
|
position: 'absolute',
|
|
marginLeft: 0,
|
|
marginTop: 0,
|
|
scale: 1
|
|
};
|
|
createEffect('transfer', {
|
|
init: function (element, target) {
|
|
this.element = element;
|
|
this.options = { target: target };
|
|
this.restore = [];
|
|
},
|
|
setup: function () {
|
|
this.element.appendTo(document.body);
|
|
},
|
|
prepare: function (start, end) {
|
|
var that = this, element = that.element, outerBox = fx.box(element), innerBox = fx.box(that.options.target), currentScale = animationProperty(element, 'scale'), scale = fx.fillScale(innerBox, outerBox), transformOrigin = fx.transformOrigin(innerBox, outerBox);
|
|
extend(start, TRANSFER_START_STATE);
|
|
end.scale = 1;
|
|
element.css(TRANSFORM, 'scale(1)').css(TRANSFORM);
|
|
element.css(TRANSFORM, 'scale(' + currentScale + ')');
|
|
start.top = outerBox.top;
|
|
start.left = outerBox.left;
|
|
start.transformOrigin = transformOrigin.x + PX + ' ' + transformOrigin.y + PX;
|
|
if (that._reverse) {
|
|
start.scale = scale;
|
|
} else {
|
|
end.scale = scale;
|
|
}
|
|
}
|
|
});
|
|
var CLIPS = {
|
|
top: 'rect(auto auto $size auto)',
|
|
bottom: 'rect($size auto auto auto)',
|
|
left: 'rect(auto $size auto auto)',
|
|
right: 'rect(auto auto auto $size)'
|
|
};
|
|
var ROTATIONS = {
|
|
top: {
|
|
start: 'rotatex(0deg)',
|
|
end: 'rotatex(180deg)'
|
|
},
|
|
bottom: {
|
|
start: 'rotatex(-180deg)',
|
|
end: 'rotatex(0deg)'
|
|
},
|
|
left: {
|
|
start: 'rotatey(0deg)',
|
|
end: 'rotatey(-180deg)'
|
|
},
|
|
right: {
|
|
start: 'rotatey(180deg)',
|
|
end: 'rotatey(0deg)'
|
|
}
|
|
};
|
|
function clipInHalf(container, direction) {
|
|
var vertical = kendo.directions[direction].vertical, size = container[vertical ? HEIGHT : WIDTH]() / 2 + 'px';
|
|
return CLIPS[direction].replace('$size', size);
|
|
}
|
|
createEffect('turningPage', {
|
|
directions: FOUR_DIRECTIONS,
|
|
init: function (element, direction, container) {
|
|
Effect.prototype.init.call(this, element, direction);
|
|
this._container = container;
|
|
},
|
|
prepare: function (start, end) {
|
|
var that = this, reverse = that._reverse, direction = reverse ? directions[that._direction].reverse : that._direction, rotation = ROTATIONS[direction];
|
|
start.zIndex = 1;
|
|
if (that._clipInHalf) {
|
|
start.clip = clipInHalf(that._container, kendo.directions[direction].reverse);
|
|
}
|
|
start[BACKFACE] = HIDDEN;
|
|
end[TRANSFORM] = TRANSFORM_PERSPECTIVE + (reverse ? rotation.start : rotation.end);
|
|
start[TRANSFORM] = TRANSFORM_PERSPECTIVE + (reverse ? rotation.end : rotation.start);
|
|
},
|
|
setup: function () {
|
|
this._container.append(this.element);
|
|
},
|
|
face: function (value) {
|
|
this._face = value;
|
|
return this;
|
|
},
|
|
shouldHide: function () {
|
|
var that = this, reverse = that._reverse, face = that._face;
|
|
return reverse && !face || !reverse && face;
|
|
},
|
|
clipInHalf: function (value) {
|
|
this._clipInHalf = value;
|
|
return this;
|
|
},
|
|
temporary: function () {
|
|
this.element.addClass('temp-page');
|
|
return this;
|
|
}
|
|
});
|
|
createEffect('staticPage', {
|
|
directions: FOUR_DIRECTIONS,
|
|
init: function (element, direction, container) {
|
|
Effect.prototype.init.call(this, element, direction);
|
|
this._container = container;
|
|
},
|
|
restore: ['clip'],
|
|
prepare: function (start, end) {
|
|
var that = this, direction = that._reverse ? directions[that._direction].reverse : that._direction;
|
|
start.clip = clipInHalf(that._container, direction);
|
|
start.opacity = 0.999;
|
|
end.opacity = 1;
|
|
},
|
|
shouldHide: function () {
|
|
var that = this, reverse = that._reverse, face = that._face;
|
|
return reverse && !face || !reverse && face;
|
|
},
|
|
face: function (value) {
|
|
this._face = value;
|
|
return this;
|
|
}
|
|
});
|
|
createEffect('pageturn', {
|
|
directions: [
|
|
'horizontal',
|
|
'vertical'
|
|
],
|
|
init: function (element, direction, face, back) {
|
|
Effect.prototype.init.call(this, element, direction);
|
|
this.options = {};
|
|
this.options.face = face;
|
|
this.options.back = back;
|
|
},
|
|
children: function () {
|
|
var that = this, options = that.options, direction = that._direction === 'horizontal' ? 'left' : 'top', reverseDirection = kendo.directions[direction].reverse, reverse = that._reverse, temp, faceClone = options.face.clone(true).removeAttr('id'), backClone = options.back.clone(true).removeAttr('id'), element = that.element;
|
|
if (reverse) {
|
|
temp = direction;
|
|
direction = reverseDirection;
|
|
reverseDirection = temp;
|
|
}
|
|
return [
|
|
kendo.fx(options.face).staticPage(direction, element).face(true).setReverse(reverse),
|
|
kendo.fx(options.back).staticPage(reverseDirection, element).setReverse(reverse),
|
|
kendo.fx(faceClone).turningPage(direction, element).face(true).clipInHalf(true).temporary().setReverse(reverse),
|
|
kendo.fx(backClone).turningPage(reverseDirection, element).clipInHalf(true).temporary().setReverse(reverse)
|
|
];
|
|
},
|
|
prepare: function (start, end) {
|
|
start[PERSPECTIVE] = DEFAULT_PERSPECTIVE;
|
|
start.transformStyle = 'preserve-3d';
|
|
start.opacity = 0.999;
|
|
end.opacity = 1;
|
|
},
|
|
teardown: function () {
|
|
this.element.find('.temp-page').remove();
|
|
}
|
|
});
|
|
createEffect('flip', {
|
|
directions: [
|
|
'horizontal',
|
|
'vertical'
|
|
],
|
|
init: function (element, direction, face, back) {
|
|
Effect.prototype.init.call(this, element, direction);
|
|
this.options = {};
|
|
this.options.face = face;
|
|
this.options.back = back;
|
|
},
|
|
children: function () {
|
|
var that = this, options = that.options, direction = that._direction === 'horizontal' ? 'left' : 'top', reverseDirection = kendo.directions[direction].reverse, reverse = that._reverse, temp, element = that.element;
|
|
if (reverse) {
|
|
temp = direction;
|
|
direction = reverseDirection;
|
|
reverseDirection = temp;
|
|
}
|
|
return [
|
|
kendo.fx(options.face).turningPage(direction, element).face(true).setReverse(reverse),
|
|
kendo.fx(options.back).turningPage(reverseDirection, element).setReverse(reverse)
|
|
];
|
|
},
|
|
prepare: function (start) {
|
|
start[PERSPECTIVE] = DEFAULT_PERSPECTIVE;
|
|
start.transformStyle = 'preserve-3d';
|
|
}
|
|
});
|
|
var RESTORE_OVERFLOW = !support.mobileOS.android;
|
|
var IGNORE_TRANSITION_EVENT_SELECTOR = '.km-touch-scrollbar, .km-actionsheet-wrapper';
|
|
createEffect('replace', {
|
|
_before: $.noop,
|
|
_after: $.noop,
|
|
init: function (element, previous, transitionClass) {
|
|
Effect.prototype.init.call(this, element);
|
|
this._previous = $(previous);
|
|
this._transitionClass = transitionClass;
|
|
},
|
|
duration: function () {
|
|
throw new Error('The replace effect does not support duration setting; the effect duration may be customized through the transition class rule');
|
|
},
|
|
beforeTransition: function (callback) {
|
|
this._before = callback;
|
|
return this;
|
|
},
|
|
afterTransition: function (callback) {
|
|
this._after = callback;
|
|
return this;
|
|
},
|
|
_both: function () {
|
|
return $().add(this._element).add(this._previous);
|
|
},
|
|
_containerClass: function () {
|
|
var direction = this._direction, containerClass = 'k-fx k-fx-start k-fx-' + this._transitionClass;
|
|
if (direction) {
|
|
containerClass += ' k-fx-' + direction;
|
|
}
|
|
if (this._reverse) {
|
|
containerClass += ' k-fx-reverse';
|
|
}
|
|
return containerClass;
|
|
},
|
|
complete: function (e) {
|
|
if (!this.deferred || e && $(e.target).is(IGNORE_TRANSITION_EVENT_SELECTOR)) {
|
|
return;
|
|
}
|
|
var container = this.container;
|
|
container.removeClass('k-fx-end').removeClass(this._containerClass()).off(transitions.event, this.completeProxy);
|
|
this._previous.hide().removeClass('k-fx-current');
|
|
this.element.removeClass('k-fx-next');
|
|
if (RESTORE_OVERFLOW) {
|
|
container.css(OVERFLOW, '');
|
|
}
|
|
if (!this.isAbsolute) {
|
|
this._both().css(POSITION, '');
|
|
}
|
|
this.deferred.resolve();
|
|
delete this.deferred;
|
|
},
|
|
run: function () {
|
|
if (this._additionalEffects && this._additionalEffects[0]) {
|
|
return this.compositeRun();
|
|
}
|
|
var that = this, element = that.element, previous = that._previous, container = element.parents().filter(previous.parents()).first(), both = that._both(), deferred = $.Deferred(), originalPosition = element.css(POSITION), originalOverflow;
|
|
if (!container.length) {
|
|
container = element.parent();
|
|
}
|
|
this.container = container;
|
|
this.deferred = deferred;
|
|
this.isAbsolute = originalPosition == 'absolute';
|
|
if (!this.isAbsolute) {
|
|
both.css(POSITION, 'absolute');
|
|
}
|
|
if (RESTORE_OVERFLOW) {
|
|
originalOverflow = container.css(OVERFLOW);
|
|
container.css(OVERFLOW, 'hidden');
|
|
}
|
|
if (!transitions) {
|
|
this.complete();
|
|
} else {
|
|
element.addClass('k-fx-hidden');
|
|
container.addClass(this._containerClass());
|
|
this.completeProxy = $.proxy(this, 'complete');
|
|
container.on(transitions.event, this.completeProxy);
|
|
kendo.animationFrame(function () {
|
|
element.removeClass('k-fx-hidden').addClass('k-fx-next');
|
|
previous.css('display', '').addClass('k-fx-current');
|
|
that._before(previous, element);
|
|
kendo.animationFrame(function () {
|
|
container.removeClass('k-fx-start').addClass('k-fx-end');
|
|
that._after(previous, element);
|
|
});
|
|
});
|
|
}
|
|
return deferred.promise();
|
|
},
|
|
stop: function () {
|
|
this.complete();
|
|
}
|
|
});
|
|
var Animation = kendo.Class.extend({
|
|
init: function () {
|
|
var that = this;
|
|
that._tickProxy = proxy(that._tick, that);
|
|
that._started = false;
|
|
},
|
|
tick: $.noop,
|
|
done: $.noop,
|
|
onEnd: $.noop,
|
|
onCancel: $.noop,
|
|
start: function () {
|
|
if (!this.enabled()) {
|
|
return;
|
|
}
|
|
if (!this.done()) {
|
|
this._started = true;
|
|
kendo.animationFrame(this._tickProxy);
|
|
} else {
|
|
this.onEnd();
|
|
}
|
|
},
|
|
enabled: function () {
|
|
return true;
|
|
},
|
|
cancel: function () {
|
|
this._started = false;
|
|
this.onCancel();
|
|
},
|
|
_tick: function () {
|
|
var that = this;
|
|
if (!that._started) {
|
|
return;
|
|
}
|
|
that.tick();
|
|
if (!that.done()) {
|
|
kendo.animationFrame(that._tickProxy);
|
|
} else {
|
|
that._started = false;
|
|
that.onEnd();
|
|
}
|
|
}
|
|
});
|
|
var Transition = Animation.extend({
|
|
init: function (options) {
|
|
var that = this;
|
|
extend(that, options);
|
|
Animation.fn.init.call(that);
|
|
},
|
|
done: function () {
|
|
return this.timePassed() >= this.duration;
|
|
},
|
|
timePassed: function () {
|
|
return Math.min(this.duration, new Date() - this.startDate);
|
|
},
|
|
moveTo: function (options) {
|
|
var that = this, movable = that.movable;
|
|
that.initial = movable[that.axis];
|
|
that.delta = options.location - that.initial;
|
|
that.duration = typeof options.duration == 'number' ? options.duration : 300;
|
|
that.tick = that._easeProxy(options.ease);
|
|
that.startDate = new Date();
|
|
that.start();
|
|
},
|
|
_easeProxy: function (ease) {
|
|
var that = this;
|
|
return function () {
|
|
that.movable.moveAxis(that.axis, ease(that.timePassed(), that.initial, that.delta, that.duration));
|
|
};
|
|
}
|
|
});
|
|
extend(Transition, {
|
|
easeOutExpo: function (t, b, c, d) {
|
|
return t == d ? b + c : c * (-Math.pow(2, -10 * t / d) + 1) + b;
|
|
},
|
|
easeOutBack: function (t, b, c, d, s) {
|
|
s = 1.70158;
|
|
return c * ((t = t / d - 1) * t * ((s + 1) * t + s) + 1) + b;
|
|
}
|
|
});
|
|
fx.Animation = Animation;
|
|
fx.Transition = Transition;
|
|
fx.createEffect = createEffect;
|
|
fx.box = function (element) {
|
|
element = $(element);
|
|
var result = element.offset();
|
|
result.width = element.outerWidth();
|
|
result.height = element.outerHeight();
|
|
return result;
|
|
};
|
|
fx.transformOrigin = function (inner, outer) {
|
|
var x = (inner.left - outer.left) * outer.width / (outer.width - inner.width), y = (inner.top - outer.top) * outer.height / (outer.height - inner.height);
|
|
return {
|
|
x: isNaN(x) ? 0 : x,
|
|
y: isNaN(y) ? 0 : y
|
|
};
|
|
};
|
|
fx.fillScale = function (inner, outer) {
|
|
return Math.min(inner.width / outer.width, inner.height / outer.height);
|
|
};
|
|
fx.fitScale = function (inner, outer) {
|
|
return Math.max(inner.width / outer.width, inner.height / outer.height);
|
|
};
|
|
}(window.kendo.jQuery));
|
|
return window.kendo;
|
|
}, typeof define == 'function' && define.amd ? define : function (a1, a2, a3) {
|
|
(a3 || a2)();
|
|
})); |