无界云图开源图片编辑器技术文档

引言

无界云图是爱趣五科技开源的一款在线图片编辑工具,工具采用 B/S 架构,底层基于 Leafjs(一款高效的 2D Canvas 渲染引擎)做的
开发,该技术文档是为了方便开发者快速接入并进行二次开发所著,文档中有一些专业术语如果有疑问的请告知我们。

技术说明

主要技术&框架如下:

  • React v1.8.2
  • Mobx v5.15.4
  • Vite v4.4.4
  • Semi-Design v2.54.0
  • Leaferjs v1.0.0
  • Typescript v5.1.6

目录结构

src
├─assets 静态资源
│  └─images
├─components 公共组件
│  ├─error-boundary 错误提示
│  ├─list-status 异步列表
│  ├─login 登录/注册模块
│  │  ├─loginMobile 手机登录
│  │  ├─loginQrcode 二维码登录
│  │  └─loginRegisterBox
│  ├─not-found 404页面
│  ├─page-loading 页面顶部的加载条
│  └─water-full 瀑布流组件
├─config 全局配置
├─icons 公共icon
├─language 多语言配置
├─layout 布局框架
│  ├─index-layout
│  └─manage-layout
├─less 全局less
├─pages 页面模块
│  ├─editor 编辑器页面
│  │  ├─common 公共组件
│  │  │  ├─dragitem 拖拽素材到画布
│  │  │  └─source 资源列表框
│  │  ├─components 编辑器大模块
│  │  │  ├─canvas 画布区域组件
│  │  │  ├─contextMenu 鼠标右键菜单
│  │  │  ├─header 编辑器顶部栏
│  │  │  ├─options 设置区域模块
│  │  │  │  ├─components 设置小模块
│  │  │  │  │  ├─align 对齐方式设置
│  │  │  │  │  ├─background 背景设置
│  │  │  │  │  ├─blur 模糊设置
│  │  │  │  │  ├─border 边框设置
│  │  │  │  │  ├─color 颜色设置
│  │  │  │  │  ├─colour 叠加模式设置
│  │  │  │  │  ├─filter 滤镜设置
│  │  │  │  │  ├─flipxy 翻转、复制、锁定、可见等快捷按钮
│  │  │  │  │  ├─group 组设置
│  │  │  │  │  ├─item 公共布局小模块
│  │  │  │  │  ├─opacity 透明度设置
│  │  │  │  │  ├─position 位置设置
│  │  │  │  │  ├─radius 圆角设置
│  │  │  │  │  ├─rotation 旋转设置
│  │  │  │  │  ├─set-color 颜色设置
│  │  │  │  │  ├─shadow 阴影设置
│  │  │  │  │  ├─size 宽高设置
│  │  │  │  │  ├─slider-input 滚动条插件
│  │  │  │  │  ├─strength 强度设置
│  │  │  │  │  ├─text-content 文字内容修改
│  │  │  │  │  └─text-style 文字样式修改
│  │  │  │  └─elements 元素的设置区域功能配置文件
│  │  │  ├─sidebar 左侧菜单
│  │  │  └─sources 左侧资源列表
├─server API服务
├─stores mobx的store管理
├─theme 主题配置
└─utils 公共插件

图层说明

图层包括:图片、文字等元素,图层可以理解为有层级的元素,上面的图层会挡住下面的图层,为了增加项目的扩展性,后续我们会针对
图层做插件化处理,让开发者可以添加自己的图层元素,比如二维码,图表,表格,词云等元素。

  • 【图片】 支持格式 jpg/gif/png/svg
  • 【文本】 支持中英文字体,文本样式支持参考 Leaferjs 的 Text 样式
  • 【组】多个元素进行编组

数据结构

我们使用 JSON 数据来保存工程数据,将工程数据传入渲染内核就可以进行视图的预览、编辑、导出等操作。

工程数据中需要明白页面图层的概念,一个工程中可以包含多个页面,比如我们在设计一个名片的时候,有正面和反面,这就涉及
到 2 个页面,而每个页面下面又有多个图层元素,比如:姓名、LOGO、地址、电话等等、职位。我们可以归纳为:

  1. 【图片图层】LOGO
  2. 【文字图层】姓名、地址、电话、职位

