【CSS Tricks】鼠标滚轮驱动css动画播放,使用js还是css?
目录
- 引言
- 一、js实现
- 1. 实现思路
- 2. 实现案例
- 3. 看下效果
- 二、css实现
- 1. 代码修改
- 2. 属性介绍
- 2.1 看下浏览器支持性
- 2.2 常用属性值
- 2.2.1 scroll()
- 2.2.2 view()
- 三、总结
引言
本篇为css的一个小技巧
页面中的动画效果随着滚轮的转动而播放,会使用户的参与感更强烈。滚轮从上至下,动画跟随从第一帧到最后一帧。可以来回滚动,实现动画时空回溯的效果。如果将动画主体替换为网站主题内容,则可以大大加深用户对于网站宣传内容的印象。
一、js实现
动画绑定滚轮的核心在于有一个进度的时间线。可以通过鼠标滚轮告诉网页,进度到了哪个节点,那么动画也就自然跳动到对应百分比的帧数。
1. 实现思路
- 设置好动画关键帧,为了方便计算,将动画周期设置为1s。
- 利用
animation-delay
为负值的特性,将动画提前某个时间点播放。 - 通过js脚本监听window的scroll事件,设置全局变量
scroll
,其值为当前页面滚动距离占内容长度减去窗口高度的百分比(这里需要思考一下)。 animation-delay
使用函数计算scroll值与动画周期1s的乘积取负值。- 此时鼠标滚动,动画跳动到对应帧数,实现动画绑定滚轮的效果。
关于css动画参数的详细解读,请参考:【CSS Tricks】css动画详解
2. 实现案例
拿代码到本地跑一下看看效果。
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /><title>Document</title></head><style>body {padding: 0;margin: 0;min-height: 500vh;background-color: rgb(139, 201, 228);animation: body 1s linear;animation-play-state: paused;animation-delay: calc(var(--scroll) * -1s);animation-fill-mode: forwards;}@keyframes body {to {background-color: rgb(19, 48, 97);}}.box {width: 300px;height: 300px;border-radius: 10px;background: #df685b;position: fixed;top: 50%;left: 50%;transform: translate(-50%, -50%);animation: box 1s linear;animation-play-state: paused;animation-delay: calc(var(--scroll) * -1s);animation-fill-mode: forwards;}@keyframes box {to {transform: translate(-50%, -50%) rotate(180deg);}}</style><body><div class="box"></div></body><script>window.addEventListener("scroll",() => {document.body.style.setProperty("--scroll",window.pageYOffset / (document.body.offsetHeight - window.innerHeight));},false);</script>
</html>
解读一下代码:
- css部分主要疑问点在
animation-play-state
、animation-delay
、animation-fill-mode
这三个属性:animation-play-state
设置为paused
,表示我不希望这个动画会自动播放,而是时时刻刻都是停止状态。我需要动画可以跟随滚轮只表现关键帧而不播放。animation-delay
是实现这个效果的核心,我们会通过js提供一个[0,1]区间的scroll
值。动画总周期是1s,可以通过-1乘以scroll
值,获得一个[-1,0]的值。delay取负值表示提前到某一帧开始播放动画,又因为animation-play-state
设置为paused
,所以会得到动画绑定滚轮的效果。animation-fill-mode
设置为forwards
,表示当delay
为-1时,不跳回到第一帧而是继续保持最后一帧的画面,避免出现滚动到底时画面突然变为初始状态的情况。
- js部分主要疑问点在于计算
scroll
值:- 如下图示意,滚动的最大距离为
window.pageYOffset
,计算滚动距离的参考位置时窗口的上边缘。
- 如下图示意,滚动的最大距离为
3. 看下效果
注意观察滚动条位置
二、css实现
继续以js实现的代码为基础修改内容。
1. 代码修改
- 将script部分代码全部删掉
- 将css部分按照如下内容修改:
body {padding: 0;margin: 0;min-height: 500vh;background-color: rgb(139, 201, 228);animation: body 1s linear;animation-timeline: scroll();}@keyframes body {to {background-color: rgb(19, 48, 97);}}.box {width: 300px;height: 300px;border-radius: 10px;background: #df685b;position: fixed;top: 50%;left: 50%;transform: translate(-50%, -50%);animation: box 1s linear;animation-timeline: scroll();}@keyframes box {to {transform: translate(-50%, -50%) rotate(180deg);}}
- 这样就够了,此时页面效果和js实现结果一样。
2. 属性介绍
animation-timeline,目前还处于试验阶段。
指定用于控制CSS动画进度的时间轴。
2.1 看下浏览器支持性
目前只有70%左右的支持度,基本上只有最新版的chrome内核浏览器和opera浏览器可以支持。
2.2 常用属性值
默认值:none,无事发生。
2.2.1 scroll()
使用方式:
animation-timeline: scroll();
scroll()CSS函数表示在顶部和底部(或左侧和右侧)之间滚动滚动条来进行时间轴绑定。滚动范围中的位置将转换为进度百分比,开始时为0%,结束时为100%。
scroll()函数的传参值有两个,一个是指定滚动条元素,一个是滚动轴向
常见使用方法:
/* 一般写这个就行 */
animation-timeline: scroll();
/* 指定滚动条元素 */
animation-timeline: scroll(nearest); /* 找最近的具有滚动条的祖先元素,可以是self */
animation-timeline: scroll(root); /* 文档根元素 */
animation-timeline: scroll(self); /* 自身 */
/* 指定滚动轴向,一般就选这俩。纵向和横向 */
animation-timeline: scroll(y);
animation-timeline: scroll(x);
/* 如果喜欢两个参数都写,举例 */
animation-timeline: scroll(y nearest);
2.2.2 view()
使用方式:
animation-timeline: view();
view()CSS函数在可视区域指定一个区间,当元素经过这个区间时开始进行时间轴进度。从元素进入区间为0%,完全离开区间为100%。
view()函数的传参值有两个,一个是指定滚动轴向,一个是指定视图区域,可视区域可以有两个值。(最多总共三个值)
常见使用方法:
/* 一般写这个就行,表示当需要动画的元素出现在屏幕可视范围内,即可开始根据滚动轴作为时间线操控动画 */
animation-timeline: view();/* 非要写话就写x、y就好,不写默认是block相当于y */
animation-timeline: view(y);
animation-timeline: view(x);/* 设置可视区域 */
animation-timeline: view(auto); /* 全部可视区域*/
animation-timeline: view(20%); /* 从可视区域顶部20%到底部0%中间的部分*/
animation-timeline: view(20% 40%);/* 从可视区域顶部20%到底部40%中间的部分*/
举个例子:
animation-timeline: view(50% 10%);/* 从可视区域顶部50%到底部10%中间的部分*/
三、总结
CSS的创建者曾说过,他最初的设想是CSS作为控制网页行为的主要Web技术。只有当CSS无法完成控制行为时,才使用js脚本作为后备手段。
如果在不考虑浏览器支持性的前提下(优先使用chrome最新版本浏览器),项目中有做滚动条绑定动画的需求,我非常建议大家尝试一下animation-timeline
,它会给你一种全新的开发体验,在实现相同效果的情况下,页面性能优化最佳。
再接再厉~
相关文章:

【CSS Tricks】鼠标滚轮驱动css动画播放,使用js还是css?
目录 引言一、js实现1. 实现思路2. 实现案例3. 看下效果 二、css实现1. 代码修改2. 属性介绍2.1 看下浏览器支持性2.2 常用属性值2.2.1 scroll()2.2.2 view() 三、总结 引言 本篇为css的一个小技巧 页面中的动画效果随着滚轮的转动…...
《Electron 基础知识》设置 Vue 中引用的文件路径别名
vite.renderer.config.mjs 文件中配置 代码第1行,引入 resolve ;代码第 6 - 10 行,设置路径别名,注意没有后缀 /; import { resolve } from pathexport default defineConfig((env) > {return {resolve: {alias: …...
day 20 二叉树 part05
654.最大二叉树 注意类似用数组构造二叉树的题目,每次分隔尽量不要定义新的数组,而是通过下标索引直接在原数组上操作,这样可以节约时间和空间上的开销。 题目链接/文章讲解:代码随想录 lass Solution { private:// 在左闭右开…...

003 Springboot操作RabbitMQ
Springboot整合RabbitMQ 文章目录 Springboot整合RabbitMQ1.pom依赖2.yml配置3.配置队列、交换机方式一:直接通过配置类配置bean方式二:消息监听通过注解配置 4.编写消息监听发送测试5.其他类型交换机配置1.FanoutExchange2.TopicExchange3.HeadersExcha…...
小猿口算脚本
实现原理:安卓adb截图传到电脑,然后用python裁剪获得两张数字图片,使用ddddocr识别数字,比较大小,再用adb命令模拟安卓手势实现>< import os import ddddocr from time import sleep from PIL import Imagedef …...

从 Reno TCP 到 Scalable TCP,HighSpeed TCP
前文 Scalable TCP 如何优化长肥管道 介绍了 Scalable TCP,但联系另一个类似的算法 HighSpeed TCP(简称 HSTCP),就会看到一个类似从 Reno TCP 经 BIC 到 CUBIC 的路线,但采用了不同的策略。 Reno TCP 经 BIC 到 CUBIC 路线的核心在于 “在长…...

使用Java调用OpenAI API并解析响应:详细教程
使用Java调用OpenAI API并解析响应:详细教程 在现代应用程序中,API调用是一个非常常见的任务。本文将通过一个完整的示例,讲解如何使用Java调用OpenAI的ChatGPT API,并通过ObjectMapper处理JSON响应。本文的示例不仅适用于OpenAI…...

深入学习并发编程中的 synchronized
文章目录 并发编程中的三个问题可见性原子性有序性 了解Java内存模型JMMsynchronized 保证三大特性synchronized 保证原子性synchronized 保证可见性synchronized 保证有序性 synchronized 的特性可重入特性不可中断特性 通过反汇编学习synchronized原理当修饰代码块时当修饰方…...
AMD R9-9950X相比较I9-14900K有哪些提升
AMD R9-9950X相比较I9-14900K有哪些提升?在处理器领域,AMD与英特尔的竞争从未停歇,每一次新品发布都引发业界的高度关注。近日,AMD推出了其新一代桌面级旗舰处理器——Ryzen 9 9950X(简称R9-9950X)…...

计算机毕业设计 基于Python的个性化旅游线路推荐系统的设计与实现 Python+Django+Vue 前后端分离 附源码 讲解 文档
🍊作者:计算机编程-吉哥 🍊简介:专业从事JavaWeb程序开发,微信小程序开发,定制化项目、 源码、代码讲解、文档撰写、ppt制作。做自己喜欢的事,生活就是快乐的。 🍊心愿:点…...
总结:Flink之DataStream各API介绍
一、介绍 本文主要是详细介绍 DataStream<T> 类中的各个方法,并给出它们的使用场景。 二、基本方法 getId(): 作用:返回转换操作的唯一标识符。场景:当需要调试或日志记录时,有时候需要知道操作的 ID。getParallelism(): 作用:获取流的并行度。场景:在优化作业时…...
设计一个日志管理系统,支持多级别日志记录
设计一个日志管理系统,支持多级别日志记录 作为一名Python程序软件专家,我经常被问到关于日志管理系统的设计和实现。今天,我将分享一篇关于设计一个日志管理系统,支持多级别日志记录的博文,希望能够帮助大家更好地理解和使用Python语言。 日志管理系统的需求 在软件开…...

Javascript动态规划算法
JavaScript中的动态规划(Dynamic Programming,简称DP)是一种通过把原问题分解为相对简单的子问题的方式来求解复杂问题的方法。它主要致力于将“合适”的问题拆分成更小的子目标,并通过建立状态转移方程、缓存并复用以往结果以及按…...
Java 循环里怎么删除元素才安全
首先 在 Java 中,当你在循环中遍历集合时,直接删除元素可能会引发 ConcurrentModificationException。为了安全地删除元素,推荐使用 Iterator 来进行删除操作。 以下是使用 Iterator 删除元素的常见模式: import java.util.Arr…...
LabVIEW晶体振荡器自动化测试系统
基于LabVIEW平台的晶体振荡器自动化测试系统解决了传统手工测试晶体振荡器繁琐且易出错的问题。该系统通过高度自动化的测试流程,提高了测试效率和精度,实现了数据的自动采集与处理,适用于电子、通信等领域的晶振测试需求。 项目背景与意义 …...

3.6.xx版本SpringBoot创建基于Swagger接口文档
介绍 基于Swagger构建的JavaAPI文档工具,实现后端功能的测试,并撰写API接口文档。 方法 pom.xml中引入依赖,要注意的是,本依赖使用的SpringBoot版本为3.6.xx <!--Knife4j--><dependency><groupId>com.github.xiaoymin<…...
Oracle 12201非PDBS模式单机部署(静默安装)
一、创建Oracle数据库的用户 groupadd oinstall groupadd dba groupadd asmadmin groupadd asmdba useradd -g oinstall -G dba,asmdba oracle -d /home/oracle passwd oracle二、配置Linux 服务器参数 cat /home/oracle/.bash_profile export ORACLE_HOSTNAMEH_orcle01 expo…...
Python 源码编译安装详解:跨平台指南及完整步骤解析
Python 源码编译安装详解:跨平台指南及完整步骤解析 文章目录 Python 源码编译安装详解:跨平台指南及完整步骤解析一 准备工作1)Ubuntu/Debian2)CentOS/RHEL3)macOS 二 下载 Python 源码三 编译与安装1)解压…...

MQTT vs HTTP:谁更适合物联网?
前言 随着物联网(IoT)技术的飞速发展中,其应用规模和使用场景正在持续扩大,但它关键的流程仍然是围绕数据传输来进行的,因此设备通信协议选择至关重要。 作为两种主要的通信协议,MQTT 协议和 HTTP 协议各…...

小北的技术博客:探索华为昇腾CANN训练营与AI技术创新——Ascend C算子开发能力认证考试(初级)
前言 哈喽哈喽友友们,这里是zyll~(小北)智慧龙阁的创始人及核心技术开发者。在技术的广阔天地里,我专注于大数据与全栈开发,并致力于成为这一领域的新锐力量。通过智慧龙阁这个平台,我期望能与大家分享我的技术心得,共同探索技术的无限可能。 Ascend C编程:小北的技术…...
IGP(Interior Gateway Protocol,内部网关协议)
IGP(Interior Gateway Protocol,内部网关协议) 是一种用于在一个自治系统(AS)内部传递路由信息的路由协议,主要用于在一个组织或机构的内部网络中决定数据包的最佳路径。与用于自治系统之间通信的 EGP&…...

UDP(Echoserver)
网络命令 Ping 命令 检测网络是否连通 使用方法: ping -c 次数 网址ping -c 3 www.baidu.comnetstat 命令 netstat 是一个用来查看网络状态的重要工具. 语法:netstat [选项] 功能:查看网络状态 常用选项: n 拒绝显示别名&#…...

新能源汽车智慧充电桩管理方案:新能源充电桩散热问题及消防安全监管方案
随着新能源汽车的快速普及,充电桩作为核心配套设施,其安全性与可靠性备受关注。然而,在高温、高负荷运行环境下,充电桩的散热问题与消防安全隐患日益凸显,成为制约行业发展的关键瓶颈。 如何通过智慧化管理手段优化散…...
LLM基础1_语言模型如何处理文本
基于GitHub项目:https://github.com/datawhalechina/llms-from-scratch-cn 工具介绍 tiktoken:OpenAI开发的专业"分词器" torch:Facebook开发的强力计算引擎,相当于超级计算器 理解词嵌入:给词语画"…...
鱼香ros docker配置镜像报错:https://registry-1.docker.io/v2/
使用鱼香ros一件安装docker时的https://registry-1.docker.io/v2/问题 一键安装指令 wget http://fishros.com/install -O fishros && . fishros出现问题:docker pull 失败 网络不同,需要使用镜像源 按照如下步骤操作 sudo vi /etc/docker/dae…...

项目部署到Linux上时遇到的错误(Redis,MySQL,无法正确连接,地址占用问题)
Redis无法正确连接 在运行jar包时出现了这样的错误 查询得知问题核心在于Redis连接失败,具体原因是客户端发送了密码认证请求,但Redis服务器未设置密码 1.为Redis设置密码(匹配客户端配置) 步骤: 1).修…...
Device Mapper 机制
Device Mapper 机制详解 Device Mapper(简称 DM)是 Linux 内核中的一套通用块设备映射框架,为 LVM、加密磁盘、RAID 等提供底层支持。本文将详细介绍 Device Mapper 的原理、实现、内核配置、常用工具、操作测试流程,并配以详细的…...
基于matlab策略迭代和值迭代法的动态规划
经典的基于策略迭代和值迭代法的动态规划matlab代码,实现机器人的最优运输 Dynamic-Programming-master/Environment.pdf , 104724 Dynamic-Programming-master/README.md , 506 Dynamic-Programming-master/generalizedPolicyIteration.m , 1970 Dynamic-Programm…...

均衡后的SNRSINR
本文主要摘自参考文献中的前两篇,相关文献中经常会出现MIMO检测后的SINR不过一直没有找到相关数学推到过程,其中文献[1]中给出了相关原理在此仅做记录。 1. 系统模型 复信道模型 n t n_t nt 根发送天线, n r n_r nr 根接收天线的 MIMO 系…...
ip子接口配置及删除
配置永久生效的子接口,2个IP 都可以登录你这一台服务器。重启不失效。 永久的 [应用] vi /etc/sysconfig/network-scripts/ifcfg-eth0修改文件内内容 TYPE"Ethernet" BOOTPROTO"none" NAME"eth0" DEVICE"eth0" ONBOOT&q…...