CSS 逐帧动画实现指南

逐帧动画(frame-by-frame animation)是一种通过快速连续显示一系列静态图像来创造运动效果的技术。以下是使用CSS实现逐帧动画的几种方法。

1. 使用 steps() 计时函数

这是实现逐帧动画最常用的方法,通过animation-timing-functionsteps()函数实现。

.sprite {width: 100px;height: 100px;background-image: url('sprite-sheet.png');animation: play 1s steps(6) infinite;
}@keyframes play {from { background-position: 0 0; }to { background-position: -600px 0; }
}

参数说明:

  • steps(6) - 表示动画分为6步完成
  • -600px - 雪碧图总宽度(6帧 × 每帧100px)

2. 完整雪碧图动画示例

<!DOCTYPE html>
<html>
<head>
<style>.character {width: 64px;height: 64px;background-image: url('https://example.com/walk-cycle.png');background-position: 0 0;animation: walk 1s steps(8) infinite;}@keyframes walk {from { background-position: 0 0; }to { background-position: -512px 0; } /* 8帧 × 64px */}
</style>
</head>
<body><div class="character"></div>
</body>
</html>

3. 多行雪碧图处理

对于包含多行动画的雪碧图:

.sprite {width: 64px;height: 64px;background-image: url('multi-row-sprite.png');animation: play 0.8s steps(8) infinite;
}/* 行走动画 */
.walk {animation-name: walk;
}@keyframes walk {from { background-position: 0 0; }to { background-position: -512px 0; }
}/* 跳跃动画 */
.jump {animation-name: jump;
}@keyframes jump {from { background-position: 0 -64px; } /* 第二行 */to { background-position: -512px -64px; }
}

4. 使用多个DOM元素实现逐帧动画

如果不使用雪碧图,可以通过切换多个元素的显示来实现:

<div class="frame-animation"><img src="frame1.png" class="frame active"><img src="frame2.png" class="frame"><img src="frame3.png" class="frame"><img src="frame4.png" class="frame">
</div>
.frame-animation {position: relative;width: 100px;height: 100px;
}.frame {position: absolute;top: 0;left: 0;opacity: 0;animation: frameAnimation 1s infinite;
}.frame.active {opacity: 1;
}@keyframes frameAnimation {0%, 25% { opacity: 0; }25.1%, 50% { opacity: 1;z-index: 1;}50.1%, 75% { opacity: 0;z-index: 0;}75.1%, 100% { opacity: 1;z-index: 1;}
}.frame:nth-child(1) { animation-delay: 0s; }
.frame:nth-child(2) { animation-delay: 0.25s; }
.frame:nth-child(3) { animation-delay: 0.5s; }
.frame:nth-child(4) { animation-delay: 0.75s; }

5. 使用CSS自定义属性控制动画帧

:root {--frame-count: 8;--frame-width: 64px;
}.sprite {width: var(--frame-width);height: 64px;background-image: url('sprite.png');animation: play 1s steps(var(--frame-count)) infinite;
}@keyframes play {to {background-position: calc(-1 * var(--frame-count) * var(--frame-width)) 0;}
}

性能优化建议

  1. 使用will-change:

    .sprite {will-change: background-position;
    }
    
  2. 减少复合操作:

    • 优先使用opacitytransform属性
    • 避免在动画中改变width/height等属性
  3. 合理使用硬件加速:

    .sprite {transform: translateZ(0);
    }
    
  4. 控制动画频率:

    @media (prefers-reduced-motion: reduce) {.sprite {animation: none;}
    }
    

浏览器兼容性

  • 现代浏览器都支持steps()函数
  • IE10及以上支持,但可能需要前缀
  • 对于更老的浏览器,可以使用JavaScript实现回退

高级技巧:与JavaScript结合

// 动态改变动画速度
const sprite = document.querySelector('.sprite');
sprite.style.animationDuration = '0.5s';// 暂停/播放动画
function toggleAnimation() {const animation = sprite.style.animationPlayState;sprite.style.animationPlayState = animation === 'paused' ? 'running' : 'paused';
}// 切换不同动画
function changeAnimation(type) {sprite.style.animationName = type;
}

