Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to load and draw emojis on canvas efficiently?

I would like to print an emoji on html canvas.

It can be done using images, but it is cumbersome. Is there a better way?

const canvas = document.querySelector("#canvas");
const contex = canvas.getContext("2d");

var img = new Image();
img.src = "emoji.jpg";
img.addEventListener(
  "load",
  () => {
    context.drawImage(img, 0, 0, 200, 200);
  }
);
img.src = "img.jpg";
#canvas {
  background: red;
}
<canvas id="canvas"></canvas>

Edit:

Okey, I think my question is misunderstood. I am able to draw emoji as an image on canvas. I don't want to do that. Because I have to screenshot all the emojis and crop them before printing them on canvas, which is cumbersome. I am looking for a more efficient way.

like image 886
user9408899 Avatar asked May 26 '19 09:05

user9408899


2 Answers

You can use fillText to draw the unicode emoji.

You can copy and paste the emojis from emojipedia.

I'm certainly not an expert on this so I don't know if there's big drawbacks to doing it this way, but here are some things to consider regardless.

  1. This might not work on all browsers / operating systems.
  2. The standard emoji will likely look different between browsers/systems unless you use a custom font
  3. You should make sure your js is being read as UTF-8 for this to work. This is standard with HTML5, so you probably don't have to change anything unless it doesn't work for you.

const canvas = document.querySelector("#canvas");
const contex = canvas.getContext("2d");

// The size of the emoji is set with the font
contex.font = '100px serif'
// use these alignment properties for "better" positioning
contex.textAlign = "center"; 
contex.textBaseline = "middle"; 
// draw the emoji
contex.fillText('😜😂😍', canvas.width / 2, canvas.height / 2)
#canvas {
  background: #ccc;
}
<canvas id="canvas"></canvas>
like image 107
Khauri Avatar answered Sep 28 '22 20:09

Khauri


If you don't want to use images then I have an example here that is pure coding. As you can see it requires way more coding tho.

index.html

<!doctype html>
<html lang="en">
<head>
<title>Smiley Face</title>
<meta charset="utf-8" />

   <link rel="stylesheet" href="css/smiley.css" >

</head>
<body>
    <canvas width="600" height="600" id="smiley">
        <p>You need canvas!</p>
        <p>This example requires a browser that supports the
        <a href="http://www.w3.org/html/wg/html5/">HTML5</a> 
        &lt;canvas&gt; feature.</p>
    </canvas>
    <script src="js/smiley.js"></script>
</body>
</html>

smiley.js

//smileyView Object literal
class smileyComponent {
  constructor() {
    //initialise window, cv & ctx, drawSmiley & call drawsmiley
    this._window = this;
    this._cv = document.getElementById('smiley');
    this._ctx = this._cv.getContext('2d');
    this.drawSmiley();
  }
  //getters
  get window() {
    return this._window;
  }
  get cv() {
    return this._cv;
  }
  get ctx() {
    return this._ctx;
  }

  drawArc(x, y, radius, startAngle, endAngle, clockwise) {
    this._ctx.arc(x, y, radius, startAngle, endAngle, clockwise);
  }
  drawLine(xs, ys, xe, ye) {
    this._ctx.moveTo(xs, ys);
    this._ctx.lineTo(xe, ye);
  }
  drawSmiley() {
    //initialise lineWidth & fillStyle
    this._ctx.fillStyle = "yellow";
    this._ctx.strokeStyle = "black";
    this._ctx.lineWidth = 5;

    //head
    this._ctx.beginPath();
    this.drawArc(300,300,200,smileyComponent.degreesToRadians(0),smileyComponent.degreesToRadians(360),true);
    this._ctx.fill();

    //left eye
    this._ctx.beginPath();
    this.drawArc(200,200,50,smileyComponent.degreesToRadians(0),smileyComponent.degreesToRadians(360),true);
    this._ctx.fillStyle = "black";
    this._ctx.fill();
    this._ctx.beginPath();
    this.drawArc(220,220,25,smileyComponent.degreesToRadians(0),smileyComponent.degreesToRadians(360),true);
    this._ctx.fillStyle = "white";
    this._ctx.fill();


    //right eye
    this._ctx.beginPath();
    this.drawArc(400,200,50,smileyComponent.degreesToRadians(0),smileyComponent.degreesToRadians(360),true);
    this._ctx.fillStyle = "black";
    this._ctx.fill();
    this._ctx.beginPath();
    this.drawArc(420,220,25,smileyComponent.degreesToRadians(0),smileyComponent.degreesToRadians(360),true);
    this._ctx.fillStyle = "white";
    this._ctx.fill();

    //nose
    this._ctx.beginPath();
    this.drawLine(300,350,300,250);
    this._ctx.stroke();


    //smile
    this._ctx.beginPath();
    this.drawArc(300,300,150,smileyComponent.degreesToRadians(160),smileyComponent.degreesToRadians(380),true);
    this._ctx.stroke();
  }

  static degreesToRadians(degrees) {
    return degrees * Math.PI / 180;
  }
}
window.onload = () => new smileyComponent();

You can check the result here.

like image 20
Ruben Szekér Avatar answered Sep 28 '22 19:09

Ruben Szekér