手把手教你撸一个能生成抖音风格动图的gif制作平台

简介: 又到了一周一次的周总结, 笔者基于之前的开源项目 blink , 开发了一款能在线配置故障艺术, 并一键生成gif动图的平台, 这里暂时取名为QT. 接下来笔者将复盘一下该可视化平台的实现步骤以及功能点, 让大家都能做自己的Gif动图生成平台.在线访问地址: 趣图——一款轻量级生成抖音风格动效的在线工具

网络异常,图片无法展示
|


前言


又到了一周一次的周总结, 笔者基于之前的开源项目 blink , 开发了一款能在线配置故障艺术, 并一键生成gif动图的平台, 这里暂时取名为QT. 接下来笔者将复盘一下该可视化平台的实现步骤以及功能点, 让大家都能做自己的Gif动图生成平台.

在线访问地址: 趣图——一款轻量级生成抖音风格动效的在线工具


正文


在开始正文之前, 我们先来看看使用效果图:


网络异常,图片无法展示
|


首先我们拆解一下功能:


  • 图形编辑区 —— 用来编辑动图样式, 问文字等
  • 预览区 —— 用来预览用户实时配置的动画效果
  • 结果展示区 —— 用来存放生成的gif效果
  • gif文件自动下载


我们大致理清了我们需要实现的功能之后, 我们就可以一步步来实现了.


在这里我想先简单介绍一下背景: 在笔者之前开源了生成自定义故障艺术的组件库Blink之后, 发现如果要将故障动图放到第三方平台, 必须需要用第三方录屏软件先把动图录制下来, 然后保存gif之后在传到第三方平台, 这个操作链路如下:

网络异常,图片无法展示
|



笔者是在忍受不了那么多步骤, 一般在笔者的认知里一般实现一件简单的事情超过3个步骤, 笔者是不能接受的,尤其是录屏这种耗时任务. 所以再三思考还是决定自己开发一个平台,将步骤压缩到2步:


网络异常,图片无法展示
|


好了, 开始我们下面的技术探索.


1.1 开发图形编辑区


图形编辑区主要是表单编辑, 笔者这里使用antd来快速搭建一个简单表单, 唯一值得注意的就是颜色组件, 这里笔者使用react-color, 因为vue3.0对jsx支持越来越好, 所以实现原理和react很像,这里笔者就直接用react来举例子. 代码如下:


<divclassName={styles.editorArea}><divclassName={styles.formItem}><spanclassName={styles.label}>文字: </span><Inputvalue={value['text']}placeholder="请输入文本内容"onChange={(e)=> onChange('text', e)} />
</div><divclassName={styles.formItem}><spanclassName={styles.label}>大小: </span><InputNumbervalue={value['fontSize']}placeholder="请输入文本大小"onChange={(e)=> onChange('fontSize', e)} />
</div><divclassName={styles.formItem}><spanclassName={styles.label}>文字颜色: </span><Colorvalue={value['textColor'][0]}onChange={(e)=> onChange('textColor', e, 1)} />
<Colorvalue={value['textColor'][1]}onChange={(e)=> onChange('textColor', e, 2)} />
</div><divclassName={styles.formItem}><spanclassName={styles.label}>背景色: </span><Colorvalue={value['themeColor']}onChange={(e)=> onChange('themeColor', e)} />
</div><divclassName={styles.formItem}><spanclassName={styles.label}></span><Buttontype="primary"onClick={generateGif}>导出Gif</Button>    {/* <Buttonstyle={{marginLeft:'20px'}}onClick={reset}>重置</Button> */}
</div></div>

大家可以不用太关注代码细节, 你可以使用任何熟悉的方式去开发, 表单编辑器主要是实现和预览区域的互通, 在react里我们用hooks组件的useState来和Blink组件互通, vue的话可以直接用data或者vuex解决问题, 具体如下图实现:

网络异常,图片无法展示
|


只要大家能实现这种过程就可以了. 在QT项目里的效果如下:


网络异常,图片无法展示
|



1.2 实现预览区


预览区域的实现很简单, 通过Blink暴露的属性来动态传递即可, 这里我们有必要了解一下Blink的内部实现, 先上一下githugb地址: 基于react的css故障艺术库 , 我们直接看组件的实现方式:


importReact, { useRef, useEffect } from'react'import'./index.less'exportdefaultfunctionBlink(props) {
const { 
text='趣谈前端',
fontSize='48px',
themeColor='#000',
textColor= ['#74fcfd', '#ea3448'],
onRef  } =propsconstref=useRef(null)
useEffect(() => {
onRef&&onRef(ref)
  }, [])
return (
<divclassName='blink'style={{backgroundColor: themeColor}} ref={ref}><divclassName="blink-item"data-text={text} style={{fontSize: fontSize}}><divclassName="text text-front"style={{color: textColor[0]}}>{text}</div><divclassName="text text-back"style={{color: textColor[1]}}>{text}</div></div></div>   )
}

至于样式问题, 笔者在github里有详细的介绍, 这里就不详细说明了. 所以说我们在项目中实现预览也很简单, 直接引入组件即可:

<Blink{...value}onRef={(ref)=> { blinkRef.current = ref.current}} />

value就是form表单的配置产物.


1.3 实现预览gif动图


实现预览gif动图是文章的重点, 我们要考虑如何将dom转化为图片, 然后再将图片转化为gif. 这块笔者思考了一会, 想出了一个解决方案, 思路如下: 先用canvas库定时截取预览区域的动画效果, 生成n张关键帧图片, 然后利用canvas将多张关键帧组装成gif动图. 笔者的思路主要采用的flash软件的关键帧动画的实现, 具体流程如下:


网络异常,图片无法展示
|