逐帧动画是游戏开发和UI动效中常用的技术,合理使用可以创建出流畅的视觉效果,同时保持较好的性能表现。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/diannao/88655.shtml
繁体地址,请注明出处:http://hk.pswp.cn/diannao/88655.shtml
英文地址,请注明出处:http://en.pswp.cn/diannao/88655.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

高版本IDEA如何开发低版本jdk项目

问题描述 我这个人比较喜欢新的东西&#xff0c;比如使用idea的时候&#xff0c;我就喜欢最新版本。 但是有个问题&#xff0c;最新版本的idea好像不支持jdk1.6&#xff0c;导致我无法去用新版本idea开发项目。 直到有一天&#xff0c;idea给了我一个提示如下&#xff0c;之…

Java设计模式->责任链模式的介绍

目录 1、责任链模式概念 1.1、定义介绍 1.2、流程图 1.3、优缺点 2、实现 3、应用场景 3.1、Springmvc流程 3.2、mybatis的执行流程 3.3、Spring的过滤器和拦截器 3.4、sentinel限流熔断 3.5、aop的加载和使用 4、举例 前言 是一种 行为型设计模式&#xff0c;它通…

【Bluedroid】蓝牙启动之 btm_acl_device_down 流程源码解析

本文详细分析Android蓝牙协议栈在设备故障时的处理流程。当蓝牙设备发生硬件故障或系统异常时,协议栈通过btm_acl_device_down触发多层次的资源清理和状态重置,包括ACL连接终止、L2CAP通道释放、SCO连接清理、BLE拓扑更新、设备数据库重置等关键操作,确保系统安全恢复。 一、…

随记:WebMvcConfigurationSupport 和WebMvcConfigurer 的区别

WebMvcConfigurationSupport &#xff08;抽象类&#xff09; 他是一个完整的 MVC 配置基类&#xff0c;他会禁用所有自动配置。默认静态资源映射也没有了。默认消息转换器&#xff08;json、xml&#xff09;也没有了。错误处理页默认的error也没有了。 WebMvcConfigurer &am…

npm run dev报错

1. 引言 1.1 什么是npm run dev npm run dev 是一个在 Node.js 项目中常用的命令&#xff0c;它允许开发者运行一个预定义的脚本&#xff0c;通常用于启动开发服务器或者执行开发环境的构建任务。这个命令是通过 package.json 文件中的 scripts 部分定义的&#xff0c;例如&…

Kotlin环境搭建与基础语法入门

目标&#xff1a;完成开发环境配置&#xff0c;编写第一个Kotlin程序&#xff0c;理解变量、数据类型和基本输出。 1. 环境搭建 步骤1&#xff1a;安装JDK 下载并安装 JDK 17&#xff08;Kotlin兼容性最佳版本&#xff09;。 配置环境变量 JAVA_HOME&#xff0c;并在终端验证…

CLion开发Qt桌面程序_git的简单使用_小团体

OS&#xff1a;Windows Qt&#xff1a;6.8.1&#xff08;6.x&#xff09; Eg&#xff1a;学生信息管理系统 前言 Qt Creator编写代码不是太方便&#xff0c;使用CLion编写代码或许是个不错的主意&#xff0c;CLion在此处主要是用于后端和测试的开发&#xff0c;界面方面还是…

C语言专题:8.函数指针(Function Pointer)

​ 在 C 语言中&#xff0c;函数也是一种“对象”&#xff0c;它在内存中有地址。因此可以定义指向函数的指针&#xff0c;用于动态调用、回调处理、构建函数表等。 掌握函数指针是理解 C 语言“底层抽象”与“模块化编程”的关键。 一、函数指针的基本概念 ​ 函数指针是一个变…

快速傅里叶变换(FFT)是什么?

快速傅里叶变换(FFT)是什么&#xff1f; 快速傅里叶变换&#xff08;FFT&#xff09; 本质上是一种极其高效的算法&#xff0c;用来计算**离散傅里叶变换&#xff08;DFT&#xff09;**及其逆变换。它是数字信号处理、科学计算和工程应用中最重要的算法之一。 要理解 FFT&…

EEG分类 - Theta 频带 power

在EEG&#xff08;脑电图&#xff09;信号处理的背景下&#xff0c;theta波段功率&#xff08;Theta Band Power&#xff09;是一个重要的特征&#xff0c;广泛应用于认知、神经科学和临床监测等领域。接下来&#xff0c;我将详细介绍theta波段功率的定义、特性、计算方法以及在…

