zoukankan      html  css  js  c++  java
  • 每日一库:Émile.js

    Émile.js是一个小型的动画库,只有短短几十行代码,但是做简单的动画足够应付了。 如果有时你不想引入巨大的基础库,想试试‘小米加步枪’的作业方式,可以参考下。 这样的动画库,现在看起来可能有点简陋了,但是还是可以学到一些基本原理。以下是源码分析和一些例子: 

    emile.js 例子

    ①改变颜色

     
    emile($('example_1'), 'background-color: rgb(0, 0, 0)', {duration: 500});

    Run | Reset

    ②直线运动

     
    emile($('example_2'), 'margin-left: 200px', {duration: 500});

    Run | Reset

    ③定制运动算法

     
    function bounce(pos) {
      if (pos < (1 / 2.75)) {
        return (7.5625 * pos * pos);
      } else if (pos < (2 / 2.75)) {
        return (7.5625 * (pos -= (1.5 / 2.75)) * pos + .75);
      } else if (pos < (2.5 / 2.75)) {
        return (7.5625 * (pos -= (2.25 / 2.75)) * pos + .9375);
      } else {
        return (7.5625 * (pos -= (2.625 / 2.75)) * pos + .984375);
      }
    }
    emile($('example_3'), 'margin-left: 200px', {duration: 1500, easing: bounce});

    Run | Reset

    ④同时改变颜色和直线运动

     
    emile($('example_4'), 'margin-left: 200px; background-color: #000', {duration: 1500, easing: bounce});

    Run | Reset

    ⑤回调函数

     
    emile($('example_5'), 'margin-left: 200px; background-color: #000', {
      duration: 1500,
      easing: bounce,
      after: function() { emile($('example_5'), 'margin-left: 0; opacity: 0.0', {duration: 1500}); }});
        

    Run | Reset

    (function(emile, container){
      var parseEl = document.createElement('div'),
        props = ('backgroundColor borderBottomColor borderBottomWidth borderLeftColor borderLeftWidth '+
        'borderRightColor borderRightWidth borderSpacing borderTopColor borderTopWidth bottom color fontSize '+
        'fontWeight height left letterSpacing lineHeight marginBottom marginLeft marginRight marginTop maxHeight '+
        'maxWidth minHeight minWidth opacity outlineColor outlineOffset outlineWidth paddingBottom paddingLeft '+
        'paddingRight paddingTop right textIndent top width wordSpacing zIndex').split(' ');
    
      function interpolate(source,target,pos){ return (source+(target-source)*pos).toFixed(3); } // interpolate 插入,插(话)
    
      function s(str, p, c){ return str.substr(p,c||1); }
      function color(source,target,pos){ //如果是颜色,调用此函数;其余的调用interpolate
        var i = 2, j, c, tmp, v = [], r = [];
        while(j=3,c=arguments[i-1],i--)
          if(s(c,0)=='r') { c = c.match(/\d+/g); while(j--) v.push(~~c[j]); } else {
            if(c.length==4) c='#'+s(c,1)+s(c,1)+s(c,2)+s(c,2)+s(c,3)+s(c,3);
            while(j--) v.push(parseInt(s(c,1+j*2,2), 16)); }
        while(j--) { tmp = ~~(v[j+3]+(v[j]-v[j+3])*pos); r.push(tmp<0?0:tmp>255?255:tmp); }
        return 'rgb('+r.join(',')+')';
      }
      
      function parse(prop){ //对值进行处理
        var p = parseFloat(prop), q = prop.replace(/^[\-\d\.]+/,'');
        return isNaN(p) ? { v: q, f: color, u: ''} : { v: p, f: interpolate, u: q }; //v值 f运动函数 q单位
      }
      
      function normalize(style){
        var css, rules = {}, i = props.length, v;
        parseEl.innerHTML = '<div style="'+style+'"></div>';
        css = parseEl.childNodes[0].style;
        
        while(i--) if(v = css[props[i]]) rules[props[i]] = parse(v);
        
        return rules;
      }  
      
      container[emile] = function(el, style, opts, after){
        el = typeof el == 'string' ? document.getElementById(el) : el; //运动元素
        opts = opts || {}; //参数项
        var target = normalize(style), //正常化样式
          comp = el.currentStyle ? el.currentStyle : getComputedStyle(el, null),
          prop, 
          current = {},
          start = +new Date,
          dur = opts.duration||200,  //运动持续时间
          finish = start+dur,  //结束时间
          interval,
          easing = opts.easing || function(pos){ return (-Math.cos(pos*Math.PI)/2) + 0.5; }; //运动算法
    
        for(prop in target) current[prop] = parse(comp[prop]);
    
        interval = setInterval(function(){
          var time = +new Date,pos = time>finish ? 1 : (time-start)/dur;
    
          for(prop in target)
            el.style[prop] = target[prop].f(current[prop].v,target[prop].v,easing(pos)) + target[prop].u;
          
          if(time>finish) { //运动结束,调用回调函数
            clearInterval(interval); 
            opts.after && opts.after();  //回调有2种形式,一种可以放入opts,一种可以作为第四个参数
            after && setTimeout(after,1);
          }
        },10);
      }
    })('emile', this);
    
    //测试用
    function $(element) { return document.getElementById(element); }
    function bounce(pos) {
      if (pos < (1 / 2.75)) {
        return (7.5625 * pos * pos);
      } else if (pos < (2 / 2.75)) {
        return (7.5625 * (pos -= (1.5 / 2.75)) * pos + .75);
      } else if (pos < (2.5 / 2.75)) {
        return (7.5625 * (pos -= (2.25 / 2.75)) * pos + .9375);
      } else {
        return (7.5625 * (pos -= (2.625 / 2.75)) * pos + .984375);
      }
    }
  • 相关阅读:
    2019山东ACM省赛K题 zoj4123 Happy Equation
    2019山东ACM省赛总结
    ds
    CCPC2018 桂林 A: Array Merge(贪心、带权并查集合并)
    temp
    BZOJ 1013 球形空间产生器(高斯消元)
    BZOJ 2973 石头游戏(矩阵构造,矩阵快速幂)
    POJ 3233 Matrix Power Series (矩阵乘法,分块矩阵)
    每日bing API
    《音乐商店》第3集:模型规划
  • 原文地址:https://www.cnblogs.com/zhuzf/p/2871247.html
Copyright © 2011-2022 走看看