了解完图层、页面的概念,接下来我们了解工程文件,工程文件就是记录页面,元素数据的总文件。工程数据说明请参考内核代
src/pages/editor/core/types/data.ts中的ViewData,下面是一个工程数据案例:


import type { ViewData, ImageLayer, BasePage, TextLayer } from './core/types/data';

export const tdata: ViewData = {
  name: 'mock数据', // 工程名称
  desc: '暂无描述', // 工程的描述
  version: '1.0.0', // 工程文件当前的版本(版本号是和我们的内核相关的)
  thumb: '', // 工程项目的封面图
  selectPageId: 'p1', // 默认展示的页面id
  createTime: 0, // 创建时间
  updateTime: 0, // 更新时间
  pages: [ // 页面
    {
      id: 'p1',
      name: 'p1',
      desc: '',
      width: 1000, // 页面的尺寸
      height: 600,
      background: { // 页面背景
        type: 'solid',
        color: '#fff',
      },
      layers: [ // 图层
        {
          id: 't1',
          name: 'test',
          desc: '',
          x: 100,
          y: 100,
          opacity: 1,
          rotation: 0,
          flipx: true,
          flipy: false,
          blur: 0,
          type: 'image',
          _dirty: '1', // 用于视图更新
          _lock: false, // 是否锁定
          _hide: false, // 是否隐藏
          width: 200,
          height: 200,
          border: {
            stroke: '#f00', // 边框色
            strokeWidth: 2,
            visible: false,
          },
          shadow: {
            x: 10,
            y: 10,
            blur: 10,
            blendMode: 'normal',
            spread: 0,
            color: 'rgba(0,0,0,0.5)',
            box: false,
            visible: true,
          },
          naturalWidth: 200,
          naturalHeight: 285,
          url: 'https://cdn.h5ds.com/video/uploads/9715/20240207/679367666016878592.png', // 图片链接
          cornerRadius: [200, 200, 200, 200], // 圆角
        } as ImageLayer,
        {
          id: 't3',
          name: 'txt',
          desc: '',
          x: 100,
          y: 100,
          opacity: 1,
          rotation: 0,
          blur: 0,
          type: 'text',
          text: '测试文字,无界云PS',
          fill: null,
          blendMode: 'normal',
          fontFamilyURL: '',
          textStyle: {
            fontSize: 20,
            fill: {
              type: 'linear',
              from: { x: 0, y: 0 },
              to: { x: 1, y: 0 },
              stops: [
                { offset: 0, color: '#FF4B4B' },
                { offset: 1, color: '#FEB027' },
              ],
            },
          },
          _dirty: '1', // 用于视图更新
          _lock: false, // 是否锁定
          _hide: false, // 是否隐藏
          border: {
            stroke: '#f00', // 边框色
            strokeWidth: 2,
            visible: false,
          },
          shadow: {
            x: 10,
            y: 10,
            blur: 10,
            blendMode: 'normal',
            spread: 0,
            color: 'rgba(0,0,0,0.5)',
            box: false,
            visible: false,
          },
        } as TextLayer,
      ],
    } as BasePage,
  ],
};

渲染内核

基于 Leaferjs 和 React 封装了一个渲染内核,渲染内核的本质为一个 React 组件,可以快速在项目中使用。

参数说明类型默认值必填
data页面模块的 JSON 数据BasePage-
target画布放入的 DOM 容器HTMLDivElement-
env当前的渲染环境‘editor’,‘preview’‘editor’
resourceHost资源文件的 HOST 地址,资源存放路径string‘’
callback渲染后的回调函数Store => void-
onControlSelect选中元素会触发(_event, ids: string[]) => void-
onDragUp鼠标弹起来会触发() => void-
onContextMenu鼠标右键会触发(_event, layers: BaseLayer[]) => void-
  • 渲染内核的使用:
import { View } from './core';

const editor = {...};

