svg 编辑器系列(2)其实在之前已经写过了,但写得不好,所以这次重写一下,顺便也把示例代码重写了。

本文主要讲解一款 svg 编辑器的DOM结构,该如何分层以及这样分层的原因。DOM 结构主要参考了一款名为 svgedit的开源 svg 编辑器。

代码实现

代码用到了 svgjs 库。不过应该还是挺好懂的。

演示链接:f-star.github.io/web-editor-…

源码地址:github.com/F-star/web-…

网页截图:

总览

DOM 结构如下:

svg 编辑器
├── workarea (视口层)└── svgcanvas (挂载层)└── svgRoot (最上层的svg)├── canvasBg (svg背景层)├── svgcontent (绘制层)|   ├── layout1 (图层一)|   ├── layout2 (图层二)|   └── ...├── guideLine (辅助线层)
复制代码

视口层

div#workarea

顾名思义,该层为编辑器的可视范围。当 svgRoot 的高或宽大于该层的宽高时,会显示滚动条。

挂载层

div#svgcanvas

挂载层负责 svg 的挂载。它会保持宽高和 svgRoot 相同。你可能会奇怪这层到底有什么用,直接挂载到适口层不也行吗?没错,直接挂载在视口层也是可行的,但软件设计需要考虑到一些可能会发生的情况。这里我们加上了这层,是考虑到后期我们可能会需要在 svgRoot 的同一层上添加一些 div 元素(毕竟svg中是无法添加 div 元素的),比如说添加一些备忘录。

svgRoot

svg#svgRoot

该元素为 根部svg 元素,它并不是真正绘制 svg 的载体,真正绘制 svg 图形的地方是它的内嵌 svg 元素,即绘制层。我们追加这层根部 svg 的目的,是为了使超出内嵌 svg 范围外的矢量图形,仍然能显示出来(svgRoot 比)。如图所示:

这里给个图片

svg背景层

svg#canvasBg

它负责显示出画布的位置,一般设置为白色。

绘制层

svg#svgcontent

矢量图形真正绘制的地方。导出的 svg 文件内容即是这个元素下的所有内容。注意要设置 overflow="visible"

绘制层的图层

g#layout

类似 PhotoShop,我们引入了“图层”的概念。图层就像叠好的一张张半透明(软件中其实是全透明)的白纸,你可以选择任意一张进行绘画。另外上层的纸的不透明的部分,会挡住它的下层的相同区域的显示。

辅助线层

作为一款编辑器,我们需要一些辅助线,提供一些选中效果以及一些交互。比如点击一个图形,就显示一个包围着它的矩形,我称之为“选中框”,此外这个矩形上有一些控制点,对它们进行拖拽等操作,可以对当前这个矩形进行缩放或者旋转。为了实现这些功能,辅助线是 svg 编辑器十分重要的部分。

但是为什么我们把辅助线层放到 根部svg 下,而不是直接放到绘制层呢?原因是在实现画布“缩放”功能的时候,画布的缩放其实是通过设置 svg#svgcontent 的 viewBox 属性来实现的(后面的svg编辑器系列会详细讲解),这种缩放会导致元素的 stroke-width(线宽)也会跟着变大变小。这样的话,用户体验就很不好了。

放大还好,选中框的线条虽然很大,但被选中的那个元素也好大。当如果是缩小的话,并缩小到很小的时候,就会有一个问题,那就是选中框也变细变小了,这样选中框的一些变形控制点也不好点中了。

辅助线层下的元素一般来说,在编辑器初始化的时候就应该进行创建,并将其设置 style="display: none;"。比如说选中框,选中一个元素时,辅助线层下相关的元素一些属性会被修改(如元素的位置),然后显示出来;取消选中时,则将相关元素全部设置为不可见。我不建议直接删除或添加这些元素,因为这会有性能损失。

初始化

