[HTML] 使用anime.js实现Win10 LodingRing 的样式

预览

废话不多说,先来预览一下效果(windows 原生的 lodingring 在uwp应用中的样式可以在windows sdk中找到,我将其移植到了WPF中*)

  • WPF中样式
    在这里插入图片描述
  • JS样式
    在这里插入图片描述
    当然了,JS中动画的参数也是我根据UWP移植过来的(无情的搬运工)
    可以看到,动画基本如出一辙
实现

作为一名c#开发者,现在还做WPF桌面应用的应该已经绝无仅有了,但是我最初学这个框架也是被Windows和VisualStudio的扁平UI吸引的。在WPF中可以相对容易的同步应用与Windows的风格,包括一些系统UI的样式。
好了,废话不多说,来看今天的主角 —— Win10加载圆环

我给你们看看WPF动画的源码吧

   <DoubleAnimationUsingKeyFrames Storyboard.TargetName="E1"
                                                                   Storyboard.TargetProperty="Opacity"
                                                                       BeginTime="0">
                                            <DiscreteDoubleKeyFrame KeyTime="0"
                                                                    Value="1" />
                                            <DiscreteDoubleKeyFrame KeyTime="0:0:3.21"
                                                                    Value="1" />
                                            <DiscreteDoubleKeyFrame KeyTime="0:0:3.22"
                                                                    Value="0" />
                                            <DiscreteDoubleKeyFrame KeyTime="0:0:3.47"
                                                                    Value="0" />
                                        </DoubleAnimationUsingKeyFrames>
                                        <DoubleAnimationUsingKeyFrames Storyboard.TargetName="E2"
                                                                       Storyboard.TargetProperty="Opacity"
                                                                       BeginTime="00:00:00.167">
                                            <DiscreteDoubleKeyFrame KeyTime="0"
                                                                    Value="1" />
                                            <DiscreteDoubleKeyFrame KeyTime="0:0:3.21"
                                                                    Value="1" />
                                            <DiscreteDoubleKeyFrame KeyTime="0:0:3.22"
                                                                    Value="0" />
                                            <DiscreteDoubleKeyFrame KeyTime="0:0:3.47"
                                                                    Value="0" />
                                        </DoubleAnimationUsingKeyFrames>
                                        <DoubleAnimationUsingKeyFrames Storyboard.TargetName="E3"
                                                                       Storyboard.TargetProperty="Opacity"
                                                                       BeginTime="00:00:00.334">
                                            <DiscreteDoubleKeyFrame KeyTime="0"
                                                                    Value="1" />
                                            <DiscreteDoubleKeyFrame KeyTime="0:0:3.21"
                                                                    Value="1" />
                                            <DiscreteDoubleKeyFrame KeyTime="0:0:3.22"
                                                                    Value="0" />
                                            <DiscreteDoubleKeyFrame KeyTime="0:0:3.47"
                                                                    Value="0" />
                                        </DoubleAnimationUsingKeyFrames>
                                        <DoubleAnimationUsingKeyFrames Storyboard.TargetName="E4"
                                                                       Storyboard.TargetProperty="Opacity"
                                                                       BeginTime="00:00:00.501">
                                            <DiscreteDoubleKeyFrame KeyTime="0"
                                                                    Value="1" />
                                            <DiscreteDoubleKeyFrame KeyTime="0:0:3.21"
                                                                    Value="1" />
                                            <DiscreteDoubleKeyFrame KeyTime="0:0:3.22"
                                                                    Value="0" />
                                            <DiscreteDoubleKeyFrame KeyTime="0:0:3.47"
                                                                    Value="0" />
                                        </DoubleAnimationUsingKeyFrames>
                                        <DoubleAnimationUsingKeyFrames Storyboard.TargetName="E5"
                                                                       Storyboard.TargetProperty="Opacity"
                                                                       BeginTime="00:00:00.668">
                                            <DiscreteDoubleKeyFrame KeyTime="0"
                                                                    Value="1" />
                                            <DiscreteDoubleKeyFrame KeyTime="0:0:3.21"
                                                                    Value="1" />
                                            <DiscreteDoubleKeyFrame KeyTime="0:0:3.22"
                                                                    Value="0" />
                                            <DiscreteDoubleKeyFrame KeyTime="0:0:3.47"
                                                                    Value="0" />
                                        </DoubleAnimationUsingKeyFrames>
                                        <DoubleAnimationUsingKeyFrames Storyboard.TargetName="E6"
                                                                       Storyboard.TargetProperty="Opacity"
                                                                       BeginTime="00:00:00.835">
                                            <DiscreteDoubleKeyFrame KeyTime="0"
                                                                    Value="1" />
                                            <DiscreteDoubleKeyFrame KeyTime="0:0:3.21"
                                                                    Value="1" />
                                            <DiscreteDoubleKeyFrame KeyTime="0:0:3.22"
                                                                    Value="0" />
                                            <DiscreteDoubleKeyFrame KeyTime="0:0:3.47"
                                                                    Value="0" />
                                        </DoubleAnimationUsingKeyFrames>
                                        <DoubleAnimationUsingKeyFrames Storyboard.TargetName="E1R"
                                                                       BeginTime="0"
                                                                       Storyboard.TargetProperty="Angle">
                                            <SplineDoubleKeyFrame KeyTime="0"
                                                                  Value="-110"
                                                                  KeySpline="0.13,0.21,0.1,0.7" />
                                            <SplineDoubleKeyFrame KeyTime="0:0:0.433"
                                                                  Value="10"
                                                                  KeySpline="0.02,0.33,0.38,0.77" />
                                            <SplineDoubleKeyFrame KeyTime="0:0:1.2"
                                                                  Value="93" />
                                            <SplineDoubleKeyFrame KeyTime="0:0:1.617"
                                                                  Value="205"
                                                                  KeySpline="0.57,0.17,0.95,0.75" />
                                            <SplineDoubleKeyFrame KeyTime="0:0:2.017"
                                                                  Value="357"
                                                                  KeySpline="0,0.19,0.07,0.72" />
                                            <SplineDoubleKeyFrame KeyTime="0:0:2.783"
                                                                  Value="439" />
                                            <SplineDoubleKeyFrame KeyTime="0:0:3.217"
                                                                  Value="585"
                                                                  KeySpline="0,0,0.95,0.37" />
                                        </DoubleAnimationUsingKeyFrames>
                                        <DoubleAnimationUsingKeyFrames Storyboard.TargetName="E2R"
                                                                       BeginTime="00:00:00.167"
                                                                       Storyboard.TargetProperty="Angle">
                                            <SplineDoubleKeyFrame KeyTime="0"
                                                                  Value="-116"
                                                                  KeySpline="0.13,0.21,0.1,0.7" />
                                            <SplineDoubleKeyFrame KeyTime="0:0:0.433"
                                                                  Value="4"
                                                                  KeySpline="0.02,0.33,0.38,0.77" />
                                            <SplineDoubleKeyFrame KeyTime="0:0:1.2"
                                                                  Value="87" />
                                            <SplineDoubleKeyFrame KeyTime="0:0:1.617"
                                                                  Value="199"
                                                                  KeySpline="0.57,0.17,0.95,0.75" />
                                            <SplineDoubleKeyFrame KeyTime="0:0:2.017"
                                                                  Value="351"
                                                                  KeySpline="0,0.19,0.07,0.72" />
                                            <SplineDoubleKeyFrame KeyTime="0:0:2.783"
                                                                  Value="433" />
                                            <SplineDoubleKeyFrame KeyTime="0:0:3.217"
                                                                  Value="579"
                                                                  KeySpline="0,0,0.95,0.37" />
                                        </DoubleAnimationUsingKeyFrames>
                                        <DoubleAnimationUsingKeyFrames Storyboard.TargetName="E3R"
                                                                       BeginTime="00:00:00.334"
                                                                       Storyboard.TargetProperty="Angle">
                                            <SplineDoubleKeyFrame KeyTime="0"
                                                                  Value="-122"
                                                                  KeySpline="0.13,0.21,0.1,0.7" />
                                            <SplineDoubleKeyFrame KeyTime="0:0:0.433"
                                                                  Value="-2"
                                                                  KeySpline="0.02,0.33,0.38,0.77" />
                                            <SplineDoubleKeyFrame KeyTime="0:0:1.2"
                                                                  Value="81" />
                                            <SplineDoubleKeyFrame KeyTime="0:0:1.617"
                                                                  Value="193"
                                                                  KeySpline="0.57,0.17,0.95,0.75" />
                                            <SplineDoubleKeyFrame KeyTime="0:0:2.017"
                                                                  Value="345"
                                                                  KeySpline="0,0.19,0.07,0.72" />
                                            <SplineDoubleKeyFrame KeyTime="0:0:2.783"
                                                                  Value="427" />
                                            <SplineDoubleKeyFrame KeyTime="0:0:3.217"
                                                                  Value="573"
                                                                  KeySpline="0,0,0.95,0.37" />
                                        </DoubleAnimationUsingKeyFrames>
                                        <DoubleAnimationUsingKeyFrames Storyboard.TargetName="E4R"
                                                                       BeginTime="00:00:00.501"
                                                                       Storyboard.TargetProperty="Angle">
                                            <SplineDoubleKeyFrame KeyTime="0"
                                                                  Value="-128"
                                                                  KeySpline="0.13,0.21,0.1,0.7" />
                                            <SplineDoubleKeyFrame KeyTime="0:0:0.433"
                                                                  Value="-8"
                                                                  KeySpline="0.02,0.33,0.38,0.77" />
                                            <SplineDoubleKeyFrame KeyTime="0:0:1.2"
                                                                  Value="75" />
                                            <SplineDoubleKeyFrame KeyTime="0:0:1.617"
                                                                  Value="187"
                                                                  KeySpline="0.57,0.17,0.95,0.75" />
                                            <SplineDoubleKeyFrame KeyTime="0:0:2.017"
                                                                  Value="339"
                                                                  KeySpline="0,0.19,0.07,0.72" />
                                            <SplineDoubleKeyFrame KeyTime="0:0:2.783"
                                                                  Value="421" />
                                            <SplineDoubleKeyFrame KeyTime="0:0:3.217"
                                                                  Value="567"
                                                                  KeySpline="0,0,0.95,0.37" />
                                        </DoubleAnimationUsingKeyFrames>
                                        <DoubleAnimationUsingKeyFrames Storyboard.TargetName="E5R"
                                                                       BeginTime="00:00:00.668"
                                                                       Storyboard.TargetProperty="Angle">
                                            <SplineDoubleKeyFrame KeyTime="0"
                                                                  Value="-134"
                                                                  KeySpline="0.13,0.21,0.1,0.7" />
                                            <SplineDoubleKeyFrame KeyTime="0:0:0.433"
                                                                  Value="-14"
                                                                  KeySpline="0.02,0.33,0.38,0.77" />
                                            <SplineDoubleKeyFrame KeyTime="0:0:1.2"
                                                                  Value="69" />
                                            <SplineDoubleKeyFrame KeyTime="0:0:1.617"
                                                                  Value="181"
                                                                  KeySpline="0.57,0.17,0.95,0.75" />
                                            <SplineDoubleKeyFrame KeyTime="0:0:2.017"
                                                                  Value="331"
                                                                  KeySpline="0,0.19,0.07,0.72" />
                                            <SplineDoubleKeyFrame KeyTime="0:0:2.783"
                                                                  Value="415" />
                                            <SplineDoubleKeyFrame KeyTime="0:0:3.217"
                                                                  Value="561"
                                                                  KeySpline="0,0,0.95,0.37" />
                                        </DoubleAnimationUsingKeyFrames>
                                        <DoubleAnimationUsingKeyFrames Storyboard.TargetName="E6R"
                                                                       BeginTime="00:00:00.835"
                                                                       Storyboard.TargetProperty="Angle">
                                            <SplineDoubleKeyFrame KeyTime="0"
                                                                  Value="-140"
                                                                  KeySpline="0.13,0.21,0.1,0.7" />
                                            <SplineDoubleKeyFrame KeyTime="0:0:0.433"
                                                                  Value="-20"
                                                                  KeySpline="0.02,0.33,0.38,0.77" />
                                            <SplineDoubleKeyFrame KeyTime="0:0:1.2"
                                                                  Value="63" />
                                            <SplineDoubleKeyFrame KeyTime="0:0:1.617"
                                                                  Value="175"
                                                                  KeySpline="0.57,0.17,0.95,0.75" />
                                            <SplineDoubleKeyFrame KeyTime="0:0:2.017"
                                                                  Value="325"
                                                                  KeySpline="0,0.19,0.07,0.72" />
                                            <SplineDoubleKeyFrame KeyTime="0:0:2.783"
                                                                  Value="409" />
                                            <SplineDoubleKeyFrame KeyTime="0:0:3.217"
                                                                  Value="555"
                                                                  KeySpline="0,0,0.95,0.37" />
                                        </DoubleAnimationUsingKeyFrames>