return (
  <View
    resourceHost="https://cdn.h5ds.com"
    callback={_store => {
      editor.store = _store;
    }}
    env="editor"
    data={pageData}
    target={document.body}
    onContextMenu={(e, layers) => {
      // 显示鼠标右键菜单
      editor.showContextMenu(e.origin, {
        layers,
      });
    }}
    onDragUp={() => {
      // 更新设置区域
      editor.updateOption();
    }}
    onControlSelect={(_e, ids) => {
      // 选中元素
      editor.setSelectedElementIds(ids);
    }}
  />
);
  • 内核 API:

在 callback 回调函数中可以获取到一个store实例,该实例下面存放了很多可以操作画布的方法。API 文档如下:

属性

.data: BasePage

工程数据中的页面数据

.record: RecordParams

操作记录类的实例,内置方法

  • add(n: RecordItem) 添加操作记录
  • debounceAdd(n: RecordItem) 加了防抖函数的记录添加
  • redo() 重做
  • undo() 撤销

.app: ILeafer

Leaferjs 的实例

.editor: IEditorBase

控制器相关业务的实例

.env: ENV

内核当前的运行环境

.resourceHost: string

资源文件的 host 地址

.helper: Object

帮助工具

.utils: Object

小工具方法的集合

方法

.setURL(url: string): string

给 URL 自动添加 resourceHost 配置,比如当前的资源路径是 /assets/img.png,资源实际地址在 cdn 中,这时候我们需要配置
resourceHost 为 cdn 的地址,然后在使用的时候可以调用这个方法得到一个完整的资源路径

const url = '/assets/img.png';

const newURL = store.setURL(url);

// newURL地址为:https://cdn.h5ds.com/assets/img.png;

.getLayerUIByIds(ids: string[]): IUI[]

通过 ID 获取 Leaferjs 的 UI 对象数组

.getLayerByIds(ids: string[]): BaseLayer[]

通过 ID 获取图层的 JSON 数据

.deleteLayers(ids: string[]): void

通过图层 ID 删除图层数据

.groupData(ids: string[]): GroupLayer

将多个图层合并成一个图层,并返回合成后的图层数据

.unGroupData(gid: string): string[]

传入一个组的 id,将该组打散并返回打散后的元素 id

.emitControl(ids: string[]): void

触发指定元素的控制器选中状态,如果传入空数组就会取消所有的控制器

.autoViewSize(): void

根据当前的窗口自动设置画布大小

.setViewSize(scale: number): void;

设置画布的缩放比例

.update(): void

当数据发生变化后,可以调用此方法触发视图的更新

.triggerRotation(elementData: BaseLayer, rotation: number): void

手动设置元素的旋转,解决外部触发旋转不是围绕中心点旋转的问题,旋转元素会导致 x,y 同时发生变化

.capture(params?: IExportOptions): Promise(string);

导出图片

.destroy(): void

销毁实例

数据&视图

数据和画布中的视图做了双向绑定,所以数据改变后只需要调用store.update()就可以触发视图的更新。为什么是手动?有时候我们为
了节约渲染开销,需要做很多数据改动后才会去触发一次 update,所以这里做了类似 react 的 setState,需要我们去手动触发 update
函数来通知视图的更新。

// 修改坐标
layer.x = 100;
layer.y = 200;

// 通知视图更新
store.update();

项目开发

  1. 安装依赖

yarn install

该过程耗时比较长,需要从远程去拉取所需依赖包,安装依赖包成功之后才可以进行接下来的操作。

  1. 进入开发调试模式

yarn dev

项目使用 vite 进行打包和调试,如果需要对项目进行二次开发和修改,可以执行该命令进入开发模式,项目启动成功后浏览器输入
:https://127.0.0.1:3002 进行项目开发和调试。

开发前请注意是否需要修改 vite 的代理配置:


// video-editor/vite.config.ts

server: {
  https: true,
  host: '0.0.0.0',
  port: 3002,
  headers: { // 因为视频编辑器的业务需求,必须加上这两个头信息才可以让ffmpeg在浏览器正常运行
    'Cross-Origin-Opener-Policy': 'same-origin',
    'Cross-Origin-Embedder-Policy': 'credentialless',
  },
  proxy: {
    '/cgi-bin': { // 微信二维码地址代理
      target: 'https://video.h5ds.com',
      changeOrigin: true,
    },
    '/api': { // api地址代理
      target: 'https://video.h5ds.com',
      changeOrigin: true,
    },
    '/fonts': { // 字体包资源的代理地址
      target: 'https://cdn.h5ds.com/assets',
      changeOrigin: true,
    },
    '/video': { // 部分素材的代理地址
      target: 'https://cdn.h5ds.com',
      changeOrigin: true,
    },
  },
},
  1. 打包发布

