Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import Vue from "vue";
- import anime from "animejs";
- import $ from "jquery";
- import async from "async";
- class VueAnimatorSequence {
- constructor(list) {
- this.list = list;
- this.vue = null;
- this.promise = Promise.resolve();
- this.animejsObjects = [];
- this.state = new Proxy(
- {
- busy: false,
- done: true,
- stopped: false,
- onStop: () => {}
- },
- {
- set: function(target, prop, value) {
- if (prop === "stopped") {
- target.onStop();
- target.stopped = value;
- } else {
- target[prop] = value;
- }
- return true;
- }
- }
- );
- }
- makeSequence() {
- let list = this.list;
- this.tasks = [];
- for (const element of list) {
- this.tasks.push(callback => {
- this.state.onStop = () => {
- //if (callback != null)
- callback(true);
- };
- this.executeCommand(element).then(() => {
- if (!this.state.stopped) callback();
- });
- });
- }
- }
- start(vue) {
- this.stop();
- this.vue = vue;
- this.state.stopped = false;
- this.state.busy = true;
- this.state.done = false;
- return new Promise((resolve, reject) => {
- this.makeSequence();
- async.waterfall(this.tasks, (err, results) => {
- resolve();
- this.stop();
- });
- });
- }
- stop() {
- this.state.onStop = () => {};
- this.state.stopped = true;
- this.state.busy = false;
- this.state.done = true;
- for (let obj of this.animejsObjects) {
- obj.seek(obj.duration);
- //obj.pause();
- }
- this.animejsObjects = [];
- }
- executeCommand(command) {
- if (typeof command === "string") {
- if (command.match(/(.+)\s?\:\s?(.+)/i)) {
- let commandName = RegExp.$1.trim();
- let values = RegExp.$2
- .trim()
- .split(";")
- .map(s => s.trim());
- let func = this["executeCommand_" + commandName];
- if (func) {
- return this["executeCommand_" + commandName](...values);
- } else {
- console.log("command not found:", command);
- return Promise.resolve();
- }
- }
- } else if (command instanceof Array) {
- return Promise.all(command.map(c => this.executeCommand(c)));
- } else {
- let props = Object.assign({}, command);
- props.targets = this.getElementTargets(command.targets);
- return new Promise((resolve, reject) => {
- props.complete = () => resolve();
- this.animejsObjects.push(anime(props));
- });
- }
- }
- executeCommand_debug(message) {
- console.log("message :", message);
- return Promise.resolve();
- }
- executeCommand_scatterText(targets, className) {
- let elements = this.getElementTargets(targets);
- for (const element of elements) {
- let text = element.innerText;
- let words = text.split(" ");
- element.innerHTML = "";
- for (const word of words) {
- element.innerHTML += `<span class="${className + "-word"}">
- ${word}</span>`;
- }
- element.style.display = "flex";
- element.style.flexWrap = "wrap";
- for (const child of element.childNodes) {
- if (child.style) {
- child.style.display = "flex";
- let letters = Array.from(child.innerText);
- child.innerHTML = "";
- for (const letter of letters) {
- child.innerHTML += `<span class="${className}">${letter}</span>`;
- }
- child.innerHTML += ` `;
- }
- }
- /*
- element.style.display = "flex";
- for (const child of element.childNodes) {
- if (child.style) {
- child.style.display = "flex";
- child.style.flexWrap = "wrap";
- child.innerHTML = child.innerText.replace(
- /([^\x00-\x80]|\w\,?\.?)/g,
- "<span class='" + className + "'>$&</span>"
- );
- }
- }*/
- }
- /*$(elements).each(function () {
- $(this).html(
- $(this)
- .text()
- .replace(/([^\x00-\x80]|\w\,?\.?)/g, "<span class='" + className + "'>$&</span>")
- );
- });*/
- return Promise.resolve();
- }
- executeCommand_css(targets, style, value) {
- let elements = this.getElementTargets(targets);
- $(elements).css(style, value);
- return Promise.resolve();
- }
- executeCommand_anime(targets, name) {
- let components = this.getComponentTargets(targets);
- return Promise.all(
- components.map(vue => vue.$animator.startAnimation(vue, name))
- );
- }
- executeCommand_wait(value) {
- value = parseInt(value);
- return new Promise((resolve, reject) => {
- setTimeout(() => {
- resolve();
- }, value);
- });
- }
- getElementTargets(query) {
- let el = this.vue.$el;
- let results = el.querySelectorAll(query);
- if (el.matches(query)) {
- results = Array.from(results);
- results.push(el);
- }
- return results;
- }
- getComponentTargets(query) {
- let names = query.split(",");
- let results = [];
- names.forEach(n => {
- Vue.AnimatorComponents.forEach(c => {
- if (c.$options.name === n) results.push(c);
- });
- });
- return results;
- }
- }
- export class VueAnimator {
- constructor() {}
- makeAnimations() {
- let conf = Vue.AnimatorData;
- this.animations = {};
- for (const key in conf) {
- if (conf.hasOwnProperty(key)) {
- const componentName = key;
- let object = conf[componentName];
- this.animations[componentName] = {};
- for (const key in object) {
- if (object.hasOwnProperty(key)) {
- const element = object[key];
- if (element instanceof Array) {
- this.animations[componentName][key] = new VueAnimatorSequence(
- element
- );
- } else {
- this.animations[componentName][key] = element;
- }
- }
- }
- }
- }
- }
- startAnimation(vue, name) {
- this.makeAnimations();
- let animations = this.animations[vue.$options.name] || {};
- let seq = animations[name];
- if (seq) {
- return seq.start(vue);
- }
- return Promise.resolve();
- }
- stop() {
- this.allAnimations().forEach(s => {
- s.stop();
- });
- }
- allAnimations() {
- let object = this.animations;
- let seqs = [];
- for (const key in object) {
- if (object.hasOwnProperty(key)) {
- const element = object[key];
- for (const key in element) {
- if (element.hasOwnProperty(key)) {
- const ele = element[key];
- if (ele instanceof VueAnimatorSequence) seqs.push(ele);
- }
- }
- }
- }
- return seqs;
- }
- }
- const Animator = {
- install(Vue, options) {
- Vue.AnimatorData = options || {};
- Vue.prototype.$animator = new VueAnimator();
- Vue.AnimatorComponents = [];
- Vue.AnimationDataAdd = function(data, comp) {
- Vue.AnimatorData[comp] = data;
- };
- Vue.mixin({
- created() {
- Vue.AnimatorComponents.push(this);
- let animations = this.$options.animation;
- if (animations) Vue.AnimationDataAdd(animations, this.$options.name);
- },
- beforeRouteLeave(to, from, next) {
- this.$animator.stop();
- this.$animator.startAnimation(this, "routeLeave").then(() => {
- next();
- });
- },
- mounted() {
- //this.$animator.stop();
- this.$animator.startAnimation(this, "mounted");
- },
- destroyed() {
- this.$animator.stop();
- }
- });
- }
- };
- export default Animator;
Advertisement
Add Comment
Please, Sign In to add comment