我无法制作类似于 Pinterest 反应的 css svg 动画表情符号

Posted

技术标签:

【中文标题】我无法制作类似于 Pinterest 反应的 css svg 动画表情符号【英文标题】:I Can't make css svg animation emoji similar to Pinterest reactions 【发布时间】: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
  frombackground-position-x:0px;
  tobackground-position-x:-500px;
<div class="emoji"></div>

我的 JSFiddle:

https://jsfiddle.net/u81xkcon/

【问题讨论】:

您的代码的唯一问题是,您没有正确设置图像的宽度......如果您改用tobackground-position-x:-100%;,它会像一个魅力;-)跨度> 【参考方案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 >
  <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>divwidth:$width;display:inline-flex;background-image: url("$svg");background-size: auto $width;animation:moveX 1s steps($s-1) infinitediv::beforecontent:"";padding-top:100%;@keyframes moveXtobackground-position:right</style><div></div>`;
        html += `<br>Sprite as IMG:<br><img src="$svg">`;
        this.shadowRoot.innerHTML = html;
      )
    
  );
</script>

【讨论】:

以上是关于我无法制作类似于 Pinterest 反应的 css svg 动画表情符号的主要内容,如果未能解决你的问题,请参考以下文章

如何创建像 pinterest 这样的长按菜单? [反应原生]

使用 Bootstrap 制作类似 Pinterest 的网格:这些框不会显示在彼此的正下方

在类似于 facebook 或 pinterest 的 tableview 单元格中显示图像

UICollectionViewLayout 示例

与 Greensock 反应 - 请 gsap.registerPlugin(CSSPlugin, Cs-s-rulePlugin)

具有不同单元格大小、pinterest 样式的 gridView