Guest User

Untitled

a guest
Jun 28th, 2019
119
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. import Vue from "vue";
  2. import anime from "animejs";
  3. import $ from "jquery";
  4. import async from "async";
  5.  
  6. class VueAnimatorSequence {
  7.   constructor(list) {
  8.     this.list = list;
  9.     this.vue = null;
  10.     this.promise = Promise.resolve();
  11.     this.animejsObjects = [];
  12.     this.state = new Proxy(
  13.       {
  14.         busy: false,
  15.         done: true,
  16.         stopped: false,
  17.         onStop: () => {}
  18.       },
  19.       {
  20.         set: function(target, prop, value) {
  21.           if (prop === "stopped") {
  22.             target.onStop();
  23.             target.stopped = value;
  24.           } else {
  25.             target[prop] = value;
  26.           }
  27.           return true;
  28.         }
  29.       }
  30.     );
  31.   }
  32.  
  33.   makeSequence() {
  34.     let list = this.list;
  35.     this.tasks = [];
  36.     for (const element of list) {
  37.       this.tasks.push(callback => {
  38.         this.state.onStop = () => {
  39.           //if (callback != null)
  40.           callback(true);
  41.         };
  42.         this.executeCommand(element).then(() => {
  43.           if (!this.state.stopped) callback();
  44.         });
  45.       });
  46.     }
  47.   }
  48.  
  49.   start(vue) {
  50.     this.stop();
  51.     this.vue = vue;
  52.     this.state.stopped = false;
  53.     this.state.busy = true;
  54.     this.state.done = false;
  55.     return new Promise((resolve, reject) => {
  56.       this.makeSequence();
  57.       async.waterfall(this.tasks, (err, results) => {
  58.         resolve();
  59.         this.stop();
  60.       });
  61.     });
  62.   }
  63.  
  64.   stop() {
  65.     this.state.onStop = () => {};
  66.     this.state.stopped = true;
  67.     this.state.busy = false;
  68.     this.state.done = true;
  69.     for (let obj of this.animejsObjects) {
  70.       obj.seek(obj.duration);
  71.       //obj.pause();
  72.     }
  73.     this.animejsObjects = [];
  74.   }
  75.  
  76.   executeCommand(command) {
  77.     if (typeof command === "string") {
  78.       if (command.match(/(.+)\s?\:\s?(.+)/i)) {
  79.         let commandName = RegExp.$1.trim();
  80.         let values = RegExp.$2
  81.           .trim()
  82.           .split(";")
  83.           .map(s => s.trim());
  84.         let func = this["executeCommand_" + commandName];
  85.         if (func) {
  86.           return this["executeCommand_" + commandName](...values);
  87.         } else {
  88.           console.log("command not found:", command);
  89.           return Promise.resolve();
  90.         }
  91.       }
  92.     } else if (command instanceof Array) {
  93.       return Promise.all(command.map(c => this.executeCommand(c)));
  94.     } else {
  95.       let props = Object.assign({}, command);
  96.       props.targets = this.getElementTargets(command.targets);
  97.       return new Promise((resolve, reject) => {
  98.         props.complete = () => resolve();
  99.         this.animejsObjects.push(anime(props));
  100.       });
  101.     }
  102.   }
  103.  
  104.   executeCommand_debug(message) {
  105.     console.log("message :", message);
  106.     return Promise.resolve();
  107.   }
  108.  
  109.   executeCommand_scatterText(targets, className) {
  110.     let elements = this.getElementTargets(targets);
  111.     for (const element of elements) {
  112.       let text = element.innerText;
  113.       let words = text.split(" ");
  114.       element.innerHTML = "";
  115.       for (const word of words) {
  116.         element.innerHTML += `<span class="${className + "-word"}">
  117.         ${word}</span>`;
  118.       }
  119.       element.style.display = "flex";
  120.       element.style.flexWrap = "wrap";
  121.       for (const child of element.childNodes) {
  122.         if (child.style) {
  123.           child.style.display = "flex";
  124.           let letters = Array.from(child.innerText);
  125.           child.innerHTML = "";
  126.           for (const letter of letters) {
  127.             child.innerHTML += `<span class="${className}">${letter}</span>`;
  128.           }
  129.           child.innerHTML += `&nbsp`;
  130.         }
  131.       }
  132.       /*
  133.       element.style.display = "flex";
  134.       for (const child of element.childNodes) {
  135.         if (child.style) {
  136.           child.style.display = "flex";
  137.           child.style.flexWrap = "wrap";
  138.           child.innerHTML = child.innerText.replace(
  139.             /([^\x00-\x80]|\w\,?\.?)/g,
  140.             "<span class='" + className + "'>$&</span>"
  141.           );
  142.         }
  143.       }*/
  144.     }
  145.     /*$(elements).each(function () {
  146.         $(this).html(
  147.             $(this)
  148.                 .text()
  149.                 .replace(/([^\x00-\x80]|\w\,?\.?)/g, "<span class='" + className + "'>$&</span>")
  150.         );
  151.     });*/
  152.     return Promise.resolve();
  153.   }
  154.  
  155.   executeCommand_css(targets, style, value) {
  156.     let elements = this.getElementTargets(targets);
  157.     $(elements).css(style, value);
  158.     return Promise.resolve();
  159.   }
  160.  
  161.   executeCommand_anime(targets, name) {
  162.     let components = this.getComponentTargets(targets);
  163.     return Promise.all(
  164.       components.map(vue => vue.$animator.startAnimation(vue, name))
  165.     );
  166.   }
  167.   executeCommand_wait(value) {
  168.     value = parseInt(value);
  169.     return new Promise((resolve, reject) => {
  170.       setTimeout(() => {
  171.         resolve();
  172.       }, value);
  173.     });
  174.   }
  175.  
  176.   getElementTargets(query) {
  177.     let el = this.vue.$el;
  178.     let results = el.querySelectorAll(query);
  179.     if (el.matches(query)) {
  180.       results = Array.from(results);
  181.       results.push(el);
  182.     }
  183.     return results;
  184.   }
  185.  
  186.   getComponentTargets(query) {
  187.     let names = query.split(",");
  188.     let results = [];
  189.     names.forEach(n => {
  190.       Vue.AnimatorComponents.forEach(c => {
  191.         if (c.$options.name === n) results.push(c);
  192.       });
  193.     });
  194.     return results;
  195.   }
  196. }
  197.  
  198. export class VueAnimator {
  199.   constructor() {}
  200.  
  201.   makeAnimations() {
  202.     let conf = Vue.AnimatorData;
  203.     this.animations = {};
  204.     for (const key in conf) {
  205.       if (conf.hasOwnProperty(key)) {
  206.         const componentName = key;
  207.         let object = conf[componentName];
  208.  
  209.         this.animations[componentName] = {};
  210.         for (const key in object) {
  211.           if (object.hasOwnProperty(key)) {
  212.             const element = object[key];
  213.             if (element instanceof Array) {
  214.               this.animations[componentName][key] = new VueAnimatorSequence(
  215.                 element
  216.               );
  217.             } else {
  218.               this.animations[componentName][key] = element;
  219.             }
  220.           }
  221.         }
  222.       }
  223.     }
  224.   }
  225.  
  226.   startAnimation(vue, name) {
  227.     this.makeAnimations();
  228.     let animations = this.animations[vue.$options.name] || {};
  229.     let seq = animations[name];
  230.     if (seq) {
  231.       return seq.start(vue);
  232.     }
  233.     return Promise.resolve();
  234.   }
  235.  
  236.   stop() {
  237.     this.allAnimations().forEach(s => {
  238.       s.stop();
  239.     });
  240.   }
  241.  
  242.   allAnimations() {
  243.     let object = this.animations;
  244.     let seqs = [];
  245.     for (const key in object) {
  246.       if (object.hasOwnProperty(key)) {
  247.         const element = object[key];
  248.         for (const key in element) {
  249.           if (element.hasOwnProperty(key)) {
  250.             const ele = element[key];
  251.             if (ele instanceof VueAnimatorSequence) seqs.push(ele);
  252.           }
  253.         }
  254.       }
  255.     }
  256.     return seqs;
  257.   }
  258. }
  259.  
  260. const Animator = {
  261.   install(Vue, options) {
  262.     Vue.AnimatorData = options || {};
  263.     Vue.prototype.$animator = new VueAnimator();
  264.     Vue.AnimatorComponents = [];
  265.     Vue.AnimationDataAdd = function(data, comp) {
  266.       Vue.AnimatorData[comp] = data;
  267.     };
  268.     Vue.mixin({
  269.       created() {
  270.         Vue.AnimatorComponents.push(this);
  271.         let animations = this.$options.animation;
  272.         if (animations) Vue.AnimationDataAdd(animations, this.$options.name);
  273.       },
  274.       beforeRouteLeave(to, from, next) {
  275.         this.$animator.stop();
  276.         this.$animator.startAnimation(this, "routeLeave").then(() => {
  277.           next();
  278.         });
  279.       },
  280.       mounted() {
  281.         //this.$animator.stop();
  282.         this.$animator.startAnimation(this, "mounted");
  283.       },
  284.       destroyed() {
  285.         this.$animator.stop();
  286.       }
  287.     });
  288.   }
  289. };
  290.  
  291. export default Animator;
Advertisement
Add Comment
Please, Sign In to add comment