D3学习之动画和变换
D3学习之动画和变换
(17.02.27-02.28)
主要学习到了D3对动画和缓动函数的一些应用,结合前面的选择器、监听事件、自定义插值器等,拓展了动画的效果和样式。
主要内容
- 单元素动画
- 多元素动画
- 使用缓动函数
- 使用中间帧函数
- 使用级联过渡
- 使用选择器过渡
- 监听过渡事件
- 自定义插值器
- 使用计时器
为什么需要动画?
人类视觉系统是一个精妙的信息处理器,因此推向可以传递海量信息,并且移动的图像更能在短时间内传达更多的信息。的确,在世界不断的演变过程中,人类的视觉系统也在不断地进化,对于移动的物体,它能够更好地聚焦。 -Parent R.2012
D3的动画与过渡
D3过渡使我们可以在网页上使用HTML或SVG创造计算机动画。D3过渡实现了一种基于插值的动画(Interpolation-based Animation)。所以D3动画的基础是插值。
单元素动画
body.append("div")
.classed("box", true)
.style("background-color", "#e9967a")
.transition() //使用d3.selection.transition函数来定义一个过渡
.duration(duration) //使用duration函数来设置过渡效果的持续时间
.style("background-color", "#add8e6")
.style("margin-left", "600px")
.style("width", "100px")
.style("height", "100px")
.transition() //要实现单元素连续动画就直接加在后面
.duration(duration)
.style("background-color", "#19e549")
.style("margin-top", "100px")
.style("margin-left","100px")
.style("width", "500px")
.style("height", "50px");
因为是动画所以不好截图显示,从代码上也可以看出是一个长方形变成正方形再变成长方形,同时伴随着颜色的变化的过程。
多元素动画
原理和单元素类似,但是操作对象变成了一个集合而不是单一的元素:
selection //selection是元素的集合
.transition().duration(duration) // <-D
.style("top", function (d) {
return chartHeight - barHeight(d) + "px"; //top是距离顶的距离
})
.style("left", function (d, i) { //更新left值和height值
return barLeft(i) + "px";
})
.style("height", function (d) {
return barHeight(d) + "px";
})
.style("background-color",randomColor())
.select("span")
.text(function (d) {
return d.value;
}); //d.value,d是字典
缓动函数
过渡是和时间相关的函数,它将时间进度映射到数值的变化,形成了对象的运动(如果数值代表位置)或者形变(如果数值描述视觉属性)。时间是均匀变化的,换句话说时间是均匀的,然而结果并不总是需要均匀的。缓动正是控制这一映射,并提供灵活性的典型技术。当一个过渡生成均匀的值变化时,我们称之为线性缓动。
D3内部已经实现了一部分缓动函数及其过渡效果(linear线性,cubic立方,sin正弦等),同时支持自定义函数(代码内的B处)。
var data = [ // <-A
"linear", "cubic", "cubic-in-out",
"sin", "sin-out", "exp", "circle", "back",
"bounce",
function(t){ // <-B
return t * t;
}
]
ease( )的传入参数是一个字符串,D3会找到同名的缓动函数,否则默认使用线性缓动。而在实现上,需要注意的有一点:
d3.selectAll("div").each(function(d){
d3.select(this)
.transition().ease(d) //这里ease()函数不能用上面each()这种方式
.duration(5000)
.style("left", "10px");
});
ease()函数不支持以下这种方式,即使用一个函数来定义不同的缓动效果:
d3.selectAll("div").ease(function(d){
return d;})
.duration(5000)
.style("left", "10px");
});
D3还提供了缓动模式修饰符,它能够和任意缓动函数结合起来,形成特殊的效果,例如sin-out或者quad-out-in。现有的模式修饰符有如下几个:
- in:默认
- out:反向
- in-out:镜像
- out-in:反向镜像
使用中间帧计算
中间帧一词源于“inbetween”,inbetween是传统动画行业的一种通用实践,当时主设计师创建完关键帧后,再由工作人员在其中插入一些中间帧。这一概念被引入现代计算机动画中,用来代表插入中间帧的各种技术和算法。
以下函数创建了一个自定义中间帧计算函数:
body.append("div").append("input")
.attr("type", "button")
.attr("class", "countdown")
.attr("value", "0")
.transition().duration(duration).ease("linear")
.styleTween("width", widthTween)
.attrTween("value", valueTween); //valueTween即中间帧计算函数
来看看valueTween():通过量化尺度对传入的时间参数插值,最终生成了跳跃的整数效果。
function valueTween(){
var interpolate = d3.scale.quantize() // 定义了量化尺度,设置了定义域和值域
.domain([0, 1])
.range([1, 2, 3, 4, 5, 6, 7, 8, 9]);
return function(t){ // <-D
return interpolate(t);
};
}
效果如下:
级联过滤
级联过滤的作用就是将复杂的过渡效果进行封装,从而可以重复使用,保证了复杂过渡效果的可重用性,这一特性很好地实现了DRY原则(Don't repeat yourself)。
function teleport(s) { //复杂的过渡效果
s.transition().duration(300)
.style("width", "200px")
.style("height", "1px")
.transition().duration(100)
.style("left", "600px")
.transition().duration(300)
.style("left", "800px")
.style("height", "80px")
.style("width", "80px")
.transition().duration(300)
.style("left", "680px")
.style("height", "1px")
.style("width", "200px")
.style("top", "80px")
.transition().duration(100)
.style("left", "10px")
.transition().duration(300)
.style("height", "80px")
.style("width", "80px")
.style("top", "10px");
}
调用这一函数:
body.append("div")
.attr("class", "dong")
.style("position", "fixed")
.style("background-color", "steelblue")
.style("left", "10px")
.style("width", "80px")
.style("height", "80px")
.call(teleport); //通过call函数来调用级联过滤
使用选择性过渡
选择性过渡用于对特定选集的部分子集应用过渡效果。以下选择器限定了data值为“cat”的对象才会移动。
.transition() // <- A
.duration(duration)
.style("left", "10px")
.filter(function(d){return d == "Cat";}) // <- B d就是数据值 选择器
.transition() // <- C
.duration(duration)
.style("left", "500px");
效果如图:
级联过滤
级联过滤的作用就是将复杂的过渡效果进行封装,从而可以重复使用,保证了复杂过渡效果的可重用性,这一特性很好地实现了DRY原则(Don't repeat yourself)。
function teleport(s) { //复杂的过渡效果
s.transition().duration(300)
.style("width", "200px")
.style("height", "1px")
.transition().duration(100)
.style("left", "600px")
.transition().duration(300)
.style("left", "800px")
.style("height", "80px")
.style("width", "80px")
.transition().duration(300)
.style("left", "680px")
.style("height", "1px")
.style("width", "200px")
.style("top", "80px")
.transition().duration(100)
.style("left", "10px")
.transition().duration(300)
.style("height", "80px")
.style("width", "80px")
.style("top", "10px");
}
调用这一函数:
body.append("div")
.attr("class", "dong")
.style("position", "fixed")
.style("background-color", "steelblue")
.style("left", "10px")
.style("width", "80px")
.style("height", "80px")
.call(teleport); //通过call函数来调用级联过滤
使用选择性过渡
选择性过渡用于对特定选集的部分子集应用过渡效果。以下选择器限定了data值为“cat”的对象才会右移。
.transition() // <- A
.duration(duration)
.style("left", "10px")
.filter(function(d){return d == "Cat";}) // <- B d就是数据值 选择器
.transition() // <- C
.duration(duration)
.style("left", "500px");
效果如图:
监听过渡事件
监听用于在触发特定动作后进行相应的操作或者在过渡时进行不同的处理。
.transition().duration(duration)
.delay(1000)
.each("start", function(){ // 在过渡开始(start)时触发,修改text值
console.log(arguments);
d3.select(this).text(function (d, i) {
return "transitioning";
});
})
.each("end", function(){ // 在过渡动画结束时修改text值为done
d3.select(this).text(function (d, i) {
return "done";
});
})
效果如下:
实现自定义插值器
先看看自定义插值器的实现:
d3.interpolators.push(function(a, b) { // <-A
var re = /^([a-z])$/, ma, mb;
if ((ma = re.exec(a)) && (mb = re.exec(b))) {
a = a.charCodeAt(0);
var delta = a - b.charCodeAt(0);
return function(t) {
return String.fromCharCode(Math.ceil(a - delta * t));
};
}
}); //自定义差值器自动加入全局,并且优先被选取(类似栈结构)
这里定义的是一个a-z的插值器,设定了检查和范围,那么在调用时只要符合参数的范围(a-z),D3会调用相应的插值器。
countdown.attr("type", "button")
.attr("class", "countdown")
.attr("value", "a") //a
.transition().ease("linear")
.duration(25000).delay(1000)
.attr("value", "z"); //z
效果如图:
使用定时器
D3定时器函数作为实现D3过渡的底层结构,可以帮助我们更灵活地创建自定义动画。
在下面这个例子中,我们构造一个自定义动画,用来显示不断变化的从0到100的数字。
function countup(target){
d3.timer(function(){
var value = countdown.attr("value");
if(value == target) return true;
countdown.attr("value", ++value);
});
}
d3.timer()函数接受一个自定义函数,并且立即反复调用这一函数,直到该函数返回true为止,因此当value等于target(也就是100)时,才会返回true,否则就会一直自加。
最后
已掌握了对过渡和动画的初步使用,在以后具体实现中应多思考来实现更复杂的效果。
D3学习之动画和变换的更多相关文章
- iOS学习——核心动画之Layer基础
iOS学习——核心动画之Layer基础 1.CALayer是什么? CALayer我们又称它叫做层.在每个UIView内部都有一个layer这样一个属性,UIView之所以能够显示,就是因为它里面有这 ...
- 纯干货:深度学习实现之空间变换网络-part2
https://www.jianshu.com/p/854d111670b6 纯干货:深度学习实现之空间变换网络-part1 在第一部分中,我们主要介绍了两个非常重要的概念:仿射变换和双线性插值,并了 ...
- iOS学习——核心动画
iOS学习——核心动画 1.什么是核心动画 Core Animation(核心动画)是一组功能强大.效果华丽的动画API,无论在iOS系统或者在你开发的App中,都有大量应用.核心动画所在的位置如下图 ...
- ECCV 2018 | 旷视科技提出GridFace:通过学习局部单应变换实现人脸校正
全球计算机视觉三大顶会之一 ECCV 2018(European Conference on Computer Vision)即将于 9 月 8 -14 日在德国慕尼黑拉开帷幕,旷视科技有多篇论文被此 ...
- D3学习笔记一
D3学习笔记一 什么是D3? D3(全称Data Driven Documents)是一个用来做Web数据可视化的JavaScript函数库.D3也称之为D3.js. D3是2011年由Mike Bo ...
- D3学习之地图
D3学习之地图 (2017.03.09-03.11) 地图的意义 在可视化领域中,将数据点投影和关联到地理区域上,是一个非常关键的内容(体现了可视化中利用读者自身知识常识从而加速吸收信息的原则). G ...
- D3 学习
D3 学习笔记 D3简介 D3全称是Data-Driven Documents数据驱动文档,是一个开源的javascript库,可以用于数据可视化图形的创建,但不仅仅只是这些.可以查看d3帮助文档还有 ...
- d3学习之路
d3学习历程: 轻量化编译器:HbuiderXHbuiderX使用教程 理解HTMl js CSS 三者关系 学习html js css :1)w3school 2)moo ...
- ReactNative学习实践--动画初探之加载动画
学习和实践react已经有一段时间了,在经历了从最初的彷徨到解决痛点时的兴奋,再到不断实践后遭遇问题时的苦闷,确实被这一种新的思维方式和开发模式所折服,react不是万能的,在很多场景下滥用反而会适得 ...
随机推荐
- 一次Tomcat6.0.33版本号与6.0.44版本号差异所引发的问题
前序(公司应用为Web应用, 部署serverLinux + Nginx + Tomcat ) 一天收到公司报警邮件,显示个别机器方法调用严重超时,寻常都是在100ms以内响应的方法,突然某段时间响应 ...
- cocos2d-x-3.6 引擎基础概念
先讲一下引擎里面几个重要的基础概念:导演.节点,场景.层,精灵. 当然实际开发人员会碰到非常多其它概念,不过不要紧.有了这些基础概念,后面自己学习起来就easy多了. 节点(Node)是cocos2d ...
- iOS应用开发最佳实践:编写高质量的Objective-C代码
本文转载至 http://www.cocoachina.com/industry/20131129/7445.html 点标记语法 属性和幂等方法(多次调用和一次调用返回的结果相同)使用点标记语法访问 ...
- AndroidManifest.xml文件详解(activity)(一)
<activity android:allowTaskReparenting=["true" | "false"] android:alwaysRetai ...
- bnuoj 34990(后缀数组 或 hash+二分)
后缀数组倍增算法超时,听说用3DC可以勉强过,不愿写了,直接用hash+二分求出log(n)的时间查询两个字符串之间的任意两个位置的最长前缀. 我自己在想hash的时候一直在考虑hash成数值时MOD ...
- 讨论cocos2d-x字体绘制原理和应用方案
转自:http://blog.csdn.net/langresser_king/article/details/9012789 个人一直认为,文字绘制是cocos2d-x最薄弱的环节.对于愤怒的小鸟之 ...
- 创建TPL自定义模板
文件布局 <!--1d7c7a527b6335cc7a623305ca940e1findex.tpl.html--> <!DOCTYPE html PUBLIC "-//W ...
- 《挑战程序设计竞赛》2.3 动态规划-进阶 POJ1065 1631 3666 2392 2184(5)
POJ1065: Description There is a pile of n wooden sticks. The length and weight of each stick are kno ...
- php strcmp()字典排序
字典排序(lexicographical order)是一种对于随机变量形成序列的排序方法.其方法是,按照字母顺序,或者数字小大顺序,由小到大的形成序列. 比如,字典中a-z,是依次递增的,a,b,c ...
- dist\_wepylogs.js
console.log('WePY开启错误监控'); console.warn("CLI报错:WARNING IN : src\pages\cloundAd.vue\n[xmldom war ...