Starting the download of the canvas featuring a stylish border design

I'm facing an issue where the canvas border is not showing up when I download the canvas with a border. The border appears on the screen, but it doesn't get included in the downloaded canvas.

let canvas=qrRef.current.querySelector("canvas")
canvas.style.border="black 30px solid"
 if(type=="PNG"){
    let image=canvas.toDataURL("image/png")
    let anchor=document.createElement("a");
    anchor.href=image;
    anchor.download=`qr-pollective.png`
    document.body.appendChild(anchor);
    anchor.click()
    document.body.removeChild(anchor)
}

console.log(canvas)

<canvas height="400" width="400" style="border: 30px solid black; border-radius: 5px; border-collapse: collapse;">

Answer №1

To add a black border to your canvas, you can create a larger canvas with enough space for the border first.

Next, copy the content of your original canvas onto this larger canvas, but offset it by 30px to accommodate the border.

Then, draw the four black rectangles that will form the border around the content. This modified canvas with the border is the one you should use for downloading.

const canvas = document.querySelector('canvas');
const biggerCanvas = document.createElement('canvas');
const w = canvas.width + 60;
const h = canvas.height + 60;
biggerCanvas.width = w;
biggerCanvas.height = h;
const ctx = biggerCanvas.getContext('2d');
ctx.drawImage(canvas, 30, 30);
ctx.beginPath();
ctx.rect(0, 0, w, 30);
ctx.fillStyle = "black";
ctx.fill();
ctx.rect(0, 0, 30, h);
ctx.fill();
ctx.rect(w - 30, 0, w - 30, h);
ctx.fill();
ctx.rect(0, h - 30, w, h);
ctx.fill();
document.body.append(biggerCanvas); //just to show it has drawn the border
<canvas height="400" width="400" style="border: 30px solid black; border-radius: 5px; border-collapse: collapse;">

Answer №2

My issue was resolved by using html2canvas. Below is the code I used:

html2canvas(canvas,{backgroundColor: "transparent"}).then(function (canvas) {
           var myImage = canvas.toDataURL();
           downloadURI(myImage, `qr-pollective.png`);
});

function downloadURI(uri, name) {
      var link = document.createElement("a");
   
      link.download = name;
      link.href = uri;
      document.body.appendChild(link);
      link.click();   

    }

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Tips for managing lag caused by large raw image re-renders in a React application

When trying to change the background position of a user-uploaded background image that is in raw Data URI format using CSS, I noticed that re-rendering becomes slow if the image size exceeds 1mb. This issue does not occur with smaller images. Is there a ...

Send the user to a customized dashboard depending on their user role permissions using Vue.js

Currently, I am developing a system that involves handling multiple role-permissions for users. To provide some context, there are 3 distinct users in this scenario: User1 (customer), User2 (employee), and User3 (admin). For each of these user types, I ha ...

How to Target a Specific Element Using its Class with jQuery

Hey there! I'm currently working with the following snippet of HTML code: <li class="grey"> <div class="row"> <button id="test" style="width:50%;" class="btn btn-blue-white cartBtn">Add to Cart</button> </div ...

Tips on creating a literal type that is determined by a specific value within an object

In the flow, I am able to create a dynamic literal type in this manner: const myVar = 'foo' type X = { [typeof myVar]: string } const myX: X = { foo: 1 } // will throw, because number const myX: X = { foo: 'bar' } // will not throw ...

Trigger the phone to vibrate once the animation has completed. This feature will only activate upon clicking the button

After the image completes its animation by sliding in from the left, I would like it to vibrate for 2 seconds using the HTML 5 vibrate API: navigator.vibrate(2000); An on-click event successfully triggers the vibration when a button is clicked: <butt ...

Using jQuery UI datepicker - how to set a parameter based on a specific condition

New to the world of JavaScript, I am trying my hand at implementing the jQuery UI datepicker widget. My goal is to add an additional line to the widget parameters if the variable selectedDate has a value. However, my current approach seems to be ineffecti ...

