threejs 贴图动画总结
引言
在三维可视化中,会涉及到很多动画,其中贴图动画是其中很重要的一种,本文介绍几种贴图动画的思路,供大家一起探讨。
流动动画
流动动画通过设置贴图的repeat属性,并不断改变贴图对象的offset让贴图产生流动效果。 这种动画不难实现,首先加载贴图,如下所示:
let img = new Image();
img.src = './images/path.png';
let texture = new eg.Texture(img);
img.onload = function () {
texture.needsUpdate = true;
}
texture.repeat.set(100,1);
tube.material.map= texture;
function render(){
tube.material.map.wrapS = eg.RepeatWrapping;
tube.material.map.offset.set(offset,0);
tube.material.map.needsUpdate = true;
offset += 0.01;
}
上面代码,实现了一个tube(管道),然后给管道加了一个贴图texture。 在渲染的时候,不断更新texture对象的offset的值,此时就可以生产流动的动画。如下图所示:
雪碧图动画(Sprite Sheet)
图集也就是常说的雪碧图,就是把一系列小图按照一定的布局放到一张大图上面。 在使用的时候,截取大图的一部分来获取某个小图。 这在web端是一种常用的手段,通常用于减少图片数量,从而降低网络请求数量。
通过雪碧图的方式,可以把动画的系列动作的每一帧都布局在雪碧图上。 然后通过雪碧图创建texture对象,设置贴图的repeat和offset,让每次绘制获取雪碧图上的某一帧图像,不断改变offset,就可以形成绘制不同帧的动画效果。比如下面的图片:
下面这个threejs的demo,就是这样的效果,所以此处不再赘述代码,有兴趣的读者可以查看demo的源代码。
https://stemkoski.github.io/Three.js/Texture-Animation.html 效果如下图所示:
GIF动画
gif图片本身自带动画,如果gif放到Image对象上,动画会自动播放,只是当把gif作为贴图对象的图片的时候。 不会自动播放动画。
要自动播放gif动画,需要使用解析gif的库,把gif图片的每一帧解析出来, 并把每一帧图像绘制到一个canvas上,把canvas作为贴图对象的图片。大致代码如下:
加载gif图片,并解析图片。其中解析图片用到了一个库omggif,利用里面的GifReader可以解析gif图片的帧数据:
import { GifReader } from 'omggif';
const loader = new FileLoader(this.manager);
loader.setPath(this.path);
loader.setResponseType('arraybuffer');
loader.load(url, (response) => {
const gifData = new Uint8Array(response);
const reader = new GifReader(gifData);
if (onLoad) onLoad(reader);
}, onProgress, onError);
然后不断的更新贴图的图像:
draw() {
if (!this.reader) {
return;
}
const { reader, image, context } = this;
const { width, height } = image;
const frameNum = ++this.frameNumber % reader.numFrames();
const frameInfo = reader.frameInfo(frameNum);
if (frameNum === 0) {
// always clear canvas to start
context.clearRect(0, 0, width, height);
} else if (this.previousFrameInfo && this.previousFrameInfo.disposal === 2) {
// disposal was "restore to background" which is essentially "restore to transparent"
context.clearRect(this.previousFrameInfo.x,
this.previousFrameInfo.y,
this.previousFrameInfo.width,
this.previousFrameInfo.height);
}
const imageData = context.getImageData(0, 0, width, height);
reader.decodeAndBlitFrameRGBA(frameNum, imageData.data);
context.putImageData(imageData, 0, 0);
this.needsUpdate = true;
this.previousFrameInfo = frameInfo;
this.timeoutId = setTimeout(this.draw.bind(this), (frameInfo.delay || 2) * 10);
}
最终的gif贴图效果如下图所示
APNG动画
APNG图片和gif图片是类似的,也是动画图片。 不过相对于gif来说。APNG可以设置半透明,边缘锯齿不严重,所以使用APNG的图片的效果要优于gif图片。
原理上类似,也是解析APNG图片,然后把没一帧一次绘制到canvas上,并不断更新texture对象。 解析APNG图片,使用了一个开源库,APNG-canvas。 有兴趣读者可以自行研究,此处不重点讲述。
解析完成后,可以把解析的帧集合进行绘制,代码如下:
draw() {
if (!this.reader) {
return;
}
const { reader, image, context } = this;
const { width, height } = image;
const frameNum = ++this.frameNumber % reader.numFrames;
const frameInfo = reader.frames[frameNum];
if (frameNum === 0) {
// always clear canvas to start
context.clearRect(0, 0, width, height);
// } else if (this.previousFrameInfo && this.previousFrameInfo.disposal === 2) {
} else if (this.previousFrameInfo) {
// disposal was "restore to background" which is essentially "restore to transparent"
context.clearRect(this.previousFrameInfo.left,
this.previousFrameInfo.top,
this.previousFrameInfo.width,
this.previousFrameInfo.height);
}
const imageData = context.getImageData(0, 0, width, height);
// reader.decodeAndBlitFrameRGBA(frameNum, imageData.data);
// context.putImageData(imageData, 0, 0);
context.drawImage(frameInfo.img,frameInfo.left,frameInfo.top,frameInfo.width,frameInfo.height);
this.needsUpdate = true;
this.previousFrameInfo = frameInfo;
this.timeoutId = setTimeout(this.draw.bind(this), frameInfo.delay);
最终的apng贴图效果如下图所示
总结
本文介绍了 theejs 贴图动画的多种实现思路。 包括 纹理流动,雪碧图,gif和apng动画。 通过这些动画能力,可以创建出丰富多彩的可视化效果。
如果对可视化感兴趣,可以和我交流,微信541002349(可入微信群)。另寻求有三维建模能力,UI设计能力的人员。
关注公号“ITMan彪叔” 可以及时收到更多有价值的文章。
threejs 贴图动画总结的更多相关文章
- 8款超绚丽的jQuery焦点图动画
随着前端技术和浏览器技术的不断发展,人们开始对网页视觉效果的要求越来越高.我们经常会在页面中看到很多炫酷的图片焦点图播放控件,有些甚至是大屏的焦点图占用大片的页面空间,从而吸引用户的眼球.本文要分享的 ...
- 用CAShapeLayer写股市K线图动画效果
用CAShapeLayer写股市K线图动画效果 说明 入市有风险,炒股需谨慎.(因项目需求,本人提供了写这种效果的源码) 效果 源码 // // ViewController.m // Path // ...
- 第166天:canvas绘制饼状图动画
canvas绘制饼状图动画 1.HTML <!DOCTYPE html> <html lang="en"> <head> <meta ch ...
- Laya的动画制作,整图动画,序列图动画,时间轴动画,龙骨动画
参考: Laya动画基础 Egret帧动画工具类 版本:2.1.1.1 序列图动画 白鹭的序列图动画,使用TexureMerger合图,然后使用MovieClip类播放. Laya的话,使用图集打包工 ...
- android 自定义ViewGroup和对view进行切图动画实现滑动菜单SlidingMenu
示意图就不展示了,和上一节的一样,滑动菜单SlidingMenu效果如何大家都比较熟悉,在这里我简单说明一下用自定义ViewGroup来实现. 实现方法:我们自定义一个ViewGroup实现左右滑动, ...
- HTML5 随音乐节奏变化的频谱图动画
这里将要介绍的HTML5 音频处理接口与Audio标签是不一样的.页面上的Audio标签只是HTML5更语义化的一个表现,而HTML5提供给JavaScript编程用的Audio API则让我们有能力 ...
- android 自定义ViewGroup和对view进行切图动画实现滑动菜单SlidingMenu[转]
http://blog.csdn.net/jj120522/article/details/8095852 示意图就不展示了,和上一节的一样,滑动菜单SlidingMenu效果如何大家都比较熟悉,在这 ...
- js实现轮播图动画
在网页浏览中,可以看到轮播图是无处不在的,这是一个前端工程最基本的技巧.首先看看几个网页的呈现的效果. QQ音乐: 网易云音乐: 天猫: 接下来将从简到难总结几种实现轮播图的方法. 1.样式一:鼠标滑 ...
- Android 开发 VectorDrawable 矢量图 (三)矢量图动画
VectorDrawable 矢量图 三部曲: Android 开发 VectorDrawable 矢量图 (一)了解Android矢量图与获取矢量图 Android 开发 VectorDrawabl ...
随机推荐
- 13-Semi-supervised Learning
半监督学习(semi-supervised learning) 1.introduction 2.Semi-supervised Learning for Generative Model 3.Low ...
- [luogu5577]算力训练
(以下以$B$为进制,$m$为幂次,$n=B^{m}$) 定义$\oplus$为$k$进制下不进位加法,$\otimes$为$\oplus$卷积 令$f_{i,j}$表示前$i$个数的$\oplus$ ...
- [uva11429]Randomness
记p(i,j)表示第i次随机时,用多少个数对应到第j个事件,特别的,p(i,0)表示转移到下一次随机数的概率,那么即要求$aj/bj=\sum_{i=1}^{inf}p(i,j)/R^{i}$,容易发 ...
- 第02章_MySQL环境搭建
第02章_MySQL环境搭建 1. MySQL的卸载 步骤1:停止MySQL服务 在卸载之前,先停止MySQL8.0的服务.按键盘上的"Ctrl + Alt + Delete"组合 ...
- Vue: 一个简单的Vue2.0 v-model双向数据绑定的实现,含源代码,小白也能看懂
首先说一下原理吧 View层(dom元素)的变动如何响应到Model层(Js变量)呢? 通过监听元素的input事件来动态的改变js变量的值,实际上不是改变的js变量的值,而是改变的js变量的gett ...
- 【论文阅读】Beyond OCR + VQA: 将OCR融入TextVQA的执行流程中形成更鲁棒更准确的模型
论文题目:Beyond OCR + VQA: Involving OCR into the Flow for Robust and Accurate TextVQA 论文链接:https://dl.a ...
- No 'Access-Control-Allow-Origin' header: 跨域问题踩坑记录
前言 前两周在服务器上部署一个系统时,遇到了跨域问题,这也不是第一次遇到跨域问题了,本来以为解决起来会很顺利,没想到解决过程中遇到了很多坑,所以觉得有必要写一篇博客记录一下这个坑. 问题产生原因 本来 ...
- P2336 [SCOI2012]喵星球上的点名(SA+莫队)
题面传送门 一道还算有点含金量的 SA 罢-- 首先按照套路我们把读入的所有字符串都粘在一起,中间用分隔符隔开并建出后缀数组出来. 我们考虑对于一个固定的字符串 \(s\),什么样的字符串 \(t\) ...
- [linux] 常用命令及参数-2
sort 1 sort是把结果输出到标准输出,因此需要输出重定向将结果写入文件 2 sort seq.txt > file.txt 3 sort -u seq.txt 输出去重重复后的行 4 s ...
- R语言与医学统计图形【8】颜色的选取
R语言基础绘图系统 基础绘图包之低级绘图函数--内置颜色. 1.内置颜色选取 功能657种内置颜色.colors() 调色板函数:palette(), rgb(), rainbow(). palett ...