const svgRoot = SVG('svgcanvas').id('svgroot');         // svg root
const canvasBg = svgRoot.nested().id('canvasBg');       // svg 内容的底色,宽高需和 svg content 同步
const svgContent = svgRoot.nested().id('svgcontent');   // svg 的真正内容位置。
const draw = svgContent.group();                        // svgContent 下创建一个 group,作为第一个“图层”(类似ps的图层概念)const guideLine = svgRoot.group().id('guideLine');                      // 放置辅助线的父容器
const selectedBox = guideLine.group().id('selectedBox');     // 选中框相关辅助线
const selectedBoxOutline = selectedBox.polygon()            // 选中框-矩形轮廓.fill('none').stroke({width: 1, color: '#4d84ff'}).hide();// 选中框的 6个 缩放控制点
const scaleGrips = (() => {   ...
})
复制代码

SVG('svgcanvas') 的意思是在 id 为 svgcanvas 的元素下创建一个根部 svg。

// 参数配置
const config = {bgcolor: '#fff',contentW: 517,contentH: 384,
}// 初始化
svgContent.size(config.contentW, config.contentH).move(config.contentW, config.contentH);   // 设置宽高和左上角坐标
canvasBg.size(config.contentW, config.contentH).move(config.contentW, config.contentH);
svgRoot.size(config.contentW * 3, config.contentH * 3);
workarea.scroll( (svgRoot.width() - workarea.w())/2,  (svgRoot.height() - workarea.h())/2 ); // 滚动条拖到中间
canvasBg.rect('100%', '100%').fill(config.bgcolor);   // canvasBg 添加 白色 rect,实现达到填充背景色效果
复制代码

svgcontent(绘制层)的宽为 w,高为 h。则有:

  • svgroot 的宽为 w * 3, 高为 h * 3;
  • canvasbg 的宽为 w,高为 h;
  • workarea 的 scrollLeft 为 (w * 3 - workarea.width) / 2,(w * 3 - workarea.height) / 2。(使画布位于视口层的正中心)

最后我们用代码绘制一个 path,并调用写好的 showSelectedBox() 方法,显示它的选中框。

结尾

这篇文章主要讲述了 svg 编辑器的层次结构(DOM结构)设计和这样设计的原因,并简单讲述了 svg 编辑器初始化时需要做的事情。

下一篇系列文章的内容应该是讲解如何进行工具(如选择工具切换为钢笔工具)的激活和切换,以及如何配合事件响应函数实现其中一个简单的工具功能。

