滑动轮播 + 动画 + 遮罩图像

swiper carousel + animation + mask image

我正在构建顶部有框架的 Swiper 旋转木马(由鼠标滚动触发)。这就是设计

红色是应该覆盖轮播的框架。中间的洞是透明的

我试过把红色图片做成mask-image,这样我就可以通过鼠标滚动来控制swiper carousel,但是中间的孔变白了,红色是透明的!而我想要的恰恰相反,我想要的是孔移植,孔外是红色。

请问有什么方法可以在滑动条轮播的顶部添加图片框,并且仍然可以触发和控制位于框下的轮播?

代码:

codePen

// https://swiperjs.com/ 
// ===================== -->

var mySwiper = new Swiper('.swiper-container', {
  // Optional parameters
  direction: 'horizontal',
  loop: true,
  speed: 1200,
  grabCursor: true,
  mousewheel: true,

  // If we need pagination
  pagination: {
    el: '.swiper-pagination',
    type: 'bullets',
    clickable: true,
  },

  // Navigation arrows
  navigation: {
    nextEl: '.swiper-button-next',
    prevEl: '.swiper-button-prev',
  },

  on: {
    slideChangeTransitionStart: function() {
      // Slide captions
      var swiper = this;
      setTimeout(function() {
        var currentTitle = $(swiper.slides[swiper.activeIndex]).attr("data-title");
        var currentSubtitle = $(swiper.slides[swiper.activeIndex]).attr("data-subtitle");
      }, 500);
      gsap.to($(".current-title"), 0.4, {
        autoAlpha: 0,
        y: -40,
        ease: Power1.easeIn
      });
      gsap.to($(".current-subtitle"), 0.4, {
        autoAlpha: 0,
        y: -40,
        delay: 0.15,
        ease: Power1.easeIn
      });
    },
    slideChangeTransitionEnd: function() {
      // Slide captions
      var swiper = this;
      var currentTitle = $(swiper.slides[swiper.activeIndex]).attr("data-title");
      var currentSubtitle = $(swiper.slides[swiper.activeIndex]).attr("data-subtitle");
      $(".slide-captions").html(function() {
        return "<h2 class='current-title'>" + currentTitle + "</h2>" + "<h3 class='current-subtitle'>" + currentSubtitle + "</h3>";
      });
      gsap.from($(".current-title"), 0.4, {
        autoAlpha: 0,
        y: 40,
        ease: Power1.easeOut
      });
      gsap.from($(".current-subtitle"), 0.4, {
        autoAlpha: 0,
        y: 40,
        delay: 0.15,
        ease: Power1.easeOut
      });
    }
  }
});

// Slide captions
var currentTitle = $(mySwiper.slides[mySwiper.activeIndex]).attr("data-title");
var currentSubtitle = $(mySwiper.slides[mySwiper.activeIndex]).attr("data-subtitle");
$(".slide-captions").html(function() {
  return "<h2 class='current-title'>" + currentTitle + "</h2>" + "<h3 class='current-subtitle'>" + currentSubtitle + "</h3>";
});
body {
  margin: 0;
}


/* Swiper */

.swiper-container {
  position: absolute;
  width: 100%;
  height: 100vh;
  mask-image: url(https://i.ibb.co/kmBv430/Frame.png);
  mask-size: contain;
}


/* .above{
  position:absolute;
  left:25%;
  background-color: #fff;
   width: 200%;
   height: 100vh;
  z-index:2;
   mask-image: radial-gradient(circle  at center, transparent 49%, white 50%); 
  mask-size: contain;
  mask-repeat: no-repeat;
} */


/* Swiper slides */

.swiper-slide {
  position: relative;
  z-index: 1;
}

.slide-1 {
  background-color: #e67204;
}

.slide-2 {
  background-color: #e67204;
}

.slide-3 {
  background-color: #e67204;
}

.rounded-circle {
  width: 400px;
  height: 300px;
  border-radius: 50%;
  position: absolute;
  top: 30%;
  left: 35%
}

.htu {
  position: absolute;
  color: #fff;
  font-size: 50px;
  top: 39%;
  left: 10%;
  z-index: 2;
}


/* Slide captions */

.slide-captions {
  position: absolute;
  top: 50%;
  left: 75%;
  color: #FFF;
  z-index: 999;
  transform: translateY(-50%);
}

.slide-captions .current-title {
  position: absolute;
  left: 60%;
  margin: 0;
  font-size: 48px;
}

.slide-captions .current-subtitle {
  margin: 10px 0 0 0;
  font-size: 28px;
}


/* Swiper arrows */

.swiper-pagination-bullet-active {
  background-color: #fff;
}


/* Swiper pagination */

.swiper-container-horizontal>.swiper-pagination-bullets {
  bottom: 50px;
}

.swiper-button-prev,
.swiper-button-next {
  color: #fff;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.3.0/gsap.min.js"></script>
<script src="https://unpkg.com/swiper@6.3.2/swiper-bundle.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<!-- Slider main container -->
<div class="swiper-container">
  <h1 class="htu">HOW TO USE</h1>
  <div class="above"></div>
  <!-- Additional required wrapper -->
  <div class="swiper-wrapper">
    <!-- Slides -->

    <div class="swiper-slide slide-1" data-title="Slide One" data-subtitle="">
      <img width="150" height="150" src="https://i.pravatar.cc/300" class="rounded-circle " alt="">
    </div>
    <div class="swiper-slide slide-2" data-title="Slide Two" data-subtitle=" ">
      <img width="150" height="150" src="https://i.pravatar.cc/300" class="rounded-circle " alt="">
    </div>

    <div class="swiper-slide slide-3" data-title="Slide Three" data-subtitle=" ">
      <img width="150" height="150" src="https://i.pravatar.cc/300" class="rounded-circle " alt="">
    </div>
  </div>
</div>

<!-- Slide captions -->
<div class="slide-captions"></div>

<!-- If we need pagination -->
<div class="swiper-pagination"></div>

<!-- If we need navigation buttons -->
<div class="swiper-button-prev"></div>
<div class="swiper-button-next"></div>

</div>

我已经通过使用 GSAP 滚动触发器触发每一层的移动解决了我的问题,它对我有用。

let tl2 = gsap.timeline({

滚动触发器:{ 触发器:“#sec-4”, 别针:真实的, 擦洗:真实,

  start : "center center",
  end: "+=" + (window.innerHeight * 8),
}
  });
  tl2.from('.step-1', 1, {y: 100, opacity:0 })
  tl2.to('.step-1', 1, {opacity:0 })
  tl2.to('.flwres-frame', 0.5 , {x: -300}, 'frist')
  tl2.to('.girl-frame', 1 , {x: -300}, 'frist')
  tl2.from('.step-2', 1, {y: 100, opacity:0 }, 'frist')
  tl2.to('.step-2', 1, {opacity:0 })
  tl2.to('.flwres-frame', 0.5 , {x: -600}, 'second')
  tl2.to('.girl-frame', 1 , {x: -670}, 'second')
  tl2.from('.step-3', 1, {y: 100, opacity:0 }, 'second')
  tl2.to('.step-3', 1, {opacity:0 })
  tl2.to('.flwres-frame', 0.5 , {x: -900}, '3rd')
  tl2.to('.girl-frame', 1 , {x: -1050}, '3rd')
  tl2.from('.step-4', 2, {y: 100, opacity:0 }, '3rd')