文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

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

2024-12-03 00:45

关注

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

正文

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

首先我们拆解一下功能:

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

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

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

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

1.1 开发图形编辑区

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

  1.  
  2.    
  3.     文字:  
  4.     'text']} placeholder="请输入文本内容" onChange={(e) => onChange('text', e)} /> 
  5.   
 
  •    
  •     大小:  
  •     'fontSize']} placeholder="请输入文本大小" onChange={(e) => onChange('fontSize', e)} /> 
  •   
  •  
  •    
  •     文字颜色:  
  •     'textColor'][0]} onChange={(e) => onChange('textColor', e, 1)} /> 
  •     'textColor'][1]} onChange={(e) => onChange('textColor', e, 2)} /> 
  •   
  •  
  •    
  •     背景色:  
  •     'themeColor']} onChange={(e) => onChange('themeColor', e)} /> 
  •   
  •  
  •    
  •      
  •     "primary" onClick={generateGif}>导出Gif 
  •     {} 
  •    
  •  
  •  

     

     

     

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

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

    1.2 实现预览区

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

    1. import React, { useRef, useEffect } from 'react' 
    2. import './index.less' 
    3.  
    4. export default function Blink(props) { 
    5.   const {  
    6.     text = '趣谈前端'
    7.     fontSize = '48px'
    8.     themeColor = '#000'
    9.     textColor = ['#74fcfd''#ea3448'], 
    10.     onRef 
    11.   } = props 
    12.  
    13.   const ref = useRef(null
    14.  
    15.   useEffect(() => { 
    16.     onRef && onRef(ref) 
    17.   }, []) 
    18.  
    19.   return ( 
    20.     'blink' style={{backgroundColor: themeColor}} ref={ref}> 
    21.       "blink-item" data-text={text} style={{fontSize: fontSize}}> 
    22.         "text text-front" style={{color: textColor[0]}}>{text} 
    23.         "text text-back" style={{color: textColor[1]}}>{text} 
    24.        
    25.       
    26.   ) 

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

    1.  { blinkRef.current = ref.current}} /> 

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

    1.3 实现预览gif动图

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

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

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

    1. const generateImg = (node, imgId, time) => { 
    2.     return new Promise((resolve, reject) => { 
    3.       setTimeout(() => { 
    4.         domtoimage.toPng(node) 
    5.         .then(function (dataUrl) { 
    6.           let img = new Image(); 
    7.           img.src = dataUrl; 
    8.           img.id = imgId; 
    9.           img.className = 'imgPiece'
    10.           document.getElementById('imgBox').appendChild(img); 
    11.           resolve(document.getElementById(imgId)); 
    12.         }) 
    13.         .catch(function (error) { 
    14.           reject(error); 
    15.         }); 
    16.       }, time
    17.     }) 
    18.  } 

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

    1. const generateGif = () => { 
    2.     document.getElementById('imgBox').innerHTML = ''
    3.     let blink = blinkRef.current
    4.     let promiseArr = []; 
    5.  
    6.     for(let i=0, len=24; i < len; i++) { 
    7.       promiseArr.push(generateImg(blink, `img${i+1}`, 16 * i)); 
    8.     } 
    9.  
    10.     Promise.all(promiseArr).then(res => { 
    11.       if(res) { 
    12.         let w = res[0].width; 
    13.         let h = res[0].height; 
    14.          // res即为所有的img集合, 可以直接传给gif.js ... 
    15.         }); 
    16.       } 
    17.     }) 
    18.   } 

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

    1.4 一键下载gif动图

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

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

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

    [[413849]]

    最后

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

    github:H5编辑器H5-Dooring

    github:Blink

    本文转载自微信公众号「趣谈前端」,可以通过以下二维码关注。转载本文请联系趣谈前端公众号。

     

    来源:趣谈前端内容投诉

    免责声明:

    ① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

    ② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

    软考中级精品资料免费领

    • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

      难度     813人已做
      查看
    • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

      难度     354人已做
      查看
    • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

      难度     318人已做
      查看
    • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

      难度     435人已做
      查看
    • 2024年上半年系统架构设计师考试综合知识真题

      难度     224人已做
      查看

    相关文章

    发现更多好内容

    猜你喜欢

    AI推送时光机
    位置:首页-资讯-后端开发
    咦!没有更多了?去看看其它编程学习网 内容吧
    首页课程
    资料下载
    问答资讯