SVG与缓冲动画结合的几个案例

最近看了不少关于SVG的教程和内容,觉得SVG还是非常神奇的,做出来的动画也非常好看。而且有许多优点:

<ul>
<li>文件体积小,能够被大量的压缩
<li>图片可无限放大而不失真(矢量图的基本特征)
<li>在视网膜显示屏上效果极佳
<li>能够实现互动和滤镜效果
</ul>
缺点就是不能够完美兼容好多浏览器,尤其是IE上,虽然IE8以上开始兼容SVG了,但是经过实际测试对SVG的兼容并不是很好,所以还是在移动端上大有前景,好多真是的案例都应用到了SVG技术。

给一个传送门,关于移动端动画的。腾讯前端动画方案

可见SVG在移动端大有前景。

下面给出我看到的一些比较好的SVG文字链接,大家可以学习一下。

小tip: 使用SVG寥寥数行实现圆环loading进度效果
SVG技术入门:如何画出一条会动的线

<!DOCTYPE html>
<html lang="en">
<head>
  <title>我的照片</title>
  <style type="text/css">
    *{
      margin: 0;
      padding: 0;
    }
    #div1{
      position: absolute;
      width: 800px;
      height: 800px;
      border: 1px solid green;
    }
  </style>

</head>
<body style="text-align: center;">
  <div id="div1">

  </div>
