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