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

142
Vistas
¿Cómo creo un círculo de lienzo con una imagen en él?

Entonces, seguí un tutorial para hacer un juego. Obviamente, esa no es la mejor manera de aprender a codificar, así que comencé a modificarlo. Actualmente, el juego tiene enemigos que se mueven lentamente hacia el jugador, pero estos enemigos son círculos de colores y nada más. Me gustaría agregar una imagen que pueda poner en los enemigos, pero no tengo idea de cómo hacerlo. Aquí hay un código que te gustaría saber:

La clase enemiga (la actualización se llama cada cuadro):

 class Enemy { constructor(x, y, radius, color, velocity) { this.x = x; this.y = y; this.radius = radius; this.color = color; this.velocity = velocity; } draw() { ctx.beginPath(); ctx.arc(this.x, this.y, this.radius, 0, Math.PI * 2, true); ctx.fillStyle = this.color; ctx.fill(); } update() { this.draw(); this.x = this.x + this.velocity.x; this.y = this.y + this.velocity.y; } }

La función para crear enemigos:

 function spawnEnemies() { setInterval(() => { const radius = Math.random() * (30 - 4) + 4; let x; let y; if (Math.random() < 0.5) { x = Math.random() < 0.5 ? 0 - radius : canvas.width + radius; y = Math.random() * canvas.height; } else { y = Math.random() < 0.5 ? 0 - radius : canvas.height + radius; x = Math.random() * canvas.width; } const color = `hsl(${Math.random() * 360}, 50%, 50%)`; const angle = Math.atan2(canvas.height / 2 - y, canvas.width / 2 - x); const velocity = { x: Math.cos(angle), y: Math.sin(angle) } enemies.push(new Enemy(x, y, radius, color, velocity)); }, 1000) }

Este código se ejecuta en la función de animación:

 enemies.forEach((enemy, index) => { enemy.update(); const dist = Math.hypot(player.x - enemy.x, player.y - enemy.y); if (isHacking) { if (dist - enemy.radius - player.radius < 11) { setTimeout(() => { for (let i = 0; i < enemy.radius * 2; i++) { particles.push(new Particle(enemy.x, enemy.y, Math.random() * 2, enemy.color, { x: (Math.random() - 0.5) * (Math.random() * 8), y: (Math.random() - 0.5) * (Math.random() * 8)} )); }}, 0) score += 25; scoreEl.innerHTML = score; setTimeout(() => { enemies.splice(index, 1); projectiles.splice(proIndex, 1); }, 0) } } else if (dist - enemy.radius - player.radius < 1) { cancelAnimationFrame(animationId); modal.style.display = 'flex'; modalScore.innerHTML = score; }

Además, esta es la primera vez que publico en el desbordamiento de pila, así que si hay algo que debería haber hecho y no hice, o viceversa, ¡házmelo saber!

about 4 years ago · Juan Pablo Isaza
2 Respuestas
Responde la pregunta

0

Hay muchas formas de hacer lo que quieras. Círculo con imagen.

Por lo que puedo adivinar de su pregunta y comentarios, desea un círculo dinámico que muestre una imagen cargada.

Crea un patrón usando la imagen.

 const imgPat = ctx.createPattern(image, "no-repeat");

Use el tamaño de la imagen para entrenar el radio máximo que puede tener sin salir de la imagen.

 const minRadius = Math.min(image.width, image.height) / 2;

Para dibujar el círculo en cualquier radio, necesitará usar la función setTransform de contexto 2D. La siguiente función hará eso

 function drawImageCircle(imgPat, minRadius, x, y, radius) { // get scale of circle image const scale = radius / minRadius; // transform to put origin at top left of bounding rectangle scaling to fit image pattern ctx.setTransform(scale, 0, 0, scale, x - radius, y - radius); ctx.fillStyle = imgPat; ctx.beginPath(); ctx.arc(minRadius, minRadius, minRadius, 0, Math.PI * 2); ctx.fill(); // reset the default transform ctx.setTransform(1, 0, 0, 1, 0, 0); }

Manifestación

Demo carga una imagen. Luego obtiene su tamaño, crea un patrón a partir de él y lo anima cambiando el radio y colocando un contorno de 4 píxeles a su alrededor.

 const image = new Image; image.src = "https://i.stack.imgur.com/C7qq2.png?s=256&g=1"; image.addEventListener("load", imageReady); const ctx = canvas.getContext("2d"); var w = canvas.width, h = canvas.height, cw = w / 2, ch = h / 2; var imgPat, minRadius; function imageReady() { imgPat = ctx.createPattern(image, "no-repeat"); minRadius = Math.min(image.width, image.height) / 2; requestAnimationFrame(renderLoop); } function drawImageCircle(imgPat, minRadius, x, y, radius) { const scale = radius / minRadius; ctx.setTransform(scale, 0, 0, scale, x - radius, y - radius); ctx.strokeStyle = "#F00"; ctx.lineWidth = 8 / scale; ctx.fillStyle = imgPat; ctx.beginPath(); ctx.arc(minRadius, minRadius, minRadius, 0, Math.PI * 2); ctx.stroke(); ctx.fill(); ctx.setTransform(1, 0, 0, 1, 0, 0); } function renderLoop(time) { ctx.setTransform(1,0,0,1,0,0); ctx.clearRect(0, 0, w, h); var x = Math.cos(time / 500) * (cw - 80) + cw; var y = Math.sin(time / 600) * (ch - 80) + ch; var rad = Math.sin(time / 333) * 10 + 30; drawImageCircle(imgPat, minRadius, x, y, rad); requestAnimationFrame(renderLoop); }
 canvas { background: #888; border: 2px solid black; }
 <canvas id="canvas" width="256" height="256"></canvas>

about 4 years ago · Juan Pablo Isaza Denunciar

0

Si su caso de uso lo admite, sugiero usar un png con transparencia circular recortada previamente para mejorar el rendimiento y evitar tener que codificar esto.

Pero continuemos y respondamos tu pregunta del comentario . Sentí que esto era lo suficientemente diferente de la imagen del clip de Canvas con dos quadraticCurves para agregar una nueva respuesta, pero ese hilo muestra el enfoque general: use context.clip() después de una ruta con context.arc , luego termine con context.drawImage .

Como también está dibujando otras cosas, envuelva su clip con context.save() y context.restore() para evitar que su clip afecte todo lo que dibuje después.

He aquí un ejemplo mínimo:

 const canvas = document.createElement("canvas"); canvas.height = canvas.width = 100; const {width: w, height: h} = canvas; document.body.appendChild(canvas); const ctx = canvas.getContext("2d"); const img = new Image(); img.onload = function () { ctx.fillRect(10, 0, 20, 20); // normal drawing before save() ctx.save(); ctx.beginPath(); ctx.arc(w / 2, h / 2, w / 2, 0, Math.PI * 2); ctx.clip(); ctx.drawImage(this, 0, 0); ctx.restore(); ctx.fillRect(0, 10, 20, 20); // back to normal drawing after restore() }; img.src = `http://placekitten.com/${w}/${h}`;

Si tiene varias imágenes, sugiero usar promesas como se describe en Imágenes onload en una función .

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