</body>
<script>
  (function(exports){
    var doc=document;
    var tagNameExpr=/^[\w-]+$/;
    var idExpr=/^#([\w-]*)$/;
    var classExpr=/^.([\w-]+)$/;
    var hasClassListProperty='classList' in document.documentElement;
    var vendor=['o','ms','moz','webkit'];
    var div=document.createElement("div");
    var $d={
      $:function (selector,context){
        var result;
        var qsa;
        var content=context||doc;
        if(idExpr.test(selector)){
          result=this.id(selector.replace("#",''));
          if(result) return result;
        }
        else if (tagNameExpr.test(selector)){
          result=this.tagName(selector,context)
        }
        else if(classExpr.test(selector)){
          result=this.className(selector,context)
        }
        else result=context.querySelectorAll(selector);
        return result;
      },
      id:function(id) {
        return doc.getElementById(id);
      },
      tagName:function(tagName,context){
        var content=context||doc;
        return document.getElementsByTagName(tagName);
      },
      node:function(name){
        return doc.createElement(name);
      },
      className:function(className,context){
        context=context||doc;
        return context.getElementsByClassName(className)
      },
      remove:function(node){
        var context=node.parentNode;
        context.removeChild(node);
      },
      setStyle:function(ele,styleNames){
        for(var n in styleNames){
          if(styleNames.hasOwnProperty(n)){
            ele.style[n]=styleNames[n]
          }
        }
      },
      getStyle: function (ele,attr) {
        if(!ele){
          return
        }
        if(attr==='float'){
          attr='cssFloat';
        }
        if(ele.style[attr]){
          return ele.style[attr]
        }
        if(window.getComputedStyle){
          getComputedStyle(ele,null)[attr]
        }else if(document.defaultView && document.defaultView.getComputedStyle){
          attr = attr.replace(/([/A-Z])/g, "-$1");
          attr = attr.toLowerCase();
          var style = document.defaultView.getComputedStyle(el, "");
          return style && style.getPropertyValue(attr);
        }else if(ele.currentStyle){
          return ele.currentStyle[ele]
        }
      },
      setAttr: function (ele,json) {
        for(var i in json){
          ele.setAttribute(i,json[i]);
        }
      }
    };
    var Tween = {
      Linear: function (t, b, c, d) { return c * t / d + b; },
      Quad: {//Quadratic二次方效果
        easeIn: function (t, b, c, d) {
          return c * (t /= d) * t + b;
        },
        easeOut: function (t, b, c, d) {
          return -c * (t /= d) * (t - 2) + b;
        },
        easeInOut: function (t, b, c, d) {
          if ((t /= d / 2) < 1) return c / 2 * t * t + b;
          return -c / 2 * ((--t) * (t - 2) - 1) + b;
        }
      },
      Cubic: {//Cubic 立方效果
        easeIn: function (t, b, c, d) {
          return c * (t /= d) * t * t + b;
        },
        easeOut: function (t, b, c, d) {
          return c * ((t = t / d - 1) * t * t + 1) + b;
        },
        easeInOut: function (t, b, c, d) {
          if ((t /= d / 2) < 1) return c / 2 * t * t * t + b;
          return c / 2 * ((t -= 2) * t * t + 2) + b;
        }
      },
      Quart: {// Quartic  四次方效果
        easeIn: function (t, b, c, d) {
          return c * (t /= d) * t * t * t + b;
        },
        easeOut: function (t, b, c, d) {
          return -c * ((t = t / d - 1) * t * t * t - 1) + b;
        },
        easeInOut: function (t, b, c, d) {
          if ((t /= d / 2) < 1) return c / 2 * t * t * t * t + b;
          return -c / 2 * ((t -= 2) * t * t * t - 2) + b;
        }
      },
      Quint: {// Quintic五次方效果
        easeIn: function (t, b, c, d) {
          return c * (t /= d) * t * t * t * t + b;
        },
        easeOut: function (t, b, c, d) {
          return c * ((t = t / d - 1) * t * t * t * t + 1) + b;
        },
        easeInOut: function (t, b, c, d) {
          if ((t /= d / 2) < 1) return c / 2 * t * t * t * t * t + b;
          return c / 2 * ((t -= 2) * t * t * t * t + 2) + b;
        }
      },
      Sine: {//Sinusoidal 正弦效果
        easeIn: function (t, b, c, d) {
          return -c * Math.cos(t / d * (Math.PI / 2)) + c + b;
        },
        easeOut: function (t, b, c, d) {
          return c * Math.sin(t / d * (Math.PI / 2)) + b;
        },
        easeInOut: function (t, b, c, d) {
          return -c / 2 * (Math.cos(Math.PI * t / d) - 1) + b;
        }
      },
      Expo: { // Exponential指数
        easeIn: function (t, b, c, d) {
          return (t == 0) ? b : c * Math.pow(2, 10 * (t / d - 1)) + b;
        },
        easeOut: function (t, b, c, d) {
          return (t == d) ? b + c : c * (-Math.pow(2, -10 * t / d) + 1) + b;
        },
        easeInOut: function (t, b, c, d) {
          if (t == 0) return b;
          if (t == d) return b + c;
          if ((t /= d / 2) < 1) return c / 2 * Math.pow(2, 10 * (t - 1)) + b;
          return c / 2 * (-Math.pow(2, -10 * --t) + 2) + b;
        }
      },
      Circ: { //circle循环
        easeIn: function (t, b, c, d) {
          return -c * (Math.sqrt(1 - (t /= d) * t) - 1) + b;
        },
        easeOut: function (t, b, c, d) {
          return c * Math.sqrt(1 - (t = t / d - 1) * t) + b;
        },
        easeInOut: function (t, b, c, d) {
          if ((t /= d / 2) < 1) return -c / 2 * (Math.sqrt(1 - t * t) - 1) + b;
          return c / 2 * (Math.sqrt(1 - (t -= 2) * t) + 1) + b;
        }
      },
      Elastic: {//  Elastic 弹性
        easeIn: function (t, b, c, d, a, p) {
          if (t == 0) return b; if ((t /= d) == 1) return b + c; if (!p) p = d * .3;
          if (!a || a < Math.abs(c)) { a = c; var s = p / 4; }
          else var s = p / (2 * Math.PI) * Math.asin(c / a);
          return -(a * Math.pow(2, 10 * (t -= 1)) * Math.sin((t * d - s) * (2 * Math.PI) / p)) + b;
        },
        easeOut: function (t, b, c, d, a, p) {
          if (t == 0) return b; if ((t /= d) == 1) return b + c; if (!p) p = d * .3;
          if (!a || a < Math.abs(c)) { a = c; var s = p / 4; }
          else var s = p / (2 * Math.PI) * Math.asin(c / a);
          return (a * Math.pow(2, -10 * t) * Math.sin((t * d - s) * (2 * Math.PI) / p) + c + b);
        },
        easeInOut: function (t, b, c, d, a, p) {
          if (t == 0) return b; if ((t /= d / 2) == 2) return b + c; if (!p) p = d * (.3 * 1.5);
          if (!a || a < Math.abs(c)) { a = c; var s = p / 4; }
          else var s = p / (2 * Math.PI) * Math.asin(c / a);
          if (t < 1) return -.5 * (a * Math.pow(2, 10 * (t -= 1)) * Math.sin((t * d - s) * (2 * Math.PI) / p)) + b;
          return a * Math.pow(2, -10 * (t -= 1)) * Math.sin((t * d - s) * (2 * Math.PI) / p) * .5 + c + b;
        }
      },
      Back: {//后退
        easeIn: function (t, b, c, d, s) {
          if (s == undefined) s = 1.70158;
          return c * (t /= d) * t * ((s + 1) * t - s) + b;
        },
        easeOut: function (t, b, c, d, s) {
          if (s == undefined) s = 1.70158;
          return c * ((t = t / d - 1) * t * ((s + 1) * t + s) + 1) + b;
        },
        easeInOut: function (t, b, c, d, s) {
          if (s == undefined) s = 1.70158;
          if ((t /= d / 2) < 1) return c / 2 * (t * t * (((s *= (1.525)) + 1) * t - s)) + b;
          return c / 2 * ((t -= 2) * t * (((s *= (1.525)) + 1) * t + s) + 2) + b;
        }
      },
      Bounce: {// Bounce反弹
        easeIn: function (t, b, c, d) {
          return c - Tween.Bounce.easeOut(d - t, 0, c, d) + b;
        },
        easeOut: function (t, b, c, d) {
          if ((t /= d) < (1 / 2.75)) {
            return c * (7.5625 * t * t) + b;
          } else if (t < (2 / 2.75)) {
            return c * (7.5625 * (t -= (1.5 / 2.75)) * t + .75) + b;
          } else if (t < (2.5 / 2.75)) {
            return c * (7.5625 * (t -= (2.25 / 2.75)) * t + .9375) + b;
          } else {
            return c * (7.5625 * (t -= (2.625 / 2.75)) * t + .984375) + b;
          }
        },
        easeInOut: function (t, b, c, d) {
          if (t < d / 2) return Tween.Bounce.easeIn(t * 2, 0, c, d) * .5 + b;
          else return Tween.Bounce.easeOut(t * 2 - d, 0, c, d) * .5 + c * .5 + b;
        }
      }
    }
    exports.selector=$d;
    exports.animate=Tween;
  })(window)

  var SVG=function (setting) {
    this.data={
      centerNode:{text:'克鲁兹'},
      otherNode:[
      ]
    };
    var defaults={
      number:9,
      angleNum:360/this.number,
      centerR:250
    };
    if(setting){
      for(var key in setting){
        defaults[key]=setting[key]
      }
    }

    this.oParent=selector.$("#div1");
    this.centerX=this.oParent.offsetWidth/2;
    this.centerY=this.oParent.offsetHeight/2;
    for(var i=0;i<defaults.number;i++){
      var x=Math.sin(i*40*Math.PI/180)*defaults.centerR+this.centerY;
      var y=Math.cos(i*40*Math.PI/180)*defaults.centerR+this.centerX;
      this.data.otherNode.push({x:x,y:y,text:i});
    }
  };
  SVG.prototype={
    svgNS:'http://www.w3.org/2000/svg',

    //oParent:document.getElementById("div1")
//    centerX:this.oParent.offsetWidth/2,
//    centerY:this.oParent.offsetHeight/2,
    init:function(){
      var that=this;
      var oSVG=this.createTag("svg",{
        'xmls':this.svgNS,
        'width':"100%",
        'height':"100%"
      });
      this.svg=oSVG;
      for(var i=0;i<this.data.otherNode.length;i++){
        that.addOtherTag(that.data.otherNode[i],that.svg);
      }
      this.addMainTag();
      this.bindEvent();
    },
    createTag: function (tag,objAttr) {
      var tag=document.createElementNS(this.svgNS,tag);
      for(var attr in objAttr){
        tag.setAttribute(attr,objAttr[attr]);
      }
      return tag;
    },
    addMainTag: function () {
      var oG=this.createTag('g',{
        'style':'cursor:pointer',
        'class':'mainCircle'
      });
      var oCircle=this.createTag('circle',{
        'cx':this.centerX,
        'cy':this.centerY,
        'r':'60',
        'fill':'white',
        'stroke':'red',
        'stroke-width':'1'
      });
      var oText=this.createTag('text',{
        'x':this.centerX,
        'y':this.centerY+8,
        'font-size':'20',
        'text-anchor':'middle'
      });
      oText.innerHTML='克鲁兹';
      this.svg.appendChild(oG);
      oG.appendChild(oCircle);
      oG.appendChild(oText);
      this.oParent.appendChild(this.svg);
    },
    addOtherTag: function (otherAttr,oSvg) {
      var line1=this.createTag('line',{
        'x1':otherAttr.x,
        'y1':otherAttr.y,
        'x2':this.centerX,
        'y2':this.centerY,
        'stroke':'#ccc',
        'stroke-width':'2'
      });
      var line2=this.createTag('line',{
        'x1':otherAttr.x,
        'y1':otherAttr.y,
        'x2':this.centerX,
        'y2':this.centerY,
        'stroke':'transparent',
        'stroke-width':'10'
      });
      var oRect=this.createTag('rect',{
        'x':(otherAttr.x+this.centerX)/2-10,
        'y':(otherAttr.y+this.centerY)/2-10,
        'fill':'#999',
        'width':'20',
        'height':'20',
        'rx':'5'
      });
      var oText1=this.createTag('text',{
        'x':(otherAttr.x+this.centerX)/2,
        'y':(otherAttr.y+this.centerY)/2+8,
        'fill':'white',
        'font-size':20,
        'text-anchor':'middle'
      });
      oText1.innerHTML="?";
      var oG1=this.createTag('g',{
        'style':'cursor:pointer',
        'class':'otherLine'
      });
      var oG2=this.createTag('g',{
        'style':'cursor:pointer',
        'class':'otherCircle'
      });

      var oCircle=this.createTag('circle',{
        'cx':otherAttr.x,
        'cy':otherAttr.y,
        'r':'30',
        'fill':'white',
        'stroke':'red',
        'stroke-width':'1'
      });
      var oText2=this.createTag('text',{
        'x':otherAttr.x,
        'y':otherAttr.y+8,
        'fill':'black',
        'font-size':20,
        'text-anchor':'middle'
      });
      oText2.innerHTML=otherAttr.text;
      oG1.appendChild(line1);
      oG1.appendChild(line2);
      oG1.appendChild(oRect);
      oG1.appendChild(oText1);
      oG2.appendChild(oCircle);
      oG2.appendChild(oText2);
      oSvg.appendChild(oG1);
      oSvg.appendChild(oG2);
    },
//    tween animation
    tweenAnimate: function (obj,start,end,dur) {
      clearInterval(obj.timer);
      var changeValue=end-start;
      var newR;
      var t=0;
      obj.timer=setInterval(function () {
        t+=5;
        newR=animate.Elastic.easeOut(t,start,changeValue,dur)
        if(t<dur){
          selector.setAttr(obj,{
            "r":newR
          })
        }
      },30)
    },
    bindEvent: function () {
      var otherLine=selector.className("otherLine");
      var mainCircle=selector.className("mainCircle");
      var otherCircle=selector.className("otherCircle");

      var that=this;
      for(var i=0;i<otherLine.length;i++){
        otherLine[i].onmouseover= function () {
          var previous=this;
          selector.setAttr(previous.getElementsByTagName('line')[0],{
            'stroke':'blue'
          });
          selector.setAttr(previous.getElementsByTagName("rect")[0],{
            'fill':'red'
          })
        };
        otherLine[i].onmouseleave= function () {
          var previous=this;
          selector.setAttr(previous.getElementsByTagName('line')[0],{
            'stroke':'#ccc'
          });
          selector.setAttr(previous.getElementsByTagName("rect")[0],{
            'fill':'#ccc'
          })
        };
      }
      for(var k=0;k<otherCircle.length;k++){
        otherCircle[k].onmouseover= function () {
          var previous=this.previousElementSibling;
          selector.setAttr(previous.getElementsByTagName('line')[0],{
            'stroke':'#547'
          });
          selector.setAttr(previous.getElementsByTagName("rect")[0],{
            'fill':'#782'
          });
          that.tweenAnimate(this.getElementsByTagName('circle')[0],30,60,400);

        };
        otherCircle[k].onmouseleave= function () {
          var previous=this.previousElementSibling;
          selector.setAttr(previous.getElementsByTagName('line')[0],{
            'stroke':'#ccc'
          });
          selector.setAttr(previous.getElementsByTagName("rect")[0],{
            'fill':'#ccc'
          });
          that.tweenAnimate((this.getElementsByTagName('circle')[0]),60,30,400)
        }
      };
    }

  }
  window.onload=function(){
    var svg=new SVG;
    svg.init()

  }

</script>

</html>

```
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,547评论 6 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,399评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,428评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,599评论 1 274
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,612评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,577评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,941评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,603评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,852评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,605评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,693评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,375评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,955评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,936评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,172评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,970评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,414评论 2 342

推荐阅读更多精彩内容