我有以下 SVG 元素:
<svg
viewBox="0 0 1000 1000"
xmlns="http://www.w3.org/2000/svg"
version="1.1"
aria-label="The Moon"
role="img"
unselectable="on"
tabindex="-1"
draggable="false"
class="absolute -z-10 top-full right-full"
data-phase="0.9033397192448547"
data-age="26.676153687326483"
>
<path d="m500,0 a10,10 0 1,1 0,1000 a10,10 0 1,1 0,-1000" fill="rgba(255, 255, 255)"></path>
<path d="m500,0 a10,10 0 1,1 0,1000 a10,10 0 1,1 0,-1000" fill="rgba(31, 41, 55, 0.60)"></path>
<path d="m500,0 a 6.133588769794187,10 0 1, 0 0,1000 a10,10 0 1, 1 0,-1000" fill="#fff"></path>
</svg>
但是,我想知道……可以使用以下方法繪制這些路徑:
ctx.beginPath()
const p = new Path2D(
`m${radius},0 a 6.133588769794187,10 0 1, 0 0,${radius * 2} a10,10 0 1, 1 0,${radius * -2}`
)
p.moveTo(x - radius / 2, y - radius / 2)
ctx.stroke(p)
ctx.fill(p)
ctx.closePath()
但是,它似乎不想在我指定的位置 [x,y] 處繪制路徑,它只是將其放置在畫布的左上角...
我似乎無法參考如何在某個 x 和 y 坐標處放置 2D 路徑......
我也試過這個,但結果同樣令人沮喪:
ctx.strokeStyle = '#fff'
ctx.lineWidth = 1
ctx.fillStyle = '#fff'
const p = new Path2D()
p.moveTo(x - radius / 2, y - radius / 2)
p.addPath(
new Path2D(
`m${radius},0 a 6.133588769794187,10 0 1, 0 0,${radius * 2} a10,10 0 1, 1 0,${radius * -2}`
)
)
ctx.stroke(p)
ctx.fill(p)
ctx.closePath()
任何指路燈都會很棒!
uj5u.com熱心網友回復:
您的路徑宣告的相關命令不會像您在這里預期的那樣作業。
它們將在創建內部 Path2D 時被決議,該內部 Path2D 還沒有終點,因此它們都將相對于初始0,0點。
一旦創建了這個內部 Path2D,宣告使用相對方法的事實將丟失,所有這些點都在內部轉換為絕對坐標。因此,您將呼叫的最終 Path2D 的最后一點addPath(path)無關緊要。
要做你想做的事情,你有幾個解決方案:
- 您可以
Mx,y在路徑宣告前加上 a :
const canvas = document.querySelector("canvas");
const ctx = canvas.getContext("2d");
ctx.strokeStyle = '#fff'
ctx.lineWidth = 1
ctx.fillStyle = '#fff'
const radius = 50;
const x = 150;
const y = 70;
const p = new Path2D(`M${x - radius / 2},${y - radius / 2}m${radius},0 a 6.133588769794187,10 0 1, 0 0,${radius * 2} a10,10 0 1, 1 0,${radius * -2}`);
ctx.stroke(p)
ctx.fill(p)
body { background: #333; }
<canvas></canvas>
盡管這樣做,您甚至可以洗掉以下內容m并將其合并到M計算中:
顯示代碼片段
const canvas = document.querySelector("canvas");
const ctx = canvas.getContext("2d");
ctx.strokeStyle = '#fff'
ctx.lineWidth = 1
ctx.fillStyle = '#fff'
const radius = 50;
const x = 150;
const y = 70;
const p = new Path2D(`M${x - radius / 2 radius},${y - radius / 2}a 6.133588769794187,10 0 1, 0 0,${radius * 2} a10,10 0 1, 1 0,${radius * -2}`);
ctx.stroke(p)
ctx.fill(p)
body { background: #333; }
<canvas></canvas>
或者您可以使用背景關系變換矩陣 (CTM) 移動實際繪制路徑的位置:
const canvas = document.querySelector("canvas");
const ctx = canvas.getContext("2d");
ctx.strokeStyle = '#fff'
ctx.lineWidth = 1
ctx.fillStyle = '#fff'
const radius = 50;
const x = 150;
const y = 70;
const p = new Path2D(`m${radius},0 a 6.133588769794187,10 0 1, 0 0,${radius * 2} a10,10 0 1, 1 0,${radius * -2}`);
// set x, y through CTM
ctx.translate(x - radius / 2, y - radius / 2);
ctx.stroke(p)
ctx.fill(p)
// reset CTM to defaults
ctx.setTransform(1, 0, 0, 1, 0, 0);
body { background: #333; }
<canvas></canvas>
或者你可以使用matrix引數Path2D.addPath(path, matrix)直接翻譯路徑:
const canvas = document.querySelector("canvas");
const ctx = canvas.getContext("2d");
ctx.strokeStyle = '#fff'
ctx.lineWidth = 1
ctx.fillStyle = '#fff'
const radius = 50;
const x = 150;
const y = 70;
const p1 = new Path2D(`m${radius},0 a 6.133588769794187,10 0 1, 0 0,${radius * 2} a10,10 0 1, 1 0,${radius * -2}`);
const p = new Path2D();
const matrix = { e: x - radius / 2 , f: y - radius / 2 };
p.addPath(p1, matrix);
ctx.stroke(p);
ctx.fill(p);
body { background: #333; }
<canvas></canvas>
這些解決方案中的每一個都有自己的優點,第一個可能更容易閱讀,CTM 最適合您想每幀更改 Path2D 的位置,最后一個最適合您需要填充 Path2D帶有圖案或漸變(也會受到 CTM 的影響)。
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/375861.html
標籤:javascript svg 帆布 html5-canvas
上一篇:jQuery影片背景影像為選單懸停狀態和選單活動狀態
下一篇:在SVG中旋轉和移動文本元素
