How to Apply Shadow to an Image with Rounded Corners on HTML5 Canvas

101 views Asked by At

I'm working on a web project where I need to display an image with rounded corners on an HTML5 canvas. I've successfully achieved the rounded corners effect, but when I apply a shadow to the image, the shadow disappears at the corners. I want to have both the rounded corners and the shadow effect visible simultaneously on the image. Can someone please provide guidance or code on how to achieve this on an HTML5 canvas or canvas api for node?

var canvas = document.getElementById ('mycanvas');    // access the canvas object
const background = document.getElementById("source");
const overlay = new Image(300, 300)
overlay.src = 'https://images.unsplash.com/photo-1518826778770-a729fb53327c?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=1887&q=80';

var context = canvas.getContext ('2d');                             // access the canvas context
const canvasWidth = background.width; // Set your desired width
const canvasHeight = background.height; // Set your desired height


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

// Draw the background image
ctx.drawImage(background, 0, 0, background.width, background.height); 


const x = (canvas.width - overlay.width) / 2;
    const y = (canvas.height - overlay.height) / 2;
    ctx.shadowColor = 'rgba(0, 0, 0, 1.0)';
    ctx.shadowBlur = 100;
    ctx.shadowOffsetX = 5;
    ctx.shadowOffsetY = 5;

    // Create a rounded rectangle for the overlay image
    const cornerRadius = 20; // Adjust as needed
    
    ctx.beginPath();
    ctx.moveTo(x + cornerRadius, y);
    ctx.lineTo(x + overlay.width - cornerRadius, y);
    ctx.quadraticCurveTo(x + overlay.width, y, x + overlay.width, y + cornerRadius);
    ctx.lineTo(x + overlay.width, y + overlay.height - cornerRadius);
    ctx.quadraticCurveTo(x + overlay.width, y + overlay.height, x + overlay.width - cornerRadius, y + overlay.height);
    ctx.lineTo(x + cornerRadius, y + overlay.height);
    ctx.quadraticCurveTo(x, y + overlay.height, x, y + overlay.height - cornerRadius);
    ctx.lineTo(x, y + cornerRadius);
    ctx.quadraticCurveTo(x, y, x + cornerRadius, y);
    ctx.closePath();
    ctx.clip();

  

    // Draw the overlay image with the shadow and rounded corners
    ctx.drawImage(overlay, x, y, overlay.width, overlay.height);
<canvas id="mycanvas" width="500" height="500"></canvas>
<div style="display:none;">
  <img id="source" src="https://images.unsplash.com/photo-1534644107580-3a4dbd494a95?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=2070&q=80" width="500" height="500" />
 
  <img id="overlay" src="" width="300" height="300" />
  
</div>

If the images are not being loaded, please try the code with your own local images, Thank you in advance

1

There are 1 answers

0
walpe On

With ctx.clip() everything out of the path will not be drawn, thats how the image will not be drawn outside of the path, and thats how you get rounded corners. But with that clip the shadow is also out of the path and not will be drawn. So what I would do, is before you clip, fill the path. Then you have a filled rectangle with rounded corners and shadow. After that you clip and draw the image over the rectangle. So just add direct before ctx.clip(); the command ctx.fill(); Hope this helps.

And also the snippet "isnt working" because you draw the images before they get fully loaded by the browser. Thats why everything is white. Would be better if you wait until the images are loaded until you start using them.