html - 如何实现与孙子的视差效果
问题描述
我之前在 codepen 和小型实验项目中实现了几次视差背景效果。
这是我最喜欢的教程 - https://keithclark.co.uk/articles/pure-css-parallax-websites/
这是参考教程中的标记:
<div class="parallax">
<div class="parallax__layer parallax__layer--back">
...
</div>
<div class="parallax__layer parallax__layer--base">
...
</div>
</div>
以及重要的 CSS 位:
.parallax {
...
perspective: 1px;
}
.parallax__layer--base {
transform: translateZ(0);
}
.parallax__layer--back {
transform: translateZ(-1px);
}
基本上 -.parallax
元素有一个透视图,这基本上意味着它可以在 3d 空间中查看事物。
(.parallax__layer--base
即前景层)位于0
z 轴上。所以它并没有离开它的起源。
(.parallax__layer--back
背景层)在 z 轴上向后放置一个像素。
所以现在,当您滚动.parallax
元素时,您可以看到这些背景和前景图层在 3d 空间中移动,从而产生视差效果。
但它只有在你滚动.parallax
元素时才有效——在一个完整的、健壮的页面上怎么样?
<div class='home'>
...
<div class="parallax">
<div class="parallax__layer parallax__layer--back">
...
</div>
<div class="parallax__layer parallax__layer--base">
...
</div>
</div>
...
</div>
css 和标记没有改变。但现在我正在滚动.home
元素,而不是.parallax
元素。前景和背景层仍然在 3d 空间中,但它只是相对于.perspective
元素。
有没有办法以某种方式将这种观点传递给主页的孙子或曾孙?或者我是否需要将整个页面分成前景和背景部分才能达到这种效果?
解决方案
我想出了一种用 JavaScript 实现这一点的“hacky”方式。
这是步骤的概要(您可以将其称为算法):
- 监听窗口滚动事件
- 等到视差容器(您定义为
base
和的父级back
)在视图中 - 就我而言,我固定
back
并更改了过渡持续时间的top
值。base
这是我的实现(特定于我的用例):
/**
* hacky parallax effect
*/
const viewportHeight =
'innerHeight' in window
? window.innerHeight
: document.documentElement.offsetHeight
const headerHeight = document.querySelector('header').offsetHeight
window.onscroll = () => {
const preFooterPosition = document
.querySelector('.pre-footer')
.getBoundingClientRect()
/** start parallax when pre-footer is in view */
if (
preFooterPosition.top <= headerHeight &&
preFooterPosition.bottom >= viewportHeight
) {
// parallax
document.querySelector('.content').classList.add('transform-content')
} else {
// reverse parallax
document
.querySelector('.content')
.classList.remove('transform-content')
}
}
.content {
display: flex;
flex-direction: column;
flex: 1;
z-index: 1;
position: relative;
top: 0;
transition: top 1s ease;
}
.transform-content {
top: -5rem;
}
.watermark {
position: absolute;
z-index: 0;
flex: 1;
display: flex;
}
<template>
<section class="pre-footer">
<div class="wrapper">
<div class="watermark">
<SVGIcon class="watermark-left" icon="LearnLongShort" />
<SVGIcon class="watermark-right" icon="FreeEducation" />
</div>
<div class="content">
<div class="content-left content-wrapper">
<div>
<h3 class="title">Evidence base</h3>
<div class="body">
<p>The Academy of Medical Cannabis Evidence Base is an advanced referencing tool for CBMP research. Containing the history of research to date and all emerging findings, this cutting-edge engine underpins our learning content.</p>
</div>
<WhiteButton text="View database" />
</div>
</div>
<div class="content-right content-wrapper">
<div>
<h3 class="title">White Papers</h3>
<div class="body">
<p>Alongside our learning platform, The Academy publishes a series of authoritative papers discussing the core topics and themes related to CBMPs. Register to view and download the archive.</p>
</div>
<WhiteButton text="Archive" />
</div>
</div>
</div>
</div>
</section>
</template>
我希望这会有所帮助。当您提出更好的解决方案时,请告诉我。与此同时,我正在推动这一点。
干杯!
推荐阅读
- azure-ad-b2c - 启用用户名登录流程后,防止 Azure B2C 用户使用电子邮件地址登录
- regex - Notepad++ - 如何将行首的数字批量复制到每行的另一部分?
- angular - RxJs 地图算子
- jenkins - 来自github的Jenkins Blue Ocean Plugin webhook集成?
- ios - React-Native ios:FBSDKAccessToken.h - 属性有先前的声明
- java - AWS CDK loadNestedStacks 的示例输入
- python - pysnmp:没有此类名称错误(此 OID 处当前不存在此类对象)
- mysql - Mysql/MariaDB 通过 AES 加密数据搜索
- php - Prestashop:迁移后在 url 中添加子文件夹
- rest - 发布嵌套对象 - 返回父对象内的嵌套对象