[英]canvas js fill an arc with image
我正在嘗試用圖像填充圓(弧)。
這是我的代碼:
draw() {
ctx.save();
let boulePat = new Image();
switch(this.couleur) {
case "red":
boulePat.src = "images/red.png";
break;
case "green":
boulePat.src = "images/green.png";
break;
case "orange":
boulePat.src = "images/orange.png";
break;
case "yellow":
boulePat.src = "images/yellow.png";
break;
case "purple":
boulePat.src = "images/purple.png";
break;
}
var pattern = ctx.createPattern(boulePat, "repeat");
ctx.beginPath();
ctx.arc(this.x, this.y, 15, 0, 2 * Math.PI);
ctx.fillStyle = pattern;
ctx.fill();
ctx.restore();
}
有了這個,我有空的或黑色的圓圈......
請問你能幫幫我嗎 ? 非常感謝。
您必須等待圖像加載,然后才能在createPattern
使用它,如下所示:
看到這個堆棧答案
請記住,圖像將從相對於畫布的0,0
坐標開始。 如有必要ctx.transform(xOffset, yOffset)
您需要將其計入任何偏移量(使用ctx.transform(xOffset, yOffset)
)。
var canvas = document.getElementById("myCanvasNoTranslate"); var canvas2 = document.getElementById("myCanvasWithTranslate"); function drawCanvas(_canvas) { var context = _canvas.getContext("2d"); draw(context); } function draw(ctx) { ctx.save(); ctx.strokeSyle = "rgb(0, 0, 0)"; ctx.lineWidth = 3; ctx.strokeRect(0, 0, 400, 200); let boulePat = new Image(); boulePat.src = "https://upload.wikimedia.org/wikipedia/commons/thumb/e/e9/16777216colors.png/100px-16777216colors.png"; boulePat.onload = function () { var pattern = ctx.createPattern(boulePat, "repeat"); ctx.fillStyle = pattern; ctx.beginPath(); ctx.arc(100, 100, 50, 0, 2 * Math.PI); // translate canvas to offset where the image coordinates are for .fill() if (ctx.canvas === canvas2) { ctx.translate(50, 50); } ctx.fill(); // restore ctx back to before the translate() ctx.restore(); } } drawCanvas(canvas); drawCanvas(canvas2);
With ctx.translate() for background fill<br/> <canvas id="myCanvasWithTranslate" height="200px" width="400px"></canvas> <br/><br/> Without ctx.translate() for background fill<br/> <canvas id="myCanvasNoTranslate" height="200px" width="400px"></canvas>
下面的代碼采用圖像 URL、弧的半徑和弧的角度/大小,並返回一個畫布,該畫布將該圖像剪輯到給定的弧,並“包含”在弧內,以便圖像填充arc 而不改變圖像的縱橫比:
async function getArcClippedCanvas(imageUrl, radius, arcSizeDeg) {
let arcSizeRad = (arcSizeDeg/360)*2*Math.PI;
// derive required width and height of canvas from radius and arc size
let width;
if(arcSizeDeg >= 180) {
width = radius*2;
} else {
width = radius*Math.sin(arcSizeRad/2)*2;
}
let height;
if(arcSizeDeg <= 180) {
height = radius;
} else {
height = radius + radius*Math.sin( (arcSizeRad-Math.PI)/2 );
}
let arcCenterX = width/2;
let arcCenterY = radius; // remember, y axis starts from top of canvas
let canvas = document.createElement("canvas");
let ctx = canvas.getContext("2d");
canvas.width = width;
canvas.height = height;
let img = new Image();
await new Promise(resolve => {
img.onload = resolve;
img.src = imageUrl;
});
let centerAngle = -Math.PI/2;
ctx.beginPath();
ctx.moveTo(arcCenterX, arcCenterY);
ctx.arc(arcCenterX, arcCenterY, radius, centerAngle - (arcSizeDeg/2)*2*Math.PI/360, centerAngle + (arcSizeDeg/2)*2*Math.PI/360);
ctx.clip();
// we want to "cover" the canvas with the image without changing the image's aspect ratio
drawImageToCanvasContained(ctx, img, 0, 0, canvas.width, canvas.height);
return canvas;
}
function drawImageToCanvasContained(ctx, img, x, y, w, h, offsetX, offsetY) {
// By Ken Fyrstenberg Nilsen: https://stackoverflow.com/a/21961894/11950764
if(arguments.length === 2) {
x = y = 0;
w = ctx.canvas.width;
h = ctx.canvas.height;
}
// default offset is center
offsetX = typeof offsetX === "number" ? offsetX : 0.5;
offsetY = typeof offsetY === "number" ? offsetY : 0.5;
// keep bounds [0.0, 1.0]
if(offsetX < 0) offsetX = 0;
if(offsetY < 0) offsetY = 0;
if(offsetX > 1) offsetX = 1;
if(offsetY > 1) offsetY = 1;
let iw = img.width;
let ih = img.height;
let r = Math.min(w / iw, h / ih);
let nw = iw * r; // new prop. width
let nh = ih * r; // new prop. height
let cx, cy, cw, ch, ar = 1;
// decide which gap to fill
if(nw < w) ar = w / nw;
if(Math.abs(ar - 1) < 1e-14 && nh < h) ar = h / nh; // updated
nw *= ar;
nh *= ar;
// calc source rectangle
cw = iw / (nw / w);
ch = ih / (nh / h);
cx = (iw - cw) * offsetX;
cy = (ih - ch) * offsetY;
// make sure source rectangle is valid
if(cx < 0) cx = 0;
if(cy < 0) cy = 0;
if(cw > iw) cw = iw;
if(ch > ih) ch = ih;
// fill image in dest. rectangle
ctx.drawImage(img, cx, cy, cw, ch, x, y, w, h);
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.