svg圖示:

一組變換(透視、旋轉、縮放和平移)應用于父元素(svgPlan):
svg.style('transform', 'perspective(30em) rotateX(33deg) scale(1.7) translate(0%, -6%)');
svgPlan 改造后:

我想在svgPlan中顯示svgIcon。
問題:轉換同時應用于父元素svgPlan和子元素svgIcon。似乎孩子會自動繼承應用于父母的樣式,這不是我想要的。我希望圖示看起來沒有任何效果。

問題:如何從父親的樣式中繼承我的子元素(我認為目前在 SVG 上是不可能的),或者應用逆變換使圖示出現沒有任何透視或樣式?

最小的可復制示例:
<div>
<svg id="svgPlan" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 2118.5 624.2" enable-background="new 0 0 2118.5 624.2" xml:space="preserve"
style="transform:perspective(30em) rotateX(30deg) scale(1.17)">
<rect width="1200" height="400" style="fill:rgb(224,224,224);stroke-width:3;stroke:rgb(0,0,0)" />
<g id="svgIcon">
<image x="550" y="120" width="120" height="120" xlink:href="https://svgshare.com/i/npz.svg">
</image>
</g>
</svg>
</div>
謝謝您的幫助。
uj5u.com熱心網友回復:
這個答案提出了與 SVG 不太相關的解決方案,而是使用更通用的方法,其中來自 CSS 的透視變換專門應用于 HTML 元素 - 其中一些可能是或可能包含 SVG 影像。
首先是一些瑣事:
- SVG 沒有第三維(“z 軸”),因此在那里不可能進行維度變換或透視。(它甚至沒有
z-index,層只是表示源順序。)SVG本質上只是二維矢量圖形。 - SVG 將許多 CSS 樣式屬性映射到它的表示屬性,但是由于沒有
rotate3d,translate3d也沒有rotatex()SVG,所以它們沒有效果。 - HTML 中的 CSS 有這些。
- 在您的代碼段中,您將 CSS 轉換應用于 HTML 節點,該節點根據定義只是一個平面矩形,就像頁面中的所有內容一樣。在您的情況下,該節點是一個 SVG 元素,但它可能是
<div>帶有背景影像或只是 HTML<img>- 在所有情況下,這些只是在無限(可能已轉換)平面內顯示(SVG)內容的“視口”矩形。 - 所以你不能“從中彈出一些東西”;您只能操作由 HTML 元素構成的“平面”。
據我了解,您的用例是在一些傾斜的影像(如“地圖”)上方顯示標記圖示,如“精靈”(始終面向相機)。從您的問題中不清楚遠處的圖示(那些離相機更遠的)是否應該更小并與更近的圖示重疊(感覺更自然,但與“不繼承”的立場相矛盾)還是每個大小相同,具有未定義的重疊策略(什么符合你的配方)。讓我們假設前者。
在“HTML”世界中,您可以嵌套轉換的元素并讓孩子與父母一起移動(在 的幫助下transform-style: preserve-3d;)以將它們帶到所需的位置,然后將否定的轉換應用于他們的孩子以使這些再次面向相機。
讓我們從基線純 SVG 平面影像開始 - 帶有兩個“標記”的“地圖”概述,沒有轉換:
<svg xmlns='http://www.w3.org/2000/svg' viewBox="0 0 800 400"
stroke-width="10" stroke="black" fill="none">
<g transform="translate(100 100)">
<rect width="500" height="200" fill="silver"></rect>
<path d="M 0 200 L 250 100 L 310 30 L 500 200" stroke="white"></path>
<g transform="translate(250 100)">
<circle r="20" fill="darkturquoise"></circle>
<image width="80" height="100" transform="translate(-40 -100)" preserveAspectRatio="none" href="data:image/svg xml;charset=utf-8,"
></image>
</g>
<g transform="translate(310 30)">
<circle r="20" fill="red"></circle>
<image width="80" height="100" transform="translate(-40 -100)" preserveAspectRatio="none" href="data:image/svg xml;charset=utf-8,"
></image>
</g>
</g>
</svg>
(我已將影像圖示提取為簡化的 dataURI,并將定位更改為組轉換,以獲得更好的可重用性和獨立性。)

