本文为稀土掘金技术社区首发签约文章,14天内禁止转载,14天后未获授权禁止转载,侵权必究!
公司想做个五年总结
这不快年底了么,公司高层打算把这五年的发展历程做一次回顾巡礼,一方面宣扬一下公司文化,另一方面歌颂一下公司这五年来取得的辉煌成就,单纯的做个海报,写个公众号文章,或整个传统ppt在内部宣讲,再剪个视频啥的已经无法满足公司想众乐乐的强烈情感了。
于是想做一个交互性良好、内容表达形式多样、章节清晰、条理分明、易于传播的“ppt”,于是在公司千人大群里号召,有没有谁能做的,问了好几次,最后只有我应下了这个大活儿。
最后我与一位主要负责这件事的领导(我称为带头大哥)和一位UI小姐姐临时组成了一个小队,来完成这项任务。
(在线观看地址,可以先看看效果。记得手指或者鼠标,向上滑动来播放)
很快就确定了中心思想,并设计了一套。。。。对联?
带头大哥没过几日就发我一个文档,上面写了对仗工整,思想明确的“对联”
- 重返这五年,重温那岁月
- 成长多措举,管理提格局
- 工作造氛围,企学见雏形
- 发展聚人才,规模逐壮大
- 搜索寻突破,拓展创业务
- 那年启征程,改变从此始
- 种得梧桐树,凤凰自然来
- 全方位服务,码农心无骛
- 创新谋发展,突破新技术
- 环境不断好,员工感幸福
- 乘势迎挑战,赋能于行业
- 磨砺积能力,自研得硕果
- 逆境砥砺行,收入节节高
- 我:哇撒~,领导,这写的很好嘛~,这每一页不做个动画都说不过去啊。
- 领导:对,就打算这么做。
- 我:哈哈哈哈,收到,那么具体做成什么样呢?
- 领导:em~,我已经安排UI小姐姐开始设计了,过一阵就能出图。
- 我:哦哦哦,好的~
领会精神的设计小姐姐就开始陆续出图了~~~
- 领导:阿强,图做好了,你看一下。
- 我:ok,哇偶这图可以啊。
- UI小姐姐:有什么问题,需要切图啥的尽管跟我说。
- 我:好的好的。
- 领导:阿强,那么我们开始研究如何做吧,要求是要做成H5,这样可以方便分享传阅,而且时间我们只有五天,我们要尽快了。
- 我:五天???做不完咋办
- 领导:你知道的,deedline不是我定的,而且这是👆面看中的亲儿子项目,献礼用的,所以。。。
- 我:懂了,我搏一把,目前来看用游戏引擎最合适,毕竟画面表现这块,用引擎更好一点。
- 领导:可以,具体设计方面到时我们再一起商量怎么做,开发这块需要的话,我也可以参与进来,毕竟我也接触过白鹭引擎,对了,你打算用啥写?
- 我:cocos creater
- 领导:嗯嗯,没问题,有什么我能帮忙的尽管跟我说,最后能做出来就行
- 我:好的,收到。
于是我做了一个工具
so,时间这么紧,而且做不完可能会有不小的后果,em~~~~,并且这件事也不是着急干就能干完的,我需要冷静的想一个办法,我忽然想到《代码整洁之道》中好像说过,具体记不清,大体意思是:“越是想快,就要写好代码”。
em~~~,好的,那么我拿出几天设计一个工具吧,不需要多么成熟,只要能够满足容易上手,可以批量制作就行,这样就能够实现人手的增加,效率也会提高的局面,到时完成就变得很有戏了,就这么办。
于是我用了两三天的时间做出了这个工具,并做了一个demo给到了带头大哥,他表示ok,还可以,能接受,而且经过我的指导,他也可以参与进来了,于是我们就开始“愉快地”批量的制作了。
工具的开发思路
我总希望用最简单的话语,描述一件事,我比较喜欢简单,那么我们就用简单的方式把我的设计讲讲。
通过鼠标或触摸滑动,推进动画进程
视频可以快进,倒退,仅仅通过拨动进度条或者滑动屏幕即可,我喜欢这种交互,那就做成这样,舒服。 首先我不想做成静态资源那种的,比如视频,gif之类的,这种是没有“生命”的,只能称之为“物质”,我简单用“阴”代指,我所需要是基于物质所焕发同时也可以创造物质的的“生命,心灵”,我称他为阳。说ta是“活”的有点过,就是说可以交互,可以整合再利用,随时可以通过ta创建视频,gif之类的静态资源,岂不妙哉。
设计好个体,非常关键
我希望设计出一系列独立个体,可以很好的串联起整个逻辑,它具备了基本的功能,同时又具备了扩展的能力,可互相联结,又彼此独立,目前有两个主要的个体,一个是单位个体entity
,另一个是动作个体recation
entity
大体应该具备以下行为:
- 描述自身运行的周期:
lenPercent
和startPercent
- 生命周期函数
- 开始:
live
- 渲染:
process
- 结束:
end
- 开始:
- 可以装载其他个体的能力:
entityArr
- 组成单位为:
entity
- 组成单位为:
- 执行动作的集合:
recationArr
- 组成单位为:
recation
,
- 组成单位为:
recation
大体应该具备以下行为:
- 描述自身运行的周期:
start
和end
- 执行的动作:
action()
那么个体设计好了,围绕个体所展开的逻辑,就顺理成章了。
代码如下:
export default cc.Class({
extends: cc.Component,
properties: {
lenPercent: cc.Float,
startPercent: cc.Float,
isAutoStart: cc.Boolean,
entityArr: {
default: [],
type: cc.Node
}
},
//externalDuration:外部时间(父节点传过来的时间),由父节点决定
//internalDuration:自己内部定的时间,有自己决定,
//为什么要区分两个呢?由于外部应该只能确定我的播放时间,不应该决定我的播放速率,而后者应该有个体自身决定,
//startTime和endTime:由父节点指定的开始和结束时间,(根据父节点的世界定的‘外部时间’!!!)
//timeLine-表示时间到哪了,(根据父节点的世界定的‘外部时间’!!!)
//totaTime-表示我在父节点应该播放的总时长,(根据父节点的世界定的‘外部时间’!!!)
//progressValue就是通过父节点传过来的timeLine,totaTime,timeLine得出我处于的播放进度百分比
//相应的往自己的子节点传的就得参照自己的
ctor() {
this.isLive = false;
this.startTime = undefined;
this.endTime = undefined;
this.internalDuration = 0;//个体内部的时长
this.externalDuration = 0;//个体相对父级的时长
this.progressValue = 0;
this.entryData = [];
this.recationArr = [];
this.startPosition = cc.v2();
this.entityArrEx = [];
},
// LIFE-CYCLE CALLBACKS:
start() {
this.startPosition = this.node.position;
},
onLoad() {
this.node.comName = this.__classname__;
this.internalDuration = this.node.getContentSize().height;
//防止设置的时间太长,强制设置为剩余的时长
if (this.lenPercent + this.startPercent > 1) {
this.lenPercent = 1 - this.startPercent;
}
if (this.isAutoStart) {
this.startPercent += Math.abs((this.node.position.y / this.node.parent.getContentSize().height));
}
},
onEnable() {
let self = this;
if (this.entityArr.length) {
this.entityArrEx = this.entityArr.map((item, index) => {
let entity = item.getComponent(item._name);
if (entity.isAutoStart) {
}
this.entryData.push(entity.initData({
startTime: this.getStarTime(entity.startPercent),
totaTime: self.internalDuration,
}));
return entity;
});
}
},
//业务接口
getStarTime(value) {
if (value <= 1) {
return value * this.internalDuration
} else {
return value
}
},
initData({ totaTime, startTime }) {
this.startTime = startTime;
this.externalDuration = this.lenPercent <= 1 ? totaTime * this.lenPercent : this.lenPercent;
//结束时间最大只能是父类节点结束时间
//因为父节点结束,子节点也必须结束
this.endTime = Math.min(totaTime, this.startTime + this.externalDuration);
return {
startTime: this.startTime,
internalDuration: this.internalDuration,
endTime: this.endTime
}
},
getCurrentTime(percent) {
return (
this.startTime + (percent <= 1 ? this.externalDuration * percent : percent)
);
},
live() {
this.isLive = true;
},
calcProgress() {
this.progressValue = (this.timeLine - this.startTime) / this.externalDuration;
},
calcReactionProgress({ start, end }) {
start = (start <= 1) ? this.internalDuration * start : start;
end = (end <= 1) ? this.internalDuration * end : end;
return Math.min((this.progressValue * this.internalDuration - start) / (end - start), 1);
},
process({ timeLine }) {
this.timeLine = timeLine;
this.calcProgress();
this.internalTimeLine = this.progressValue * this.internalDuration;
let actionArr = this.recationArr.filter((item) => {
if (item) {
let isOk = (timeLine > this.getCurrentTime(item.start) &&
timeLine <= this.getCurrentTime(item.end)) ||
(!item.start && !item.end)
if (isOk) {
item.isAction = true
} else {
if (item.isAction) {
item.action(this.calcActionData(item, true))
}
item.isAction = false
}
return isOk;
}
});
actionArr.forEach((item) => {
item.action(this.calcActionData(item));
});
},
update() {
let self = this;
this.actionEntityArr = this.entityArrEx.filter((entity) => {
if ((self.internalTimeLine) > entity.startTime && self.internalTimeLine <= entity.endTime) {
if (!entity.isLive) {
entity.live();
}
entity.process({
timeLine: self.progressValue * self.internalDuration,
});
return true;
} else {
if (entity.isLive) {
entity.end();
}
}
return false;
});
},
calcActionData(item, isEnd) {
let params = {};
let actionLen = (item.end - item.start) || 1;
let progress;
progress = Math.min((this.progressValue - item.start) / actionLen, 1);
if (isEnd) {
let isEndForce = window.GLOBAL.dir > 0;
let isEndForceStart = window.GLOBAL.dir < 0;
if (isEndForce) {
progress = 1
} else if (isEndForceStart) {
progress = 0
}
params = {
isEndForce: isEndForce,
isEndForceStart: isEndForceStart
}
}
params = {
actionLen,
progress,
...params,
...item
}
return params;
},
end() {
this.isLive = false;
//如果滑动非常快,并且是快进而非后退,那么就要直接强行设置反馈为结束
// if (window.GLOBAL.dir > 0) {
// }
this.recationArr.forEach(item => {
if (item.isAction) {
item.isAction = false
item.action(this.calcActionData(item, true))
}
});
},
});
整体思路简单说
- 就是设置一个进度条,通过触摸屏幕进行前进和后退。
- 设置每一part的时间占比,然后串联起来。
- 每一个part内部,也设置内部节点的运动的事件占比,以及具体做什么运动。
- 然后根据定时循环,判断当前时刻应该执行节点的是哪个,执行的节点该执行的运动是哪个
就这么简单。
这个思路完全可以使用在dom上,完全可以用react和vue实现,我会陆续重构完毕。
我跟领导就开始设计怎么做了
开场
-
领导:阿强,这个就是我们项目的开场。
- 第一张就是首页图,然后过一会自动转场。
- 第二张就是过场之后显示的。
-
我:哦哦,懂了,话说,怎么转场呢?
-
领导:看到小飞机没有~
-
就这个。
还有第二页的这个。
(A):第一页上来,左下角一个人坐着飞机向上飞,然后小飞机往右上角飞,飞离出去之后,开始转场到二张。
-
(B)然后第二页左下飞入这个小飞机,飞到中心处,也就是图片上的位置,那么开场part就ok了。)
-
-
我:ok,明白了,开整。
实现方式:
A实现:
目标就是让这个节点移动一段距离停下来,那么写一个脚本plane0_1,上来就执行一个移动一段距离的动作。
import entity from '../../base/entity';
cc.Class({
extends: entity,
properties: {
},
// LIFE-CYCLE CALLBACKS:
onLoad() {
this._super();
let self = this;
// 就是上来,就执行一个运动,moveBy就是一段时间,移动移动距离的动画api
var action = cc.moveBy(1, cc.v2(this.node.getContentSize().width + 100, 200))
// 执行动作
this.node.runAction(action);
},
});
挂载到节点上就可以了。
这里简单介绍一下,我设置了几个参数:
- lenPercent:就是节点运动的总时长
- startPercent:就是运动的开始时刻
- isAutoStart:就是自动启动,无视startPercent的设置
- entityArr:就是复制管理的节点,这样自己的运动周期内就能操作其关联的节点的运动。
B实现:主要就是实现这个节点移动飞行
那么根据上面描述的思路,我们不难实现这个小飞机的移动,无非就是设置这个小飞机在这个part里的开始时刻是多少,运动多久,运动到哪,只要把这些定好,动画自动产生。
那么开发脚本
import entity from '../../base/entity';
cc.Class({
extends: entity,
properties: {
plane: cc.Node
},
// LIFE-CYCLE CALLBACKS:
onLoad() {
this._super();
let self = this;
// 向右上角移动一段距离
var action = cc.moveBy(1, cc.v2(this.node.getContentSize().width + 500, 500))
// spawn是同时执行运动的函数,目的是让moveBy运动结合一个缩小的运动,这样,有种越发越远,又越小的视觉感。
let action2 = cc.spawn(action, cc.scaleTo(1, 2))
// 执行动作
this.node.runAction(cc.sequence(cc.delayTime(1), action2, cc.callFunc(() => {
self.node.active = false;
self.node.parent.active = false;
self.plane.runAction(cc.moveTo(1, cc.v2(0, 0)))
})));
},
});
那么下面整体实现,基本都是依靠上面这些思路,实现的,单纯的开始套就能实现下面的动画了。 是不是很神奇,这套思路,完全可以套用到react和vue上。
-
整好了,领导~,看下效果
领导:行,可以,就这样。
part1
-
重返这五年,重温那岁月
领导:这张呢~
-
我:坐飞机的小女孩往上飞出去,做小角的男人飞入画面
-
领导:差不多,不过坐小飞机的小女孩这块,应该再丰富一点。
- 记得我们刚才说的那个小飞机没,这个小女孩飞的时候,渐渐的变小,有种往远飞的感觉,然后变成小飞机飞走~
-
我:哦哦哦,懂了,开整
-
整好了,领导~,看下效果
-
领导:行,可以,就这样。
part2
- 成长多措举,管理提格局
- 工作造氛围,企学见雏形
-
我:这个要做成啥样?
-
领导:入场就是从右边缓缓进来,还有看到这个没
-
这些圆片一点一点的滑入屏幕,然后屏幕出现内容
-
这张图
- 就是屏幕上一点一点出现内容,然后人物一点一点入画。
-
-
我:懂了,开整
-
整好了,领导~,看下效果
-
领导:对,是这样。
part3
- 发展聚人才,规模逐壮大
- 搜索寻突破,拓展创业务
- 领导:这个主要想表达的就是公司不断的壮大,业务上不断的突破,所以要有种过程感,你看着发挥吧
- 我:收到,我试试
-
整好了,领导~,看下效果
-
- 领导:嗯,很不错,可以可以,有过程的画面感。
- 日历还能动啊,而且日历动的同时,后面的背景一点一点的显示,也寓示了我们的办公楼越来越大,可以,有细节,不错。
- 过场加入了云彩变大,切换很自然嘛。
part4
那年启征程,改变从此始
领导:这个该咋设计呢?你看飞机这么多,我们能让这些飞机各飞各的么?
-
我:可以啊,我试试
-
整好了,领导~,看下效果
-
领导:可以的,就这样吧。
part5
- 种得梧桐树,凤凰自然来
- 领导:这个柱状图能不能表现出一点一点增长的效果,还有向上箭头能不能也可以有个升的过程
-
还有这个拿笔的人物
- 可不可以有种书写感,就是表现出在写字
-
- 我:哦哦哦,我试试,应该可以,针对这些情况,我再丰富几种表现手段
-
整好了,领导~,看下效果
-
- 领导:嗯,可以,就是这效果。
part6
- 全方位服务,码农心无骛
- 创新谋发展,突破新技术
- 领导:这就可以自由发挥了,用一个合理的方式一点一点介绍就好。
- 我:懂,开整
-
整好了,领导~,看下效果
-
- 领导:嗯,很不错嘛,有ppt的感觉,挺好的
- 我:哈哈哈,确实有点。
part7
- 环境不断好,员工感幸福
- 乘势迎挑战,赋能于行业
-
领导:第一张就是简单的显隐就可以,主要是第二张的这个
- 这个,我跟UI小姐姐说了,希望做成一个列表,但小姐姐做成了这种,那么就需要滚动了。
-
我:就像滚动页面那样,哦哦哦,我明白了,开整。
-
整好了,领导~,看下效果
-
领导:行,可以的,就这样。
part8
- 磨砺积能力,自研得硕果
-
领导:阿强,这个主要是表现我们去的成就,我们仅仅把文字凸显出来就好,其他就不要求了
- 但,我觉得第一幅图,还是可以做点文章的,他表示我们获得的证书,你看看能不能实现,物理下落,然后一本本摞起来的效果
-
我:哈哈哈,好的,我试试,效果我尽量做,可能物理效果没那么像,但摞起来的效果肯定是有的。
-
领导:可以,你试试
-
我:好的,开整。
-
整好了,领导~,看下效果
-
领导:辛苦了,阿强,再加把劲,我们要成功了。
-
我:好的~~~下一个就是结尾了吧,加油~
尾声
- 逆境砥砺行,收入节节高
- 领导:阿强这个结尾,我们收好,我们要有种意境,这样就有感觉,你能懂么
- 我:我懂你
- 领导:你看奥第一幅和第二幅区别,是一个没有河水,一个有河水,还有就是一个有没破晓,一个有日出
- 你看你能衔接好,这可是一个艰巨的任务,干完这个我们就胜利了
- 我:好的领导,我一定完成任务
-
many hours later
-
可算整好了,我的大哥~,效果我是尽力了。
-
- 领导:干的漂亮,阿强,有意境了,非常不错,辛苦了。
- 我:嘿嘿,马马虎虎,我尽力了,我打包好就上线吧。
- 领导:好的好的,辛苦了。
这就是在线预览地址,可以看看效果。
结尾
目前项目仅仅用了5天时间就出来了个雏形,还很粗糙,很多地方可以进一步的优化。
这仅仅是一个开始,未来,我会使用react或者vue3,整一个lowcode制作工具,这样就可以更加的方便制作了。
然后开源,敬请期待。
有问题随时交流,我建立一个小清晰qq群,叫“闲D岛”,技术问答群,有问必答,有兴趣可以加群号:551406017
题外话
有一说一,我比较低调,一般出风头的事儿,我是没啥想法的,主要是我觉得争名逐利的画面太尴尬,我来不了这个,但也不知我那天是怎么了,当群里问了好几次都没人回应,我就来了点脾气,即然没谁上,那我试试吧。就这样我接下了这个任务,现在再想,可能就是因为这点脾气,我才敢去做的,也许有点莽了,如果没做成呢?哈哈哈,那就不能想了,还好我实现了,我让这个脾气变得更像勇气了,有时候真不妨大胆一点,觉得自己可以,那就试一试,真没准行呢,别怕输,输丢什么人,怕才丢人呢。
今天的文章年底了,接个大活儿,做一个回顾公司五年发展的总结ppt,要求做成H5网页分享到此就结束了,感谢您的阅读。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/17305.html