我document.elementFromPoint用來確定某個點的 svg 形狀是什么。當我注意到我為相同的輸入獲得不同的輸出時,我正在elementFromPoint對這張
這正是我為重現性所做的。
- 我從鏈接的 svg 中剪切并粘貼了 svg 標記,并將其插入到 html 檔案的正文中。html 檔案是使用單個 ! vscode 中的 emmet 快捷方式。身體里沒有別的東西。唯一的 CSS 是
body{margin:0;}. - 在 chrome 中,我四處打電話
elementFromPoint。大部分在 0.25,50,但有時只是稍微向右或向左一點。有時會一遍又一遍地用相同的引數呼叫,看看它是否會改變。 - 在此期間沒有進行滾動。甚至沒有選項,因為沒有滾動條。
我的問題是為什么會發生這種情況?它有規律嗎?有沒有辦法防止它?謝謝。
uj5u.com熱心網友回復:
雖然我不能告訴你為什么會發生這種情況,或者如何防止這種情況發生,但“模式”,或者讓我們更好地說,可以縮小不一致行為的原因。
讓我們看看呼叫回傳的路徑elementFromPoint。其中有兩個,如果省略 id 和類,即使考慮到它們的父元素,它們看起來也一樣:
<g transform="translate(-1.775,-1.575)">
<path d="M 1.9,551.3 V 1.7 H 1102 V 551.3 H 2.3" />
</g>
如果您重寫路徑以便transform決議,您將在(瀏覽器)視口坐標中獲得路徑 - 為清楚起見,我已將VandH命令重寫為L:
<path d="M 0.125,549.725 L 0.125,0.125 L 1100.125,0.125 L 1100.125,549.725 L 0.525,549.725" />
SVG 包含一個樣式表,用于描述這些元素的填充和描邊。這是相關的摘錄:
.seabase {
fill: #C6ECFF;
stroke: none;
}
.mapborder {
fill: none;
stroke: #0978AB;
}
path, circle {
stroke-width: 0.25;
}
那么應該從什么回傳document.elementFromPoint(0.25,50)呢?在給定坐標處找到的最頂層元素,前提是該pointer-events屬性允許該元素成為命中測驗的目標。
pointer-events沒有為元素明確設定,因此應用默認值visiblePainted。這意味著(至少部分)不透明的填充或描邊都可以被擊中。
兩個候選者的底部元素<path />, 有一個可見的填充,但沒有邊框。點(0.25,50)在該填充內。
兩個候選元素的最頂部元素<path />沒有填充,但有一個寬度為 0.25 的可見邊框,一半延伸到路徑輪廓的內側,一半延伸到路徑輪廓的外側。在左側,有一個垂直子路徑M 0.125,549.725 L 0.125,0.125。不涉及角落的細節,筆畫可以等效地繪制為具有定義的填充路徑
M 0,549.725 L 0,0.125 L 0.25,0.125 L 0.25,549.725 Z
換句話說,該點(0.25,50)正好在筆畫的輪廓上。規范對后果非常清楚:
形狀的零寬度幾何輪廓??包含在要繪制的區域中。
該點應該擊中mapborder元素,因為該點是其可見的繪制筆劃的一部分。如果正如您所描述的,瀏覽器有時會回傳該seabase元素,則它是錯誤的。
I could go on and speculate about the reasons for this behavior, but that is moot, I think.
Can you prevent it? Only if you would be able to consistently avoid the exact outline of all paths, or if they have a stroke, the outline of that stroke. That's hardly practical, since you would have to find out if the browser missed something it should have hit, while you don't know what was missed.
Finally, there is a second interface that can be used. It is part of the SVG specification, while elementFromPoint is part of the CSSOM spec. Whether that makes a difference in the browser implementation, I cannot say.
document.querySelector('.seabase').isPointInFill(new DOMPoint(2.025,48.425));
document.querySelector('.mapborder').isPointInStroke(new DOMPoint(2.025,48.425));
請注意,您需要提供一個要測驗的元素,您無法獲得哪個元素在頂部的資訊,并且坐標在本地用戶空間中表示(transform應用之前)。
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/421881.html
標籤:
上一篇:以編程方式減去SVG路徑
