loading效果实现

1,033 阅读2分钟

loading一般可以通过以下几种形式实现

  • 使用gif或者iconfont
  • 使用border-radius
  • 使用canvas、svg

border-radius实现loading

绘制loading圆

.loading-css {
    width: 50px; 
    height: 50px;
    display: inline-block;
    border: 3px solid #f3f3f3;
    border-top: 3px solid #409efff;
    border-radius: 50%;
}

<div class="loading-css"></div>

image.png

设置动画

@keyframes loading {
    0% {
        transform: rotate(0deg);
    }
    100% {
        transform: rotate(360deg);
    }
}
.loading-css {
    animation: loading 0.8s infinite linear; 
}

了解stroke-dasharray、stroke-dashoffset

stroke-dasharray:用于创建虚线,之所以后面跟的是array的,是因为值其实是数组。

stroke-dasharray = '10',表示虚线长10,间隔为10

image.png

stroke-dasharray = '10, 5',表示虚线长10,间隔为5

image.png

stroke-dasharray = '20, 10, 5',表示虚线长20,间隔为10,虚线长为5,以此类推

image.png

stroke-dashoffset: 偏移,这个属性是正数偏移x值的时候,相当于往左移动了x个长度单位,负数偏移x的时候,相当于往右移动了x个长度单位

stroke-dashoffset="10",表示虚线整体左移了10个单位

<svg xmlns="http://www.w3.org/2000/svg" version="1.1">
  <g fill="none" stroke="black" stroke-width="4">
    <path stroke-dasharray="10" stroke-dashoffset="10" d="M5 20 l215 0" />
  </g>
</svg>

image.png

了解canvas

首先在开始使用canvas前需要了解widthstyle.width的区别,值得注意的是在不写width和height的时候,默认为300*150

当在标签上写上width、height时

<canvas id="myCanvas" width="200" height="100" style="border:1px solid #c3c3c3;">
</canvas>

<script>
    var c=document.getElementById("myCanvas");
    var ctx=c.getContext("2d");
    ctx.moveTo(0,0);
    ctx.lineTo(200,100);
    ctx.stroke();
</script>

image.png

style.width = 100、style.height = 100,canvas进行缩小

假设style大小为100*100,canvas画布大小200*100lineTo(200, 100)

<canvas id="myCanvas" width="200" height="100" style="width: 100px; height: 100px; border:1px solid #c3c3c3;">
</canvas>

image.png

200100=200x\frac{200}{100} = \frac{200}{x}

100100=100y\frac{100}{100} = \frac{100}{y}

可以得到lineTo的最后坐标为(100, 100)

image.png

style.width = 300、style.height = 300,canvas进行放大

假设style大小为300*300,canvas画布大小300*150lineTo(300, 300)

<canvas id="myCanvas" width="300px" height="150px" style="width: 300px; height: 300px; border:1px solid #c3c3c3;">
您的浏览器不支持 HTML5 canvas 标签。
</canvas>

image.png

300300=300x\frac{300}{300} = \frac{300}{x}

150300=300y\frac{150}{300} = \frac{300}{y}

x = 300

y = 600

可以得到lineTo的最后坐标为(300, 600),宽度高度超过300以后的直线将被隐藏

image.png

总结

  • canvas.width / canvas.height 表示画布真实大小,其实我们并不可见
  • canvas.style.width / canvas.style.height 表示画布输出到浏览器我们可见的最终的大小
  • 解决缩放后直线模糊的问题具体见(解决canvas画图模糊的问题)[segmentfault.com/a/119000000…]

开始画loading

画一个圆

圆周长为 20 * 2 * 3.14 = 126

.loading-svg {
  margin: auto;
  width: 50px;
  height: 50px;
}
.path {
  stroke: #409eff;
  stroke-width: 2;
}

svg

<svg class="loading-svg">
    <circle
      cx="25"
      cy="25"
      r="20"
      fill="none"
      class="path"
    ></circle>
  </svg>

canvas

image.png

第一阶段 起始位置

.path {
  stroke: #409eff;
  stroke-width: 2;
+ stroke-dasharray: 10, 116;
+ stroke-dashoffset: -20;
}

image.png

第二阶段 loading大部分

stroke-dasharray: 95, 126;
stroke-dashoffset: -20;

image.png

第三阶段 loading尾声

stroke-dasharray: 6, 120;
stroke-dashoffset: -120;

image.png

添加最终动画

path {
    stroke: #409eff;
    stroke-width: 2;
    stroke-dasharray: 10, 116;
    stroke-dashoffset: -20;
+   animation: loading-rotate 1.5s infinite ease-in-out;
}
@keyframes loading-rotate {
  0% {
    stroke-dasharray: 1, 126;
    stroke-dashoffset: 0;
  }
  50% {
    stroke-dasharray: 95, 126;
    stroke-dashoffset: -31;
  }
  100% {
    stroke-dasharray: 6, 120;
    stroke-dashoffset: -120;
  }
}

最终效果

3333.gif

参考

SVG学习之stroke-dasharray 和 stroke-dashoffset 详解 canvas.width和canvas.style.width区别以及应用