一个基于svg的圆形loading动画

前言

很多时候大家都要做一些loading动画,现在给大家带来的是用svg画出来的loading动画,稍微封装就可以使用了。

代码

<%--
  Created by IntelliJ IDEA.
  User: Administrator
  Date: 2015/9/16
  Time: 16:01
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>一个基于svg的loading控件。</title>
  <script type="text/javascript" src="/static/lib/jquery-1.11.0.min.js"></script>
  <script type="text/javascript" src="/static/vendor/laytpl/laytpl.js"></script>
</head>
<body>
<h2>原型。</h2>
<svg width="200" height="200">
  <ellipse rx="90" ry="90" cx="100" cy="100" stroke="#f2f2f2" fill="none" stroke-width="10"></ellipse>
  <path fill="none" stroke="#3daf2c" stroke-width="10" d="M100,10 A90,90 0 1 1 10,90"></path>
</svg>
<h3>控件模样。</h3>
<div id="container">

</div>
<script type="text/javascript">
  function SVGLoading(_opts){
    var settings={
      strokeWidth:10 //边框宽度。
      ,strokeNormalColor:"#f2f2f2" //普通状态下边框颜色。
      ,strokeActivityColor:"#3daf2c" //激活状态下边框颜色。
      ,radius:80 //该圆形loading框的半径。
      ,percent:47 //当前默认显示的百分比。
      ,container:""
    };

    var appData={
      width:0
      ,height:0
      ,rx:0
      ,ry:0
      ,cx:0
      ,cy:0
      ,stroke1:""
      ,stroke2:""
      ,strokeWidth:0
      ,d:""
    };
    var _d_data={
      move_point:{x:0,y:0}
      ,radiusPoint:{x:0,y:0}
    };


    var _tpl_html='<svg width="{{d.width}}" height="{{d.height}}"><ellipse rx="{{d.rx}}" ry="{{d.ry}}" cx="{{d.cx}}" cy="{{d.cy}}" stroke="{{d.stroke1}}" fill="none" stroke-width="{{d.strokeWidth}}"></ellipse><path ui="path" fill="none" stroke="{{d.stroke2}}" stroke-width="{{d.strokeWidth}}" d="{{d.d}}"></path></svg>';

    var tpl=laytpl(_tpl_html);
    var _root="";
    var _el_path="";
    var app={
      init:function(){
        $.extend(settings,_opts);
        var _me=this;
        _me.initData();
        _me.initView();
      }
      //--计算原始的尺寸及其他信息。
      ,initData:function(){
        var me=this;
        appData.width=settings.radius*2;
        appData.height=settings.radius*2;
        appData.strokeWidth=settings.strokeWidth;
        appData.rx=parseInt((settings.radius-settings.strokeWidth));
        appData.ry=appData.rx;
        appData.cx=parseInt(settings.radius);
        appData.cy=appData.cx;
        appData.stroke1=settings.strokeNormalColor;
        appData.stroke2=settings.strokeActivityColor;
        _d_data.move_point={
          x:appData.cx
          ,y:appData.cy-appData.ry
        };
        _d_data.radiusPoint={
          x:appData.cx
          ,y:appData.cy
        };
      }
      ,initView:function(){
        var me=this;
        _root=$(settings.container);
        appData.d=me.caculateD(settings.percent);
        var html1=tpl.render(appData);
        _root.html(html1);
        _el_path=_root.find('[ui="path"]')[0];
      }
      //--计算 路径的d。
      ,caculateD:function(percent){

        var me=this;
        var _is_big_arc=false;
        var _realpercent=percent;
        if(_realpercent<0){
          _realpercent=0;
        }
        else if(_realpercent>100){
          _realpercent=100;
        }
        if(_realpercent>50){
          _is_big_arc=true;
        }
        var _endPoint=me.caculatePointByPercent(percent);

        var _bigArc=0;
        if(_is_big_arc){
          _bigArc=1;
        }

        var _str="M"+_d_data.move_point.x+","+_d_data.move_point.y+" A"+appData.rx+","+appData.rx+" 0 "+_bigArc+" 1 "+_endPoint.x+","+_endPoint.y+"";

        return _str;


      }
      //--计算 路径的d。
      ,caculateDbyAngle:function(angle){

        var me=this;
        var _is_big_arc=false;
        var _angle=360+angle;
        _angle=_angle%360;

        if(_angle>180){
          _is_big_arc=true;
        }
        var _endPoint=me.caculatePointByAngle(_angle);

        var _bigArc=0;
        if(_is_big_arc){
          _bigArc=1;
        }

        var _str="M"+_d_data.move_point.x+","+_d_data.move_point.y+" A"+appData.rx+","+appData.rx+" 0 "+_bigArc+" 1 "+_endPoint.x+","+_endPoint.y+"";

        return _str;


      }
      //--计算当前percent的终点。
      ,caculatePointByPercent:function(percent){
        var _res={x:0,y:0};
        /**
         圆点坐标:(x0,y0)
         半径:r
         角度:a0

         则圆上任一点为:(x1,y1)
         x1   =   x0   +   r   *   cos(ao   *   3.14   /180   )
         y1   =   y0   +   r   *   sin(ao   *   3.14   /180   )
         * */


         var Angle0=(percent/100)*360;
        Angle0=(360+Angle0-90)%360;
        _res.x= _d_data.radiusPoint.x+appData.rx*Math.cos(Angle0*Math.PI/180);
        _res.y= _d_data.radiusPoint.y+appData.rx*Math.sin(Angle0*Math.PI/180);

        return _res;
      }
      ,caculatePointByAngle:function(angle){
        var _res={x:0,y:0};
        /**
         圆点坐标:(x0,y0)
         半径:r
         角度:a0

         则圆上任一点为:(x1,y1)
         x1   =   x0   +   r   *   cos(ao   *   3.14   /180   )
         y1   =   y0   +   r   *   sin(ao   *   3.14   /180   )
         * */


        //处理一下角度问
                /**
                 * 为什么要这样处理?
                 * 因为我们看上去认为的角度跟实际上圆角的角度有90度的差距。
                 * 例如对于零度来说,在我们的圆形是 | 一条垂直的竖线就是零度了,但对于实际计算这个已经是902、度了。
                 * **/
        var Angle0=angle;
        Angle0=360+angle-90;
        Angle0=Angle0%360;

        _res.x= _d_data.radiusPoint.x+appData.rx*Math.cos(Angle0*Math.PI/180);
        _res.y= _d_data.radiusPoint.y+appData.rx*Math.sin(Angle0*Math.PI/180);
        //--注意,这个得到的坐标是以正常的坐标系,即,左下角x,从左到右为x,从下到上为y,现在这个不是,现在的页面的坐标系是从上到下才是y轴,y轴要处理一下。


        return _res;
      }
      ,setPercent:function(percent){
        var me=this;
        var _d_str=me.caculateD(percent);
        //_el_path.d=_d_str;
        $(_el_path).attr("d",_d_str);
      }
      ,setAngle:function(angle){
        var me=this;
        var _d_str=me.caculateDbyAngle(angle);
        //_el_path.d=_d_str;
        $(_el_path).attr("d",_d_str);
      }
    };


    app.init();

    var returnObject={
      setPercent:function(percent){
        app.setPercent(percent);
      }
      ,setAngle:function(angle){
        app.setAngle(angle);
      }

    };

    return returnObject;
  };
  var _loading={};
  function InitSVGLoading(){
    _loading=SVGLoading({
      container:$("#container")
    });
  };
  InitSVGLoading();
  var _current_percent=0;
 setInterval(function(){
    _loading.setPercent(_current_percent);
    _current_percent=_current_percent+0.1;
    _current_percent=_current_percent%100;

  },10);
