UNPKG

axe-light

Version:

A Lightweight javascript library extensively for creating animations

518 lines (512 loc) 19.1 kB
/** * * * AXE v1.0.0 and is a lightweight javascript library for creating animations * Lear more about AXE <https://github.com/matnex-mix/AXE.JS/wiki/Introduction> * Copyright (C) <2019> <Jolaosho AbdulMateen (Matnex Mix)> * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. * ** */ if(!String.prototype.endsWith) { String.prototype.endsWith = function($str) { if(this[this.length-1] == $str) return true; return false; } } function AXE($opt) { if(!$opt.a) { return; console.error("AXE: Animation Keyframes not Set"); console.trace(); } else if(!$opt.n) { return; console.error("AXE: Animation Name not Set"); console.trace(); } else if(!$opt.t) { return; console.error("AXE: Animation Duration not Set"); console.trace(); } this.animation = $opt.a; this.name = $opt.n; this.duration = $opt.t; this.iteration = $opt.i||1; this.delay = $opt.d||0; this.timing = $opt.f||"ease-in"; this.mode = $opt.m||""; this.direction = $opt.z||""; this.pseudo = $opt.pseudo||""; !this.pseudo||(this.pseudo = ":"+this.pseudo); this.prepare(); this.build(); }; AXE.prototype.compile_keyframes = function($frames) { if(typeof this != "object") return; var $build_object = {}; try { $ex = $frames.split(/\s*AT[0-9.,%]+\s*/); $mex = $frames.match(/AT[0-9.,%]+/g); $ex.shift(0, 1); $mex.forEach( function($mex_i, $mex_e){ $cur_build_object = {}; $frame_string = $ex[$mex_e].split(";"); $frame_string[$frame_string.length-1]||$frame_string.pop(); $frame_string.forEach(function($fs){ $cur = $fs.split(/\s*:\s*/); $curs = ""; if($cur[0] == "t") { $curs = $cur[1].split(/\s/); $cur[1] = {}; $curs.forEach(function($curS){ $curi = $curS.indexOf("-"); $curS = [$curS.substring(0,$curi), $curS.substring($curi+1)]; $cur[1][$curS[0]] = $curS[1]||""; }); } $cur_build_object[$cur[0]] = $cur[1]||""; }); $nm = $mex_i.substring(2).split(","); $nm.forEach(function($nim) { $build_object[$nim] = $cur_build_object; }); }); this.compiled_frames = $build_object; } catch($ex) { console.log("AXE: Keyframes Sequence Not Properly Formed"); console.trace(); } delete($build_object, $cur_build_object, $cur, $curs, $frames, $frame_string, $ex, $mex); }; AXE.prototype.define_vars = function($vars) { if(typeof this != "object") return; if($vars.startsWith("DEF")) { $real_vars = $vars.replace("DEF", "").replace(":", "").trim(); $real_vars = $real_vars.match(/\$?[A-Za-z_]{1,6}\[[A-Za-z0-9.`]*\]/g); try { this.vars = this.vars||{}; for ($ri = 0; $ri < $real_vars.length; $ri++) { $propv = $real_vars[$ri].replace(/]$/, "").split("["); if($propv[1].startsWith("`")) { this.vars[$propv[0]] = eval($propv[1].substring(1)); } else this.vars[$propv[0]] = $propv[1]; } } catch (ex) { console.log(ex); console.warn("AXE: You have an error in your definition syntax, kindly check and retry"); } }; delete($vars, $real_vars, $propv, $ri); }; AXE.prototype.prepare = function() { if(typeof this != "object") return; $anim = this.animation; if($anim.indexOf("DEF") != -1 && $anim.indexOf("||") != -1) { $anim = $anim.split(/\|\|/); this.define_vars($anim[0].trim()); } else this.compile_keyframes($anim); }; AXE.prototype.build = function() { $class = ".axe-"+this.name+this.pseudo+"{\n"; $arrs = ["", "-webkit-", "-ms-", "-os-"]; $this = this; $arrs.forEach(function($arr){ $class += "\t"+$arr+"animation-name: axeframes-"+$this.name+";\n"; $class += "\t"+$arr+"animation-duration: "+$this.duration+"s;\n"; $class += "\t"+$arr+"animation-iteration-count: "+$this.iteration+";\n"; $class += "\t"+$arr+"animation-delay: "+$this.delay+"s;\n"; $class += "\t"+$arr+"animation-timing-function: "+$this.timing+";\n"; $class += "\t"+$arr+"animation-fill-mode: "+$this.mode+";\n"; $class += "\t"+$arr+"animation-direction: "+$this.direction+";\n"; }); $class += "}"; $Keyframes = "@Keyframes axeframes-"+this.name+" {\n" $axe_obj = this.compiled_frames; for ( $axe in $axe_obj ){ $axes = $axe; if(!$axe.endsWith("%")) $axes = ((parseFloat($axe)/this.duration)*100)+"%"; $Keyframes += "\t"+$axes+" {\n"; for( $axe_ind in $axe_obj[$axe] ) { $axe_main = $axe_obj[$axe][$axe_ind]; $axe_ind = $axe_ind.trim(); if($XE.cssProps[$axe_ind]) { if(typeof $axe_main == "object") { $axe_mains = ""; for($axe_n in $axe_main) { $axe_lit = $axe_n; if($XE.cssProps["-"+$axe_ind+$axe_n]) $axe_lit = $XE.cssProps["-"+$axe_ind+$axe_n].long_name; $axe_mains += $axe_lit+"("+$axe_main[$axe_n]+") "; } $axe_main = $axe_mains; } if(RegExp(/\d+/).test($axe_main)) $axe_main+=$XE.cssProps[$axe_ind].default_unit; $XE.cssProps[$axe_ind].browser_support.forEach(function($br) { $brow = $XE.cssProps[$axe_ind].browser_support[$br]; $Keyframes += "\t\t-"+$br+"-"+$XE.cssProps[$axe_ind].long_name+": "+$axe_main+";\n"; }); $Keyframes += "\t\t"+$XE.cssProps[$axe_ind].long_name+": "+$axe_main+";\n"; } } $Keyframes += "\t}\n"; } $Keyframes += "}"; $el = document.getElementById("axestyle-"+this.name); if(!$el) { $el = document.createElement("style"); $el.id = "axestyle-"+this.name; document.head.appendChild($el); } $el.innerHTML = $class+"\n\n"+$Keyframes; } AXE.prototype.reset = function($new_opt) { this.animation = $new_opt.a||this.animation; if($new_opt.n) { document.head.removeChild(document.getElementById("axestyle-"+this.name)); this.name = $new_opt.n; } this.duration = $new_opt.t||this.duration; this.iteration = $new_opt.i||this.iteration||1; this.delay = $new_opt.d||this.delay||0; this.timing = $new_opt.f||this.timing||"ease-in"; this.mode = $new_opt.m||this.mode||""; this.direction = $new_opt.z||this.direction||""; this.pseudo = $new_opt.pseudo||this.pseudo||""; !this.pseudo||(this.pseudo = ":"+this.pseudo); this.prepare(); this.build(); } AXE.prototype.setFrames = function($frame_object) { $df_object = this.compiled_frames; if(typeof $frame_object == "string") { this.compile_keyframes($frame_object); $frame_object = this.compiled_frames; } try { for ($frame in $frame_object) { if(!$df_object[$frame] || $frame.axe_write) { $df_object[$frame] = {}; } for ($frames in $frame_object[$frame]) { $df_object[$frame][$frames] = $frame_object[$frame][$frames]; } } this.compiled_frames = $df_object; this.build(); } catch(ex) { console.error("AXE Error: Unknown Error Ocurred"); console.trace(); this.compiled_frames = $df_object; } } AXE.prototype.apply = function($el_s) { if(typeof $el_s == "string") $el_s = document.querySelector($el_s); if($el_s.length) { $el_s.forEach(function($el_){ $el_.classList.add("axe-paused"); $el_.classList.add("axe-"+this.name); $el_.setAttribute("data-axe-class", "axe-"+this.name); }); } $el_s.classList.add("axe-paused"); $el_s.setAttribute("data-axe-class", "axe-"+this.name); $axec = $XE.control($el_s); if(this.ini) this.ini($axec); return $axec; } function AXECONTROLS($el_s) { try { if(typeof $el_s == "string") $el_s = document.querySelector($el_s); if($el_s.length) { $el_s.forEach(function($el_, $i){ $obj = {DOM: $el_, index: $i} $obj.__proto__ = this.__proto__; $this = this; $el_.onanimationstart = function(){ $this.runEvents("start"); }; $el_.onanimationcancel = function(){ $this.runEvents("cancel"); }; $el_.onanimationiteration = function(){ $this.runEvents("cycle"); }; $el_.onanimationend = function(){ $this.runEvents("end"); }; this[$i] = $obj; }); this.length = $el_s.length; } else { $obj = {DOM: $el_s, index: 0}; $obj.__proto__ = this.__proto__; $this = this; $el_s.onanimationstart = function(){ $this.runEvents("start"); }; $el_s.onanimationcancel = function(){ $this.runEvents("cancel"); }; $el_s.onanimationiteration = function(){ $this.runEvents("cycle"); }; $el_s.onanimationend = function(){ $this.runEvents("end"); }; this[0] = $obj; this.length = 1; } this.index = -1; } catch (ex) { console.log("AXE: Catched Exception; "+ex); } }; AXECONTROLS.prototype.start = function (){ if(this.index == -1) { this.forEach(function($v){ $v.start(); }); return; } $class = this.DOM.dataset.axeClass; this.DOM.classList.add($class); this.play(); }; AXECONTROLS.prototype.pause = function (){ if(this.index == -1) { this.forEach(function($v){ $v.pause(); }); return; } this.DOM.classList.add("axe-paused"); this.runEvents("pause"); }; AXECONTROLS.prototype.play = function (){ if(this.index == -1) { this.forEach(function($v){ $v.play(); }); return; } this.DOM.classList.remove("axe-paused"); this.runEvents("play"); }; AXECONTROLS.prototype.end = function (){ if(this.index == -1) { this.forEach(function($v){ $v.end(); }); return; } $class = this.DOM.dataset.axeClass; this.DOM.classList.remove($class); this.pause(); }; AXECONTROLS.prototype.restart = function (){ if(this.index == -1) { this.forEach(function($v){ $v.restart(); }); return; } this.end(); $this = this; setTimeout(function() { $this.start(); }, 10); this.runEvents("restart"); }; AXECONTROLS.prototype.forEach = function($_do){ for($i = 0; $i < this.length; $i++) { $_do(this[$i], $i); } }; AXECONTROLS.prototype.event = function($event_name, $_do) { if(!this.events) this.events = {}; if(!this.events[$event_name]) this.events[$event_name] = []; this.events[$event_name].push(btoa($_do)); }; AXECONTROLS.prototype.r_event = function($event_name, $_do) { if(!this.events[$event_name]) { console.warn("AXE: Attempting to Remove function of undefined Event Type"); return; } $i = this.events[$event_name].indexOf(btoa($_do)); if($i != -1) this.events[$event_name].shift($i, 1); }; AXECONTROLS.prototype.runEvents = function($event_name) { if(!this.events) this.events = {}; if(this.index == -1) { this.forEach(function($this){ $this.runEvents($event_name); }); return; } if(this.events[$event_name]) { this.events[$event_name].forEach(function($_do){ eval("("+atob($_do)+")()"); }); } } AXECONTROLS.prototype.moment = function ($ct) { $ct = $ct.split(","); $func = btoa($ct.join(',')).replace(/=/gi,""); eval($func+' = function () { $this[$ct[0]](); }'); if(!$ct[2]) { if(this.index == -1) { var $this = this; this.forEach(function($obj){ eval('$obj.DOM.addEventListener($ct[1].trim(), '+$func+')'); }); } else { var $this = this; eval('this.DOM.addEventListener($ct[1].trim(), '+$func+')'); } } else { $els = document.querySelectorAll($ct[2].trim()); if($els.length > 1) { var $this = this; $els.forEach(function($obj){ eval('$obj.addEventListener($ct[1].trim(), '+$func+')'); }); } else { var $this = this; eval('$els[0].addEventListener($ct[1].trim(), '+$func+')'); } } } AXECONTROLS.prototype.r_moment = function($ct) { if($ct.toUpperCase() === "CLEAR") $XE.moments = {}; else { $id = btoa($ct).replace(/=/gi,""); if($XE.moments[$id]) delete($XE.moments[$id]); $ct = $ct.split(","); if(!$ct[2]) { if(this.index == -1) { var $this = this; this.forEach(function($obj){ eval('$obj.DOM.removeEventListener($ct[1].trim(), '+$id+')'); }); } else { var $this = this; eval('this.DOM.removeEventListener($ct[1].trim(), '+$id+')'); } } else { $els = document.querySelectorAll($ct[2].trim()); if($els.length > 1) { var $this = this; $els.forEach(function($obj){ eval('$obj.removeEventListener($ct[1].trim(), '+$id+')'); }); } else { var $this = this; eval('$els[0].removeEventListener($ct[1].trim(), '+$id+')'); } } } } function AXEEASY($name, $opt) { if(typeof $xeasy !== "object") { console.log("AXE: Cannot use Easy-Axe, Module not loaded"); console.trace(); return; } if($xeasy[$name]) { $easy = new AXE($xeasy[$name]); if($opt) $easy.reset($opt); if($xeasy[$name].ini) $xeasy[$name].ini($easy); return $easy; } else { console.warn("AXE: Trying to Use undefined AXE-EASY Animation"); console.trace(); } } var $XE = { "$": function ($opt) { return new AXE($opt); }, OPTIMIZE: { registerCssProp: function($short_name, $long_name, $browser_support, $dft_ext) { if(!$short_name) return console.log("AXE: registerCssProp; short_name not specified"); if(!$long_name) return console.log("AXE: registerCssProp; long_name not specified"); $browser_support = $browser_support||""; $browser_support = $browser_support.replace("o", "|os|").replace("m", "|moz|").replace("e", "|ms|").replace("w", "|webkit|"); $browser_support = $browser_support.split(/\s*\|\|?\s*/)||[]; $browser_support.pop(); $browser_support.shift(0, 1); $XE.cssProps[$short_name] = {"long_name": $long_name, "browser_support": $browser_support||"", "default_unit": $dft_ext||""} }, cssPropExists: function($short_name) { return $XE.cssProps.hasOwnProperty($short_name); } }, cssProps: {}, Initialize: function() { $axe_style = document.createElement("style"); $axe_style.innerHTML = ".axe-paused{animation-play-state: paused !important;}"; document.head.appendChild($axe_style); }, moments: {}, control: function($el_s) { return new AXECONTROLS($el_s); }, easy: function($axe_name, $axe_options) { return AXEEASY($axe_name, $axe_options); } } if(document.readyState != "loading") { document.addEventListener("DOMContentLoaded", function() { $XE.Initialize(); }); } else { $XE.Initialize(); } $XE.OPTIMIZE.registerCssProp("t", "transform", "mwoe"); $XE.OPTIMIZE.registerCssProp("-tr", "rotate"); $XE.OPTIMIZE.registerCssProp("-trX", "rotateX"); $XE.OPTIMIZE.registerCssProp("-trY", "rotateY"); $XE.OPTIMIZE.registerCssProp("-ts", "scale"); $XE.OPTIMIZE.registerCssProp("-tsX", "scaleX"); $XE.OPTIMIZE.registerCssProp("-tsY", "scaleY"); $XE.OPTIMIZE.registerCssProp("-tsk", "skew"); $XE.OPTIMIZE.registerCssProp("-tskX", "skewX"); $XE.OPTIMIZE.registerCssProp("-tskY", "skewY"); $XE.OPTIMIZE.registerCssProp("-tt", "translate"); $XE.OPTIMIZE.registerCssProp("-ttX", "translateX"); $XE.OPTIMIZE.registerCssProp("-ttY", "translateY"); $XE.OPTIMIZE.registerCssProp("bg","background"); $XE.OPTIMIZE.registerCssProp("bga","background-attachment"); $XE.OPTIMIZE.registerCssProp("bgc","background-color"); $XE.OPTIMIZE.registerCssProp("bgi","background-image"); $XE.OPTIMIZE.registerCssProp("bgp","background-position"); $XE.OPTIMIZE.registerCssProp("bgr","background-repeat"); $XE.OPTIMIZE.registerCssProp("b","border"); $XE.OPTIMIZE.registerCssProp("bb","border-bottom"); $XE.OPTIMIZE.registerCssProp("bbc","border-bottom-color"); $XE.OPTIMIZE.registerCssProp("bbs","border-bottom-style"); $XE.OPTIMIZE.registerCssProp("bbw","border-bottom-width"); $XE.OPTIMIZE.registerCssProp("bc","border-color"); $XE.OPTIMIZE.registerCssProp("bl","border-left"); $XE.OPTIMIZE.registerCssProp("blc","border-left-color"); $XE.OPTIMIZE.registerCssProp("bls","border-left-style"); $XE.OPTIMIZE.registerCssProp("blw","border-left-width"); $XE.OPTIMIZE.registerCssProp("br","border-right"); $XE.OPTIMIZE.registerCssProp("brc","border-right-color"); $XE.OPTIMIZE.registerCssProp("brs","border-right-style"); $XE.OPTIMIZE.registerCssProp("brw","border-right-width"); $XE.OPTIMIZE.registerCssProp("bs","border-style"); $XE.OPTIMIZE.registerCssProp("bt","border-top"); $XE.OPTIMIZE.registerCssProp("btc","border-top-color"); $XE.OPTIMIZE.registerCssProp("bts","border-top-style"); $XE.OPTIMIZE.registerCssProp("btw","border-top-width"); $XE.OPTIMIZE.registerCssProp("bw","border-width"); $XE.OPTIMIZE.registerCssProp("clr","clear"); $XE.OPTIMIZE.registerCssProp("clp","clip"); $XE.OPTIMIZE.registerCssProp("col","color"); $XE.OPTIMIZE.registerCssProp("cur","cursor"); $XE.OPTIMIZE.registerCssProp("dis","display"); $XE.OPTIMIZE.registerCssProp("fil","filter"); $XE.OPTIMIZE.registerCssProp("fl","float"); $XE.OPTIMIZE.registerCssProp("f","font"); $XE.OPTIMIZE.registerCssProp("ff","font-family"); $XE.OPTIMIZE.registerCssProp("fs","font-size"); $XE.OPTIMIZE.registerCssProp("fv","font-variant"); $XE.OPTIMIZE.registerCssProp("fw","font-weight"); $XE.OPTIMIZE.registerCssProp("h","height"); $XE.OPTIMIZE.registerCssProp("lef","left"); $XE.OPTIMIZE.registerCssProp("lts","letter-spacing"); $XE.OPTIMIZE.registerCssProp("lh","line-height"); $XE.OPTIMIZE.registerCssProp("ls","list-style"); $XE.OPTIMIZE.registerCssProp("lsi","list-style-image"); $XE.OPTIMIZE.registerCssProp("lsp","list-style-position"); $XE.OPTIMIZE.registerCssProp("lst","list-style-type"); $XE.OPTIMIZE.registerCssProp("m","margin"); $XE.OPTIMIZE.registerCssProp("mb","margin-bottom"); $XE.OPTIMIZE.registerCssProp("ml","margin-left"); $XE.OPTIMIZE.registerCssProp("mr","margin-right"); $XE.OPTIMIZE.registerCssProp("mt","margin-top"); $XE.OPTIMIZE.registerCssProp("o","opacity"); $XE.OPTIMIZE.registerCssProp("ov","overflow"); $XE.OPTIMIZE.registerCssProp("ox","overflow-x"); $XE.OPTIMIZE.registerCssProp("oy","overflow-y"); $XE.OPTIMIZE.registerCssProp("p","padding"); $XE.OPTIMIZE.registerCssProp("pb","padding-bottom"); $XE.OPTIMIZE.registerCssProp("pl","padding-left"); $XE.OPTIMIZE.registerCssProp("pr","padding-right"); $XE.OPTIMIZE.registerCssProp("pt","padding-top"); $XE.OPTIMIZE.registerCssProp("pba","page-break-after"); $XE.OPTIMIZE.registerCssProp("pbb","page-break-before"); $XE.OPTIMIZE.registerCssProp("pos","position"); $XE.OPTIMIZE.registerCssProp("sda","stroke-dasharray"); $XE.OPTIMIZE.registerCssProp("sdo","stroke-dashoffset"); $XE.OPTIMIZE.registerCssProp("sw","stroke-width"); $XE.OPTIMIZE.registerCssProp("ta","text-align"); $XE.OPTIMIZE.registerCssProp("td","text-decoration"); $XE.OPTIMIZE.registerCssProp("ti","text-indent"); $XE.OPTIMIZE.registerCssProp("tt","text-transform"); $XE.OPTIMIZE.registerCssProp("top","top"); $XE.OPTIMIZE.registerCssProp("va","vertical-align"); $XE.OPTIMIZE.registerCssProp("vis","visibility"); $XE.OPTIMIZE.registerCssProp("w","width"); $XE.OPTIMIZE.registerCssProp("z","z-index");