yarn build

打包成功后会生成 dist 目录,直接部署到服务器即可。具体的部署文档请参考部署说明文档。

  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
EPON_EoC EoC EoC双向网改造导致电视播放异常故障排查.pdf EoC头端无法管理故障排查.pdf EoC终端注册不上故障排查.pdf EoC终端配置下发不生效故障排查.pdf EoC网络PPPoE拨号上网故障排查.pdf EPON EPON网络监控业务不通问题排查.pdf OLT上无法ping通ONU的管理地址故障排.pdf ONU注册类故障排查.pdf ONU长发光故障排查.pdf SMB V5交换机POE问题排查.pdf 网络监控业务不通故障排查.pdf 网络监控业务不通问题排查.pdf iMC管理软件 EAD_iNode APM应用监控故障排查.pdf DAM软件分发故障排查.pdf EAD可控软件管理故障排查.pdf EAD补丁管理故障排查.pdf EAD防病毒软件故障排查.pdf iMC BIMS组件问题分析.pdf iMC双机冷备方案故障排查.pdf WSM资源管理故障排查.pdf 桌面资产管理故障排查.pdf PLAT iMC APM 数据库管理故障排查.pdf iMC Dbman备份故障排查.pdf iMC license故障排查.pdf iMC告警管理故障排查.pdf iMC安装部署故障排查.pdf iMC性能管理故障排查.pdf iMC拓扑管理故障排查.pdf iMC数据库故障排查.pdf iMC设备管理故障排查.pdf iMC页面响应慢故障排查.pdf iMC页面显示乱码故障排查.pdf iNode安装运行故障排查.pdf Portal无感知认证排错.pdf Portal认证页面无法弹出故障排查.pdf WSM射频管理故障排查.pdf WSM无法识别或同步AC故障排查.pdf 备份设备配置文件失败故障排.pdf 拓扑常见问题排查.pdf 访客二维码认证故障排查.pdf 访客基本功能排错.pdf 防内网外连.pdf 防破解故障排查.pdf UAM_iNode 802.1x认证故障排查.pdf EIA之BYOD特性故障排查.pdf LDAP用户管理故障排查.pdf UAM Portal认证故障排查.pdf 证书认证故障排查.pdf UBA_NTA iMC NTAUBA管理NetStream日志故障排查.pdf iMC UBA管理NAT及FLOW日志故障排查.pdf 计算产品 CAS CAS日志下载失败问题排查.pdf cloudos创建主机失败排查.pdf CVK主机存储池暂停失败问题排查.pdf DRX业务扩展异常排查.pdf H3C CAS主机性能缓慢问题排查.pdf H3C CAS计算平台License使用.pdf H3C CAS计算平台虚拟机优化.pdf H3C CAS虚拟机暂停问题排查.pdf H3Cloud OS操作系统新建虚机异常问题排查.pdf 主机Overlay方案新建虚机转发不通故障排查.pdf 学堂学生机无法连接课堂问题排查.pdf 虚拟机启动异常故障排查.pdf 虚拟机手动迁移失败故障排查流程.pdf 虚拟机状态不一致排查.pdf 零存储集群添加节点异常问题排查.pdf 机架服务器 FlexServer R390服务器指示灯告警故障排查.pdf 刀片服务器开机故障排查.pdf 交换技术 AAA Radius故障排查.pdf TACACS故障排查.pdf QoS QoS故障排查.pdf 以太网二层技术 BPDU Tunnel故障排查.pdf QinQ故障排查.pdf Voice Vlan故障排查.pdf 以太口故障排查.pdf 以太网链路聚合故障排查.pdf 可靠性 RRPP故障排查.pdf TRACK故障排查.pdf VRRP故障排查.pdf 堆叠技术 IRF II故障排查.pdf 安全接入 802.1x与EAD故障排查.pdf
提供的源码资源涵盖了安卓应用、小程序、Python应用和Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值