图中我们涉及到了几个有意思的插件, 笔者在H5-Dooring项目中也用到过,分别为:


  • dom-to-image —— 转门将dom转化为图片的库


  • gif.js —— 将多张图片转化为gif动图


实现过程中由于dom-to-image产生图片的过程是异步的, 但是我们要将所以图片生成完之后才能传给gif.js, 这里笔者用了promise.all;来实现(注意, 考点). 我们先将第一步骤二次封装成新的promise对象, 代码如下:



constgenerateImg= (node, imgId, time) => {
returnnewPromise((resolve, reject) => {
setTimeout(() => {
domtoimage.toPng(node)
        .then(function (dataUrl) {
letimg=newImage();
img.src=dataUrl;
img.id=imgId;
img.className='imgPiece';
document.getElementById('imgBox').appendChild(img);
resolve(document.getElementById(imgId));
        })
        .catch(function (error) {
reject(error);
        });
      }, time)
    })
 }

其次我们使用promise.all来将图片统一收集传给gif.js对象:

constgenerateGif= () => {
document.getElementById('imgBox').innerHTML='';
letblink=blinkRef.current;
letpromiseArr= [];
for(leti=0, len=24; i<len; i++) {
promiseArr.push(generateImg(blink, `img${i+1}`, 16*i));
    }
Promise.all(promiseArr).then(res=> {
if(res) {
letw=res[0].width;
leth=res[0].height;
// res即为所有的img集合, 可以直接传给gif.js ...        });
      }
    })
  }

关于gif.js的使用方法, 官网里也有详细的介绍, 这里笔者不一一举例了, 感兴趣的朋友可以研究一下.


1.4 一键下载gif动图


实现现在gif文件我们采用file-saver模块来实现, 实现思路也很简单, 如下:

saveAs(image, `${uuid(6, 10)}.gif`);

image即是gif.js或者其他动图插件生成的gif图片, uuid主要是给图片命名. 我们可以看看几个下载好的gif例子:



网络异常,图片无法展示
|



网络异常,图片无法展示
|


网络异常,图片无法展示
|


网络异常,图片无法展示
|


最后


在H5编辑器H5-Dooring中,后期也会实现类似的功能,大家感兴趣的可以了解一下。

github地址:H5编辑器H5-Dooring



目录
相关文章
|
Web App开发 移动开发 前端开发
素材锦囊——50个高质量的 PSD 素材免费下载《上篇》
  您是否在寻找高品质的 PSD 文件?在这里,我收集了50个新鲜出炉的精美 PSD 文件,分享给设计师朋友们。 在这个 PSD 文件集合中,你可以找到 UI 工具包,设计界面,图标集,网站模板,网页徽章和 PSD 图标等等。
1246 0
|
移动开发 JavaScript 前端开发
60个精美的移动开发PSD素材资源免费下载 - 上篇
  本文与大家分享60个精美的移动开发PSD素材资源,如果你正在开发一个手机项目,相信这些精美的PSD素材一定能帮上你的大忙,其它朋友也可以收藏起来,说不定以后会用到的 :) inSET HD Android GUI PSD Vector Kit Dream Smartphone ...
1110 0
|
前端开发 C#
精品素材:20个很好看的抽象图片素材免费下载
  在这个集合里,我们向大家分享一批可以免费下载的抽象图片素材,可以免费下载使用。我们都知道通过使用美观和瞩目的背景,可以创建有绝对的吸引力的设计。这是设计师花了这么多的时间创建背景的重要原因。   通过创造性地使用背景,你的整个作品看起来更有趣和有吸引力的。
1064 0
|
存储 移动开发 前端开发
有点意思的gif动图生成平台开发实战(二)
笔者之前利于业余时间开发了一个gif动图生成平台, 具体开发背景我也在上一篇文章手把手教你撸一个能生成抖音风格动图的gif制作平台中介绍过了, 我们今天继续来实现该平台, gif动图平台的实现方式比较将完全用前端的手段来实现, 所以大家在接下来的内容中会发现很多有意思的前端插件. 接下来我们看看主要要实现的功能点:
212 0
|
移动开发 JavaScript 前端开发
60个精美的移动开发PSD素材资源免费下载 - 下篇
  本文与大家分享60个精美的移动开发PSD素材资源,如果你正在开发一个手机项目,相信这些精美的PSD素材一定能帮上你的大忙,其它朋友也可以收藏起来,说不定以后会用到的 :) Htc Dream HTC Touch Diamond PSD HTC Hero PSD iPhon...
977 0
|
自然语言处理 Python Windows
|
6月前
|
前端开发 容器
实战!小白切图,手把手教你完成音乐播放器页面
实战!小白切图,手把手教你完成音乐播放器页面
|
移动开发 前端开发 JavaScript
56套高质量的2012圣诞节矢量图素材免费下载(下篇)
  转眼间,2012年圣诞节就要来了。这篇文章给大家带来56套高质量的可以免费下载使用的圣诞节矢量图素材。设计师经常需要去网上搜罗一些矢量图片素材用于设计任务,网上的各种资源琳琅满目,要找到合适的素材可能需要花费大量的时间,这些高质量的2012年圣诞节矢量图素材既能为设计师节省时间,又能有很不错的效果。
925 0
|
6月前
|
vr&ar
简单易懂的 全景图高清下载方法以及原理简要解析(支持下载建E、720yun、酷雷曼、景站、酷家乐、百度街景原图)
这篇文章介绍了一种简单易懂的全景图高清下载方法,使用在线网站全景管家,支持下载包括建E、720yun、酷雷曼等多个平台的全景图原图,并简要解析了全景图的原理和制作方法。
简单易懂的 全景图高清下载方法以及原理简要解析(支持下载建E、720yun、酷雷曼、景站、酷家乐、百度街景原图)

热门文章

最新文章