基于Web的svg编辑器(2)——层次结构设计(DOM结构)相关推荐

  1. N个富文本编辑器/基于Web的HTML编辑器

    转自:http://www.cnblogs.com/lingyuan/archive/2010/11/15/1877447.html 基于WEB的HTML 编辑器,WYSIWYG所见即所得的编辑器,或 ...

  2. Tridiv:基于 Web 的 CSS 编辑器,创建炫丽 3D 图形

    Tridiv 是一个基于 Web 的编辑器,使用 CSS 创建 3D 形状.它提供了一个传统的四个面板的操作界面,给出了从每个平面的视图,以及一个预览窗格中示出的最终的效果.使用 Tridiv 可以创 ...

  3. 在线富文本编辑器-基于Web的HTML编辑器大全(一)

    基于WEB的HTML 编辑器,WYSIWYG所见即所得的编辑器,或是一个富文本的编辑器,是我们在开发WEB应用和内容管理系统时接收用户输入时必需要考虑的问题.下面是网上牛人收集的一些开源的WEB在线的 ...

  4. 基于Web的Markdown编辑器HedgeDoc

    什么是 HedgeDoc ? HedgeDoc 是一个开源的.基于 web 的.自托管的.协作的markdown编辑器.您可以使用它轻松地在笔记.图形甚至演示文稿上进行实时协作.用户需要做的就是将你的 ...

  5. 基于excel在线编辑的二次开发_基于Web的免费在线矢量图(SVG)编辑工具:Method-Draw...

    说明:Method Draw是一款基于Web的在线SVG编辑器,是SVG Edit的一个分支.其目的是改进SVG Edit的可用性,并减少其一些功能来提供更好的操作和体验,使用方法也是很多的,本地打开 ...

  6. 基于web的在线复杂公式编辑器的实现

    基于web的在线复杂公式编辑器的实现 直接调用word的公式编辑器,关键是解决web调用word,借用word的公式编辑器,解决在线编辑公式的问题.如何在线使用word是关键所在. 由于能力问题没有解 ...

  7. Firefox Profilemaker 基于Web的浏览器配置编辑器

    相信不少Firefox用户都有自己的浏览器配置习惯,但是在迁移或重装后的重配置过程却是一件费时费力的事情.不过本文介绍的Firefox Profilemaker,则是一款基于Web的浏览器配置编辑工具 ...

  8. Snacktools:一套基于Web应用的富媒体编辑器

    SnackTools 提供了一套基于Web的应用程序设计软件,它能够帮助用户以最简单的方式创建和管理丰富媒体的内容网站. SnackTools 是一套基于Web的应用程序设计软件,它的诞生致力于帮助人 ...

  9. JSP+SQL基于WEB的开放性实验管理系统设计与实现(源代码+论文+开题报告+中英文献+答辩PPT)

    毕 业 设 计(论文)任 务 书 毕 业 设 计(论文)任 务 书 毕业设计(论文)题目 基于WEB的开放性实验管理系统 毕业设计(论文)时间 毕业设计(论文)进行地点 毕业设计(论文)内容及要求:高 ...

  10. 1.0 java_Mybatis_oracle基于WEB的仓库管理系统的设计与实现(源码+数据库sql+论文+视频齐全)----库管理系统---源码在底部

    基于Web的仓库管理系统的设计与实现 摘 要 仓库物品的管理是与我们的日常生活息息相关的一个重大问题.随着我国经济飞速的发展,改革开放的不断深入,企业要想在激烈的市场竞争中立于不败之地,要想继续的发展 ...

最新文章

  1. 翻译:java.util.regex.Pattern
  2. 【Python教程】 正则表达式 re模块中,反斜杠 “\“分割字符串的正确操作方法
  3. java io内存泄露_java内存泄露和OutOfMemory
  4. LinQ高级查询、组合查询
  5. c# 相对路径的一些文献
  6. 自己从零安装hadoop-HA集群
  7. 8006.ros2发布与订阅
  8. SAP BC430 课程中文自学笔记
  9. 天堂2 服务器修改,服务器技术交流_新天堂2-战乱的序幕架设教程_-921根据地_只做有质量的游戏 - Powered by Discuz!...
  10. Betwin实现电脑一分为二
  11. php中的资源是什么意思,PHP 和 COM
  12. 【Java分享客栈】我为什么极力推荐XXL-JOB作为中小厂的分布式任务调度平台
  13. 激活win10企业长期服务版
  14. std::uninitialized_copy::_Unchecked_iterators::_Deprecate
  15. Excel表格公式大全
  16. DfE给学生提供的笔记本电脑感染了恶意软件
  17. 为什么包装类型间的相等判断应该用 equals
  18. IPhone 视图切换的的2种方法
  19. 微生信在线绘制KEGG Pathway通路分类汇总图
  20. asp mysql 查询_ASP基础教程:数据库查询语言(1)

热门文章

  1. VMware下载(官网)
  2. kali win10双系统_小米win10+kali 双系统
  3. 中标麒麟linux系统微信安装,Linux安装wine微信安装和遇到的问题及解决方法
  4. 新浪通行证在线申诉找回密码业务逻辑错误导致严重安全漏洞
  5. 网站通行证的交互设计分析
  6. Slickedit 打开Qt工程
  7. 兄弟打印机内存已满清零方法_兄弟打印机清零大全
  8. HTML CSS 个人网页设计 WEB前端大作业代码
  9. 简明python教程gitbook_简明Python教程 Byte of Python
  10. 显示器屏幕尺寸及分辨率