likes
comments
collection
share

css实现多张图片旋转动画以及炫光效果

作者站长头像
站长
· 阅读数 3

css实现多张图片旋转动画以及炫光效果

最近遇到一个需求,需要将动态的背景图片用css动画的方式替代。主要原因是因为动态背景图特别大,打包出来的体积非常大,而且无法压缩。最后决定将一个动态背景图拆分成几个静态图片,然后用css动画的方式实现旋转和炫光效果。要求根据不同的父组件的宽高都能居中显示。

效果展示

css实现多张图片旋转动画以及炫光效果

css实现多张图片旋转动画以及炫光效果

技术难点:

  1. 动画旋转的步骤不难,难得是怎么把几张图片都叠加在一起,并且刚好都是居中的,看起来像是一张图片呢?
  2. 炫光效果实现,简单研究了一下,发现还是用线性渐变实现局部炫光效果,整体的话让图片在一定的时间内实现由暗到明再到暗的效果。有技术的同学可以深入研究一下怎么实现无边框只在图片内容上显示渐变炫光。ps: 由于我觉得有div背景框的限制,炫光效果太丑了。

css 图片居中对齐技巧

需要居中对齐,我发现只要父组件实现相对定位,子组件实现绝对定位就没什么问题,但是如何叠加呢,想要子组件再套子组件?属实没有必要,直接把几张图片放在用<di>包裹的标签中,然后用一个大的组件一起包裹起来,用同样的css就能解决问题。

图片叠加旋转代码实现:

// react
 import "./styles.css";

export default function App() {
  const imageStyle = {
    position: 'absolute',
    top: '60%',
    left: '50%',
    transform: 'translate(-50%, -50%)',
    width: '100%',
    height: '100%',
    display: 'flex',
    justifyContent: 'center',
    alignItems: 'center',
  };
  return (
    <div
      style={{
        display: 'flex',
        justifyContent: 'center',
        alignItems: 'start',
        width: '95%',
        height: '90%',
      }}
  >
    <div style={imageStyle}>
      <img src={bg} className={`bg`} />
    </div>
    <div style={imageStyle}>
      <img src={outerBg} className={`outer-image`} />
    </div>
    <div style={imageStyle}>
      <img src={innerBg} className={`inner-image`} />
    </div>
  </div>
  );
}
// less
@prefix: .td-lego-circular-solid-pie;

@{prefix}-bg {
  animation: innerLoading 8s linear infinite;
}
@{prefix}-outer-image {
  animation: outerLoading 5s linear infinite;
}
@{prefix}-inner-image {
  animation: innerLoading 3s linear infinite;
}
@keyframes innerLoading {
  /*以百分比来规定改变发生的时间 也可以通过"from"和"to",等价于0% 和 100%*/
  0% {
    /*rotate(2D旋转) scale(放大或者缩小) translate(移动) skew(翻转)*/
    transform: rotate(0deg);
  }
  100% {
    transform: rotate(360deg);
  }
}

@keyframes outerLoading {
  /*以百分比来规定改变发生的时间 也可以通过"from"和"to",等价于0% 和 100%*/
  0% {
    /*rotate(2D旋转) scale(放大或者缩小) translate(移动) skew(翻转)*/
    transform: rotate(360deg);
  }
  100% {
    transform: rotate(0deg);
  }
}

炫光技巧和呼吸灯效果,这个就是css的线性渐变问题了,有机会用径向渐变实现更好的效果。

  1. 整体炫光的话会出现长方形的边框,所以会比较丑。所以利用css加上了呼吸效果。
  2. 呼吸灯效果主要是利用filter属性改变了图片的明暗度。在3s时间内让图片从正常-到加强亮度到150%,加强饱和度到140%-然后回归正常,一直循环,然后实现了呼吸灯的效果。主要代码就是css中的breathe动画。

炫光技巧和呼吸等效果代码实现

// react
<div
      className={`${prefixName}-container`}
      style={{
        ...style,
        width,
        height,
      }}
    >
<div className={`${prefixName}-data-wrap`}>
    <div className={`${prefixName}-title-wrap`}>
      <div
        className={`${prefixName}-title`}
        style={{
          ...theme.typography.h3,
          color: theme.colors.gray50,
          lineHeight: '65px',
        }}
      >
        {title}
      </div>
    </div>
    <div className={`${prefixName}-total`} >
      {data}
    </div>
  </div>
</div>
// less
@{prefix}-container {
  position: relative;
  flex: 1;
  overflow: hidden;
  background-image: url('../assets/other_datashow_bg.png');
  background-repeat: no-repeat;
  background-size: 100% 100%;
  animation: breathe 3s linear infinite;

  @{prefix}-data-wrap {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
  }

  @{prefix}-title-wrap {
    flex: 1;
    align-items: center;
    justify-content: center;
    width: 156px;
    height: 65px;
    background-image: url('./assets/rectangle.svg');
    background-repeat: no-repeat;
    background-size: 100% 100%;

    @{prefix}-title {
      text-align: center;
    }
  }

  @{prefix}-total {
    margin-top: 12px;
    text-align: center;
  }
}

@{prefix}-title-wrap:after {
  position: absolute;
  top: 0;
  left: 0;
  width: 156px;
  height: 65px;
  content: '';
  background: linear-gradient(45deg, transparent 40%, rgba(255, 255, 255, 0.15) 50%, transparent 60%);
  background-size: 300% 100%;
  animation: shine 15s linear infinite;
}

@keyframes shine {
  0% {
    background-position-x: 400%;
  }

  50% {
    background-position-x: 0%;
  }

  100% {
    background-position-x: -400%;
  }
}

@keyframes breathe {
  0% {
    opacity: 1;
  }

  50% {
    filter: brightness(150%) saturate(140%);
  }

  100% {
    opacity: 1;
  }
}