有点意思的gif动图生成平台开发实战(二)
精彩回顾
如何实现H5可视化编辑器的实时预览和真机扫码预览功能 在线IDE开发入门之从零实现一个在线代码编辑器 基于React+Koa实现一个h5页面可视化编辑器-Dooring TS核心知识点总结及项目实战案例分析
前言
笔者之前利于业余时间开发了一个gif动图生成平台, 具体开发背景我也在上一篇文章手把手教你撸一个能生成抖音风格动图的gif制作平台中介绍过了, 我们今天继续来实现该平台, gif动图平台的实现方式比较将完全用前端的手段来实现, 所以大家在接下来的内容中会发现很多有意思的前端插件. 接下来我们看看主要要实现的功能点:
纯前端实现图片上传和预览
基于react-beautiful-dnd实现元素自由拖动排序
使用javascript实现生成uuid的函数
使用file-saver实现前端下载文件
使用gif.js实现基于图片生成gif动图
控制gif动图播放速度的方法
正文
还是按照笔者一贯的风格, 在实现功能之前我们先看看实现后的预览效果:
在线地址: http://io.nainor.com/qt
1. 基本页面搭建
2. 实现图片上传预览功能
FileReader 对象允许Web应用程序异步读取存储在用户计算机上的文件(或原始数据缓冲区)的内容,使用 File 或 Blob 对象指定要读取的文件或数据。
const uploadprops = useMemo(() => ({
name: 'file',
multiple: true,
listType:"picture-card",
onPreview: () => {},
showUploadList: false,
beforeUpload(file, fileList) {
// 解析并提取excel数据
let reader = new FileReader();
reader.onload = function(e) {
let url = e.target.result;
setImageList(prev => [...prev, {id: uuid(6, 16), url}])
};
reader.readAsDataURL(file);
}
}), []);
<img src={item.url} id={item.id} alt=""/>
3. 使用react-beautiful-dnd实现元素自由拖动排序
大家在研究过H5-Dooring | 一款强大的开源H5编辑器 后就会发现react-dnd这个模块很熟悉, 因为该开源编辑器就使用了react-dnd实现的组件拖拽和组件数据传递的. 笔者在社区又发现了一个比较有意思的拖拽库react-beautiful-dnd, 同样可以实现优雅平滑的智能拖拽效果, 基本案例如下:
const imgList = [
{
id: uuid(6, 10),
url: '图片的base64位地址'
}
]
// 生成uuid
function uuid(len: number, radix: number) {
let chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.split('');
let uuid = [],
i;
radix = radix || chars.length;
if (len) {
for (i = 0; i < len; i++) uuid[i] = chars[0 | (Math.random() * radix)];
} else {
let r;
uuid[8] = uuid[13] = uuid[18] = uuid[23] = '-';
uuid[14] = '4';
for (i = 0; i < 36; i++) {
if (!uuid[i]) {
r = 0 | (Math.random() * 16);
uuid[i] = chars[i === 19 ? (r & 0x3) | 0x8 : r];
}
}
}
return uuid.join('');
}
实现后的效果如下图:
4. 控制gif动图播放速度的方法
控制gif的播放速度方法我们可以用slider组件实现, gif.js也提供速度的接口, 我们只需要实现速度值的计算即可. 我们都知道滑块滑动越长, 数值越大, 与之对应的 速度越大, 时间间隔越小, 所以我们在前端层设计的展示效果如下:
具体代码如下:
const handleSpeed = (v) => {
let realSpeed = (20 - v + 1) / 10;
setSpeed(realSpeed)
}
当然大家可以用更简单的方式来实现, slider组件也提供反向取值的操作.
5. 基于图片序列生成gif动图
6. 使用file-saver实现前端下载文件
import { saveAs } from 'file-saver';
// resultImage为gif生成的gif图片对象
saveAs(resultImage, `${uuid(6, 10)}.gif`);