The code below takes an image URL, the radius of the arc, and the angle/size of the arc, and returns a canvas that has that image clipped to the given arc, and "contained" within the arc such that the image fills the arc without changing the image's aspect ratio:
  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);
  }