前端实现序列帧_使用javascript和css模拟帧动画的3种方法分析

我们平时在开发前端页面的时候,经常会播放一段帧序列。这段帧序列就像gif图片那样,反复循环播放。那大家可能会说,直接用gif图片就好了,干嘛还去模拟呢?那是因为要做得更加灵活,我们要做到以下几点:

1、我们希望这段帧动画只循环播放所指定的次数。

2、我们希望帧动画结束的瞬间执行某种操作。这个在游戏中大量存在。

3、我们想自如的控制播放的速度。

4、我们想尽可能让这个帧动画的实现方式兼容大部分浏览器,在移动和pc端都能运行良好。

有了以上四点要求,那就不是gif图片所能完成的了。下面,我们先探讨有哪些技术可以实现我所说的功能。首先我们先准备好一张帧序列图片。如下图所示:

48155520_1.png

一、使用CSS3动画。

CSS3动画的timing-function里有一个step-end方式,可以不用缓慢过渡,而是直接以跳帧的方式实现变化。这个方式我认为是最省事

的办法了,然而在CSS3还未完全兼容的时代,step-end的兼容性更加差。就不说IE,我在智能机的几种基于webkit的低版本浏览器中测试时也

发现一些不兼容现象。考虑到css3的普及速度,此种方式依然值得大家学习。具体代码实现参考如下(篇幅考虑仅列出webkit的写法):

48155520_2.gif

<html>

<head>

<styletype="text/css">#anim{background-image: url(anim.png);width:120px;height:120px;-webkit-animation: auto-circle 0.5s step-end infinite;

}@-webkit-keyframes auto-circle{0%{

background-position-x: 0;

}20%{background-position-x: 120px;

}40%{background-position-x: 240px;

}60%{background-position-x: 360px;

}80%{background-position-x: 480px;

}100%{background-position-x: 600px;

}}style>

head>

<body>

<divid="anim">

div>

body>

html>

48155520_2.gif

以上代码可以在chrome浏览器中正常运行,然而,不知大家注意到一个问题没有。从0%到100%,其实只播放了帧动画的5帧,第6帧没有播放。这是因

为100/6无法得到整数值,所以无法均等分割。这也是这种方式的局限之一。由于苹果谷歌对translate2d和translate3d都有较好的支

持甚至硬件加速,为了得到更好的性能,我们可以不用background-position,而使用CSS3中的Transforms。当然,这需要外层

套一个overflow:hidden;的div。改善后的代码如下所示:

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Phaser3中实现序列帧动画方法有以下几: 1. 使用动画(Animation)方式 这方式与我上一条回答中提到的方法类似,只需要将 `frames` 参数指定为序列帧即可。 ```javascript this.anims.create({ key: 'play', frames: this.anims.generateFrameNumbers('spritesheet', { start: 0, end: 7 }), frameRate: 10, repeat: -1 }); this.add.sprite(400, 300, 'spritesheet').play('play'); ``` 上述代码中,我们使用了 `generateFrameNumbers()` 方法生成了一个序列帧数组,其中 `{ start: 0, end: 7 }` 表示从 0 到 7 的序列帧。然后将该序列帧数组作为 `frames` 参数传递给 `this.anims.create()` 方法,创建了一个名为 `play` 的动画。最后使用 `play()` 方法播放动画。 2. 使用精灵表(Spritesheet)方式 这方式需要将序列帧图像合并成一张精灵表,然后使用 `Phaser.GameObjects.Sprite` 类的 `setFrame()` 方法设置当前。 ```javascript this.load.spritesheet('spritesheet', 'assets/spritesheet.png', { frameWidth: 64, frameHeight: 64 }); this.add.sprite(400, 300, 'spritesheet').setFrame(0); ``` 上述代码中,我们使用 `this.load.spritesheet()` 方法加载了一个名为 `spritesheet` 的精灵表,其中 `frameWidth` 和 `frameHeight` 分别指定了每图像的宽度和高度。然后使用 `Phaser.GameObjects.Sprite` 类的 `setFrame()` 方法设置当前。 3. 使用纹理集(Texture Atlas)方式 这方式需要将序列帧图像和其它相关信息打包成一个纹理集,然后使用 `Phaser.GameObjects.Sprite` 类的 `setFrame()` 方法设置当前。 ```javascript this.load.atlas('atlas', 'assets/atlas.png', 'assets/atlas.json'); this.add.sprite(400, 300, 'atlas', 'frame0.png'); ``` 上述代码中,我们使用 `this.load.atlas()` 方法加载了一个名为 `atlas` 的纹理集,其中 `atlas.png` 是纹理集图像,`atlas.json` 是包含序列帧信息的 JSON 文件。然后使用 `Phaser.GameObjects.Sprite` 类的 `setFrame()` 方法设置当前。 总的来说,使用动画方式是最常用的实现序列帧动画方法,但是如果需要对每图像进行更加细致的控制,可以选择使用精灵表或纹理集方式。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值