我正在做一个Reaction项目,我想在其中创建一种效果,当用户向下滚动页面时,圆形背景元素会放大.但是,我也希望在这个圆形背景中保留一个固定大小的图像.从本质上讲,圆圈会变大,但图像大小保持不变.

以下是我为该组件编写的当前代码:


import React, { useEffect, useState } from "react";
import PersonImg from "../assets/person.png";
import Image from "next/image";

const CircleScroll = () => {
  const [scaleFactor, setScaleFactor] = useState(1);

  // Update the scale factor based on the scroll position
  const handleScroll = () => {
    const scrollY = window.scrollY;

    const newScaleFactor = 1 + (scrollY / window.innerHeight) * 30;

    if (newScaleFactor <= window.innerWidth / 70) {
      setScaleFactor(newScaleFactor);
    }
  };

  useEffect(() => {
    window.addEventListener("scroll", handleScroll);
    return () => {
      window.removeEventListener("scroll", handleScroll);
    };
  }, []);

  return (
    <div
      className="grow-element flex justify-center items-center relative"
      style={{ transform: `scale(${scaleFactor})` }}
    >
      <Image
        className="w-[100px] h-[100px] fixed top-0"
        src={PersonImg}
        alt="person-image"
        width={"100"}
        height={"100"}
      />
    </div>
  );
};

export default CircleScroll;

和css

  width: 150px;
  height: 150px;
  background-color: #FFE67B;
  border-radius: 50%;
  position: fixed;
  bottom: 0;
  transform: translate(-50%, -50%);
  transition: transform 0s ease-in-out;
  z-index: -10;
  border-radius: 50%;
}

When I scroll the page, the background element gets bigger but along with that the image too. I want the image to be fixed at the top of the element without increasing it's size. Any help on this would be appreciated. I've also attached the image if it looks confusing. enter image description here

enter image description here

推荐答案

transform将影响元素及其子元素,这就是图像将更大的原因.

第一种方法是从div分中抽取image分:

$(window).on("scroll", function () {
  let r = $(window).scrollTop() / window.innerHeight;
  //console.log(r)
  $(".main").css("transform", `scale(${r})`);
});
* {
  font-family: sans-serif;
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

.main,.main-img {
  z-index: -1;
  position: fixed;
  bottom: 0;
  left:50%;
  text-align: center;
  height: 100px;
  width: 100px;
  border-radius: 50%;
  background: yellow;
  background-size: cover;
  background-position: center;
  background-attachment: fixed;
}
.text {
  height: 100vh;
  width: 100%;
}

.container {
  width: 80%;
  margin: 0 auto;
}

h2 {
  padding: 1rem;
  text-align: center;
  text-transform: uppercase;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="main">
  
</div>
<img class="main-img" src="https://gravatar.com/avatar/ca219a282cd65353e6372369d7568863?s=400&d=robohash&r=x" width="100" style="margin-top: calc(100vh - 100px)">
<!-- <div class="cover"></div> -->
<div class="text">
  <div class="container">
    <h2>Hello</h2>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
  </div>
</div>

另一种方式,正如我 comments 的那样,使用clip-path可以得到类似的结果.

以下是使用简单的html和css的演示:

$(window).on("scroll", function () {
  let y = 100 + $(window).scrollTop() + "px";
  $(".main").css("clip-path", `circle(${y} at 50% 80%)`);
});
* {
  font-family: sans-serif;
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

.main {
  z-index: -1;
  position: fixed;
  bottom: 0;
  text-align: center;
  height: 100vh;
  width: 100%;
  background: yellow;
  background-size: cover;
  background-position: center;
  background-attachment: fixed;
  clip-path: circle(100px at 50% 80%);
}
.text {
  height: 100vh;
  width: 100%;
}

.container {
  width: 80%;
  margin: 0 auto;
}

h2 {
  padding: 1rem;
  text-align: center;
  text-transform: uppercase;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="main">
  <img src="https://gravatar.com/avatar/ca219a282cd65353e6372369d7568863?s=400&d=robohash&r=x" width="100" style="margin-top: calc(100vh - 100px)">
</div>
<!-- <div class="cover"></div> -->
<div class="text">
  <div class="container">
    <h2>Hello</h2>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
    <p>1</p>
  </div>
</div>

Javascript相关问答推荐

jsfat的黑色画布输出

除了在Angular 16中使用快照之外,什么是可行且更灵活的替代方案?

使用useParams路由失败

有条件的悲剧

如何使用侧边滚动按钮具体滚动每4个格?

通过在页面上滚动来移动滚动条

如何在Javascript中使用Go和检索本地托管Apache Arrow Flight服务器?

XSLT处理器未运行

如何在ASP.NET JavaScript中使用Google Charts API仅对绘制为负方向的条形图移动堆叠条形图标签位置

闭包是将值复制到内存的另一个位置吗?

如何在使用rhandsontable生成表时扩展数字输入验证?

如何将innerHTML字符串修剪为其中的特定元素?

有条件重定向到移动子域

在使用REACT更改了CSS类之后,无法更改CSS样式

同一类的所有div';S的模式窗口

删除元素属性或样式属性的首选方法

如何使本地html页面在重新加载时保持当前可隐藏部分的打开状态?

如何根据输入数量正确显示alert ?

Pevent触发material 用户界面数据网格中的自动保存

是否设置以JavaScript为背景的画布元素?