GSAP

3Blue1Brown给我留下了深刻印象。利用动画制作视频,内容简洁,演示清晰。前两天刚好碰到一件事,我就顺便学习了一下怎么用代码做动画。

javascrip为例,有两个动画引擎,GSAPAnimajs。由于网速的原因,询问了GPT后,我选择了GSAP来制作我的第一个动画视频。

制作动画视频不同于动画,要协调多个动作,还需要对齐时间,所以使用时间线Timeline是必要的。

需要两条时间线分别播放字幕和动画,这需要协调好他们

而且很多片段需要后期调整,所以也必须使用相对时间><,label这三种模式。

制作动画重要的是想好脚本,然后声明HTML元素,再恰当时刻将元素呈现出来

预览

代码

代码无需开启web服务器,可以直接再浏览器中打开

<!DOCTYPE html>
<html>
<head>
<script src="https://cdn.jsdelivr.net/npm/gsap@3.12.5/dist/gsap.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/gsap@3.12.5/dist/TextPlugin.min.js"></script>
<link href="https://cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free@6.5.2/css/fontawesome.min.css" rel="stylesheet"/>
<script src="https://cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free@6.5.2/js/all.min.js"></script>
<style>
#screen{
height: 720px;
width: 1280px;
position: relative;
background-color: black;
}
#screen > *{
position: absolute;
display: inline-block;
}
.person_{
top:20px;
color: white;
transform: scale(0,0);
}
#person3_{
left: 905px;
}
#person2_{
left: 590px;
}
#person1_{
left: 290px;
}
#person1,#person2,#person3{
width: 50px;
height: 50px;
background-color: green;
border: 5px;
color: white;
text-align: center;
display: flex;
justify-content: center;
align-items: center;
border-radius: 5px;
padding: 5px;
top: 50px;
left: -100px;
}
#text{
position: absolute;
width: 100%;
text-align: center;
color: white;
bottom: 10px;
} .year{
position: absolute;
width: 120px;
height: 30px;
left:130px;
color: white;
font-size: 18px;
transform:scale(0,0)
}
#year2000{
top:120px;
}
#year2000_{
top:200px;
}
#year2001{
top:600px;
}
.food{
color: bisque;
width: 50px;
height: 30px;
transform: scale(0,0);
}
#food1{
top:120px;
left: 290px;
}
#food2{
top:120px;
left: 560px;
}
#food3{
top:120px;
left: 890px;
}
#food4{
top:120px;
left: 290px;
}
#food5{
top:120px;
left: 560px;
}
#food6{
top:120px;
left: 890px;
}
#food7,#food8,#food9,#food10{
top:200px;
left: 290px;
}
#food11{
top:600px;
left: 290px;
}
#food12{
top:600px;
left: 560px;
}
#food13{
top:600px;
left: 890px;
}
#food14{
top:600px;
left: 890px;
}
.coins{
color: gold;
width: 50px;
height: 30px;
transform: scale(0,0);
}
.iconnum{
padding-left: 5px;
}
#coin1{
top: 120px;
left: 610px;
}
#coin2{
top: 120px;
left: 610px;
}
#coin3{
top: 200px;
left: 610px;
}
#coin4{
top: 280px;
left: 610px;
}
#coin5{
top: 600px;
left: 610px;
}
.industry{
color: rgb(204, 203, 203);
width: 50px;
height: 30px;
transform: scale(0,0);
}
#ind1{
top: 120px;
left: 340px;
}
#ind2{
top: 120px;
left: 660px;
}
#ind3{
top: 120px;
left: 940px;
}
#ind4{
top: 120px;
left: 340px;
}
#ind5{
top: 120px;
left: 660px;
}
#ind6{
top: 120px;
left: 940px;
}
#ind7{
top: 200px;
left: 940px;
}
#ind8{
top: 200px;
left: 940px;
}
#ind9{
top: 600px;
left: 340px;
}
#ind10{
top: 600px;
left: 660px;
}
.yearnext{
color: white;
width: 50px;
height: 50px;
transform: scale(1,0);
left: 160px;
}
#yn1{
top: 140px;
}
#yn2{
top: 220px;
}
.yearnext_{
color: white;
width: 50px;
height: 50px;
transform: scale(1,0);
}
#yn1_1{
left: 120px;
top:160px;
}
#yn1_2{
left: 180px;
top:160px;
}
#yn2_3{
left: 120px;
top:300px;
}
.changeline{
color: white;
transform: scale(0,1);
}
#cl1{
top: 285px;
left: 530px;
}
#cl2{
top: 285px;
left: 710px;
}
#cl3{
top: 290px;
left: 900px;
}
#cl4{
top: 340px;
left: 340px;
}
#cl5{
top: 350px;
left: 900px;
}
#curve{
top: 455px;
left: -180px;
transform: scale(1,0);
}
#complete{
color: white;
left: 50px;
top:340px;
transform: scale(0);
}
</style>
</head>
<body>
<div id="screen">
<div id="person1_" class="person_">租地农场主</div>
<div id="person2_" class="person_">领主、地主</div>
<div id="person3_" class="person_">工厂主</div>
<div id="person1" class="person">生产阶级</div>
<div id="person2" class="person">土地所有者</div>
<div id="person3" class="person">非生产阶级</div>
<div id="text"></div>
<div class="year" id="year2000">1758 年初</div>
<div class="year" id="year2000_">1758 年末</div>
<div class="year" id="year2001">1759 年初</div>
<div class="coins" id="coin1"><i class="fa-solid fa-coins"></i><span class="iconnum">20</span></div>
<div class="coins" id="coin2"><i class="fa-solid fa-coins"></i><span class="iconnum">20</span></div>
<div class="coins" id="coin3"><i class="fa-solid fa-coins"></i><span class="iconnum" id="coin3_num">20</span></div>
<div class="coins" id="coin4"><i class="fa-solid fa-coins"></i><span class="iconnum" id="coin4_num">10</span></div>
<div class="coins" id="coin5"><i class="fa-solid fa-coins"></i><span class="iconnum" id="coin5_num">20</span></div>
<div class="industry" id="ind1"><i class="fa-solid fa-gears"></i><span class="iconnum">10</span></div>
<div class="industry" id="ind2"><i class="fa-solid fa-gears"></i><span class="iconnum">10</span></div>
<div class="industry" id="ind3"><i class="fa-solid fa-gears"></i><span class="iconnum">10</span></div>
<div class="industry" id="ind4"><i class="fa-solid fa-gears"></i><span class="iconnum" id="ind4_num">10</span></div>
<div class="industry" id="ind5"><i class="fa-solid fa-gears"></i><span class="iconnum" id="ind5_num">10</span></div>
<div class="industry" id="ind6"><i class="fa-solid fa-gears"></i><span class="iconnum" id="ind6_num">0</span></div>
<div class="industry" id="ind7"><i class="fa-solid fa-gears"></i><span class="iconnum" id="ind7_num">10</span></div>
<div class="industry" id="ind8"><i class="fa-solid fa-gears"></i><span class="iconnum" id="ind8_num">10</span></div>
<div class="industry" id="ind9"><i class="fa-solid fa-gears"></i><span class="iconnum" id="ind9_num">10</span></div>
<div class="industry" id="ind10"><i class="fa-solid fa-gears"></i><span class="iconnum" id="ind10_num">10</span></div>
<div class="food" id="food1"><i class="fa-solid fa-wheat-awn"></i><span class="iconnum">20</span></div>
<div class="food" id="food2"><i class="fa-solid fa-wheat-awn"></i><span class="iconnum">10</span></div>
<div class="food" id="food3"><i class="fa-solid fa-wheat-awn"></i><span class="iconnum">20</span></div>
<div class="food" id="food4"><i class="fa-solid fa-wheat-awn"></i><span class="iconnum" id="food4_num">20</span></div>
<div class="food" id="food5"><i class="fa-solid fa-wheat-awn"></i><span class="iconnum" id="food5_num">10</span></div>
<div class="food" id="food6"><i class="fa-solid fa-wheat-awn"></i><span class="iconnum" id="food6_num">10</span></div>
<div class="food" id="food7"><i class="fa-solid fa-wheat-awn"></i><span class="iconnum" id="food7_num">10</span></div>
<div class="food" id="food8"><i class="fa-solid fa-wheat-awn"></i><span class="iconnum" id="food8_num">10</span></div>
<div class="food" id="food9"><i class="fa-solid fa-wheat-awn"></i><span class="iconnum" id="food9_num">10</span></div>
<div class="food" id="food10"><i class="fa-solid fa-wheat-awn"></i><span class="iconnum" id="food10_num">20</span></div>
<div class="food" id="food11"><i class="fa-solid fa-wheat-awn"></i><span class="iconnum" id="food11_num">20</span></div>
<div class="food" id="food12"><i class="fa-solid fa-wheat-awn"></i><span class="iconnum" id="food12_num">10</span></div>
<div class="food" id="food13"><i class="fa-solid fa-wheat-awn"></i><span class="iconnum" id="food13_num">10</span></div>
<div class="food" id="food14"><i class="fa-solid fa-wheat-awn"></i><span class="iconnum" id="food14_num">10</span></div>
<div class="yearnext" id="yn1"><i class="fa-solid fa-arrow-down-long"></i></div>
<div class="yearnext" id="yn2"><i class="fa-solid fa-arrow-down-long"></i></div>
<div class="yearnext_" id="yn1_1">生产</div>
<div class="yearnext_" id="yn1_2">消费</div>
<div class="yearnext_" id="yn2_3">流通</div>
<div class="changeline" id="cl1"><i class="fa-solid fa-minus"></i></div>
<div class="changeline" id="cl2"><i class="fa-solid fa-minus"></i></div>
<div class="changeline" id="cl3"><i class="fa-solid fa-minus"></i></div>
<div class="changeline" id="cl4"><i class="fa-solid fa-minus"></i></div>
<div class="changeline" id="cl5"><i class="fa-solid fa-minus"></i></div>
<div id="complete">完成循环</div>
<div id="curve">
<svg xmlns="http://www.w3.org/2000/svg" version="1.1">
<!-- 定义箭头样式 -->
<defs>
<marker id="arrow" markerWidth="10" markerHeight="10" refX="8" refY="3" orient="auto">
<path d="M0,0 L0,6 L9,3 z" fill="white" />
</marker>
</defs>
<path d="M300 150 Q 150 75, 300 0 " style="fill:none;stroke:white;stroke-width:1;marker-end: url(#arrow);" />
</svg>
</div>
</div>
<div style="padding: 10px;">
<input id="seek" type="range" oninput="setcur()" style="width: 800px;"/>
<button onclick="seekto()">跳转</button>
<span>当前</span>
<input id="cur" type="number" />
<span>总时长</span>
<input id="total" type="number" />
</div>
<!-- 字幕 -->
<script>
let tlzm = gsap.timeline(); tlzm
.to("#text", {
text: {
value: "在魁奈的《经济表》中",
delimiter:" "
},
duration:0,
ease: "none"
},1)
.to("#text", { text: { value: "", delimiter:" " }, duration:0, },'>+=3')
.to("#text", {
text: {
value: "商品货币循环被一个连线图表构造出来",
delimiter:" "
},
duration:0,
ease: "none"
},'>')
.to("#text", { text: { value: "", delimiter:" " }, duration:0, },'>+=6')
.to("#text", {
text: {
value: "这个循环在3大阶级之间进行",
delimiter:" "
},
duration:0,
ease: "none"
},'>')
.to("#text", { text: { value: "", delimiter:" " }, duration:0, },'>+=4')
.to("#text", {
text: {
value: "而阶级内部的交换不在考虑范围内",
delimiter:" "
},
duration:0,
ease: "none"
},'>')
.to("#text", { text: { value: "", delimiter:" " }, duration:0, },'>+=5')
.to("#text", {
text: {
value: "这三个阶级分别是",
delimiter:" "
},
duration:0,
ease: "none"
},'>')
.to("#text", { text: { value: "", delimiter:" " }, duration:0, },'>+=4')
.to("#text", {
text: {
value: "非生产阶级,可以认为是工厂主和工人",
delimiter:" "
},
duration:0,
ease: "none"
},'>')
.to("#text", { text: { value: "", delimiter:" " }, duration:0, },'>+=5')
.to("#text", {
text: {
value: "土地所有者阶级,通常是领主、地主",
delimiter:" "
},
duration:0,
ease: "none"
},'>')
.to("#text", { text: { value: "", delimiter:" " }, duration:0, },'>+=6')
.to("#text", {
text: {
value: "生产阶级,可以认为是租地农场主和农业工人",
delimiter:" "
},
duration:0,
ease: "none"
},'>')
.to("#text", { text: { value: "", delimiter:" " }, duration:0, },'>+=7')
.to("#text", {
text: {
value: "所有循环都有开端",
delimiter:" "
},
duration:0,
ease: "none"
},'>')
.to("#text", { text: { value: "", delimiter:" " }, duration:0, },'>+=4')
.to("#text", {
text: {
value: "我们把《经济表》发表的那年作为开端",
delimiter:" "
},
duration:0,
ease: "none"
},'>')
.to("#text", { text: { value: "", delimiter:" " }, duration:0, },'>+=4')
.to("#text", {
text: {
value: "首先是生产阶级",
delimiter:" "
},
duration:0,
ease: "none"
},'>')
.to("#text", { text: { value: "", delimiter:" " }, duration:0, },'>+=3')
.to("#text", {
text: {
value: "生产阶级手中拥有价值20亿利弗尔的农产品,作为种子和食物",
delimiter:" "
},
duration:6,
ease: "none"
},'>')
.to("#text", { text: { value: "", delimiter:" " }, duration:0, },'>+=7')
.to("#text", {
text: {
value: "同时,他们还拥有价值100亿利弗尔的工业品作为生产资料和生活用品",
delimiter:" "
},
duration:0,
ease: "none"
},'>+1')
.to("#text", { text: { value: "", delimiter:" " }, duration:0, },'>+=8')
.to("#text", {
text: {
value: "分摊到每一年,生产资料和生活用品会损耗或消耗10亿利弗尔",
delimiter:" "
},
duration:0,
ease: "none"
},'>')
.to("#text", { text: { value: "", delimiter:" " }, duration:0, },'>+=7')
.to("#text", {
text: {
value: "然后是土地所有者阶级",
delimiter:" "
},
duration:0,
ease: "none"
},'>')
.to("#text", { text: { value: "", delimiter:" " }, duration:0, },'>+=3')
.to("#text", {
text: {
value: "他们有价值10亿利弗尔的食物,20亿利弗尔货币和价值10亿利弗尔的工业品",
delimiter:" "
},
duration:0,
ease: "none"
},'>')
.to("#text", { text: { value: "", delimiter:" " }, duration:0, },'>+=7')
.to("#text", {
text: {
value: "最后是非生产阶级",
delimiter:" "
},
duration:0,
ease: "none"
},'>')
.to("#text", { text: { value: "", delimiter:" " }, duration:0, },'>+=4')
.to("#text", {
text: {
value: "他们的初始条件是价值20亿利弗尔的农业品原料和食物",
delimiter:" "
},
duration:0,
ease: "none"
},'>')
.to("#text", { text: { value: "", delimiter:" " }, duration:0, },'>+=8')
.to("#text", {
text: {
value: "在这一年内,三大阶级进行了生产和消费,直到年末",
delimiter:" "
},
duration:0,
ease: "none"
},'>')
.to("#text", { text: { value: "", delimiter:" " }, duration:0, },'>+=8')
.to("#text", {
text: {
value: "生产阶级消耗工业品和农产品,生产出价值50亿利弗尔的农产品原料",
delimiter:" "
},
duration:0,
ease: "none"
},'>')
.to("#text", { text: { value: "", delimiter:" " }, duration:0, },'>+=8')
.to("#text", {
text: {
value: "土地所有者阶级则什么也没生产,只是消费。最终剩下的是20亿利弗尔货币",
delimiter:" "
},
duration:0,
ease: "none"
},'>')
.to("#text", { text: { value: "", delimiter:" " }, duration:0, },'>+=8')
.to("#text", {
text: {
value: "非生产阶级则消耗20亿利弗尔农产品,生产出20亿利弗尔的工业品",
delimiter:" "
},
duration:0,
ease: "none"
},'>')
.to("#text", { text: { value: "", delimiter:" " }, duration:0, },'>+=7')
.to("#text", {
text: {
value: "生产消费阶段结束,接下来是交换阶段",
delimiter:" "
},
duration:0,
ease: "none"
},'>')
.to("#text", { text: { value: "", delimiter:" " }, duration:0, },'>+=5')
.to("#text", {
text: {
value: "我们把各阶级的产品和货币各自划分为若干份",
delimiter:" "
},
duration:0,
ease: "none"
},'>')
.to("#text", { text: { value: "", delimiter:" " }, duration:0, },'>+=5')
.to("#text", {
text: {
value: "以方便接下来的交换",
delimiter:" "
},
duration:0,
ease: "none"
},'>')
.to("#text", { text: { value: "", delimiter:" " }, duration:0, },'>+=5')
.to("#text", {
text: {
value: "首先发起交换的,只能是拥有货币的土地所有者阶级",
delimiter:" "
},
duration:0,
ease: "none"
},'>')
.to("#text", { text: { value: "", delimiter:" " }, duration:0, },'>+=6')
.to("#text", {
text: {
value: "他们用10亿利弗尔货币从生产阶级那交换等价的农产品",
delimiter:" "
},
duration:0,
ease: "none"
},'>')
.to("#text", { text: { value: "", delimiter:" " }, duration:0, },'>+=6')
.to("#text", {
text: {
value: "再用剩下的10亿利弗尔货币从非生产阶级那交换等价的工业品",
delimiter:" "
},
duration:0,
ease: "none"
},'>')
.to("#text", { text: { value: "", delimiter:" " }, duration:0, },'>+=7')
.to("#text", {
text: {
value: "之后土地所有者阶级退出流通环节",
delimiter:" "
},
duration:0,
ease: "none"
},'>')
.to("#text", { text: { value: "", delimiter:" " }, duration:0, },'>+=5')
.to("#text", {
text: {
value: "接下来非生产者阶级使用手中的10亿利弗尔货币,从生产阶级那里交换10亿利弗尔的农产品",
delimiter:" "
},
duration:0,
ease: "none"
},'>')
.to("#text", { text: { value: "", delimiter:" " }, duration:0, },'>+=9')
.to("#text", {
text: {
value: "然后他们就耗尽货币,只能等待生产阶级先发起交换",
delimiter:" "
},
duration:0,
ease: "none"
},'>')
.to("#text", { text: { value: "", delimiter:" " }, duration:0, },'>+=6')
.to("#text", {
text: {
value: "生产阶级花费10亿利弗尔货币从非生产阶级那里交换10亿利弗尔的工业品",
delimiter:" "
},
duration:0,
ease: "none"
},'>')
.to("#text", { text: { value: "", delimiter:" " }, duration:0, },'>+=8')
.to("#text", {
text: {
value: "非生产阶级再次获得10亿利弗尔货币",
delimiter:" "
},
duration:0,
ease: "none"
},'>')
.to("#text", { text: { value: "", delimiter:" " }, duration:0, },'>+=5')
.to("#text", {
text: {
value: "他们将用来交换到最后所需的农产品原料和粮食",
delimiter:" "
},
duration:0,
ease: "none"
},'>')
.to("#text", { text: { value: "", delimiter:" " }, duration:0, },'>+=5')
.to("#text", {
text: {
value: "至此三大阶级交换完成,货币和产品都到了所需的人手中",
delimiter:" "
},
duration:0,
ease: "none"
},'>')
.to("#text", { text: { value: "", delimiter:" " }, duration:0, },'>+=7')
.to("#text", {
text: {
value: "接下来就是领主和地主老爷的收税和收租环节",
delimiter:" "
},
duration:0,
ease: "none"
},'>')
.to("#text", { text: { value: "", delimiter:" " }, duration:0, },'>+=5')
.to("#text", {
text: {
value: "生产阶级交换所得到的货币又作为租金,回到了土地所有者阶级手中",
delimiter:" "
},
duration:0,
ease: "none"
},'>')
.to("#text", { text: { value: "", delimiter:" " }, duration:0, },'>+=7')
.to("#text", {
text: {
value: "好了,现在其实整个经济循环已经回到了初始状态,但为了明显一点,让我们整理一下",
delimiter:" "
},
duration:0,
ease: "none"
},'>')
.to("#text", { text: { value: "", delimiter:" " }, duration:0, },'>+=8')
.to("#text", {
text: {
value: "将各阶级的产品和货币各自汇总",
delimiter:" "
},
duration:0,
ease: "none"
},'>')
.to("#text", { text: { value: "", delimiter:" " }, duration:0, },'>+=5')
.to("#text", {
text: {
value: "和上一年初的初始状态对比一下会发现他们并没有什么变化",
delimiter:" "
},
duration:0,
ease: "none"
},'>')
.to("#text", { text: { value: "", delimiter:" " }, duration:0, },'>+=6')
.to("#text", {
text: {
value: "马克思评价说",
delimiter:" "
},
duration:0,
ease: "none"
},'>+=4')
.to("#text", { text: { value: "", delimiter:" " }, duration:0, },'>+=3')
.to("#text", {
text: {
value: "魁奈的《经济表》用几根粗线条表明,国民生产的具有一定价值的年产品",
delimiter:" "
},
duration:0,
ease: "none"
},'>+=1')
.to("#text", { text: { value: "", delimiter:" " }, duration:0, },'>+=8')
.to("#text", {
text: {
value: "要怎样通过流通进行分配,才能在其他条件不变的情况下,使它的的简单再生产(即原有规模的再生产)进行下去",
delimiter:" "
},
duration:0,
ease: "none"
},'>+=1')
.to("#text", { text: { value: "", delimiter:" " }, duration:0, },'>+=9')
.to("#text", {
text: {
value: "上一年的收获,当然构成生产期间的起点",
delimiter:" "
},
duration:0,
ease: "none"
},'>+=1')
.to("#text", { text: { value: "", delimiter:" " }, duration:0, },'>+=5')
.to("#text", {
text: {
value: "无数单个流通(交换)行为,从一开始就被综合为,根据他们所具有的社会特征划分出来的大体量运动。——几个巨大的、职能确定的、经济上的社会阶级之间的流通",
delimiter:" "
},
duration:0,
ease: "none"
},'>+=1')
.to("#text", { text: { value: "", delimiter:" " }, duration:0, },'>+=15')
.to("#text", {
text: {
value: "《经济表》提醒我们,价值的创造固然重要,但在目前的商品社会中,商品和货币的循环也是极其重要的、为生产创造条件的活动",
delimiter:" "
},
duration:0,
ease: "none"
},'>+=1')
.to("#text", { text: { value: "", delimiter:" " }, duration:0, },'>+=12')
</script>
<!-- 动画 -->
<script>
gsap.registerPlugin(TextPlugin)
// 创建Timeline类型的实例
let tl = gsap.timeline();
function seekto(){
var cur=document.getElementById("seek").value;
tl.seek(cur);
tlzm.seek(cur);
}
function setcur(){
var cur=document.getElementById("seek").value;
document.getElementById("cur").value=cur;
} //非生产阶级,可以认为是工厂主和工人 4s
tl.to("#person3", {
x: 1000,
duration:1
},3+1+5+1+3+1+4+1+3+1)
tl.to("#person3_", {
scale: 1,
duration:1
},'>+0.5')
//土地所有者阶级,通常是领主、地主 5s
.to("#person2", {
x: 700,
duration:1
},'>+2.5')
tl.to("#person2_", {
scale: 1,
duration:1
},'>+0.5')
//生产阶级,可以认为是租地农场主和农业工人 6s
.to("#person1", {
x: 400,
duration:1
},'>+3.5')
tl.to("#person1_", {
scale: 1,
duration:0.5
},'>+0.5')
//所有循环都有开端 4s
.to("#year2000", {
scale: 1,
duration:0.5
},'>+5')
//首先是生产阶级
.to("#food1", {
scale: 1,
duration:0.5
},'>+14')
//同时,他们还拥有价值100亿利弗尔的工业品作为生产资料和生活用品
.to("#ind1", {
scale: 1,
duration:0.5
},'>+18')
//然后是土地所有者阶级
.to("#food2", {
scale: 1,
duration:0.5
},'>+10')
.to("#coin1", {
scale: 1,
duration:0.5
},'>+1.5')
.to("#ind2", {
scale: 1,
duration:0.5
},'>+1.5')
//最后是非生产阶级
.to("#food3", {
scale: 1,
duration:0.5
},'>+8')
//在这一年内,三大阶级进行了生产和消费,直到年末
.to("#year2000_", {
scale: 1,
duration:0.5
},'>+8')
.to("#yn1", {
scaleY: 3,
duration:0.5,
transformOrigin: "center 0%"
},'>+1')
.to("#yn1_1", {
scaleY: 1,
duration:0.5,
transformOrigin: "center 0%"
},'>+1')
.to("#yn1_2", {
scaleY: 1,
duration:0.5,
transformOrigin: "center 0%"
},'>+1')
.addLabel("food4")
//生产阶级消耗工业品和农产品,生产出价值50亿利弗尔的农产品原料
.to("#food4", {
y: 80,
duration:1
},'food4+=3')
.to("#food4", {
scale: 1,
duration:0
},'food4+=3')
.to("#food4_num", {
innerHTML: 50,
snap: 'innerHTML',
duration:1,
ease: "none",
},'food4+=3')
.to("#ind4", {
y: 80,
duration:1
},'food4+=3')
.to("#ind4", {
scale: 1,
duration:0
},'food4+=1')
.to("#ind4_num", {
innerHTML: 0,
snap: 'innerHTML',
duration:1,
ease: "none",
},'food4+=3')
.to("#ind4", {
scale:0,
duration:0.5,
},'>+0.5')
.addLabel("food5")
//土地所有者阶级则什么也没生产,只是消费。最终剩下的是20亿利弗尔货币
.to("#food5", {
scale: 1,
duration:0
},'food5+=8')
.to("#food5", {
y: 80,
duration:1
},'food5+=8')
.to("#coin2", {
scale: 1,
duration:0
},'food5+=8')
.to("#coin2", {
y: 80,
duration:1
},'food5+=8')
.to("#ind5", {
scale: 1,
duration:0
},'food5+=8')
.to("#ind5", {
y: 80,
duration:1
},'food5+=8')
.to("#food5_num", {
innerHTML: 0,
snap: 'innerHTML',
duration:1,
ease: "none",
},'food5+=8')
.to("#ind5_num", {
innerHTML: 0,
snap: 'innerHTML',
duration:1,
ease: "none",
},'food5+=8')
.to("#food5", {
scale: 0,
duration:0.5,
},'>+1')
.to("#ind5", {
scale: 0,
duration:0.5,
},'<')
.addLabel("food6")
//非生产阶级则消耗20亿利弗尔农产品,生产出20亿利弗尔的工业品
.to("#food6", {
scale: 1,
duration:0
},'food6+=2')
.to("#food6", {
y: 80,
duration:1
},'food6+=2')
.to("#ind6", {
scale: 1,
duration:0
},'food6+=2')
.to("#ind6", {
y: 80,
duration:1
},'food6+=2')
.to("#food6_num", {
innerHTML: 0,
snap: 'innerHTML',
duration:1,
ease: "none",
},'food6+=2')
.to("#ind6_num", {
innerHTML: 20,
snap: 'innerHTML',
duration:1,
ease: "none",
},'food6+=2')
.to("#food6", {
scale: 0,
duration:0.5
},'>+1')
//生产消费阶段结束,接下来是交换阶段
.to("#yn2", {
scaleY: 15,
duration:0.5,
transformOrigin: "center 0%"
},'>+5')
.to("#yn2_3", {
scaleY: 1,
duration:0.5,
transformOrigin: "center 0%"
},'>+1')
.addLabel("food7")
//我们把各阶级的产品和货币各自划分为若干份
.to("#food7", {
y: 80,
duration:1
},'food7+=2')
.to("#food7", {
scale: 1,
duration:0
},'food7+=2')
.to("#food8", {
y: 140,
duration:1
},'food7+=2')
.to("#food8", {
scale: 1,
duration:0
},'food7+=2')
.to("#food9", {
y: 200,
duration:1
},'food7+=2')
.to("#food9", {
scale: 1,
duration:0
},'food7+=2')
.to("#food10", {
y: 260,
duration:1
},'food7+=2')
.to("#food10", {
scale: 1,
duration:0
},'food7+=2')
.to("#coin3", {
scale: 1,
duration:0
},'>+2')
.to("#coin3", {
y: 80,
duration:1
},'<')
.to("#ind7", {
scale: 1,
duration:0
},'>+2')
.to("#ind7", {
y: 80,
duration:1
},'<')
.to("#ind8", {
scale: 1,
duration:0
},'<')
.to("#ind8", {
y: 140,
duration:1
},'<')
.addLabel("change1")
//首先发起交换的,只能是拥有货币的土地所有者阶级
//他们用10亿利弗尔货币从生产阶级那交换等价的农产品
.to("#coin3_num", {
text: {
value:10
},
duration:0
},'change1+=12')
.to("#coin4", {
scale:1,
duration:0
},'change1+=12')
.to("#coin4", {
x:-320,
duration:1
},'change1+=12')
.to("#food7", {
x:270,
duration:1
},'change1+=12')
.to("#cl1", {
scaleX:14,
duration:0.5,
transformOrigin: "100% center"
},'change1+=10')
.addLabel("change2")
//再用剩下的10亿利弗尔货币从非生产阶级那交换等价的工业品
.to("#cl2", {
scaleX:14,
duration:0.5,
transformOrigin: "0% center"
},'change2+=3')
.to("#coin3", {
x:335,
duration:1,
},'change2+=4')
.to("#ind7", {
x:-285,
duration:1,
},'change2+=4')
.addLabel("change3")
//生产阶级花费10亿利弗尔货币从非生产阶级那里交换10亿利弗尔的工业品
.to("#cl3", {
scaleX:40,
rotation:-5,
duration:0.5,
transformOrigin: "100% center"
},'change3+=11')
.to("#food8", {
x:655,
y:80,
duration:1,
},'change3+=13')
.to("#coin3", {
y:140,
x:-320,
duration:1,
},'change3+=13')
.addLabel("change4")
.to("#cl4", {
scaleX:41,
duration:0.5,
transformOrigin: "0% center"
},'change4+=12')
.to("#coin3", {
y:140,
x:335,
duration:1,
},'change4+=14')
.to("#ind8", {
x:-655,
duration:1,
},'change4+=14')
.addLabel("change5")
//非生产阶级再次获得10亿利弗尔货币
//他们将用来交换到最后所需的农产品原料和粮食
.to("#cl5", {
scaleX:40,
rotation:-5,
duration:0.5,
transformOrigin: "100% center"
},'change5+=9')
.to("#food9", {
x:655,
y:140,
duration:1,
},'change5+=11')
.to("#coin3", {
x:-320,
y:200,
duration:1,
},'change5+=11')
.addLabel("tex")
//三大阶级交换完成
.to("#coin3", {
x:0,
y:80,
duration:1,
},'tex+=12.5')
.to("#coin4", {
x:0,
y:0,
duration:1,
},'tex+=12.5')
.to("#coin4", {
scaleY:0,
duration:0,
},'tex+=13.5')
.to("#coin3_num", {
innerHTML: 20,
snap: 'innerHTML',
duration:1,
ease: "none",
},'tex+=13.5')
//好了,现在其实整个经济循环已经回到了初始状态,但为了明显一点,让我们整理一下
.to("#year2001",{
scale:1,
duration:0.5
},">+5.5")
.to("#food11",{
scale:1,
duration:0
},">+5.5")
.fromTo("#food11",{
y:-140,
},{
y:0,
duration:1
},">")
.to("#ind9",{
scale:1,
duration:0
},">+0.5")
.fromTo("#ind9",{
y:-260,
x:-50,
},{
y:0,
x:0,
duration:1
},">")
.to("#food12",{
scale:1,
duration:0
},">+0.5")
.fromTo("#food12",{
y:-320,
},{
y:0,
duration:1
},">")
.to("#coin5",{
scale:1,
duration:0
},">+0.5")
.fromTo("#coin5",{
y:-320,
},{
y:0,
duration:1
},">")
.to("#ind10",{
scale:1,
duration:0
},">+0.5")
.fromTo("#ind10",{
y:-320,
},{
y:0,
duration:1
},">")
.addLabel("food13")
.to("#food13",{
scale:1,
duration:0
},"food13+=0.5")
.fromTo("#food13",{
y:-320,
x:55
},{
y:0,
x:0,
duration:1
},"food13+=0.5")
.to("#food14",{
scale:1,
duration:0
},"food13+=0.5")
.fromTo("#food14",{
y:-320,
x:55
},{
y:0,
x:0,
duration:0.7
},"food13+=0.5")
.addLabel("food14")
.to("#food14",{
scale:0,
duration:0
},"food14+=0")
.to("#food13_num", {
innerHTML: 20,
snap: 'innerHTML',
duration:1,
ease: "none",
},'food14+=0')
.to("#curve",{
scaleY:3.1,
duration:1,
transformOrigin: "100% 100%"
},">+1")
.to("#complete",{
scale:1,
duration:1
},">+1") // .to("#coin1", {
// x: 330,
// y:80,
// duration:1
// },'>+1') let duration=tl.duration();
document.getElementById("total").value=duration;
document.getElementById("seek").max=duration;
document.getElementById("seek").min=0;
document.getElementById("seek").value=0;
</script>
<script type="text/template">
经济循环由3大阶级构成
1.租地农场主、土地所有者、工厂主依次进场
</script>
</body>
</html>

