绘画板 02——抽象并实现图形绘制功能

本贴最后更新于 2984 天前,其中的信息可能已经天翻地覆

github 地址: https://github.com/wangyuheng/painter

DEMO 地址: http://painter.crick.wang/

针对上个版本的基础代码进行抽象和封装

将所有的图形绘制工具,都“继承”一个 DrawTool 工具类,在此工具类中绑定、解绑事件,代码如下

(function() {
	var defaultListener = {
		mousedown: function() {
			console.log('mousedown you should implement this function!');
		},
		mousemove: function() {
			console.log('mousemove you should implement this function!');
		},
		mouseup: function() {
			console.log('mouseup   you should implement this function!');
		}
	};
	var DrawTool = {
		init: function(svgDoc, listeners) {
			var l = $.extend({}, defaultListener, listeners);
			svgDoc.on('mousedown', l.mousedown);
			svgDoc.on('mousemove', l.mousemove);
			svgDoc.on('mouseup', l.mouseup);
		},
		stop: function(svgDoc, listeners) {
			var l = $.extend({}, defaultListener, listeners);
			svgDoc.off('mousemove', l.mousemove);
			svgDoc.off('mousedown', l.mousedown);
			svgDoc.off('mouseup', l.mouseup);
		}
	};


	this.DrawTool = DrawTool;
})();

所有 js 独立代码都采用闭包形式,避免的参数污染。 拆分后的目录结构如下

1474421007892

还是以矩形为例,Rect 在构造函数中继承使用了 DrawTool 的 init 方法,并重写 stop 方法,暴露出去。

var Rect = function(parentEle) {
    parent = parentEle;
    svgDoc = parent.doc();
    DrawTool.init(svgDoc, listener);
    this.stop = function () {
        DrawTool.stop(svgDoc, listener);
    };
};

this.DrawTool.Rect = Rect;

通过在 Rect 类内部定义 mousedown、mousemove、mouseup 事件方法,调用 svgjs 提供的绘制方法,实现图形的绘制工作。完整代码如下:

(function() {

	var parent = null;
	var drawing = false;
	var element = null;
	var startPoint = null;

	function mousedown(event) {
		console.log('rect mousedown');
		drawing = true;
		startPoint = svgDoc.transformPoint(event);
		element = parent.rect(0, 0).style("fill-opacity", '0.0').stroke({
			width: '2',
			color: '#000000'
		});
	}

	function mousemove(event) {
		console.log('rect mousemove');
		if (drawing) {
			var svgPoint = svgDoc.transformPoint(event);
			var x = svgPoint.x;
			var y = svgPoint.y;

			var newWidth = x - startPoint.x;
			var newHeight = y - startPoint.y;
			var startX = startPoint.x;
			var startY = startPoint.y;
			if (newWidth < 0) {
				startX += newWidth;
			}

			if (newHeight < 0) {
				startY += newHeight;
			}
			newWidth = Math.abs(newWidth);
			newHeight = Math.abs(newHeight);
			element.x(startX).y(startY).width(newWidth).height(newHeight);
		}
	};

	function mouseup(event) {
		console.log('rect mouseup ' + element);
		drawing = false;
	}

	var listener = {
		mousedown: mousedown,
		mousemove: mousemove,
		mouseup: mouseup,
	};


	var Rect = function(parentEle) {
		parent = parentEle;
		svgDoc = parent.doc();
		DrawTool.init(svgDoc, listener);
		this.stop = function () {
			DrawTool.stop(svgDoc, listener);
		};
	};

	this.DrawTool.Rect = Rect;

})();

有一个特殊的类为折线 polyline 工具类,此图形为连续绘制,需要记录上一个 element,并且在 stop 方法中清空之前的 element,并且监听鼠标右键点击事件,结束图形绘制。
阻止鼠标右键方法为

function mousedown(event) {
    if (event.button == 2) {
        document.oncontextmenu=function(){return false;}
        drawing=false;
        points  = [];
        element = null;
        return;
    }
    if (!drawing) {
        drawing = true;
        var currPoint = svgDoc.transformPoint(event);
        points.push([currPoint.x, currPoint.y]);
    }
}

