canvas 花字编辑器

1,658 阅读4分钟

背景

我们可以用 canvas 在图片上添加花字效果,可以用 node-canvas 导出有花字的图片。但这只适用于几个花字模版,也不适合后期修改。如果要批量化生成花字并且达到修改的效果和生产出花字的效果一致,就需要模版化花字并且做到前台所见即所得,最好需要一个花字的编辑器来展示和编辑效果。

做一个花字编辑器,给到设计师生产花字

技术方案

这里只是一个demo

竞品分析

此调研在2021年7月,因此各软件会有更新,仅供参考。

能力抖音快手淘宝
花字
模版
边框
滤镜
画笔(笔触)
形状
点9图
实时编辑

通过对比,我们发现花字编辑器的核心难点在于,点9图、实时编辑和多端渲染(需要充分考虑移动端、PC端的渲染差异)。

点9图

点9图是一种特殊的图片格式,可以保证图片拉伸时,所设定的关键部分不变形。

   移动端系统支持点9图渲染,PC端我们需要自己实现一套点9图渲染引擎。

普通图片经过原图拉伸之后,会产生缺角部分的形变,但我们希望边角部分始终不变。所以在这张点9图中,两个缺角,其实就是整张图的关键部分。大多数的点9图,其实也就是对边角有一些特殊要求。我们通常可以通过4个方向的padding,来将这些关键部分划分出来。

image.png

  • 点9图实现:三个步骤(对应3个canvas)
    1. 裁剪区块(SourceCanvas 对源图片进行裁剪)
    2. 区块拉伸(ScaleCanvas 对某一个区块进行拉伸、平铺)
    3. 区块拼接(TargetCanvas 将处理好的区块拼接起来,导出目标尺寸的新图片)

image.png

image.png

  • 拉伸区块的变形问题

对于一些素材,在上图的2、4、5... 等用于拉伸的区块上可能也存在一些图案,所以我们给定一个宽高比,在宽高比之内,做拉伸,到达宽高比之后,将两张原图拼接,并重新拉伸到相应的大小,之后不停的拼接。这种处理方式,可以同时解决相框特效,因为本质上,相框其实就是区块5为透明的点9图

定位与线性布局

定位的协议,我们先设定了上、下、左、右、中5个方向的二进制值,最后通过位运算得出细分的9个点,实现一个9宫格式的定位。而对于线性布局,它原本也是移动端的概念,我们在PC端上实现了横纵两种配置。

/*定位协议*/
上:00001 (二进制)
左:00010
下:00100
右:01000
中:10000
// 设置好上述五个方向的值之后,对每个方向互相做或运算。
如:
   00001
|  00010
---------
   00011
​
上左 = 上|左 = 00001 | 00010 = 00011 (十进制:3)
上中 = 上|中 = 00001 | 10000 = 10001 (十进制:17)
上右 = 上|右 = 00001 | 01000 = 01001 (十进制:9)
​
左中 = 左|中 = 00010 | 10000 = 10010 (十进制:18)
中 = 10000                          (十进制:16)
右中 = 右|中 = 01000 | 10000 = 11000 (十进制:24)
​
下左 = 下|左 = 00100 | 00010 = 00110 (十进制:6)
下中 = 下|中 = 00100 | 10000 = 10100 (十进制:20)
下右 = 下|右 = 00100 | 01000 = 01100 (十进制:12)

实现方式

初始化时,以各个图片的配置计算其位置。

  • 将花字的各个元素合并成一个整体Group
  • 所有元素以Group左上角为原点对齐,初始化时没有任何偏移
  • 计算出整个Group的最大宽高,以该尺寸作为一个初始状态OriginSize
  • 依照上述初始状态,对每一个元素做初始化的偏移。如定位值为17,那么他的left应该为(OriginSize.width - Self.width) / 2
  • 初始化后,之后的计算基本与定位值无关,我们记录初始化后的各个子元素与文本之间的距离,并把它们保存起来,文本change时,对每一个子元素重新设定位置,即可 (上图中可以看到“VLOG MY LIFE”、“HAVE A NICE DAY”这两个黄色文字,其实是以图片形式展现的,他们的定位值分别为17、20)

image.png

多花字的线性布局中,初始化时、所有元素的垂直、水平偏移都需要累加上之前所有元素的宽高和;文本编辑时,将以初始化的位置为基础,依照文本框宽高的变化,对各个元素的位置进行动态计算。

image.png