Как эффективно загрузить и нарисовать эмодзи на холсте? - PullRequest
0 голосов
/ 26 мая 2019

Я хотел бы напечатать эмодзи на холсте html.

Это можно сделать с помощью изображений, но это громоздко.Есть ли лучший способ?

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>

Редактировать:

Окей, я думаю, что мой вопрос неправильно понят.Я могу рисовать эмодзи в виде изображения на холсте.Я не хочу этого делать.Потому что я должен сделать скриншот всех смайликов и обрезать их, прежде чем печатать их на холсте, что обременительно.Я ищу более эффективный способ.

Ответы [ 3 ]

0 голосов
/ 26 мая 2019

Я думаю, что ваш подход не является правильным.Чтобы использовать метод CanvasRenderingContext2D.drawImage(), вам нужно загрузить изображение, затем вы измените изображение и нарисуете его на холсте, поэтому вам также нужно изменить размер холста.Как насчет того, чтобы использовать эмодзи, предоставленные символами эмодзи Юникода .

Этот пример поможет вам использовать эмодзи через его значение codepoint.Нам просто нужно передать шестнадцатеричный код методом String.fromCodePoint.Этот метод возвращает строку, созданную с использованием указанной последовательности кодов.Затем мы можем напечатать эту строку на холсте как смайлик.У этого подхода будет много времени нарезки, изменения размера и рендеринга каждого смайлика.Это короткий пример:

let canvas1, canvas2, ctx1, ctx2;

let emoji = [];

let emo,
  size = 80,
  rad = 20;

let emojis = [
        0x1F600, 0x1F601, 0x1F603, 0x1F603, 0x1F604, 0x1F605, 0x1F606,
        0x1F607, 0x1F609, 0x1F60A, 0x1F642, 0x1F643, 0x1F355, 0x1F354,
];

for (let i = 0; i < 2; i++) {
  emoji.push({
    x: size,
    y: size,
    src: getEmoji()
  });
}


window.onload = function() {
  canvas1 = document.getElementById('canvas-01');
  ctx1 = canvas1.getContext('2d');
  loadEmoji(canvas1, ctx1, 0);


  canvas2 = document.getElementById('canvas-02');
  ctx2 = canvas2.getContext('2d');
  loadEmoji(canvas2, ctx2, 1);
}


function loadEmoji(canvas, ctx, index) {
  // Use the intrinsic size of image in CSS pixels for the canvas element
  canvas.width = w = size * 2.5;
  canvas.height = h = size * 2.5;

  ctx.font = size * 2 + 'px Arial';
  ctx.textBaseline = 'middle'; 
  ctx.textAlign = 'center';

  emo = emoji[index];
  emo.x = w/2;
  emo.y = h-size-10;

  ctx.fillText(emo.src, emo.x, emo.y);
}

function getEmoji() {
  let len = emojis.length;

  let emos = Math.floor(Math.random() * len);
  return String.fromCodePoint(emojis[emos]);
}
#canvas-01,
#canvas-02 {
  background: red;
}
<canvas id="canvas-01"></canvas>
<canvas id="canvas-02"></canvas>

Примечание

Помните, что это может работать не во всех браузерах, и смайлики будут меняться в зависимости от операционной системы, в которой они былиотображается.

0 голосов
/ 26 мая 2019

Вы можете использовать fillText для рисования смайликов Юникода.

Вы можете скопировать и вставить эмодзи из эмоджипдия .

Я, конечно, не эксперт в этом, поэтому я не знаю, есть ли большие недостатки в этом, но вот некоторые вещи, которые следует учитывать независимо.

  1. Это может не работать во всех браузерах / операционных системах.
  2. Стандартные эмодзи, скорее всего, будут выглядеть по-разному в разных браузерах / системах, если вы не используете собственный шрифт
  3. Вы должны убедиться, что ваш js читается как UTF-8, чтобы это работало. Это стандартно для HTML5, поэтому вам, вероятно, не нужно ничего менять, если это не работает для вас.

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>
0 голосов
/ 26 мая 2019

Если вы не хотите использовать изображения, у меня есть пример, который представляет собой чистое кодирование. Как вы можете видеть, это требует гораздо большего кодирования.

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();

Вы можете проверить результат здесь .

...