绘画板 06——铅笔与自定义鼠标图标

本贴最后更新于 2980 天前,其中的信息可能已经时移世异

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

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

自定义鼠标图标

可以通过 css 设置 cursor 的方式指定鼠标图标样式

| default | 默认光标(通常是一个箭头) |
| auto | 默认。浏览器设置的光标。 |
| crosshair | 光标呈现为十字线。 |
| pointer | 光标呈现为指示链接的指针(一只手) |
| move | 此光标指示某对象可被移动。 |
| e-resize | 此光标指示矩形框的边缘可被向右(东)移动。 |
| ne-resize | 此光标指示矩形框的边缘可被向上及向右移动(北/东)。 |
| nw-resize | 此光标指示矩形框的边缘可被向上及向左移动(北/西)。 |
| n-resize | 此光标指示矩形框的边缘可被向上(北)移动。 |
| se-resize | 此光标指示矩形框的边缘可被向下及向右移动(南/东)。 |
| sw-resize | 此光标指示矩形框的边缘可被向下及向左移动(南/西)。 |
| s-resize | 此光标指示矩形框的边缘可被向下移动(南)。 |
| w-resize | 此光标指示矩形框的边缘可被向左移动(西)。 |
| text | 此光标指示文本。 |
| wait | 此光标指示程序正忙(通常是一只表或沙漏)。 |
| help | 此光标指示可用的帮助(通常是一个问号或一个气球)。 |

也可以通过 url 指定自定义的图标样式,通常为.cur 文件。

$("#svgPanel").css("cursor", "url(style/img/cur/tool_pencil.cur), auto");

auto 为指定图标不存在时,鼠标显示的样式。

铅笔

通过 svg 的 path 属性,可以绘制出鼠标移动轨迹,实现铅笔画图效果。svgjs 提供了 path()函数,值为

  • M = moveto
  • L = lineto
  • H = horizontal lineto
  • V = vertical lineto
  • C = curveto
  • S = smooth curveto
  • Q = quadratic Belzier curve
  • T = smooth quadratic Belzier curveto
  • A = elliptical Arc
  • Z = closepath

所以 mousedown 时做 M+ 坐标点,mousemove 时,为 L+ 坐标点,可以指定不同的路径数据以达到不同的绘制效果,所以在构造函数中增加了一个 prefix 字段。

pencil.js 代码如下

(function() {

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

	var plot = null;
	var plotPrefix = null;
	var defaultPlotPrefix = 'L';

	function mousedown(event) {
		console.log('pencil mousedown');
		drawing = true;
		startPoint = svgDoc.transformPoint(event);
		plot = 'M' + startPoint.x + ' ' + startPoint.y;
		element = parent.path(plot).fill(GlobalStatus.getFillColor()).style("fill-opacity", GlobalStatus.getFillOpacity()).stroke({
			width: GlobalStatus.getLineSize(),
			color: GlobalStatus.getFontColor()
		});
		return false;
	}

	function mousemove(event) {
		console.log('pencil mousemove');
		if (drawing) {
			var startPoint = svgDoc.transformPoint(event);
			console.log(plot);
			plot += plotPrefix + startPoint.x + ' ' + startPoint.y;
			element.plot(plot);
		}
		return false;
	};

	function mouseup(event) {
		console.log('pencil mouseup ' + element);
		drawing = false;
		if (element.attr("d").split(plotPrefix).length > 2) {
			element.pickable();
		}
		return false;
	}

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


	var Pencil = function(parentEle, prefix) {
		parent = parentEle;
		svgDoc = parent.doc();
		DrawTool.init(svgDoc, listener);
		plotPrefix = prefix || defaultPlotPrefix;
		this.stop = function() {
			DrawTool.stop(svgDoc, listener);
		};
	};

	this.DrawTool.Pencil = Pencil;

})();

在首页监听铅笔的点击事件,并在页面加载完成后默认调用 $("#tool_pencil").click();

    $("#tool_pencil").on("click", function() {
        resetCurrentDrawTool();
        currentDrawTool = new DrawTool.Pencil(svgDoc);
        $("#svgPanel").css("cursor", "url(style/img/cur/tool_pencil.cur), auto");
    });
	

加了一个彩蛋,监听铅笔按钮的双击事件,可以绘制映射线。

    $("#tool_pencil").on("dblclick", function() {
        resetCurrentDrawTool();
        currentDrawTool = new DrawTool.Pencil(svgDoc, 'T');
        $("#svgPanel").css("cursor", "url(style/img/cur/tool_pencil.cur), auto");
    });

在 Tools 的 listener 方法中,都加了一个 return false; 避免事件向上传递。

在模拟的下拉列表 lizeSize 中,通过属性 data-line-size 记录 width 值,在 GlobalStatus.getLineSize()中调用。

将已选择元素抽象到在 GlobalStatus 中,并提供管理方法。

pickedElementList: [],
pushPicked: function(o){
	return this.pickedElementList.push(o);
},
removePicked: function(o) {
	return this.pickedElementList.remove(o);
},
getPickeds: function(){
	return this.pickedElementList;
}
  • 开源

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

    408 引用 • 3574 回帖
  • SVG
    24 引用 • 73 回帖
  • Painter
    14 引用 • 31 回帖

相关帖子

欢迎来到这里!

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

注册 关于
请输入回帖内容 ...
  • crick77
    作者

    @Vanessa V 大有没有漂亮的 .cur 赏几个啊。。。

    1 回复
  • 没有呀。才科普了一下啥是 cur

    1 回复
  • crick77
    作者

    看来这种技术 out 了 我得看看有没有新的了。。。。