Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

138
Views
¿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 answers
Answer question

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 Report

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 Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!