【问题标题】:How to animate rotateX on scroll in pure JS?如何在纯JS中滚动动画rotateX?
【发布时间】:2021-09-05 20:11:44
【问题描述】:

我正在尝试使用rotateX 类似于70deg(或任何数字)的图像创建滚动效果。

每当有人将图像滚动到视口中时,图像的rotateX 必须变为0deg

同理,如果有人将图片滚动出视口,图片的rotateX必须再次变为70deg

这是我的代码:

let a = 70
function test(){
let image = document.querySelector("img");
let imageTop = image.getBoundingClientRect().top;
  
let screenpos = window.innerHeight /2
// console.log("test")
   if(imageTop < screenpos){
    image.style.border = "5px solid green"
    // console.log(window.scrollY/10)
     
    image.style.transform = `rotateX(${a=a-2}deg)`
    // console.log("its reached ")
  }

  
}


window.addEventListener("scroll",function(){
   test()
})
body {
  background-color: #ccc;
  text-align: center;
  margin-top: 100px;
  font-family: sans-serif;
}
.bgcolor {
  background-color: black;
  color: rgba(255, 255, 255, 0.8);
}
div{
  perspective:800px;
  margin-top:400px;
  margin-bottom:200px;
}
div img {
  transform:rotateX(66deg);
  transition:.9s;
/*   border: 1px solid #000; */
  
  }
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  <h1>Scroll Please</h1>
  <div><img src="https://cdn.pixabay.com/photo/2021/06/10/22/14/stork-6327150__340.jpg" alt="Bird Image"></div>
  
</body>
</html>

【问题讨论】:

  • 真的是关于页面的顶部和底部,还是旋转取决于窗口中有多少图像可见?你想要的效果应该是什么样的?
  • @MauriceNino 效果应该类似于当图像进入视口高度时,图像的rotateX必须随着滚动数的增加一点一点地变为零
  • 只是为了确保我理解,您想要的是:当图像在视口中逐渐可见时,它会从围绕 X 轴的 70 度旋转到 0 度,因为它会消失离开视口的顶部 - 反之亦然?那正确吗? IntersectionObserver 在这里会很有用。
  • @AHaworth 我想要的一切都很好,但是当它消失在视口顶部时,你的意思是什么
  • @AHaworth 现在我明白了是的,这就是我想要的

标签: javascript html css


【解决方案1】:

我使用Intersection Observer API 的 Mozilla 文档中的示例为您创建了一个小型 sn-p。

为了更好地了解正在发生的一切,请随时查看链接的文档。

const image = document.querySelector("img");

// Create the Observer on page load
window.addEventListener("load", (event) => {
  createObserver();
}, false);

// Setup the Observer
function createObserver() {
  let observer;

  let options = {
    root: null,
    rootMargin: "0px",
    threshold: buildThresholdList()
  };

  observer = new IntersectionObserver(handleIntersect, options);
  observer.observe(image);
}

// Getting an array with 1000 values between 0.0 and 1.0
function buildThresholdList() {
  let thresholds = [];
  let numSteps = 1000;

  for (let i=1.0; i<=numSteps; i++) {
    let ratio = i/numSteps;
    thresholds.push(ratio);
  }

  thresholds.push(0);
  return thresholds;
}

// What to do with the observer intersections
function handleIntersect(entries, observer) {
  entries.forEach((entry) => {
    // Only get values between 0 and 0.5, so that the image only 
    // ...starts animating when half visible
    const maxxedIntersect = entry.intersectionRatio > 0.5 
        ? entry.intersectionRatio - 0.5 
        : 0;
    
    // Scale the number (0.0 ... 0.5) between 0 and 70
    const scaled = scaleBetween(maxxedIntersect, 0, 70, 0, 0.5);
    
    // Get the value that the thing should rotate
    // When the element is fully visible, the scaled value will be 70, 
    // ... so we have to sub from 70 to get 0 in this example
    const rotateValue = parseInt(70 - scaled);
    
    // Apply the style
    image.style.transform = `rotateX(${rotateValue}deg)`
  });
}

// Helper function for scaling numbers between min and max
// Look here: https://stackoverflow.com/a/31687097/9150652
function scaleBetween(unscaledNum, minAllowed, maxAllowed, min, max) {
  return (maxAllowed - minAllowed) * (unscaledNum - min) / (max - min) + minAllowed;
}
body {
  background-color: #ccc;
  text-align: center;
  margin-top: 100px;
  font-family: sans-serif;
}
.bgcolor {
  background-color: black;
  color: rgba(255, 255, 255, 0.8);
}
div > img{
  margin-top: 400px;
  margin-bottom: 600px;
  perspective: 800px;
  border: 5px solid green;
  transition: .1s;
}
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
  </head>
  <body>
    <h1>Scroll Please</h1>
    <div>
      <img src="https://cdn.pixabay.com/photo/2021/06/10/22/14/stork-6327150__340.jpg" 
           alt="Bird Image">
    </div>
  </body>
</html>

【讨论】:

  • 逻辑似乎有点复杂,但无论如何非常感谢:)。
  • 我想知道为什么在我传递图像并向下滚动后图像正在旋转X,如果这个问题看起来有用,你可以投票
  • @ShayanKanwal 好吧,你要做的不是一个微不足道的主题,所以逻辑当然会有点复杂。请注意,这已经是简化版本,无需手动检查交叉点。
  • @ShayanKanwal 那是因为它再次淡出视口。请检查代码和文档,甚至还有一个非常互动的示例向您显示百分比和类似的东西。
  • 好的,我会玩代码,如果我遇到困惑,我会问你。顺便说一句,如果这个问题看起来有用,你可以点赞。这对我来说意义重大。
猜你喜欢
  • 2013-07-11
  • 2019-01-18
  • 2021-12-29
  • 1970-01-01
  • 2015-12-29
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多