由于是 xaml 生成的动画,没办法循环设置参数(UWP源码中也是如此),当时看到的时候就在想,调这个参数的美工真TM是个天才…
可以看到,其中有许多的贝塞尔缓动关键帧,要是用原生CSS3实现的话似乎有些麻烦,而且也不知道切换缓动函数的时候润不润,不润的话就很难受了,于是我就找到了anime.js这个动画库,刚好发现了其可以实现这个级别的动画。

/**
 * @param  {} size     : int        the rect clip width of the loding svg
 * @param  {} dotsize  : int        the r of a loading dot
 * @param  {} dotcolor : "#xxxxxx"  the color of the dot
 */
function CreateLodingRing(size, dotsize, dotcolor) {
  //#region Create Element
  var ring = Object();

  let loadingring = document.createElementNS("http://www.w3.org/2000/svg", "svg");
  loadingring.id = "winloding";
  loadingring.setAttribute("viewBox", "0 0" + " " + size + " " + size);
  for (let i = 0; i < 6; i++) {
    let dot = document.createElementNS("http://www.w3.org/2000/svg", "circle");
    dot.style.transformOrigin = "center center";
    dot.style.opacity = 0;
    dot.setAttribute("class", "d" + (i + 1));
    dot.setAttribute("fill", dotcolor);
    dot.setAttribute("cx", size / 2);
    dot.setAttribute("cy", dotsize + 2);
    dot.setAttribute("r", dotsize);
    loadingring.appendChild(dot);
  }
  document.body.appendChild(loadingring);
  console.log(loadingring);

  //#endregion
  var tl = anime.timeline({
    loop: true
  });
  // #region add animation
  // tl.add({
  //   targets: "#winloding d1",
  //   rotate: [
  //     { value: -110, duration: 0, easing: "cubicBezier(0.13,0.21,0.1,0.7)" },
  //     { value: 10, duration: 433, easing: "cubicBezier(0.02,0.33,0.38,0.77)" },
  //     { value: 93, duration: 767, easing: "cubicBezier(0, 0, 1, 1)" },
  //     { value: 205, duration: 417, easing: "cubicBezier(0.57,0.17,0.95,0.75)" },
  //     { value: 357, duration: 400, easing: "cubicBezier(0,0.19,0.07,0.72)" },
  //     { value: 439, duration: 766, easing: "cubicBezier(0, 0, 1, 1)" },
  //     { value: 585, duration: 434, easing: "cubicBezier(0,0,0.95,0.37)" }
  //   ]
  // })
  //   .add(
  //     {
  //       targets: "#winloding d2",
  //       rotate: [
  //         { value: -116, duration: 0, easing: "cubicBezier(0.13,0.21,0.1,0.7)" },
  //         { value: 4, duration: 433, easing: "cubicBezier(0.02,0.33,0.38,0.77)" },
  //         { value: 87, duration: 767, easing: "cubicBezier(0, 0, 1, 1)" },
  //         { value: 199, duration: 417, easing: "cubicBezier(0.57,0.17,0.95,0.75)" },
  //         { value: 351, duration: 400, easing: "cubicBezier(0,0.19,0.07,0.72)" },
  //         { value: 433, duration: 766, easing: "cubicBezier(0, 0, 1, 1)" },
  //         { value: 579, duration: 434, easing: "cubicBezier(0,0,0.95,0.37)" }
  //       ]
  //     },
  //     167
  //   )
  //   .add(
  //     {
  //       targets: "#winloding d3",
  //       rotate: [
  //         { value: -122, duration: 0, easing: "cubicBezier(0.13,0.21,0.1,0.7)" },
  //         { value: -2, duration: 433, easing: "cubicBezier(0.02,0.33,0.38,0.77)" },
  //         { value: 81, duration: 767, easing: "cubicBezier(0, 0, 1, 1)" },
  //         { value: 193, duration: 417, easing: "cubicBezier(0.57,0.17,0.95,0.75)" },
  //         { value: 345, duration: 400, easing: "cubicBezier(0,0.19,0.07,0.72)" },
  //         { value: 427, duration: 766, easing: "cubicBezier(0, 0, 1, 1)" },
  //         { value: 573, duration: 434, easing: "cubicBezier(0,0,0.95,0.37)" }
  //       ]
  //     },
  //     334
  //   )
  //   .add(
  //     {
  //       targets: "#winloding d4",
  //       rotate: [
  //         { value: -128, duration: 0, easing: "cubicBezier(0.13,0.21,0.1,0.7)" },
  //         { value: -8, duration: 433, easing: "cubicBezier(0.02,0.33,0.38,0.77)" },
  //         { value: 75, duration: 767, easing: "cubicBezier(0, 0, 1, 1)" },
  //         { value: 187, duration: 417, easing: "cubicBezier(0.57,0.17,0.95,0.75)" },
  //         { value: 339, duration: 400, easing: "cubicBezier(0,0.19,0.07,0.72)" },
  //         { value: 421, duration: 766, easing: "cubicBezier(0, 0, 1, 1)" },
  //         { value: 567, duration: 434, easing: "cubicBezier(0,0,0.95,0.37)" }
  //       ]
  //     },
  //     501
  //   )
  //   .add(
  //     {
  //       targets: "#winloding d5",
  //       rotate: [
  //         { value: -134, duration: 0, easing: "cubicBezier(0.13,0.21,0.1,0.7)" },
  //         { value: -14, duration: 433, easing: "cubicBezier(0.02,0.33,0.38,0.77)" },
  //         { value: 69, duration: 767, easing: "cubicBezier(0, 0, 1, 1)" },
  //         { value: 181, duration: 417, easing: "cubicBezier(0.57,0.17,0.95,0.75)" },
  //         { value: 331, duration: 400, easing: "cubicBezier(0,0.19,0.07,0.72)" },
  //         { value: 415, duration: 766, easing: "cubicBezier(0, 0, 1, 1)" },
  //         { value: 561, duration: 434, easing: "cubicBezier(0,0,0.95,0.37)" }
  //       ]
  //     },
  //     668
  //   )
  //   .add(
  //     {
  //       targets: "#winloding d6",
  //       rotate: [
  //         { value: -140, duration: 0, easing: "cubicBezier(0.13,0.21,0.1,0.7)" },
  //         { value: -20, duration: 433, easing: "cubicBezier(0.02,0.33,0.38,0.77)" },
  //         { value: 63, duration: 767, easing: "cubicBezier(0, 0, 1, 1)" },
  //         { value: 175, duration: 417, easing: "cubicBezier(0.57,0.17,0.95,0.75)" },
  //         { value: 325, duration: 400, easing: "cubicBezier(0,0.19,0.07,0.72)" },
  //         { value: 409, duration: 766, easing: "cubicBezier(0, 0, 1, 1)" },
  //         { value: 555, duration: 434, easing: "cubicBezier(0,0,0.95,0.37)" }
  //       ]
  //     },
  //     835
  //   );
  // #endregion

  for (let i = 0; i < 6; i++) {
    let basevalue = -110 - 6 * i;

    tl.add(
      {
        targets: "#winloding .d" + (i + 1),
        rotate: [
          { value: basevalue, duration: 0, easing: "cubicBezier(0.13,0.21,0.1,0.7)" },
          { value: basevalue + 120, duration: 433, easing: "cubicBezier(0.02,0.33,0.38,0.77)" },
          { value: basevalue + 203, duration: 767, easing: "linear" },
          { value: basevalue + 315, duration: 417, easing: "cubicBezier(0.57,0.17,0.95,0.75)" },
          { value: basevalue + 467, duration: 400, easing: "cubicBezier(0,0.19,0.07,0.72)" },
          { value: basevalue + 549, duration: 766, easing: "linear" },
          { value: basevalue + 695, duration: 434, easing: "cubicBezier(0,0,0.95,0.37)" }
        ],
        opacity: [
          { value: 1, duration: 1, easing: "linear" },
          { value: 1, duration: 3210, easing: "linear" },
          { value: 0, duration: 10, easing: "linear" },
          { value: 0, duration: 260, easing: "linear" }
        ]
      },
      167 * i
    );
  }

  ring.timeline = tl;
  ring.svgitem = loadingring;

  return ring;
}

JS中的参数与WPF一模一样,这应该是最贴近Win10原版的动画样式了[狗头](不常用JS,写的不好请见谅)。

解释一下 (*)标注的问题,由于WPF动画不能将动画参数作为动态绑定源,因此和UWP中的实现是稍微有区别的,不是复制粘贴就行

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值