Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

258
Vistas
Centering a Canvas no-repeat pattern fill

I'm trying to replicate the animated icon that mapbox has here https://docs.mapbox.com/mapbox-gl-js/example/add-image-animated/

enter image description here

Except I want to have an image for the inner circle.

enter image description here

So far I can get fairly close by using a create pattern as above. But the image is repeating instead of being centered in the inner circle.

How can I have my image cropped and centered in the inner circle ?

    // Copy pasta from mapbox example ... 
    // Draw the outer circle.
    context.clearRect(0, 0, this.width, this.height)
    context.beginPath()
    context.arc(this.width / 2, this.height / 2, outerRadius, 0, Math.PI * 2)
    
    context.fillStyle = `hsl(46deg 85% 67% / ${1 - t})`
    context.fill()

    // Draw the inner circle.
    context.beginPath()
    context.arc(this.width / 2, this.height / 2, radius, 0, Math.PI * 2)
    
    // I've added this 
    const pattern = context.createPattern(image, 'repeat')
    context.fillStyle = pattern

    // I've tried this but the image isn't cropped and isn't centered. 
    // context.drawImage(image, this.width / 2, this.height / 2, 150, 150)

    context.strokeStyle = 'white'
    context.lineWidth = 2 + 4 * (1 - t)
    context.fill()
    context.stroke()
about 4 years ago · Juan Pablo Isaza
1 Respuestas
Responde la pregunta

0

Actually, I think you were almost there.

Since you don't want it to repeat, first set the pattern to not repeat:

const pattern = ctx.createPattern(img, 'no-repeat');

The pattern fill calculation starts in the upper left hand corner (0, 0), so that alone won't do it. We'll have to transform the pattern as well:

pattern.setTransform(
    new DOMMatrix(
    [
        // No rotation, 1-1 scale
        1, 0, 0, 1,
        // Translate to center, offset by half-image
        canvas.width / 2 - img.width / 2, 
        canvas.height / 2 - img.height / 2
    ])
);

Docs:

  • CanvasPattern#setTransform
  • DOMMatrix

Here's a demo of how to use it. I couldn't get their CodePen demo to work, so I had to base it off if that and improvise a bit:

const canvas = document.querySelector('canvas');
const ctx = canvas.getContext('2d');

const size = 300;

const img = new Image();
img.src = 'https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/fillStyle/canvas_fillstyle.png';
img.onload = function() {
  const pattern = ctx.createPattern(img, 'no-repeat');
  const radius = (size / 2) * 0.3;
    const outerRadius = (size / 2) * 0.7 + radius;
  
  ctx.fillStyle = `hsl(46deg 85% 67% / ${0})`;
  ctx.arc(canvas.width / 2, canvas.height / 2, outerRadius, 0, Math.PI * 2);
  ctx.fill();

  ctx.beginPath();
  ctx.arc(canvas.width / 2, canvas.height / 2, radius, 0, Math.PI * 2);

  pattern.setTransform(new DOMMatrix([1, 0, 0, 1, canvas.width / 2 - img.width / 2, canvas.height / 2 - img.height / 2]));
  ctx.fillStyle = pattern;

  ctx.strokeStyle = 'white';
  ctx.lineWidth = 2;
  ctx.fill();
  ctx.stroke();
};
canvas
{
  border: 1px solid black;
  background-color: gray;
}
<canvas width="400" height="400"></canvas>
<div>For reference, here's the original image:</div>
<img src="https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/fillStyle/canvas_fillstyle.png" />

about 4 years ago · Juan Pablo Isaza Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda