import { window } from 'ssr-window';
|
import { requestAnimationFrame, cancelAnimationFrame } from './utils';
|
|
function animate(initialProps, initialParams) {
|
const els = this;
|
const a = {
|
props: Object.assign({}, initialProps),
|
params: Object.assign({
|
duration: 300,
|
easing: 'swing', // or 'linear'
|
/* Callbacks
|
begin(elements)
|
complete(elements)
|
progress(elements, complete, remaining, start, tweenValue)
|
*/
|
}, initialParams),
|
|
elements: els,
|
animating: false,
|
que: [],
|
|
easingProgress(easing, progress) {
|
if (easing === 'swing') {
|
return 0.5 - (Math.cos(progress * Math.PI) / 2);
|
}
|
if (typeof easing === 'function') {
|
return easing(progress);
|
}
|
return progress;
|
},
|
stop() {
|
if (a.frameId) {
|
cancelAnimationFrame(a.frameId);
|
}
|
a.animating = false;
|
a.elements.each((index, el) => {
|
const element = el;
|
delete element.dom7AnimateInstance;
|
});
|
a.que = [];
|
},
|
done(complete) {
|
a.animating = false;
|
a.elements.each((index, el) => {
|
const element = el;
|
delete element.dom7AnimateInstance;
|
});
|
if (complete) complete(els);
|
if (a.que.length > 0) {
|
const que = a.que.shift();
|
a.animate(que[0], que[1]);
|
}
|
},
|
animate(props, params) {
|
if (a.animating) {
|
a.que.push([props, params]);
|
return a;
|
}
|
const elements = [];
|
|
// Define & Cache Initials & Units
|
a.elements.each((index, el) => {
|
let initialFullValue;
|
let initialValue;
|
let unit;
|
let finalValue;
|
let finalFullValue;
|
|
if (!el.dom7AnimateInstance) a.elements[index].dom7AnimateInstance = a;
|
|
elements[index] = {
|
container: el,
|
};
|
Object.keys(props).forEach((prop) => {
|
initialFullValue = window.getComputedStyle(el, null).getPropertyValue(prop).replace(',', '.');
|
initialValue = parseFloat(initialFullValue);
|
unit = initialFullValue.replace(initialValue, '');
|
finalValue = parseFloat(props[prop]);
|
finalFullValue = props[prop] + unit;
|
elements[index][prop] = {
|
initialFullValue,
|
initialValue,
|
unit,
|
finalValue,
|
finalFullValue,
|
currentValue: initialValue,
|
};
|
});
|
});
|
|
let startTime = null;
|
let time;
|
let elementsDone = 0;
|
let propsDone = 0;
|
let done;
|
let began = false;
|
|
a.animating = true;
|
|
function render() {
|
time = new Date().getTime();
|
let progress;
|
let easeProgress;
|
// let el;
|
if (!began) {
|
began = true;
|
if (params.begin) params.begin(els);
|
}
|
if (startTime === null) {
|
startTime = time;
|
}
|
if (params.progress) {
|
// eslint-disable-next-line
|
params.progress(els, Math.max(Math.min((time - startTime) / params.duration, 1), 0), ((startTime + params.duration) - time < 0 ? 0 : (startTime + params.duration) - time), startTime);
|
}
|
|
elements.forEach((element) => {
|
const el = element;
|
if (done || el.done) return;
|
Object.keys(props).forEach((prop) => {
|
if (done || el.done) return;
|
progress = Math.max(Math.min((time - startTime) / params.duration, 1), 0);
|
easeProgress = a.easingProgress(params.easing, progress);
|
const { initialValue, finalValue, unit } = el[prop];
|
el[prop].currentValue = initialValue + (easeProgress * (finalValue - initialValue));
|
const currentValue = el[prop].currentValue;
|
|
if (
|
(finalValue > initialValue && currentValue >= finalValue) ||
|
(finalValue < initialValue && currentValue <= finalValue)) {
|
el.container.style[prop] = finalValue + unit;
|
propsDone += 1;
|
if (propsDone === Object.keys(props).length) {
|
el.done = true;
|
elementsDone += 1;
|
}
|
if (elementsDone === elements.length) {
|
done = true;
|
}
|
}
|
if (done) {
|
a.done(params.complete);
|
return;
|
}
|
el.container.style[prop] = currentValue + unit;
|
});
|
});
|
if (done) return;
|
// Then call
|
a.frameId = requestAnimationFrame(render);
|
}
|
a.frameId = requestAnimationFrame(render);
|
return a;
|
},
|
};
|
|
if (a.elements.length === 0) {
|
return els;
|
}
|
|
let animateInstance;
|
for (let i = 0; i < a.elements.length; i += 1) {
|
if (a.elements[i].dom7AnimateInstance) {
|
animateInstance = a.elements[i].dom7AnimateInstance;
|
} else a.elements[i].dom7AnimateInstance = a;
|
}
|
if (!animateInstance) {
|
animateInstance = a;
|
}
|
|
if (initialProps === 'stop') {
|
animateInstance.stop();
|
} else {
|
animateInstance.animate(a.props, a.params);
|
}
|
|
return els;
|
}
|
|
function stop() {
|
const els = this;
|
for (let i = 0; i < els.length; i += 1) {
|
if (els[i].dom7AnimateInstance) {
|
els[i].dom7AnimateInstance.stop();
|
}
|
}
|
}
|
|
export { animate, stop };
|