2010-02-01 108 views
22

已經實現了SVG規範(Firefox等)的瀏覽器爲我們免費提供了命中測試 - 如果我在SVG對象上附加了mousedown偵聽器,每當點擊形狀時我都會收到通知。這是驚人的,特別是對於複雜的多邊形形狀。命中測試SVG形狀?

我想知道是否有一種方法可以利用這個功能進行更多的命中測試。我想知道給定的矩形是否與我的任何SVG形狀相交。

例如,我爲我的元素添加了3個複雜的多邊形。現在我想知道矩形(40,40,100,100)是否與其中的任何一個相交。有沒有人有一個想法,我怎麼可能鉤住已有的偉大的測試支持,而不是自己添加所有的代碼?

謝謝

回答

13

我不知道任何交叉整個矩形的方式。但是你可以交叉點,所以你可以建立一個更復雜的檢查出來的是:

var el= document.elementFromPoint(x, y); 

將使你在一個特定的相對頁面統籌疊最高的元素。如果SVG內沒有形狀命中,您將獲得<svg>元素。

這是一個非標準Mozilla extension,但它也適用於WebKit。不幸的是,雖然它存在於Opera中,但它不會看到<svg>,因此在該瀏覽器中,該元素將始終是SVGSVGElement。

+2

感謝您指出您的解決方案當時不是標準配置。它仍然是一個工作草案,但幸運的是,這個方法已經成爲CSSOM規範(非常方便!):http://dev.w3.org/csswg/cssom-view/#dom-document-elementfrompoint – natevw 2011-12-02 20:26:58

+0

很多很多,感謝這個... – Sudarshan 2013-09-24 10:19:50

+0

elementFromPoint()中使用的座標是絕對的,因此除非您的SVG從0,0開始,否則您需要在絕對座標和相對座標之間進行調整 – 2014-10-28 19:07:01

21

的SVG 1.1 DOM有着恰到好處的方法(遺憾的是它沒有在Mozilla中實現):

var nodelist = svgroot.getIntersectionList(hitrect, null); 

對於一個完整的工作示例見here

+0

太棒了!所以在我們之間我們有了所有的主要瀏覽器。那麼除了*那個*,顯然...... – bobince 2010-02-02 12:02:38

+0

好吧,所以我們只需等待webkit中的這個實現,然後safari和chrome就需要發佈針對這些更改構建的新版本。 – user246114 2010-02-05 15:54:09

+1

博客文章消失了。 – 2014-05-13 19:41:07

0

getIntersectionList在Opera中正常工作。我的問題是,SVG 1.1 Full規範中有關這個功能的函數要求必須渲染元素(以及指針事件的可能目標)才能被檢測爲點擊。不幸的是,這使得這些功能在世界上只有部分地區目前可見的遊戲世界中進行命中測試時毫無用處。

+2

「不透明度:0」或「可見度:隱藏」仍然意味着所討論的元素根據svg呈現,但元素將不可見。你應該能夠調整'pointer-events'來適應這些不可見的元素。 – 2012-12-11 17:19:04

0

Chrome的checkIntersection(和getIntersectionList)版本測試元素邊界框,而不是元素本身。我能夠編寫自己的checkIntersection,它使用了一個畫布,它對於小矩形很適用,對於大矩形很慢,所以對於測試來說很不錯。這項技術將在Chrome中用作checkIntersection的polyfill,用於小型矩形和其他可能會破壞checkIntersection實現的瀏覽器。

  1. 創建使用包含您的SVG的outerHTML(您可能需要在它的樣式規則以及),像so數據URI(此圖像不必須是在頁面)的圖像。如果需要,可以使用onload事件處理程序來確定何時加載它。
  2. 創建一個帆布使用您的點擊測試矩形(這畫布並不需要在頁面)

爲了測試一個矩形與您的任何形狀的相交,這樣做:

  1. 確保畫布的大小與您的矩形相同(設置它的寬度和高度)
  2. 清除使用畫布背景clearRect()方法
  3. 畫在畫布上的SVG在-x畫布,所以-y那部分與畫布重疊的圖像對應於要使用的區域drawImage()
  4. 使用上下文的getImageData()獲取畫布的ImageData。數據數組的每個第四個元素都是字母字節,非零值表示SVG的一部分與矩形重疊。如果所有的第4個字節都是0,那麼你的SVG不會與矩形相交。