创建你自己的表情包生成器

Avatar of Omayeli Arenyeka
Omayeli Arenyeka

DigitalOcean 为您旅程的每个阶段提供云产品。立即开始使用 200 美元的免费额度!

几乎每次我在 Twitter 订阅源中看到新的表情包时,我都会想到一个机智的版本来创建。我并不是唯一一个这样想的人。表情包通常是承认共同经历或想法的一种方式。在一个在线流传的“这是鸽子吗”表情包的变体中,一位设计师 Daryl Ginn 嘲笑了大多数声称使用人工智能的应用程序的 基础性质

https://twitter.com/darylginn/status/996541055192453120

一些人回复了他的推文,说了一些类似“用这个替换这个”的话。Daryl 的版本让他们想到了其他可能的变体。像 imgFlip 这样的平台存在是为了使表情包生成快速且容易。但是,它们所能允许的自定义程度是有限的。对于许多表情包,创建新版本只能由具有 Photoshop 知识的人完成。但事实并非如此!对于一些需要在图像上使用 Impact 字体以外内容的表情包,可以使用 HTML Canvas API 创建表情包生成器。在本教程中,我们将为 #saltbae 表情包制作一个生成器。

但首先…

让我们看看一些有趣交互式表情包示例!

网站 pablo.life 允许您通过更改文本和图像来创建您自己的 Kanye West TLOP 专辑封面。

这是我最喜欢的之一

数字代理机构 R/GA 创建了 Straight Outta Somewhere 活动,用户“通过上传自己的照片并在‘Straight Outta ____’之后填写空白来向世界展示他们的出身”。用户可以下载和分享表情包。

开发人员 Isaac Hepworth 创建了 特朗普行政命令生成器

Spotify 与 Migos 合作创建了一系列 可下载的情人节卡片,可以通过更改姓名进行自定义。

让我们构建我们自己的表情包生成器!

现在,教程。在 #saltbae 表情包的一个流行版本中,Salt Bae(真名 Nusret Gökçe)撒的不是盐,而是其他东西。

加载图像

我们首先要做的是将原始图像加载到画布上。您可以通过两种方式之一加载图像:从 URL 加载或从 DOM 中存在的 <img> 标签加载,但该标签是隐藏的。

以下是如何使用隐藏的图像标签进行操作

<canvas id="canvas" width="1024" height="1024">
  Canvas requires a browser that supports HTML5.
</canvas>
<img crossOrigin="Anonymous" id="salt-bae" src="http://res.cloudinary.com/dlwnmz6lr/image/upload/v1520011253/170203-salt-bae-mn-1530_060e5898cdcf7b58f97126d3cfbfdf71.nbcnews-ux-2880-1000_kllh1d.jpg"/>

我在 Cloudinary 上托管图像,并添加了 crossOrigin 属性,因此我们不会遇到任何 CORS 问题

function drawImage(text) {
  const canvas = document.getElementById('canvas');
  const ctx = canvas.getContext('2d');
  ctx.clearRect(0, 0, canvas.width, canvas.height);
  const img = document.getElementById('salt-bae');  
  ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
}

window.onload = function() {
  drawImage();
}

我们正在使用画布 drawImage 函数将图像绘制到画布上。它也可以用于绘制视频或图像的一部分。该方法提供了不同的执行方式。我们通过指示图像的位置以及图像的宽度和高度来绘制图像。

ctx.drawImage(img, x, y, width, height);

或者,我们可以从 URL 加载图像

function loadAndDrawImage(src) {
  // Create an image object. (Not part of the dom)
  const image = new Image();
  
  // After the image has loaded, draw it to the canvas
  image.onload = () => { 
    // draw image 
  };

  // Then set the source of the image that we want to load
  image.src = src;
}

现在我们加载一个图像来替换 Salt Bae 撒的盐。首先,我们使用前面提到的其中一项技术加载图像,然后像对 Salt Bae 基础图像一样将其绘制到屏幕上。