视频观看

B站链接——《经济表》动画

我录制运行结果后,又通过tts给视频配了音,发布在了bilibili,欢迎来查看效果

不过要吐槽的是B站把60帧的选项给搞没了,投上去的720P60帧视频全都变成了30帧

导致高速动画效果惨不忍睹,要是没有大会员,那观看起来真的不太好

使用GSAP制作动画视频的更多相关文章

  1. 在线Youtube视频下载,修改文本,剪切制作动画的最新方法

    刚刚(减去编写本文章的时间,大概20分钟前吧)在看国外最新技术资讯的时候发现有个方法可以让我们快速去下载Youtube上面的视频,不敢独享,我自己都没有怎么玩就所以立刻post上来广而告之,希望对大家 ...

  2. 如何用 Keynote 制作动画演示(转)

    原文:如何用 Keynote 制作动画演示 Keynote 里的很多特效可以用来制作效果不错的演示,一页页的将需要演示的内容交代清楚后,直接输出成 m4v 的视频格式,为了方便贴到博客或者发布到 Tw ...

  3. 前端制作动画的几种方式(css3,js)

    制作动态的网页是是前端工程师必备的技能,很好的实现动画能够极大的提高用户体验,增强交互效果,那么动画有多少实现方式,一直对此有选择恐惧症的我就总结一下,以便在开发的时候选择最好的实现方式. 1.css ...

  4. CSS3制作动画的三个属性

    CSS3属性中有关于制作动画的三个属性:Transform,Transition,Animation:我们一起学习完了Transform和Transition,让我们对元素实现了一些基本的动画效果,这 ...

  5. requestAnimationFrame制作动画:旋转风车

    在以往,我们在网页上制作动画效果的时候,如果是用javascript实现,一般都是通过定时器和间隔来实现的,出现HTML5之后,我们还可以用CSS3 的transitions和animations很方 ...

  6. canvas学习之制作动画

    html部分 ...... <body> <canvas id="myCanvas" width="400" height="400 ...

  7. html5 requestAnimationFrame制作动画:旋转风车

    详细内容请点击 在以往,我们在网页上制作动画效果的时候,如果是用javascript实现,一般都是通过定时器和间隔来实现的,出现HTML5之后,我们还可以用CSS3 的transitions和anim ...

  8. Python+Matplotlib制作动画

    注: 在"实验设计与数据处理"的课后作业中,有一个数据可视化的作业,利用课程上学习的某种方法找一个二维函数的最大值,并将这个寻找的过程可视化.在作业里面利用了Matplotlib的 ...

  9. HTML5标签canvas制作动画

    摘要: canvas可以绘制图像,自然而然的就可以制作动画,因为动画的每一帧都是图像.我们可以利用javascript的setInterval函数来实现动画效果. 下面是一个例子,小圆绕着红点圆心不停 ...

  10. 手把手教你制作AppPreview视频并上传到appStore进行审核

    手把手教你制作AppPreview视频并上传到appStore进行审核 注意,你需要使用iMovie才能够制作AppPreview视频文件,用QuickTime录制的无效! 最终效果 1. 新建一个事 ...

