我用 fabritor 做了一个截图美化应用

偶尔间看到一款国外的应用:Screely,是一款截图美化工具。通常用截图工具截的图标注一下就发出去了,截图有大有小,发到文章或者社交网络并不整齐也不美观(可以参见我之前发我的文章😂,妥妥反面案例)。Screely 就是解决这个问题的,他可以给截图加上背景、圆角、Mac窗口,也可以加上标注和贴纸。这样分享截屏既美观也不会突兀。

如果你经常上推的话就会发现,大多数博主发的图片都带有背景、圆角。整体美观度会提升不少。

然后我就在想,我能不能也做一个类似的工具😎。这时候我想到了 fabritor,是时候让她继续发挥余热了。

fabritor 作为一个图片编辑器,已经比较完善了,做一个截图美化工具应该问题不大,随便折腾一下,有那味了。

是的,我做了 Photor

fork 一下 fabritor 的代码,停停写写,也差不多有一个月的时间,完成了名为 Photor 的截图美化工具,等不及的可以先去官网试用一下:www.photor.fun/

基本包含了截图美化工具的所有功能,包括上传、背景、边距、圆角、窗口、水印、定制截图尺寸、各类标注、裁剪等等。

简单推广过一波,目前 UV 稳定在 100 左右,说明还是有用户的。😂

简单技术分析

总体还是基于 fabritor 实现,像画布尺寸、背景渐变、圆角、裁剪、各类标注图形的基础方法,代码都是直接来自于 fabritor,下面会挑几个不一样的点说一下。

定制尺寸

很多网站上传图片会有建议尺寸甚至强制尺寸,这时候临时去截取和缩放都会比较麻烦,索性加一个定制尺寸的功能。定制尺寸其实直接修改的就是画布的尺寸,画布固定后,缩放图片即可。但图片上有时候还会附带 Mac 窗口,有时候缩放会比较奇怪,还需要优化。

标注绘制

fabritor 内,矩形等形状都是直接添加到画布然后编辑的,而对于截图标注的话,还是鼠标拖动绘制的好。之前掘金文章下面也有同学问过,fabricjs 提供了丰富的鼠标事件,事件内附带鼠标位置,要实现也不是很难。

这里以矩形为例:

typescript 复制代码
// mouse down 事件,在鼠标按下位置创建矩形。
drawShapeRef.current = {
  isDraw: true,
  lastPoint: opt.absolutePointer,
  tmp: createRect({
    left: opt.absolutePointer.x, 
    top: opt.absolutePointer.y, 
    width: 1, height: 1, rx: 10, ry: 10, 
    fill: 'rgba(0,0,0,0)', 
    stroke: '#D31638', 
    strokeWidth: 6 
  }),
  type: 'rect'
}

// mouse move 事件,修改矩形属性
tmp.set({
  left: Math.min(opt.absolutePointer.x, lastPoint.x),
  top: Math.min(opt.absolutePointer.y, lastPoint.y),
  width: Math.abs(opt.absolutePointer.x - lastPoint.x),
  height: Math.abs(opt.absolutePointer.y - lastPoint.y)
});

// mouse up 完成绘制
canvas.setActiveObject(tmp);

Mac 窗口

如果分享的是代码图片的话,带一个 Mac 窗口可以加分很多。我现在采用的方案是使用 圆形和矩形的组合(Group)。fabricjs 里使用组合的话可以比较方便的做一些复杂的图形。之前 issue 里有同学问过如何实现一个复杂的图形,我也是建议这样做。

typescript 复制代码
fabric.FMacWindow = fabric.util.createClass(fabric.Group, {
  type: 'f-mac-window',

  initialize (options) {
    this.callSuper('initialize', [
      this.background,
      this.closeCircle,
      this.minCircle,
      this.maxCircle
    ], rest, false);
  }
})

不过组合起来简单,但有个问题是 Mac 窗口覆盖到图片上,只能有两个圆角,而 fabricjs 默认是四个圆角的,也没有给出配置实现,只能自定义实现了。

所以需要自定义一下 rect 的 _render 。