苍穹外卖day3--公共字段填充+新增菜品

1.公共字段填充 1.1 问题分析 在新增员工或者新增菜品分类时需要设置创建时间、创建人、修改时间、修改人等字段&#xff0c;在编辑员工或者编辑菜品分类时需要设置修改时间、修改人等字段。这些字段属于公共字段&#xff0c;也就是也就是在我们的系统中很多表中都会有这些字段…

每次选择都是成本

概述 我们每个人都在做选择&#xff0c;而且无时无刻不在做选择。 有的人有的选&#xff0c;而有的人却没得选。 因此从侧面来说&#xff0c;有的选反而更是一种幸福。 我们学习的目的就是为了让我们自己在未来能有更好地选择&#xff0c;也可以底气十足地选择不去做什么&a…

AI in CSR Writing: Revolutionizing Clinical Trial Reports

一、AI在CSR撰写中的实际应用 1.1 自动化数据整合与报告生成 1.1.1 数据提取与汇总 AI自动从EDC、实验室系统、安全数据库提取数据,生成统计图表和表格,如人口统计学、疗效终点、安全性事件表,减少人工操作。 1.1.2 动态报告生成 基于预设模板,AI自动填充数据结果,如自动…

《Java反射到底该不该用?性能、灵活性与可维护性三者博弈》

大家好呀&#xff01;今天我们要聊一个Java中超级强大但也需要谨慎使用的特性——反射机制(Reflection) &#x1f3ad;。我会用最通俗易懂的方式&#xff0c;带大家彻底搞懂这个"程序界的魔术师"&#xff01; 一、什么是Java反射&#xff1f;&#x1f914; 想象一下…

从Java API调用者到架构思考:我的Elasticsearch认知升级之路

前言&#xff1a;我的Elasticsearch学习历程 作为一名Java开发者&#xff0c;记得第一次使用ES的Java High Level REST Client时&#xff0c;我被它强大的搜索能力所震撼&#xff0c;但也为复杂的集群调优所困扰。经过多个项目的实战积累和系统性学习&#xff0c;我终于建立了对…

高云GW5AT-LV60 FPGA图像处理板

GW5AT-LV60开发板体积小巧&#xff0c;长100mm宽为61.8mm&#xff0c;还没有一部Ipone SE2体积大&#xff0c;该板卡采用了核心板和载板分离的形式&#xff0c;核心板的形式可方便开发者在项目中根据实际需求来开发自己的载板&#xff0c;只需要为核心板提供5V的电源就能满足基…

[XILINX]ZYNQ7010_7020_软件LVDS设计

若该文为原创文章&#xff0c;未经允许不得转载风释雪QQ:627833006WX:Cheng18375816918CSDN博客: 风释雪FPGA知乎&#xff1a;风释雪FPGA 1.版本说明 日期作者版本说明2024xxxx风释雪初始版本 2.概述 ZYNQ 7010/7020 HR/HP Bank LVDS Rx/TX&#xff1b; 3.目标 ZYNQ 7010 LVD…

桌面小屏幕实战课程:DesktopScreen 11 SPI 水墨屏

飞书文档https://x509p6c8to.feishu.cn/docx/doxcnlzpIgj3gosCZufBTCZxlMb SPI说明 SPI是串行外设接口&#xff08;Serial Peripheral Interface&#xff09;的缩写&#xff0c;是一种高速的&#xff0c;全双工&#xff0c;同步的通信总线&#xff0c;并且在芯片的管脚上占用…

SpringCloud Gateway 组件的使用

作者&#xff1a;小凯 沉淀、分享、成长&#xff0c;让自己和他人都能有所收获&#xff01; 我发现了一个很有意思的缩写单词 gw、wg&#xff0c;都是网关的意思。因为 gw gateway、wg wangguan&#xff0c;所以在各个系统开发中&#xff0c;既有 gw 也有 wg 的存在。而网关…

随机地址生成器 - Cloudflare Workers

分享一个完全开源免费部署在 Cloudflare Workers 上的随机地址生成器&#xff0c;支持全球 24 个国家/地区。 &#x1f517; 工具地址: https://address.chat-tempmail.com ✨ 特性 &#x1f30d; 支持生成 24 个国家/地区的地址&#x1f4f1; 响应式设计&#xff0c;完美支持…