基于background-position的一些设计思路

423 阅读1分钟

一、基本用法

  • background-position:x, y;背景图片相对容器原点的起始位置
  • 取值
    关键字:top | center | bottom | left | center | right
    百分比:百分数
    具体值:px、rem、em等确值
    默认值为:0% 0%(即坐标原点)

二、一些应用

1、逐帧动画

比如我们要实现一个类似微信语音播放的小动画,如下:

屏幕录制2022-06-29 17.15.41.gif

首先需要准备这样一张竖版拼接逐帧图(横图同理)

voice-l.png

这个小动画的原理实际是背景定位的移动,这里用到了step()逐步动画,可以让动画不连续,逐步运动。

.voice{
      background-image: url('@/assets/img/voice.png');
      background-repeat: no-repeat;
      background-position: 0px -40px;
      background-size: 100%;
      animation: play 1.5s steps(2) infinite;
}
  @keyframes play {
    0% {
      background-position-y: -40px;
    }
    50% {
      background-position-y: 0px;
    }
    100% {
      background-position-y: -40px;
    }
  }

这种小动画应用场景丰富,比如阿里云官网的小tab

屏幕录制2022-06-29 17.28.13.gif

2、悬停预览长图

如图的长图预览功能

屏幕录制2022-06-29 17.58.51.gif

鼠标hover时,通过判断鼠标X坐标相对于图片宽度来确定background-position-y的位置

这是我实现的预览长图小组件

css

  .longImg {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    transition: opacity 0.1s linear;
    display: none;
    background: #fff;
  }
  .mask {
    width: 100%;
    height: 100%;
    position: absolute;
    top: 0;
    left: 0;
    background: rgba(0, 0, 0, 0.2);
    opacity: 0;
    transition: opacity 0.3s ease;
  }
  .longImg_track {
    opacity: 0;
    transition: opacity 0.3s ease;
    width: calc(100% - 24px);
    height: 4px;
    background: rgba(0, 0, 0, 0.6);
    border-radius: 2px;
    position: absolute;
    bottom: 8px;
    left: 12px;
    .longImg_progress {
      height: 100%;
      background: $cWhite;
      border-radius: 2px;
    }
  }
  &:hover .longImg {
    display: block;
  }
  &:hover .mask {
    opacity: 1;
  }
  &:hover .longImg_track {
    opacity: 1;
  }

html

  <div class="imgPreview">
    <!-- 需要划动的长图部分 -->
    <img
      class="longImg"
      :src="imgUrl"
      alt=""
      :style="{ 'object-position': ' 0px ' + progressWidth }"
    />
      <div
        class="mask"
        @mouseenter="handleProgressGet"
        @mousemove="handleProgressChange"
        @mouseleave="handleProgressHide"
      ></div>
    </el-tooltip>
    <!-- 长图进度条 -->
    <div class="longImg_track" v-if="isLong">
      <div class="longImg_progress" :style="{ width: progressWidth }"></div>
    </div>
  </div>

js

 data() {
    return {
      percent: 0, //进度条百分比
      imgX: 0, //容器X坐标
      imgW: 0, //容器宽度
    };
  },
  methods: {
    handleProgressGet(event) {
      this.imgX = event.target.getBoundingClientRect().x;
      this.imgW = event.target.getBoundingClientRect().width;
    },
    handleProgressChange(event) {
      let x = event.clientX; //鼠标x坐标
      this.percent = ((x - this.imgX) / this.imgW) * 100;
    },
    handleProgressHide() {
      this.percent = 0;
    },
  },
 computed: {
    progressWidth() {
      return this.percent + "%";
    },
  },