基于滚动的动画
基于滚动的动画
基于滚动的动画免费下载 在 HTML、CSS 和 JavaScript 中
HTML:
<!-- The `.container` element will contain all the images -->
<!-- It will be used also to perform the 'custom scroll' behavior -->
<div class="container">
<!-- Each following `div` correspond to one image -->
<!-- The images will be set using CSS backgrounds -->
<div class="image vh-fix"></div>
<div class="image vh-fix"></div>
<div class="image vh-fix"></div>
<div class="image vh-fix"></div>
<div class="image vh-fix"></div>
<div class="image vh-fix"></div>
<div class="image vh-fix"></div>
<div class="image vh-fix"></div>
<div class="image vh-fix"></div>
<div class="image vh-fix"></div>
</div>
CSS:
身体 {
// `overflow-x` 应该被隐藏,所以水平滚动条
// 执行转换时不出现
溢出-x:隐藏; //设置背景
高度:100vh;
背景颜色:#9f9eac;
背景图像: url("数据:图像/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='100%25' height='100%25' viewBox= '0 0 1600 800'%3E%3Cg %3E%3C 路径填充='%23aeadbc' d='M486 705.8c-109.3-21.8-223.4-32.2-335.3-19.4C99.5 692.1 49 703 0 719.8V800h843.8- 115.9-33.2-230.8-68.1-347.6-92.2C492.8 707.1 489.4 706.5 486 705.8z'/%3E%3Cpath 填充='%23bdbccc' d='M1600 0H0v719.8c49-16.8 99.5-27.5.1 11.5.3-16.8 99.3-3 -12.7 226-2.4 335.3 19.4c3.4 0.7 6.8 1.4 10.2 2c116.8 24 231.7 59 347.6 92.2H1600V0z'/%3E%3C路径填充='%23cdccdd'd='M478.4 581c3.2 9.58.6.54193.2 .2 52.5 388.7 133.5 593.5 176.6c174.2 36.6 349.5 29.2 518.6-10.2V0H0v574.9c52.3-17.6 106.5-27.7 161.1-30.9C268.4 537.4 375.7 554.2 478.4 581z'/%3E%3Cpath fill='%23dcdbee' d ='M0 0v429.4c55.6-18.4 113.5-27.3 171.4-27.7c102.8-0.8 203.2 22.7 299.3 54.5c3 1 5.9 2 8.9 3c183.6 62 365.7 146.1 562.4 192.1c186.7 43.7 376.3 34.4 557.9-12.6V0H0z'/ %3E%3C路径填充='%23ecebff'd='M181.8 259.4c98.2 6 191.9 35.2 281.3 72.1c2.8 1.1 5.5 2.3 8.3 3.4c171 71.6 342.7 158.5 531.3 207.7c198.8 51.8 403.4 40.8 597.3-14.8V0H0v283.2C59 263.6 120.6 255.7 181.8 259.4z'/%3E%3Cpath fill='%23dcdbee' d='M1600 0H0v136.3c62.3-20.9 127.7-27.5 192.2 -19.2c93.6 12.1 180.5 47.7 263.3 89.6c2.6 1.3 5.1 2.6 7.7 3.9c158.4 81.1 319.7 170.9 500.3 223.2c210.5 61 430.8 49 636.6-16.6V0z'/%3E%3Cpath fill='%23cdccdd' d= 'M454.9 86.3C600.7 177 751.6 269.3 924.1 325C208.6 67.4 431.3 60.8 637.8 637.9-5.3c12.8-4.1 25.4-8.4-8.4 38.1-12.9v0h288.1c56 %3E%3Cpath 填充='%23bdbccc' d='M1600 0H498c118.1 85.8 243.5 164.5 386.8 216.2c191.8 69.2 400 74.7 595 21.1c40.8-11.2 81.1-25.2 120%.3-%1.4' '%23aeadbc' d='M1397.5 154.8c47.2-10.6 93.6-25.3 138.6-43.8c21.7-8.9 43-18.8 63.9-29.5V0H643.4c62.9 41.7 129.7 78.2 202.1 107.4C1020.4 178.1 1214.2 196.1 1397.5 154.8z'/%3E%3Cpath 填充='%239f9eac' d='M1315.3 72.4c75.3-12.6 148.9-37.1 216.8-72.4h-723C966.8 71 1144.7 101 1315.3 72.4z'/%3E%3C/ g%3E%3C/svg%3E");
/* SVGBackgrounds.com 提供的背景 */
背景附件:固定;
背景位置:中心;
背景尺寸:封面;
} // `div` 元素的样式(用 Javascript 插入)
// 用于使页面可滚动
// 将使用 Javascript 设置适当的 `height` 值
.假滚动{
位置:绝对;
顶部:0;
宽度:1px;
} // 所有图片的容器
。容器 {
// 2列网格
显示:网格;
网格模板列:1fr 1fr;
网格间隙:0 10%;
证明项目:结束; // 这将使所有项目(图像)向右对齐 // 固定定位,因此不受默认滚动的影响
// 它将使用 `transform` 移动,以实现自定义滚动行为
位置:固定;
顶部:0;
左:0;
宽度:100%;
} // 图像元素的样式
// 主要是定位和背景样式
。图片 {
位置:相对;
宽度:300px;
高度:100vh;
背景重复:不重复;
背景位置:中心; // 这会将所有偶数图像向左对齐
// 为了获得居中定位的图像,尊重视口
&:nth-child(2n) {
自我证明:开始;
} // 使用 SCSS `for` 循环设置每个 `background-image`
@for $i 从 1 到 10 {
&:nth-child(#{$i}) {
背景图片: url('https://cdn.jsdelivr.net/gh/lmgonzalves/scroll-based-animation/img/image#{$i}.jpg');
}
}
} // 调整小屏幕的布局
@media screen and (max-width: 760px) {
。容器 {
// 1 列网格
网格模板列:1fr;
// 修复图像居中
对齐项目:中心;
} // 修复图像居中
.image:nth-child(2n) {
自我辩护:中心;
}
}
JavaScript:
/**
* 正则表达式针对以下用户代理进行了测试和匹配:
* 苹果手机
* Mozilla/5.0 (iPhone; CPU iPhone OS 10_3 像 Mac OS X)
* AppleWebKit/602.1.50(KHTML,如 Gecko)
* CriOS/56.0.2924.75 手机/14E5239e Safari/602.1
* iPad
* Mozilla/5.0 (iPad; CPU OS 9_0 像 Mac OS X)
* AppleWebKit/600.1.4(KHTML,如 Gecko)
* CriOS/45.0.2454.89 移动/13A344 Safari/600.1.4 (000205)
*/ const iOSChromeDetected = /CriOS/.test(navigator.userAgent); if (iOSChromeDetected) {
常量 getHeight = 函数 getComputedHeightFrom(element) {
const computedHeightString = getComputedStyle(element).height;
const elementHeight = Number(computedHeightString.replace('px', ''));
返回元素高度;
}; 常量 calculateVh = 函数 calculateVhFrom(elementHeight) {
常量近似Vh = (elementHeight / initialViewportHeight) * 100;
const elementVh = Math.round(approximateVh);
返回元素Vh;
}; 常量 setDataAttribute = 函数 setDataAttributeUsing(elementVh, element) {
常量 dataAttributeValue = `${elementVh}`;
element.setAttribute('data-vh', dataAttributeValue);
}; 常量 setHeight = 函数 setHeightBasedOnVh(element) {
常量横向=方向;
常量 vhRatio = Number(element.dataset.vh / 100);
如果(风景){
element.style.height = `${vhRatio * LandscapeHeight}px`;
} 别的 {
element.style.height = `${vhRatio * portraitHeight}px`;
}
}; 常量初始化 = 函数初始化数据属性和高度(元素){
常量元素高度 = 获取高度(元素);
常量元素Vh = 计算Vh(元素高度);
setDataAttribute(elementVh, element);
设置高度(元素);
}; 常量 initialViewportHeight = window.innerHeight;
常量元素 = Array.from(document.getElementsByClassName('vh-fix'));
常量状态栏高度 = 20;
const PortraitHeight = screen.height - statusBarHeight;
const LandscapeHeight = screen.width - statusBarHeight; window.onload = 函数(){
window.addEventListener('orientationchange', function() {
元素.forEach(setHeight);
}); 元素.forEach(初始化);
};
} // 演示 (功能() { // 用于 `translateX` 动画的缓动函数
// 来自:https://gist.github.com/gre/1650294
函数easeOutQuad(t){
返回 t * (2 - t)
} // 返回一个介于 `min` 和 `max` 之间的随机数(整数)
函数随机(最小,最大){
返回 Math.floor(Math.random() * (max - min + 1)) + min
} // 也返回一个随机数,但也可以是负数
函数 randomPositiveOrNegative (min, max) {
return random(min, max) * (Math.random() > 0.5 ? 1 : -1)
} // 为元素设置 CSS `transform` 属性
函数 setTransform (el, 变换) {
el.style.transform = 变换
el.style.WebkitTransform = 变换
} // 当前滚动位置
无功电流 = 0
// 目标滚动位置
变量目标 = 0
// 从 `current` 移动到 `target` 的轻松或速度
变轻松 = 0.075
// `requestAnimationFrame` 的实用变量
var rafId = 未定义
var rafActive = 假
// 容器元素
var container = document.querySelector('.container')
// 带有 `.image` 元素的数组
var images = Array.prototype.slice.call(document.querySelectorAll('.image'))
// 用于存储维度的变量
var windowWidth, containerHeight, imageHeight // 用于指定变换参数和限制的变量
var rotateXMaxList = []
var rotateYMaxList = []
var translateXMax = -200 // 用随机值填充 `rotateXMaxList` 和 `rotateYMaxList`
图像.forEach(函数(){
rotateXMaxList.push(randomPositiveOrNegative(20, 40))
rotateYMaxList.push(randomPositiveOrNegative(20, 60))
}) // `fakeScroll` 是使页面可滚动的元素
// 这里我们创建它并将它附加到 `body`
var fakeScroll = document.createElement('div')
fakeScroll.className = '假滚动'
document.body.appendChild(fakeScroll)
// 在 `setupAnimation` 函数(如下)中,我们将正确设置 `height` // 获取维度并设置所有动画
函数设置动画(){
// 更新维度
windowWidth = window.innerWidth
containerHeight = container.getBoundingClientRect().height
imageHeight = containerHeight / (windowWidth > 760 ? images.length / 2 : images.length)
// 为假滚动元素设置 `height`
fakeScroll.style.height = containerHeight + 'px'
// 启动动画,如果它还没有运行
开始动画()
} // 更新滚动 `target`,如果动画还没有运行,则启动动画
函数更新滚动(){
目标 = window.scrollY || window.pageYOffset
开始动画()
} // 启动动画,如果它还没有运行
函数启动动画(){
如果(!rafActive){
rafActive = true
rafId = requestAnimationFrame(updateAnimation)
}
} // 进行计算并相应地应用 CSS `transform`
函数更新动画(){
// `target` 和 `current` 滚动位置的区别
var diff = 目标 - 当前
// `delta` 是添加到 `current` 滚动位置的值
// 如果 `diff < 0.1`,使 `delta = 0`,所以动画不会是无穷无尽的
var delta = Math.abs(diff) < 0.1 ? 0 : 差异 * 轻松 if (delta) { // 如果 `delta !== 0`
// 更新 `current` 滚动位置
当前 += 增量
// 四舍五入以获得更好的性能
当前 = parseFloat(current.toFixed(2))
// 再次调用 `update`,使用 `requestAnimationFrame`
rafId = requestAnimationFrame(updateAnimation)
} else { // 如果 `delta === 0`
// 更新`current`,结束动画循环
当前=目标
rafActive = 假
取消动画帧(rafId)
} // 更新图片
更新动画图像() // 设置自定义滚动效果对应的 CSS `transform`
setTransform(容器, 'translateY('+ -current +'px)')
} // 给定 `current` 滚动位置,计算每个 `image` 的 CSS `transform` 值
函数更新动画图像(){
// 这个值是 `current` 滚动位置和图像的 `height` 之间的 `ratio`
var 比率 = 当前 / imageHeight
// 在循环中使用的一些变量
var intersectionRatioIndex、intersectionRatioValue、intersectionRatio
var rotateX, rotateXMax, rotateY, rotateYMax, translateX // 对于每个 `image` 元素,进行计算并相应地设置 CSS `transform`
images.forEach(函数(图像,索引){
// 计算 `intersectionRatio`,类似于提供的值
// IntersectionObserver API
intersectionRatioIndex = 窗口宽度 > 760 ? parseInt(index / 2) : 索引
交点比率值 = 比率 - 交点比率指数
intersectionRatio = Math.max(0, 1 - Math.abs(intersectionRatioValue))
// 计算当前 `image` 的 `rotateX` 值
rotateXMax = rotateXMaxList[索引]
rotateX = rotateXMax - (rotateXMax * intersectionRatio)
rotateX = rotateX.toFixed(2)
// 计算当前`image`的`rotateY`值
rotateYMax = rotateYMaxList[索引]
rotateY = rotateYMax - (rotateYMax * intersectionRatio)
rotateY = rotateY.toFixed(2)
// 计算当前`image`的`translateX`值
如果(窗口宽度> 760){
translateX = translateXMax - (translateXMax * easeOutQuad(intersectionRatio))
translateX = translateX.toFixed(2)
} 别的 {
翻译X = 0
}
// 如果图像低于视口中心,则反转 `rotateX` 和 `rotateY` 值
// 同时更新 `translateX` 值,实现交替效果
如果(intersectionRatioValue < 0){
旋转X = -rotateX
旋转Y = -旋转Y
translateX = 索引 % 2 ? -translateX:0
} 别的 {
translateX = 索引 % 2 ? 0:翻译X
}
// 使用计算值设置 CSS `transform`
setTransform(image, 'perspective(500px) translateX('+ translateX +'px) rotateX('+ rotateX +'deg) rotateY('+ rotateY +'deg)')
})
} // 监听 `resize` 事件以重新计算尺寸
window.addEventListener('resize', setupAnimation)
// 监听 `scroll` 事件以更新 `target` 滚动位置
window.addEventListener('scroll', updateScroll) // 最初设定
设置动画() })()
HTML、CSS 和 JavaScript 代码片段开启, AllWebCodes.com
完毕!享受 基于滚动的动画片段
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明