使用vue开发一个双向展开的卷轴组件

我们在项目实践中,偶尔会为了增加页面内容的显示效果,使用卷轴展开的形式展示页面内容,以此来增加良好的交互和趣味性,卷轴的展开方式有两种,一种是向左或者向右单向展开,另一种是从中间向两边双向展开。
单向展开的卷轴实现起来相对比较容易,笔者不做讲解,这里笔者主要说明双向卷轴的实现。
先上效果图,感兴趣的继续,没兴趣的过。
在这里插入图片描述
思路:
1.显示未展开状态下的显示样式。
2.显示完全展开状态下的显示样式。
3.解决展开中状态下卷轴布始终居中问题和未展开部分隐藏问题。

1和2都非常简单,重点是3,咱们先解决未展开部分隐藏问题,这里笔者需要有个空间容器的概念,以ABC来举例:
A是房子,B是窗户,C是一张比窗户大的画布,那么我们想象站在房子外看窗户,肯定只能看到部分画布,这时,假设窗户可以逐渐变大,最终的效果我们就可以全部的画布。这里窗户就是卷轴的可见区域,窗户周围的画布我们看不到overflow:hidden,因此我们的元素层级为A包含B,B包含C。B处于A的中间位置,这个容易控制,居中设置就可以,C比B大,而且还要显示中间,所以C要相对于B进行定位,top:0;left:0;再来一个transform:translateX()将C向左移动就可以将C置于中间显示位置。
因为C是相对于B的定位,所以当B的大小变化时,C的移动就需要动态变化,不断更改移动的位置,以此来保证C位于B的显示中间。这里笔者使用了定时间,不断更改B的宽度大小和C的移动距离。
结构代码如下:

<template>
  <div class="c-reel">
    <div class="view" ref="view" :style="{width: viewWidth}">
      <div class="content" ref="reel" :style="scrollStyle">
        <slot></slot>
      </div>
      <img class="jz left-jz" src="../assets/questions/jz1.png" alt="左卷轴" :style="{left: jzLeft}" />
      <img class="jz right-jz" src="../assets/questions/jz2.png" alt="右卷轴" :style="{right: jzRight}" />
    </div>
  </div>
</template>

设置C居中的代码如下:

/**
     * 处理内部展开卷轴的移动位置
     * 展开卷轴的宽度-可见区域的宽度,再除以2得到的值就是内部卷轴应该向左移动的位置
     * 随着可见区域的扩大,向左移动位置应该动态改变,保证卷轴处于中间位置
     */
    handleTransform() {
      let viewWidth = this.$refs.view.clientWidth; // 可见区域的宽度
      let scrollWidth = this.$refs.reel.clientWidth; // 获取展开卷轴的宽度
      let translateX = (scrollWidth - viewWidth) / 2;
      this.scrollStyle = {
        transform: "translateX(-" + translateX + "px)"
      };
    }

样式代码如下:

<style lang="less" scoped>
.c-reel {
  position: absolute;
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -65%);
  width: 100%;
  height: 6rem;
  .view {
    position: absolute;
    top: 0;
    left: 50%;
    transform: translateX(-50%);
    width: 0.88rem;
    height: 100%;
    overflow: hidden;
    .content {
      width: 100vw;
      height: 100%;
      background: url("../assets/questions/jz.png") no-repeat center;
      background-size: 100% 100%;
      overflow: hidden;
      position: relative;
    }
  }
  .jz {
    position: absolute;
    top: 0;
    width: 0.44rem;
    height: 100%;
    &.left-jz {
      left: 0;
    }
    &.right-jz {
      right: 0;
    }
  }
}
</style>

详细代码请看这里


欢迎关注博主:小圣贤君,有问题可以留言哦~

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值