function getRandomInt(min, max) {
  min = Math.ceil(min);
  max = Math.floor(max);
  return Math.floor(Math.random() * (max - min)) + min; //The maximum is exclusive and the minimum is inclusive
}

function drawBackgroundImage(canvas, ctx) {
  ctx.clearRect(0, 0, canvas.width, canvas.height);
  const img = document.getElementById('salt-bae');  
  ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
}

function getRandomImageSize(min, max, width, height) {
  const ratio = width / height;  // Used for aspect ratio
  width = getRandomInt(min, max);
  height = width / ratio;  
  return { width, height };
}

function drawSalt(src, canvas, ctx) {
  // Create an image object. (Not part of the dom)
  const image = new Image();
  image.src = src;
  
  // After the image has loaded, draw it to the canvas
   image.onload = function() {
    for (let i = 0; i < 8; i++) {
      const randomX = getRandomInt(10, canvas.width/2);
      const randomY = getRandomInt(canvas.height-300, canvas.height);
      const dimensions = getRandomImageSize(20, 100, image.width, image.height);
      ctx.drawImage(image, randomX, randomY, dimensions.width, dimensions.height);
    }
  }
  return image;
}

onload = function() {
  const canvas = document.getElementById('canvas');
  const ctx = canvas.getContext('2d');
  drawBackgroundImage(canvas, ctx);
  const saltImage = drawSalt('http://res.cloudinary.com/dlwnmz6lr/image/upload/v1526005050/chadwick-boseman-inspired-workout-program-wide_phczey.webp', canvas, ctx);
};

现在我们可以让用户撒一些除了盐以外的东西了。

上传图像

我们将添加一个触发图像上传的按钮,并包含一个事件监听器来监听更改。

<input type="file" class="upload-image">`
function updateImage(file, img){
  img.src = URL.createObjectURL(file);
}

onload = function() {
  const canvas = document.getElementById('canvas');
  const ctx = canvas.getContext('2d');
  drawBackgroundImage(canvas, ctx);
  const saltImage = drawSalt('http://res.cloudinary.com/dlwnmz6lr/image/upload/v1526005050/chadwick-boseman-inspired-workout-program-wide_phczey.webp', canvas, ctx);
  const input = document.querySelector("input[type='file']");
  /*
   * Add event listener to the input to listen for changes to its selected
   * value, i.e when files are selected 
   */
  input.addEventListener('change', function() {
    drawBackgroundImage(canvas, ctx); // clear canvas and re-draw
    updateImage(this.files[0], saltImage);
  });
};

URL.createObjectURL() 创建一个包含 URL 的 DOMString,该 URL 表示参数中给定的对象,在本例中为上传的文件。

我们甚至可以稍微提高一下游戏水平,例如提供一些默认选项。我添加了一些表情符号,您可以作为起点进行尝试。

下载最终图像

生成新表情包后,我们希望用户能够下载和分享它。通常的做法是使用 toDataURL 方法在新标签页中打开画布,但是用户必须右键单击才能从该标签页保存图像,这很不方便。

因此,我们可以利用 HTML5 中添加到链接的 download 属性。我们创建一个链接,单击该链接时,将 download 属性设置为 canvas.toDataURL 的结果。toDataURL() 方法“返回一个包含以指定格式表示的图像的 data URI。”

function addLink() {
  var link = document.createElement('a');
  link.innerHTML = 'Download!';
  link.addEventListener('click', function(e) {
    link.href = canvas.toDataURL();
    link.download = "salt-bae.png";
  }, false);
  link.className = "instruction";
  document.querySelectorAll('section')[1].appendChild(link);
}

就是这样!我们的表情包生成器完成了。

一些很酷的链接

  • Darius Kazemi 一直在制作许多生成表情包的 Twitter 机器人。
  • Vox Media 有一个名为 meme 的表情包生成器,它是开源的。

尽情创作表情包吧!