同样覆盖在图片上时,图片上方的两个圆角也要去掉。

定制线条 control

fabricjs 内,默认的线条 control 也像矩形一样,并不像常见的线条 control,通常线条只需要两个端点修改长度和位置就好。

fabricjs 使用 new fabric.Control 定制。

typescript 复制代码
const linePositionHandler = (x, y) => {
  return (dim, finalMatrix, fabricObject) => {
    const points = fabricObject.calcLinePoints();
    const localPoint = new fabric.Point(points[x], points[y]);
    
    // move 不会改变 x1 y1 x2 y2
    // fabricObject.toLocalPoint(new fabric.Point(points[x], points[y]), 'center', 'center');
    const point = fabric.util.transformPoint(localPoint, fabric.util.multiplyTransformMatrices(
      fabricObject.canvas.viewportTransform,
      fabricObject.calcTransformMatrix()
    ));
    return point;
  }
}

const changeLineEnd = (eventData, transform, x, y) => {
  const { target } = transform;
  target.set({ x2: x, y2: y  });
  return true;
}

const changeLineStart = (eventData, transform, x, y) => {
  const { target } = transform;
  target.set({ x1: x, y1: y  });
  return true;
}

const objectControls = fabric.Object.prototype.controls;

if (fabric.Line) {
  const lineControls: any = fabric.Line.prototype.controls = {};
  lineControls.copy = objectControls.copy;
  lineControls.del = objectControls.del;

  lineControls.l1 = new fabric.Control({
    positionHandler: linePositionHandler('x1', 'y1'),
    actionHandler: changeLineStart,
    cursorStyleHandler: () => 'crosshair',
    actionName: 'line-change',
    render: objectControls.br.render
  });

  lineControls.l2 = new fabric.Control({
    positionHandler: linePositionHandler('x2', 'y2'),
    actionHandler: changeLineEnd,
    cursorStyleHandler: () => 'crosshair',
    actionName: 'line-change',
    render: objectControls.br.render
  });
}

图片文字模糊

使用 fabritor 的同学不知道有没有发现,如果图片上有文字,就能感觉出添加到画布的图片是糊的。

我这里找到一个 issue:github.com/fabricjs/fa... 里面讨论了图片和 clipPath 一起使用时,为了性能和缓存,是要牺牲图片清晰度的。

禁用缓存是可以解决这个问题,但会牺牲一定性能。

typescript 复制代码
fabric.Object.prototype.needsItsOwnCache = () => false

浏览器插件

此外,为了更方便的使用截图,我还开了浏览器插件,已经上架到 Chrome 和 Edge 插件商店。即可以截取这个页面,也可以选定部分区域,截图后直接进入 Photor 内编辑。

可以通过官方底部的链接下载使用。

写在后面

开发 Photor 这个应用,一方面是为了拿 fabritor 做点事情,另一方面也是尝试一下独立开发一个完整的产品。如果你也喜欢这种截图方式,不妨日常使用一下。(本文截图都是使用 Photor 制作

相关推荐
东东2332 分钟前
前端开发中如何取消Promise操作
前端·javascript·promise
掘金安东尼7 分钟前
官方:什么是 Vite+?
前端·javascript·vue.js
柒崽9 分钟前
ios移动端浏览器,vh高度和页面实际高度不匹配的解决方案
前端
渣哥25 分钟前
你以为 Bean 只是 new 出来?Spring BeanFactory 背后的秘密让人惊讶
javascript·后端·面试
烛阴33 分钟前
为什么游戏开发者都爱 Lua?零基础快速上手指南
前端·lua
大猫会长43 分钟前
tailwindcss出现could not determine executable to run
前端·tailwindcss
Moonbit1 小时前
MoonBit Pearls Vol.10:prettyprinter:使用函数组合解决结构化数据打印问题
前端·后端·程序员
533_1 小时前
[css] border 渐变
前端·css
云中雾丽1 小时前
flutter的dart语言和JavaScript的消息循环机制的异同
前端
欧雷殿1 小时前
典型程序员跨界做在地社区是怎样一种体验?
程序员·产品·创业