Home > Enterprise >  Changing the letter by pressing a key
Changing the letter by pressing a key

Time:10-21

I have a canvas with some styling applied. There is a single letter centered in the canvas. Please take a look at the code below. As the title suggest, I am trying to change the letter by pressing a key. For example:

Letter A centered in canvas: I press the g - key, it changes to the letter g (Uppercase included)

As to my knowledge, I might have to use the method "keyup" with a "document.addEventListener". Currently I am going through a course on learning JS, but I have noticed a strong reliance on certain libraries in the course, which I frankly dislike. I am not trashing the benefits, but I would prefer building a base with pure JS before using certain libraries. Some guidance would be appreciated.

body {
    background-color: #000000;
}

canvas {
    padding: 0;
    margin: auto;
    display: block;
    position: absolute;
    top: 0;
    bottom: 0;
    left: 0;
    right: 0;
    background-color: #111416; 
    border: 10px solid #a60000;
    border-style: double;
    box-shadow: 0 0 20px 5px #a60000;
}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    
    <link rel="stylesheet" href="canvas.css">
    <canvas id="myCanvas" width="800" height="800"></canvas>

    <script> 
    
    // Get id from the canvas element
    var canvas = document.getElementById("myCanvas");

    // Provide 2D rendering context for the drawing surface of canvas
    var context = canvas.getContext("2d");

    // Get width and height of the canvas element
    var canvW = document.getElementById("myCanvas").width;
    var canvH = document.getElementById("myCanvas").height;

    let text = "f";

    context.fillStyle = "#a60000";
    context.font = "700px serif"; 

    // Measure the size of the letter and the specific font
    // Always centers the letter regardless of size
    // Display size of letter 
    
    const metrics = context.measureText(text);
    const mx = metrics.actualBoundingBoxLeft * -1;
    const my = metrics.actualBoundingBoxAscent * -1; 
    const mw = metrics.actualBoundingBoxLeft   metrics.actualBoundingBoxRight;
    const mh = metrics.actualBoundingBoxAscent   metrics.actualBoundingBoxDescent;

    const x = (canvW -mw) *0.5 - mx; 
    const y = (canvH - mh) *0.5 - my; 

    context.save();
    context.translate(x, y);
    context.beginPath();
    context.rect(mx, my, mw, mh);
    context.stroke();
    context.fillText(text, 0, 0);
    context.restore();

    const onKeyUp = (e) => {
        text = e.key.toUpperCase();
        manager.render();
    };

    document.addEventListener("keyup", onKeyUp);

    </script>
    
</body>
</html>

ies I hardly understand.

CodePudding user response:

Your function call manager.render() results in an error as it's not present in the provided code snippet. I created one and moved your drawing stuff into it. The render function takes the input as an argument. Besides that I just had to add clearRect() to prevent overlapping letters.

// Get id from the canvas element
var canvas = document.getElementById("myCanvas");

// Provide 2D rendering context for the drawing surface of canvas
var context = canvas.getContext("2d");

// Get width and height of the canvas element
var canvW = document.getElementById("myCanvas").width;
var canvH = document.getElementById("myCanvas").height;


context.fillStyle = "#a60000";
context.font = "700px serif"; 
render("t");

function render(text) {
  // Measure the size of the letter and the specific font
  // Always centers the letter regardless of size
  // Display size of letter 
  const metrics = context.measureText(text);
  const mx = metrics.actualBoundingBoxLeft * -1;
  const my = metrics.actualBoundingBoxAscent * -1; 
  const mw = metrics.actualBoundingBoxLeft   metrics.actualBoundingBoxRight;
  const mh = metrics.actualBoundingBoxAscent   metrics.actualBoundingBoxDescent;

  const x = (canvW -mw) *0.5 - mx; 
  const y = (canvH - mh) *0.5 - my; 

  context.clearRect(0,0,canvas.width,canvas.height)
  context.save();
  context.translate(x, y);
  context.beginPath();
  context.rect(mx, my, mw, mh);
  context.stroke();
  context.fillText(text, 0, 0);
  context.restore();
}

const onKeyUp = (e) => {
  const text = e.key.toUpperCase();
  render(text);
};

document.addEventListener("keyup", onKeyUp);
body {
    background-color: #000000;
}

canvas {
    padding: 0;
    margin: auto;
    display: block;
    position: absolute;
    top: 0;
    bottom: 0;
    left: 0;
    right: 0;
    background-color: #111416; 
    border: 10px solid #a60000;
    border-style: double;
    box-shadow: 0 0 20px 5px #a60000;
}
<canvas id="myCanvas" width="800" height="800"></canvas>   

CodePudding user response:

The problem is that you dont redraw the canvas again after the hitting the button. For that you have to call the method context.clearRect(0, 0, canvas.width, canvas.height);In the eventlistener you have to call a function to redraw by wrapping your logic into a function. Now you can pass to the function the text as parameter you want to have rendered. Working Example:

code:

const redraw = function (text) {
  var canvas = document.getElementById('myCanvas');

  // Provide 2D rendering context for the drawing surface of canvas
  var context = canvas.getContext('2d');
  context.clearRect(0, 0, canvas.width, canvas.height);

  // Get width and height of the canvas element
  var canvW = document.getElementById('myCanvas').width;
  var canvH = document.getElementById('myCanvas').height;

  context.fillStyle = '#a60000';
  context.font = '700px serif';

  // Measure the size of the letter and the specific font
  // Always centers the letter regardless of size
  // Display size of letter

  const metrics = context.measureText(text);
  const mx = metrics.actualBoundingBoxLeft * -1;
  const my = metrics.actualBoundingBoxAscent * -1;
  const mw = metrics.actualBoundingBoxLeft   metrics.actualBoundingBoxRight;
  const mh = metrics.actualBoundingBoxAscent   metrics.actualBoundingBoxDescent;

  const x = (canvW - mw) * 0.5 - mx;
  const y = (canvH - mh) * 0.5 - my;
  context.save();
  context.translate(x, y);
  context.beginPath();
  context.rect(mx, my, mw, mh);
  context.stroke();
  context.fillText(text, 0, 0);
  context.restore();
};
redraw('I');

const onKeyUp = (e) => {
  text = e.key.toUpperCase();
  redraw(text);
};

document.addEventListener('keyup', onKeyUp);
  • Related