【问题标题】:I Can't make css svg animation emoji similar to Pinterest reactions我无法制作类似于 Pinterest 反应的 css svg 动画表情符号
【发布时间】:2021-04-07 11:49:21
【问题描述】:

我无法使用类似于 Pinterest 的 SVG 精灵制作 CSS 动画。 精灵是 90 帧,但我无法让它工作

Pinterest 反应表情符号

View Pinterest Sprite 90 frames in Svg

我的代码:

.emoji{
  width: 110px;
  height: 110px;
  background-image : url(https://s.pinimg.com/webapp/style/images/wow-0a7ea725.svg);
  animation: moveX 1s steps(90) infinite;
}

@keyframes moveX{
  from{background-position-x:0px;}
  to{background-position-x:-500px;}
}
<div class="emoji"></div>

我的 JSFiddle:

https://jsfiddle.net/u81xkcon/

【问题讨论】:

  • 您的代码的唯一问题是,您没有正确设置图像的宽度......如果您改用to{background-position-x:-100%;},它会像一个魅力;-)跨度>

标签: css svg css-animations


【解决方案1】:

给你

.emoji {
  width: 110px;
  display: inline-flex;
  background-image: url(https://s.pinimg.com/webapp/style/images/wow-0a7ea725.svg);
  background-size: auto 100%;
  animation: moveX 1s steps(90) infinite;
}

.emoji::before {
  content: "";
  padding-top: 100%; /* keep the square ratio */
}

@keyframes moveX {
  to {
    background-position: right; /* you only need to move to right */
  }
}
<div class="emoji"></div>
<div class="emoji" style="width:50px"></div>

【讨论】:

  • 好朋友,谢谢。但我有一个问题......为什么动画在 X 轴上振动?
  • @DavidPumaRios 精灵没有完全对齐或者浏览器渲染问题
  • @DavidPumaRios 我已经更新了代码以摆脱它。在 Y 轴上使用 100% 以避免任何跳跃空间
  • ::before 是干什么用的?我看不出有什么用...否则,很好的答案!
  • @Christoph 来保持平方比例,注意我是如何使用两个不同宽度的 div 的,我从未指定高度,因为伪元素会这样做。
【解决方案2】:

如果您接受 Temani 他的出色回答,请添加一个现代 W3C 标准 Web 组件,该组件使用 Template Literal 解析来创建 SVG 精灵客户端 在 shadowDOM 中

并在&lt;template&gt;中做一些更好的动画计算)

您无需下载 65KB SVG 文件,并获得:

<svg-spriter w=100 h=100 s=40 width="130px">
  <template>
    <g id="sprite${n}_${s}" transform="translate(${n*w})">
      <rect x='5' y='5' width='90' height='90' rx='20' fill='#ffad65'></rect>
      <circle cx='30' cy='30' r='${12+(n<10?-n:n)*.1}'></circle>
      <circle cx='80' cy='30' r='${12+(n<10?n:-n)*.1}'></circle>
      <ellipse cx='60' cy='70' rx="${10+(n<20?n*0.5:((20-n)*-0.5))}" ry="5"></ellipse>
    </g>
  </template>
</svg-spriter>
<script>
  customElements.define("svg-spriter", class extends HTMLElement {
    constructor() { super().attachShadow({mode: "open"}) }
    connectedCallback() {
      const parsed = (template, vars = {}) => new Function('vars', [
        'let f = ( ' + Object.keys(vars).join(', ') + ' ) =>',
        '`' + template + '`','return f(...Object.values(vars))'
      ].join('\n'))(vars);
      setTimeout(() => { // wait till <template> is parsed by the Browser
        let attr = (x) => this.getAttribute(x);
        let [w, h, s] = ["w", "h", "s"].map(a => ~~attr(a));
        let width = attr("width");
        let frame = this.querySelector("template").innerHTML;
        let svg =
          (`data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 ${s*w} ${h}'>` +
            Array(s).fill().map((s, n) => parsed(frame, {n,w,h,s})).join("") + "</svg>").replace(/#/g, "%23").replace(/\n/g, "").replace(/</g, "%3C").replace(/>/g, "%3E").replaceAll('"', "'");
        let html = `<style>div{width:${width};display:inline-flex;background-image: url("${svg}");background-size: auto ${width};animation:moveX 1s steps(${s-1}) infinite}div::before{content:"";padding-top:100%;}@keyframes moveX{to{background-position:right}}</style><div></div>`;
        html += `<br>Sprite as IMG:<br><img src="${svg}">`;
        this.shadowRoot.innerHTML = html;
      })
    }
  });
</script>

【讨论】:

    猜你喜欢
    • 2021-08-29
    • 1970-01-01
    • 2017-02-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多