随机推荐

  1. centos7了解

    A,B,C,D四个任务有依赖关系①init:总时间T1+T2+T3+T4+T5+T6+T7②upstart:总时间T1+T2+T3,启动速度加快,但是有依赖关系的服务还是必须先后启动.③systemd ...

  2. wpf 斗地主 单机版 没有机器人出牌算法

    斗地主的游戏流程实现了,剩余的音效和机器人的出牌算法,抓地主算法就用最简单的实现. 主要实现了各种牌组的组合,牌组的大小比较,总共有16种牌组 基础牌组 单张.炸弹.炸弹型飞机带对子.炸弹型飞机什么都 ...

  3. Gitea 代码仓库平台

    引言 Gitea 是一个自己托管的 Git 服务程序.他和 GitHub,Bitbucket or Gitlab 等比较类似.它是从 Gogs 发展而来,不过它已经 Fork 并且命名为 Gitea. ...

  4. 如何解决 IntelliJ Idea 编译 Java 项目时,找不到包或找不到符号的问题?

    执行 Maven Reimport 描述: 重新导入 Maven 包. 操作步骤: -> 选择 Project 目录右键 -> Maven -> Reimport 执行 Invali ...

  5. shell脚本的调试

    参数: -n :读一遍脚本中的命令但不执行,用于检查脚本中的语法错误 -v :一边执行脚本,一边将执行过的脚本命令打印到标准错误输出 -x :提供跟踪执行信息,将执行的每一条命令和结果依次打印出来 使 ...

  6. 使用Newtonsoft.Json进行Json与XML相互转换

    XML的解析得考虑子节点父节点,让人头昏眼花,而JSON的解析好像没啥难度.今天突然发现Newtonsoft.Json中有关于Json和XML互转的方法,所以顺带记录总结一下. 一.关于Newtons ...

  7. 011. jenkins 备份

    Jenkins目录介绍 1. 主配置文件: /etc/sysconfig/jenkins 2. Jenkins主目录: /var/lib/jenkins/ [root@node1 plugins]# ...

  8. .NET集成DeveloperSharp实现"高效分页"&"无主键分页"

    DeveloperSharp系列近期又被制造业ERP.民航飞行App.建筑BIM.电力掌上营业厅.等多家大型采用,站在巨人的肩膀上你能走的更远. 支持.Net Core2.0及以上,支持.Net Fr ...

  9. 算法金 | 10 大必知的自动化机器学习库(Python)

    大侠幸会,在下全网同名[算法金] 0 基础转 AI 上岸,多个算法赛 Top [日更万日,让更多人享受智能乐趣] 一.入门级自动化机器学习库 1.1 Auto-Sklearn 简介: Auto-Skl ...

  10. xv6 磁盘中断流程和启动时调度流程

    首发公号:Rand_cs 本文讲述 xv6 中的一些细节流程,还有对之前文中遗留的问题做一些补充说明,主要有以下几个问题: 一次完整的磁盘中断流程 进入调度器后的详细流程 sched 函数中的条件判断 ...