Skip to content

Instantly share code, notes, and snippets.

@tesh254
Created June 26, 2021 12:40
Show Gist options
  • Save tesh254/9c4e424bad1a36438bb07f2c1da7c33c to your computer and use it in GitHub Desktop.
Save tesh254/9c4e424bad1a36438bb07f2c1da7c33c to your computer and use it in GitHub Desktop.
Generate a custom QR code with the help of node canvas, enabling headless QR generation.
import QRCode from "qrcode";
import { createCanvas, loadImage, CanvasRenderingContext2D, Image } from "canvas";
import { IQrOptions } from "../interfaces";
import SpacesService from "./spaces.service";
export default class QRGeneratorService {
private qrOptions: IQrOptions;
private text: string;
constructor(text: string, options: IQrOptions) {
this.qrOptions = options;
this.text = text;
}
public async generateQRCode() {
try {
const initQR = await this.qrGenerator();
const UPLOAD_DATA = new SpacesService().uploadToBucket(initQR, "image/png", "jpg", true)
return UPLOAD_DATA;
} catch (error) {
console.log(error)
throw {
...error
}
}
}
public async qrGenerator() {
const canvas = createCanvas(150, 150);
const ctx = canvas.getContext("2d");
const WIDTH = this.qrOptions.size || 720
await QRCode.toCanvas(canvas, this.text, {
margin: 1,
color: {
dark: this.qrOptions.color || "#000000",
light: this.qrOptions.background || "#ffffff"
},
width: WIDTH
})
if (this.qrOptions.logo) {
// ctx.save()
const LOGO_SIZE = this.qrOptions.logo_size || 120;
const image = await loadImage(this.qrOptions.logo);
const IMAGE_POSITION = (WIDTH / 2) - (LOGO_SIZE / 2);
let x = IMAGE_POSITION;
let y = IMAGE_POSITION;
let radius = 12;
ctx.beginPath();
ctx.moveTo(x + radius, y);
ctx.lineTo(x + LOGO_SIZE - radius, y);
ctx.quadraticCurveTo(x + LOGO_SIZE, y, x + LOGO_SIZE, y + radius);
ctx.lineTo(x + LOGO_SIZE, y + LOGO_SIZE - radius);
ctx.quadraticCurveTo(x + LOGO_SIZE, y + LOGO_SIZE, x + LOGO_SIZE - radius, y + LOGO_SIZE);
ctx.lineTo(x + radius, y + LOGO_SIZE);
ctx.quadraticCurveTo(x, y + LOGO_SIZE, x, y + LOGO_SIZE - radius);
ctx.lineTo(x, y + radius);
ctx.quadraticCurveTo(x, y, x + radius, y);
ctx.closePath();
ctx.clip()
ctx.drawImage(image, IMAGE_POSITION, IMAGE_POSITION, LOGO_SIZE, LOGO_SIZE)
}
return canvas.toBuffer("image/png")
}
private roundRect(ctx: CanvasRenderingContext2D, x: number, y: number, width: number, height: number, radius: number) {
ctx.beginPath();
ctx.moveTo(x + radius, y);
ctx.lineTo(x + width - radius, y);
ctx.quadraticCurveTo(x + width, y, x + width, y + radius);
ctx.lineTo(x + width, y + height - radius);
ctx.quadraticCurveTo(x + width, y + height, x + width - radius, y + height);
ctx.lineTo(x + radius, y + height);
ctx.quadraticCurveTo(x, y + height, x, y + height - radius);
ctx.lineTo(x, y + radius);
ctx.quadraticCurveTo(x, y, x + radius, y);
ctx.closePath();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment