我正在创建一个项目,其中一个容器包含当用户滚动页面时在容器内滚动的图像。它根据滚动速度自行增大或缩小的容器,因此它会更改 css 变换样式,并根据滚动速度输入变换值。因此,当您滚动时,页面中心的任何对象都会出现凸起效果(当向上和向下滚动时,它会增加图像的容器 div)
这是我想要重新创建的效果:
效果:
const container = document.querySelector('.container');
const images = document.querySelectorAll('.container img');
const containerHeight = container.offsetHeight;
const centerPosition = window.innerHeight / 2;
function updateScrollPosition() {
const scrollPosition = window.scrollY;
const scrollSpeed = Math.abs(window.scrollY - containerHeight) / 100;
const bulgeAmount = -1 * scrollSpeed;
const newContainerHeight = containerHeight + scrollSpeed;
const translateY = Math.max(-2000, Math.min(0, bulgeAmount));
container.style.height = `${newContainerHeight}px`;
container.style.transform = `translateY(${translateY}px)`;
images.forEach(image => {
const imageTopPosition = image.getBoundingClientRect().top;
const distanceFromCenter = centerPosition - imageTopPosition;
const imageBulgeAmount = bulgeAmount / 5;
const imageTranslateY = Math.max(-2000, Math.min(0, imageBulgeAmount));
image.style.transform = `translate3d(0px, ${imageTranslateY}px, 0px)`;
});
}
window.addEventListener('scroll', updateScrollPosition);
在此实现中,我们将滚动速度计算为当前滚动位置与原始容器高度之间的绝对差除以 100。然后我们使用此值来调整容器的高度和 translateY 值。我们还根据 bulgeAmount 值单独调整每个图像的 translateY 值。 Math.max 和 Math.min 函数用于防止 translateY 值超过一定范围,以避免视觉故障。 translate3d CSS 属性用于启用硬件加速以获得更流畅的性能。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Distortion and Bounce Effect with Three.js</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<script src="./js/app.js"></script>
<div class="container">
<img src="img/img51.jpg" />
<img src="img/img52.jpg" />
<img src="img/img64.jpg" />
<img src="img/img71.jpg" />
</div>
</body>
</html>
.body{
background-color: rgb(110, 109, 109);
}
.container{
border-radius: 16px;
height: 550px;
width: 750;
max-width: 800px;
display: flex;
flex-wrap: wrap;
justify-content: center;
align-items: center;
overflow: hidden;
overflow-y: scroll;
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
.container img {
width: 100%;
height: 100%;
object-fit: cover;
border-radius: 16px;
}
@media only screen and (min-width: 350px) {
/* Set a specific width for larger screens */
.container {
width: 80%;
}
}
正如您所见,脚本看起来不错,但是当我使用包裹查看结果时,我只能看到容器和图像;效果不起作用。我仍然想知道为什么。
所以相反,我尝试使用 pixijs.io 算法,但它没有产生我想要的效果
这是结果:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Bulge Effect on Scroll</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/pixi.js/6.1.3/pixi.min.js"></script>
<style>
body {
margin: 0;
padding: 0;
overflow-x: hidden;
background-color: #222222;
}
#canvas-container {
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 80vw;
height: 80vh;
border-radius: 16px;
overflow: hidden;
}
</style>
</head>
<body>
<div id="canvas-container"></div>
<script>
const canvasContainer = document.getElementById('canvas-container');
const app = new PIXI.Application({
width: canvasContainer.offsetWidth,
height: canvasContainer.offsetHeight,
backgroundColor: 0x222222
});
canvasContainer.appendChild(app.view);
// Create a container for the images
const container = new PIXI.Container();
container.width = app.screen.width;
container.height = app.screen.height;
container.position.set(app.screen.width / 2, app.screen.height / 2);
app.stage.addChild(container);
// Load the images
const loader = new PIXI.Loader();
const images = [
'img/img51.jpg',
'img/img52.jpg',
'img/img64.jpg',
'img/img71.jpg'
];
images.forEach((img) => loader.add(img));
loader.load(setup);
// Setup the images
function setup() {
images.forEach((img) => {
const texture = PIXI.Texture.from(img);
const sprite = new PIXI.Sprite(texture);
sprite.anchor.set(0.5);
sprite.width = app.screen.width;
sprite.height = app.screen.height;
container.addChild(sprite);
});
// Apply bulge effect on scroll
let scrollPosition = 0;
const maxScroll = -2000;
app.ticker.add(() => {
const delta = (scrollPosition - window.scrollY) * 0.1;
scrollPosition = window.scrollY;
container.children.forEach((sprite) => {
const x = sprite.x - app.screen.width / 2;
const y = sprite.y - app.screen.height / 2;
const distance = Math.sqrt(x * x + y * y);
const angle = Math.atan2(y, x);
const radius = distance / 20;
const distortionX = Math.sin(angle * 10) * radius * delta;
const distortionY = Math.cos(angle * 10) * radius * delta;
sprite.position.set(sprite.x + distortionX, sprite.y + distortionY);
});
container.scale.y = PIXI.utils.clamp(1 + (scrollPosition / maxScroll), 1, 2);
});
}
</script>
</body>
</html>
在此脚本中,我使用 PIXI.Application 类创建了一个新的 PixiJS 应用程序并将其添加到 canvas-container div。然后我为图像创建了一个容器,使用 PIXI.Loader 加载图像,并将它们添加到容器中。
但如你所见,它并不是那么好.
所以有人知道如何创造这种效果吗?:
请不要删除这是我能做的最好的解释!