Creating a designed pattern for a textbox: Let's get creative with your text

How can I create a Textbox that only allows numeric values or the letter 'A'? <input type="text" id="txt" name="txt" pattern="^[0-9][A]*$" title="Allow numeric value or only Letter 'A'&quo ...

A step-by-step guide on integrating Google Tag Manager with a NextJS website

After consulting this answer and this article, I have implemented a <Script> tag to incorporate Google Tag Manager into my NextJS website: components/layout.tsx: import React from "react"; import Head from "next/head"; import ...

Creating a Full Page Background Image That Fits Perfectly Without Resizing or Cropping

Can someone help me achieve the same effect as the website linked below, where the background image fades instead of being a slideshow? The image should be 100% in width and height without any cropping. I have managed to set this up with the codes provided ...

What are the placeholders for the "localIdentName" query tag in a custom CSS-loader for Webpack?

Just starting out with Webpack and experimenting with the css-loader. I came across the option to specify a localIdentName query tag on the Github page under "Local Scope". This tag allows us to define our own custom values for how classes should be named ...

Struggling to center with margin 0 auto

I'm having trouble aligning the middle paragraph in an HTML footer. I attempted to use floats for layout: the first paragraph is floating to the left, the third paragraph is floating to the right, and the second (middle) paragraph has a margin of 0 au ...

Discrepancy in CSS rendering in Chrome and Firefox

When viewing in Chrome, the stats display properly within the gray box at the bottom left corner. However, when using Firefox, the stats appear positioned much lower below the box, with the bottom half of them hidden from view. Here is my CSS code being ...

Issues with Internet Explorer causing headaches with CSS :first-child selector malfunctioning, experiencing strange behavior when utilizing Google Web Fonts

Having some trouble with the layout of a website, particularly in IE. The issue can be observed at . When comparing the page in IE to Firefox, there are noticeable differences. Firstly, the top module on the right side is not displaying correctly in IE. I ...

Ways to retrieve the highest date value in an array

I'm running into an issue where I am trying to find the maximum day in an array of dates, but for some reason it keeps returning either Invalid Date or null. I'm not sure what's going wrong. Do you think I should convert the values to a diff ...

Dealing with TypeScript and the Mongoose loadClass problem

Working with Mongoose's class schemas has been very beneficial for me. Incorporating TypeScript into my Node project has enhanced the development process. I made sure to refer to Mongoose the Typescript way...? in order to ensure that my Model align ...

Hero Sticky Transition with 100vhDivElement

My code is giving me some trouble. I want the div with text to stay at the bottom of the hero section with a transparent background. When that div reaches the top, it should stick with a black background. The issue is that I have set it in the javascript v ...

Creating a full-width input field with text aligned to the right:

.wrap { white-space: nowrap; } input { width: 100%; } body { /* just so you can see it overflowing */ border: 1px solid black; margin: 40px; padding: 10px; } <span class="wrap"><input type="text">.pdf</span> Observing the cod ...

Looking for a unique Full Screen Crosshair Cursor with either HTML5 or JQuery?

We've all seen that iconic military crosshair cursor in movies and animations. One example can be found at the beginning of a YouTube video titled "Dishonorable Disclosures" - https://www.youtube.com/watch?v=X-Xfti7qtT0 Another instance is with the ...

Flipping the camera rotation matrix in three.js

I am struggling with a scenario involving objects and a camera being controlled by a trackball. Whenever I add a new object to the main object, I want it to maintain its original orientation regardless of how the camera has moved around. For instance, with ...

The HTML checkbox is initialized as checked when the page loads

Is there a way to set the checkbox as unchecked in HTML? I have tried multiple ways, but it always loads as checked <input id="chkBox" checked type="checkbox" /> <input id="chkBox" checked=false type="checkbox" /> <input id="chkBox" checked ...