用背景图像写在画布上

时间:2018-09-22 10:08:07

标签: javascript html canvas fonts

因此,我正在尝试构建一个Meme-Creator。您已经可以从画布上传图片作为background-img。现在,我正在尝试制作Meme字体,但它实际上并没有工作。但是,这在图片中造成了很大的差距。感谢您的帮助和关注! :D

var canvas = document.getElementById("meme-canvas");
var ctx = canvas.getContext("2d");
var width = canvas.width;
var height = canvas.height;

function readImage() {
  if (this.files && this.files[0]) {
    var FR = new FileReader();
    FR.onload = function(e) {
      var img = new Image();
      img.addEventListener("load", function() {
        ctx.clearRect(0, 0, width, height);
        canvas.width = img.width;
        canvas.height = img.height;
        ctx.drawImage(img, 0, 0);
      });
      img.src = e.target.result;
    };
    FR.readAsDataURL(this.files[0]);
  }
}

function Text() {
  ctx.clearRect(0, 0, width, height);

  var textT = document.getElementById("top-text").value;
  var textB = document.getElementById("bottom-text").value;

  ctx.font = "60px Impact";
  ctx.lineWidth = 3;
  ctx.strokeText(textT, 10, 65);
  ctx.strokeText(textB, 10, 400);
}

document.getElementById("image-input").addEventListener("change", readImage, false);
<input type="file" id="image-input" accept="image/*">
<input type="text" id="top-text" oninput="Text()">
<input type="text" id="bottom-text" oninput="Text()">

<canvas style="position: absolute; width: 400px; top: 100px; left: 10px;" id="meme-canvas"></canvas>

2 个答案:

答案 0 :(得分:2)

我对您的脚本进行了一些更改。因为您需要多次绘制图像,所以我编写了一个绘制图像的函数。每当2个文本输入之一更改其值时,以及每次必须重新绘制所有内容时,都会清除画布。

textT和textB也只能声明一次。您无需在Text函数中声明它们。

我需要多次使用字体大小(60),因此我已将变量fontSize = 60设置为

由于您不知道画布的大小(取决于上传的图像的大小),因此需要计算底部文本textB = height - fontSize/2的位置,其中height是画布的高度:{{ 1}}

我希望它有用。

height = canvas.height = img.height;
var canvas = document.getElementById("meme-canvas");
var ctx = canvas.getContext("2d");
var width = (canvas.width = 400);
var height = (canvas.height = 400);
var fontSize = 60;
var img = new Image();

var textT = document.getElementById("top-text");
var textB = document.getElementById("bottom-text");

function readImage() {
  if (this.files && this.files[0]) {
    var FR = new FileReader();
    FR.onload = function(e) {
      img.addEventListener("load", function() {
        width = canvas.width = img.width;
        height = canvas.height = img.height;
        drawImage();
      });
      img.src = e.target.result;
    };
    FR.readAsDataURL(this.files[0]);
  }
}

function drawImage() {
  ctx.drawImage(img, 0, 0);
}

function Text() {
  ctx.font = fontSize + "px Impact";
  ctx.textAlign = "center";
  ctx.lineWidth = 3;
  
  ctx.clearRect(0, 0, width, height);

  drawImage();
  ctx.strokeText(textT.value, width / 2, 65);
  ctx.strokeText(textB.value, width / 2, height - fontSize/2);
}

document
  .getElementById("image-input")
  .addEventListener("change", readImage, false);

textT.addEventListener("input", Text);
textB.addEventListener("input", Text);
canvas{position: absolute; left: 10px; top:60px;border:1px solid #d9d9d9;}

答案 1 :(得分:1)

我遇到的一些问题:

  • 如果更改画布的大小,则不应使用这些变量,因为这些变量将不正确,否则您将需要对其进行跟踪
  • 如果您执行clearRect,则必须知道要清除的内容并重新绘制。
  • 字体看起来不太清晰,所以我添加了白色阴影以获得更好的对比度
  • 底部文本必须相对于画布高度

这是代码:

var canvas = document.getElementById("meme-canvas");
var ctx = canvas.getContext("2d");
var img = new Image();

function readImage() {
  if (this.files && this.files[0]) {
    var FR = new FileReader();
    FR.onload = function(e) {
      img.addEventListener("load", function() {
        canvas.width = img.width;
        canvas.height = img.height;
        draw();
      });
      img.src = e.target.result;
    };
    FR.readAsDataURL(this.files[0]);
  }
}

function draw() {
  var textT = document.getElementById("top-text").value;
  var textB = document.getElementById("bottom-text").value;

  ctx.clearRect(0, 0, canvas.width, canvas.height);
  ctx.font = "60px Impact";
  ctx.shadowColor = "white" 
  ctx.shadowOffsetX = ctx.shadowOffsetY = 2
  ctx.lineWidth = 3;
  if (img) ctx.drawImage(img, 0, 0);
  ctx.strokeText(textT, 10, 45);
  ctx.strokeText(textB, 10, canvas.height -10);
}

document.getElementById("image-input")
        .addEventListener("change", readImage, false);
<input type="file" id="image-input" accept="image/*"><br>
<input type="text" id="top-text" placeholder="Top text" oninput="draw()"><br>
<input type="text" id="bottom-text" placeholder="Bottom text" oninput="draw()"><br>

<canvas  id="meme-canvas"></canvas>