您现在的位置是:亿华云 > IT科技
手把手教你撸一个能生成抖音风格动图的gif制作平台
亿华云2025-10-08 23:19:21【IT科技】4人已围观
简介前言又到了一周一次的周总结, 笔者基于之前的开源项目 blink , 开发了一款能在线配置故障艺术, 并一键生成gif动图的平台, 这里暂时取名为QT. 接下来笔者将复盘一下该可视化平台的实现步骤以及
前言
又到了一周一次的手把手教周总结, 笔者基于之前的开源项目 blink , 开发了一款能在线配置故障艺术, 并一键生成gif动图的平台, 这里暂时取名为QT. 接下来笔者将复盘一下该可视化平台的实现步骤以及功能点, 让大家都能做自己的Gif动图生成平台.
在线访问地址: 趣图——一款轻量级生成抖音风格动效的在线工具
正文
在开始正文之前, 我们先来看看使用效果图:
首先我们拆解一下功能:
图形编辑区 —— 用来编辑动图样式, 问文字等 预览区 —— 用来预览用户实时配置的动画效果 结果展示区 —— 用来存放生成的gif效果 gif文件自动下载我们大致理清了我们需要实现的功能之后, 我们就可以一步步来实现了.
在这里我想先简单介绍一下背景: 在笔者之前开源了生成自定义故障艺术的组件库Blink之后, 发现如果要将故障动图放到第三方平台, 必须需要用第三方录屏软件先把动图录制下来, 然后保存gif之后在传到第三方平台, 这个操作链路如下:
笔者是在忍受不了那么多步骤, 一般在笔者的认知里一般实现一件简单的事情超过3个步骤, 笔者是不能接受的,尤其是录屏这种耗时任务. 所以再三思考还是决定自己开发一个平台,将步骤压缩到2步:
好了, 开始我们下面的技术探索.
1.1 开发图形编辑区
图形编辑区主要是表单编辑, 笔者这里使用antd来快速搭建一个简单表单, 唯一值得注意的就是颜色组件, 这里笔者使用react-color, 因为vue3.0对jsx支持越来越好, 所以实现原理和react很像,这里笔者就直接用react来举例子. 代码如下:
<div className={ styles.editorArea}> <div className={ styles.formItem}> <span className={ styles.label}>文字: </span> <Input value={ value[text]} placeholder="请输入文本内容" onChange={ (e) => onChange(text, e)} /> </div> <div className={ styles.formItem}> <span className={ styles.label}>大小: </span> <InputNumber value={ value[fontSize]} placeholder="请输入文本大小" onChange={ (e) => onChange(fontSize, e)} /> </div> <div className={ styles.formItem}> <span className={ styles.label}>文字颜色: </span> <Color value={ value[textColor][0]} onChange={ (e) => onChange(textColor, e, 1)} /> <Color value={ value[textColor][1]} onChange={ (e) => onChange(textColor, e, 2)} /> </div> <div className={ styles.formItem}> <span className={ styles.label}>背景色: </span> <Color value={ value[themeColor]} onChange={ (e) => onChange(themeColor, e)} /> </div> <div className={ styles.formItem}> <span className={ styles.label}></span> <Button type="primary" onClick={ generateGif}>导出Gif</Button> { /* <Button style={ { marginLeft: 20px}} onClick={ reset}>重置</Button> */} </div> </div>大家可以不用太关注代码细节, 你可以使用任何熟悉的方式去开发, 表单编辑器主要是云服务器实现和预览区域的互通, 在react里我们用hooks组件的useState来和Blink组件互通, vue的话可以直接用data或者vuex解决问题, 具体如下图实现:
只要大家能实现这种过程就可以了. 在QT项目里的效果如下:
1.2 实现预览区
预览区域的实现很简单, 通过Blink暴露的属性来动态传递即可, 这里我们有必要了解一下Blink的内部实现, 先上一下githugb地址: 基于react的css故障艺术库 , 我们直接看组件的实现方式:
import React, { useRef, useEffect } from react import ./index.less export default function Blink(props) { const { text = 趣谈前端, fontSize = 48px, themeColor = #000, textColor = [#74fcfd, #ea3448], onRef } = props const ref = useRef(null) useEffect(() => { onRef && onRef(ref) }, []) return ( <div className=blink style={ { backgroundColor: themeColor}} ref={ ref}> <div className="blink-item" data-text={ text} style={ { fontSize: fontSize}}> <div className="text text-front" style={ { color: textColor[0]}}>{ text}</div> <div className="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对象, 代码如下:
const generateImg = (node, imgId, time) => { return new Promise((resolve, reject) => { setTimeout(() => { domtoimage.toPng(node) .then(function (dataUrl) { let img = new Image(); 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对象:
const generateGif = () => { document.getElementById(imgBox).innerHTML = ; let blink = blinkRef.current; let promiseArr = []; for(let i=0, len=24; i < len; i++) { promiseArr.push(generateImg(blink, `img${ i+1}`, 16 * i)); } Promise.all(promiseArr).then(res => { if(res) { let w = res[0].width; let h = 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
github:Blink
本文转载自微信公众号「趣谈前端」,格动可以通过以下二维码关注。图的台转载本文请联系趣谈前端公众号。制作平
手把手教很赞哦!(75434)
相关文章
- 在数以亿计的网站中,我们应该抓住每一个可能带来宣传的机会,域名可以带有企业的名字,一般可以使用汉语拼音或者英语单词或者是相关缩写的形式,只要用户记住了你企业的名字,就能很容易的打出你的网站域名,同样的,记住了网站域名也能很快的记住你公司的名字。
- 没想到 Shell 命令竟然还能这么玩?
- 十一种流行的无/低代码后端数据平台
- 领导给了一堆无序杂乱的数据,我写了个Python自动化脚本
- 5. 四种状态过后,域名管理机构释放域名给公众注册。
- 保姆级 Go+ 快速入门体验教程,你会吗?
- 量化分析预测股市?试试这个 Python 库
- Springboot强大的类型转换功能,你必须要掌握
- a、变更前的公司证件扫描件(代码证或者营业执照)及联系人身份证复印件、变更后的公司证件扫描件(代码证或者营业执照)及新的联系人身份证复印件;身份证复印件需本人签名,公司证件复印件需加盖公章。
- Kafka 夺命连环11问