软件项目技术点(4)——实现点击画布上元素

时间:2022-08-22 14:44:54

元素和影子

我们在主画布上绘制所有添加到画布上的元素,主画布上的所有元素存储在commonElements中。

在hitCanvas上,对应每一个元素commonElement都有一个对应的hitElement元素,这些元素存储在另外一个集合hitElements中。每一个hitElement元素对应的是我们在另外一个hitCanvas画布上绘制的各色矩形,并且每个矩形用的颜色rgb值都是不一样的(创建元素时随机生成的颜色值)。

commonElements和hitElements这两个集合都是哈希表,hashtable的键值均为一个六位的rgb颜色值。

当我们的鼠标在画布上点击时,点到的元素呈现编辑状态,但是怎么计算得到具体点击到哪个元素上呢?这个rgb值是最关键的。

下面是展示的一个作品中commonElements和hitElements的所有元素:

软件项目技术点(4)——实现点击画布上元素软件项目技术点(4)——实现点击画布上元素

主画布canvas的元素绘制如下: 

软件项目技术点(4)——实现点击画布上元素

hitCanvas上每个元素的矩形如下图,

软件项目技术点(4)——实现点击画布上元素

生成随机色值

我们生成随机色值的方法如下:

 1 public getUniqueColorKey() {
2 var key, elements = this.commonElements;
3 while (true) {
4 key = Common.Util.getRandomColor();//方法如下
5 if (key && !(elements.has(key))) {//判断生成的key是否已经使用
6 break;
7 }
8 }
9 return key;
10 }
11
12 //另一个文件中的getRandomColor
13 public static getRandomColor() {
14 var randColor = (Math.random() * 0xFFFFFF << 0).toString(16);
15 while (randColor.length < 6) {
16 randColor = "0" + randColor;
17 }
18 return "#" + randColor;
19 }

getRandomColor生成随机颜色的方法参见 http://www.neatstudio.com/archives/?article-1008.html

软件项目技术点(4)——实现点击画布上元素

getImageData获取像素点数据

当鼠标点击到canvas画布上时,通过hitCanvas上的鼠标点坐标获取到该点的data

editor.canvas.canvasImp.getActiveElement(mouseInfo, editor.hitCanvas.context);//获取点击的元素
 1         public getActiveElement(e, cxt) {
2 var p = cxt.getImageData(e.mouseX, e.mouseY, 1, 1).data;
3 if (p[3] == 255) {
4 // fully opaque pixel
5 var colorKey = "#" + Common.Util.rgbToHex(p[0], p[1], p[2]);
6 var activeEle = this.commonElements.get(colorKey);
7 return activeEle;
8 }
9 return null;
10 }

getImageData() 方法返回 ImageData 对象,该对象拷贝了画布指定矩形的像素数据。

对于 ImageData 对象中的每个像素,都存在着四方面的信息,即 RGBA 值:

  • R - 红色 (0-255)
  • G - 绿色 (0-255)
  • B - 蓝色 (0-255)
  • A - alpha 通道 (0-255; 0 是透明的,255 是完全可见的)

color/alpha 以数组形式存在,并存储于 ImageData 对象的 data 属性中。

如取画布点(500,300),该点对应上面hitCanvas图中黄色块的某一点坐标,得到的ImageData如下

软件项目技术点(4)——实现点击画布上元素