現在讓我們介紹坡度和圖示“精靈”。
- SVG 現在沒有圖示,圖示是分開的
<img>。 - 每個都
<img>被定位并轉換到地圖上的相應位置。此處的自定義屬性有助于可重用性,但靜態值也可以硬編碼。 - 自定義屬性
--slope并calc簡化“自動化”并允許從范圍輸入啟動更改。
.scene {
position: fixed;
width: 500px;
height: 200px;
margin: 50px 10px;
transform-origin: center center;
transform-style: preserve-3d; /* this is important */
--rotx-positive: calc( var(--slope, 30) * 1deg );
--rotx-negative: calc( var(--rotx-positive) * -1 );
transform:
perspective(5em)
/* slope: */
rotateX(var(--rotx-positive));
}
img {
position: absolute;
top: calc(1px * var(--y));
left: calc(1px * var(--x));
transform:
/* to have the bottom center peak touching the POI: */
translate(-50%, -100%)
/* negate the slope: */
rotatex( var(--rotx-negative) );
transform-origin: bottom center;
}
Slope:
<input type="range" value="30" min="0" max="90" value="0"
oninput="s.style.setProperty('--slope', this.value);o.value=this.value">
<output id="o">30</output>°.
<div class="scene" id="s">
<svg xmlns='http://www.w3.org/2000/svg' viewBox="0 0 500 200"
stroke-width="10" stroke="black" fill="none">
<rect width="500" height="200" fill="silver"></rect>
<path d="M 0 200 L 250 100 L 310 30 L 500 200" stroke="white"></path>
<g transform="translate(250 100)">
<circle r="20" fill="darkturquoise"></circle>
</g>
<g transform="translate(310 30)">
<circle r="20" fill="red"></circle>
</g>
</svg>
<img style="--x: 250; --y: 100;" width="80" height="100" src="data:image/svg xml;charset=utf-8,">
<img style="--x: 310; --y: 30;" width="80" height="100" src="data:image/svg xml;charset=utf-8,">
</div>
應該呈現如下內容:

對于單個 3D 變換,這適合;對于多個同時進行的轉換,應該涉及更多的數學運算或更多的嵌套包裝器進行轉換。請參閱使用此技術在筆中的 3d 空間中生成類似精靈的“點”的嵌套變換層的示例。
uj5u.com熱心網友回復:
當您使用 HTML 來應用透視、旋轉等時,您應該使用 HTML 和 javascript 來放置您的圖示。此外,您似乎希望保持圖示的大小獨立于它們在矩形上的放置位置。
您可以通過從 svgPlan 中洗掉它們來簡單地“取消繼承”它們的行為,計算它們的位置并使用 HTML/Javascript 放置它們。因此,您可以完全控制正在發生的事情。
<!DOCTYPE html>
<div style="position:relative; with:auto; height:auto;">
<div style="position:absolute; width:100%; height:100%;">
<svg
id="svgPlan"
x="0px" y="0px" viewBox="0 0 2118.5 624.2" enable-background="new 0 0 2118.5 624.2" xml:space="preserve"
style="transform:perspective(30em) rotateX(30deg) scale(1.17)"
>
<rect width="1200" height="400" style="fill:rgb(224,224,224);stroke-width:3;stroke:rgb(0,0,0)" />
</svg>
</div>
<div style="position:absolute; width:100%; height:100%;">
<svg
id="svgIcon"
x="0px" y="0px" viewBox="0 0 2118.5 624.2" enable-background="new 0 0 2118.5 624.2" xml:space="preserve"
>
<image x="550" y="120" width="120" height="120" xlink:href="https://svgshare.com/i/npz.svg"></image>
</svg>
</div>
</div>
uj5u.com熱心網友回復:
可以通過取消rotateX讓圖示(放置在單獨的疊加 svg 上)面向viewpoint同一透視投影下的圖示來獲得該圖片。
例如:
<div>
<svg id="svgPlan" xmlns="http://www.w3.org/2000/svg" version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" x="0px" y="0px" viewBox="0 0 2118.5 624.2" enable-background="new 0 0 2118.5 624.2" preserveAspectRatio="none" style="position: absolute; transform: perspective(30em) rotateX(30deg) scale(1.17) scaleZ(1.17);">
<rect width="1200" height="400" style="fill:rgb(224,224,224);stroke-width:3;stroke:rgb(0,0,0)" />
<rect width="610" height="160" y="240" fill="none" stroke="blue"/>
</svg>
<svg id="svgIcon" xmlns="http://www.w3.org/2000/svg" version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" viewBox="0 0 2118.5 624.2" preserveAspectRatio="none"
style="position: absolute;
transform: perspective(30em) rotateX(30deg) scale3d(1.17, 1.17, 1.17)
translate3d(calc(100% * 610 / 2118.5 - 50%), calc(100% * 240 / 624.2 - 50%), 0)
rotateX(-30deg)
translate3d(calc(-100% * 610 / 2118.5 50%), calc(-100% * 240 / 624.2 50%),0)">
<image x="550" y="120" width="120" height="120" xlink:href="https://i.stack.imgur.com/KZVZ0.png" preserveAspectRatio="xMidYMin slice"></image>
</svg>
</div>
但是,由于透視投影對圖示的縮放效果仍然存在。
應用于圖示的變換的簡要說明
perspective(30em) rotateX(30deg) scale3d(1.17, 1.17, 1.17):應用于的變換副本svgPlantranslate3d(calc(100% * 610 / 2118.5 - 50%), calc(100% * 240 / 624.2 - 50%), 0): 從 css transform-origin(50%, 50%) 翻譯回原來的位置(610,240)rotateX(-30deg): 變換取消旋轉translate3d(calc(-100% * 610 / 2118.5 50%), calc(-100% * 240 / 624.2 50%),0): 從圖示底部中心(610, 240) 轉換為 css transform-origin(50%, 50%)
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/529263.html
上一篇:畫布的正確漸變