至此,已完成图形的基本绘制功能

  • 开源

    Open Source, Open Mind, Open Sight, Open Future!

    408 引用 • 3575 回帖 • 1 关注
  • SVG
    24 引用 • 73 回帖
  • Painter
    14 引用 • 31 回帖

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...
  • 88250

    加油,看上去还有很多操作要实现。

    1 回复
  • 其他回帖
  • crick77
    作者

    让 V 大给我做套样式吧

    1 回复
  • crick77
    作者

    一起集思广益啊

  • R

    很赞,加点应用场景的创意就牛掰了。

    1 回复
  • 查看全部回帖

推荐标签 标签

  • 前端

    前端技术一般分为前端设计和前端开发,前端设计可以理解为网站的视觉设计,前端开发则是网站的前台代码实现,包括 HTML、CSS 以及 JavaScript 等。

    247 引用 • 1348 回帖 • 1 关注
  • Notion

    Notion - The all-in-one workspace for your notes, tasks, wikis, and databases.

    6 引用 • 38 回帖
  • iOS

    iOS 是由苹果公司开发的移动操作系统,最早于 2007 年 1 月 9 日的 Macworld 大会上公布这个系统,最初是设计给 iPhone 使用的,后来陆续套用到 iPod touch、iPad 以及 Apple TV 等产品上。iOS 与苹果的 Mac OS X 操作系统一样,属于类 Unix 的商业操作系统。

    85 引用 • 139 回帖
  • NGINX

    NGINX 是一个高性能的 HTTP 和反向代理服务器,也是一个 IMAP/POP3/SMTP 代理服务器。 NGINX 是由 Igor Sysoev 为俄罗斯访问量第二的 Rambler.ru 站点开发的,第一个公开版本 0.1.0 发布于 2004 年 10 月 4 日。

    311 引用 • 546 回帖
  • 开源

    Open Source, Open Mind, Open Sight, Open Future!

    408 引用 • 3575 回帖 • 1 关注
  • flomo

    flomo 是新一代 「卡片笔记」 ,专注在碎片化时代,促进你的记录,帮你积累更多知识资产。

    5 引用 • 107 回帖
  • 友情链接

    确认过眼神后的灵魂连接,站在链在!

    24 引用 • 373 回帖
  • 资讯

    资讯是用户因为及时地获得它并利用它而能够在相对短的时间内给自己带来价值的信息,资讯有时效性和地域性。

    55 引用 • 85 回帖
  • Git

    Git 是 Linux Torvalds 为了帮助管理 Linux 内核开发而开发的一个开放源码的版本控制软件。

    209 引用 • 358 回帖
  • SQLServer

    SQL Server 是由 [微软] 开发和推广的关系数据库管理系统(DBMS),它最初是由 微软、Sybase 和 Ashton-Tate 三家公司共同开发的,并于 1988 年推出了第一个 OS/2 版本。

    21 引用 • 31 回帖 • 1 关注
  • PWA

    PWA(Progressive Web App)是 Google 在 2015 年提出、2016 年 6 月开始推广的项目。它结合了一系列现代 Web 技术,在网页应用中实现和原生应用相近的用户体验。

    14 引用 • 69 回帖 • 155 关注
  • Hexo

    Hexo 是一款快速、简洁且高效的博客框架,使用 Node.js 编写。

    21 引用 • 140 回帖 • 2 关注
  • 30Seconds

    📙 前端知识精选集,包含 HTML、CSS、JavaScript、React、Node、安全等方面,每天仅需 30 秒。

    • 精选常见面试题,帮助您准备下一次面试
    • 精选常见交互,帮助您拥有简洁酷炫的站点
    • 精选有用的 React 片段,帮助你获取最佳实践
    • 精选常见代码集,帮助您提高打码效率
    • 整理前端界的最新资讯,邀您一同探索新世界
    488 引用 • 384 回帖 • 9 关注
  • jQuery

    jQuery 是一套跨浏览器的 JavaScript 库,强化 HTML 与 JavaScript 之间的操作。由 John Resig 在 2006 年 1 月的 BarCamp NYC 上释出第一个版本。全球约有 28% 的网站使用 jQuery,是非常受欢迎的 JavaScript 库。

    63 引用 • 134 回帖 • 722 关注
  • GitLab

    GitLab 是利用 Ruby 一个开源的版本管理系统,实现一个自托管的 Git 项目仓库,可通过 Web 界面操作公开或私有项目。

    46 引用 • 72 回帖 • 1 关注
  • Bootstrap

    Bootstrap 是 Twitter 推出的一个用于前端开发的开源工具包。它由 Twitter 的设计师 Mark Otto 和 Jacob Thornton 合作开发,是一个 CSS / HTML 框架。

    18 引用 • 33 回帖 • 661 关注
  • Swagger

    Swagger 是一款非常流行的 API 开发工具,它遵循 OpenAPI Specification(这是一种通用的、和编程语言无关的 API 描述规范)。Swagger 贯穿整个 API 生命周期,如 API 的设计、编写文档、测试和部署。

    26 引用 • 35 回帖 • 1 关注
  • Tomcat

    Tomcat 最早是由 Sun Microsystems 开发的一个 Servlet 容器,在 1999 年被捐献给 ASF(Apache Software Foundation),隶属于 Jakarta 项目,现在已经独立为一个顶级项目。Tomcat 主要实现了 JavaEE 中的 Servlet、JSP 规范,同时也提供 HTTP 服务,是市场上非常流行的 Java Web 容器。

    162 引用 • 529 回帖
  • CodeMirror
    1 引用 • 2 回帖 • 131 关注
  • RabbitMQ

    RabbitMQ 是一个开源的 AMQP 实现,服务器端用 Erlang 语言编写,支持多种语言客户端,如:Python、Ruby、.NET、Java、C、PHP、ActionScript 等。用于在分布式系统中存储转发消息,在易用性、扩展性、高可用性等方面表现不俗。

    49 引用 • 60 回帖 • 362 关注
  • 深度学习

    深度学习(Deep Learning)是机器学习的分支,是一种试图使用包含复杂结构或由多重非线性变换构成的多个处理层对数据进行高层抽象的算法。

    53 引用 • 40 回帖
  • ReactiveX

    ReactiveX 是一个专注于异步编程与控制可观察数据(或者事件)流的 API。它组合了观察者模式,迭代器模式和函数式编程的优秀思想。

    1 引用 • 2 回帖 • 156 关注
  • Solidity

    Solidity 是一种智能合约高级语言,运行在 [以太坊] 虚拟机(EVM)之上。它的语法接近于 JavaScript,是一种面向对象的语言。

    3 引用 • 18 回帖 • 399 关注
  • Openfire

    Openfire 是开源的、基于可拓展通讯和表示协议 (XMPP)、采用 Java 编程语言开发的实时协作服务器。Openfire 的效率很高,单台服务器可支持上万并发用户。

    6 引用 • 7 回帖 • 95 关注
  • etcd

    etcd 是一个分布式、高可用的 key-value 数据存储,专门用于在分布式系统中保存关键数据。

    5 引用 • 26 回帖 • 530 关注
  • LaTeX

    LaTeX(音译“拉泰赫”)是一种基于 ΤΕΧ 的排版系统,由美国计算机学家莱斯利·兰伯特(Leslie Lamport)在 20 世纪 80 年代初期开发,利用这种格式,即使使用者没有排版和程序设计的知识也可以充分发挥由 TeX 所提供的强大功能,能在几天,甚至几小时内生成很多具有书籍质量的印刷品。对于生成复杂表格和数学公式,这一点表现得尤为突出。因此它非常适用于生成高印刷质量的科技和数学类文档。

    12 引用 • 54 回帖 • 62 关注
  • 数据库

    据说 99% 的性能瓶颈都在数据库。

    342 引用 • 708 回帖