</script>
</body>
</html>

jquery.js和laytpl.js请在网上下载。

效果

这里写图片描述

这里写图片描述

兼容性

大家别执着于兼容性了,ie6-9都恐怕没办法运行,但是,ios,安卓【假如不是古董级别】,chrome,safari,firefox都可以运行,作为一名开发html5的前端,这个兼容性还不够么。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
SVG动画是一种使用Scalable Vector Graphics (可缩放矢量图形)格式来创建动画效果的技术。与其他常见的图像格式(如JPEG或PNG)不同,SVG具有矢量特性,可以缩放并保持清晰度。 要加载SVG动画,首先需要将SVG文件嵌入到HTML文档中。可以通过`<object>`或`<embed>`标签来实现。例如: ```html <object type="image/svg+xml" data="animation.svg"> Your browser does not support SVG </object> ``` 在加载完成后,可以使用CSS或JavaScript来控制SVG动画的行为。可以添加CSS样式来改变动画的外观,或者使用JavaScript来控制动画的播放、暂停和重放。 要实现加载动画,可以在SVG文件中添加动画元素和属性。例如,可以使用`<animate>`元素来定义属性的动画效果。例如,要创建一个从左到右移动的动画效果,可以使用以下代码: ```html <rect width="100" height="50"> <animate attributeName="x" from="0" to="200" dur="1s" fill="freeze" repeatCount="indefinite" /> </rect> ``` 在上面的示例中,`<rect>`元素定义了一个矩形,`<animate>`元素定义了矩形的x属性动画。`attributeName`属性指定要动画化的属性,`from`和`to`属性指定属性的起始值和终止值,`dur`属性指定动画的持续时间,`fill`属性指定动画结束后属性的保持方式,`repeatCount`属性指定动画的重复次数。 通过调整属性和添加其他SVG元素和动画,可以创造出各种各样的加载动画效果。无论是旋转、缩放、渐变还是路径动画,都可以通过SVG轻松实现。 总之,加载SVG动画涉及将SVG文件嵌入到HTML文档中,并使用CSS或JavaScript来控制动画的行为。通过使用SVG的矢量特性和丰富的动画元素和属性,可以创建各种各样的引人注目的加载动画效果。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值