如何从 Canvas 和 JS 中的输入旋转动态文本?
How to rotate dynamic text from input in Canvas and JS?
我正在使用 Canvas 和 Javascript 进行一个框样式项目,但我无法按我想要的方式旋转文本(从下到上书写)。
(来源:hostpic.xyz)
我遵循了教程 (https://newspaint.wordpress.com/2014/05/22/writing-rotated-text-on-a-javascript-canvas/) 并尝试在我的代码中对其进行调整,但我做不到。
您可以在下面的 JSFiddle link 上找到代码,您可以在其中输入文本,在 JSFiddle 示例中应将其写为 "brand" 单词。
一切都在 init() 函数中:
function init() {
var elem = document.getElementById('elem');
var circle_canvas = document.createElement("canvas");
var context = circle_canvas.getContext("2d");
var img = new Image();
img.src = "https://unblast.com/wp-content/uploads/2018/11/Vertical-Product-Box-Mockup-1.jpg";
context.drawImage(img, 0, 0, 500, 650);
circle_canvas.width = 500;
circle_canvas.height = 650;
context.fillStyle = "#000000";
//context.textAlign = 'center';
var UserInput = document.getElementById("UserInput");
context.save();
context.translate( circle_canvas.width - 1, 0 );
UserInput.oninput = function() {
context.clearRect(0, 0, 500, 650);
context.drawImage(img, 0, 0, 500, 650);
var text = UserInput.value;
console.log(text);
if (text.length < 12) {
context.rotate(3*Math.PI/2);
console.log("-12");
context.font = "50px Righteous";
context.fillText(text, -350, -170);
context.restore();
} else {
context.rotate(3*Math.PI/2);
context.font = "25px Righteous";
context.fillText(text, -350, -170);
context.restore();
}
}
elem.appendChild(circle_canvas);
}
init();
我在 context.rotate() 函数中尝试了很多值,但无论如何我的文本都是颠倒的。
(来源:hostpic.xyz)
你离这里很近了。我建议执行 canvas 平移到屏幕中间 (width / 2, height / 2
) 然后旋转 270 度:
context.translate(canvas.width / 2, canvas.height / 2);
context.rotate(270 * Math.PI / 180);
除此之外,我建议进行一轮代码清理以避免不一致的变量名和硬编码数字(尝试使所有内容与 img.width
和 img.height
成正比,然后避免文字值。这使得它更容易动态调整您的代码,而无需重新键入所有值。您可以在 img.onload
函数触发后访问 img.width
和 img.height
。
另一个有用的函数是 context.measureText(text)
,它可以更简单地按比例缩放文本大小。
完整示例:
function init() {
var userInput = document.getElementById("user-input");
var elem = document.getElementById("elem");
var canvas = document.createElement("canvas");
var context = canvas.getContext("2d");
var img = new Image();
img.onload = function () {
canvas.width = img.width / 3;
canvas.height = img.height / 3;
context.drawImage(img, 0, 0, canvas.width, canvas.height);
context.fillStyle = "#000000";
context.textAlign = "center";
elem.appendChild(canvas);
userInput.oninput = function () {
var text = userInput.value;
var textSizePx = 50 - context.measureText(text).width / 10;
context.font = textSizePx + "px Righteous";
context.clearRect(0, 0, canvas.width, canvas.height);
context.drawImage(img, 0, 0, canvas.width, canvas.height);
context.save();
context.translate(canvas.width / 2, canvas.height / 2);
context.rotate(270 * Math.PI / 180);
context.fillText(text, 0, -canvas.width / 20);
context.restore();
}
};
img.src = "https://unblast.com/wp-content/uploads/2018/11/Vertical-Product-Box-Mockup-1.jpg";
}
init();
<div id="elem">
<input type="text" id="user-input" maxlength="15">
</div>
随着概念验证工作的进行,一个问题是在 canvas 上缩放图像会导致视觉伪影。这个问题可以通过with JS或者通过缩小源图像本身来解决,但是在这一点上,最好将图像作为一个元素来规避整个问题。
同样,也没有明显的理由在 canvas 上呈现文本;我们也可以为此制作一个元素。将文本移动到 HTML/CSS 可以更有效地改变它的外观(我在这里没有做太多样式,所以这是一个练习,可以让它更自然地融入图像)。
这是一个没有 canvas 的重写,看起来更干净并且应该更易于维护:
function init() {
var userInput = document.querySelector("#user-input");
var img = document.querySelector("#product-img");
var imgRect = img.getBoundingClientRect();
var overlayText = document.querySelector("#overlay-text");
var overlay = document.querySelector("#overlay");
overlay.style.width = (imgRect.width * 0.86) + "px";
overlay.style.height = imgRect.height + "px";
userInput.addEventListener("input", function () {
overlayText.innerText = userInput.value;
overlayText.style.fontSize = (50 - userInput.value.length * 2) + "px";
});
}
init();
#product-img {
position: absolute;
}
#overlay {
position: absolute;
display: flex;
}
#overlay-text {
font-family: Verdana, sans-serif;
color: #333;
transform: rotate(270deg);
margin: auto;
cursor: default;
}
<div>
<input type="text" id="user-input" maxlength="15">
</div>
<div id="product-container">
<img id="product-img" src="https://unblast.com/wp-content/uploads/2018/11/Vertical-Product-Box-Mockup-1.jpg" width=666 height=500 />
<div id="overlay">
<div id="overlay-text"></div>
</div>
</div>
我正在使用 Canvas 和 Javascript 进行一个框样式项目,但我无法按我想要的方式旋转文本(从下到上书写)。
(来源:hostpic.xyz)
我遵循了教程 (https://newspaint.wordpress.com/2014/05/22/writing-rotated-text-on-a-javascript-canvas/) 并尝试在我的代码中对其进行调整,但我做不到。
您可以在下面的 JSFiddle link 上找到代码,您可以在其中输入文本,在 JSFiddle 示例中应将其写为 "brand" 单词。
一切都在 init() 函数中:
function init() {
var elem = document.getElementById('elem');
var circle_canvas = document.createElement("canvas");
var context = circle_canvas.getContext("2d");
var img = new Image();
img.src = "https://unblast.com/wp-content/uploads/2018/11/Vertical-Product-Box-Mockup-1.jpg";
context.drawImage(img, 0, 0, 500, 650);
circle_canvas.width = 500;
circle_canvas.height = 650;
context.fillStyle = "#000000";
//context.textAlign = 'center';
var UserInput = document.getElementById("UserInput");
context.save();
context.translate( circle_canvas.width - 1, 0 );
UserInput.oninput = function() {
context.clearRect(0, 0, 500, 650);
context.drawImage(img, 0, 0, 500, 650);
var text = UserInput.value;
console.log(text);
if (text.length < 12) {
context.rotate(3*Math.PI/2);
console.log("-12");
context.font = "50px Righteous";
context.fillText(text, -350, -170);
context.restore();
} else {
context.rotate(3*Math.PI/2);
context.font = "25px Righteous";
context.fillText(text, -350, -170);
context.restore();
}
}
elem.appendChild(circle_canvas);
}
init();
我在 context.rotate() 函数中尝试了很多值,但无论如何我的文本都是颠倒的。
(来源:hostpic.xyz)
你离这里很近了。我建议执行 canvas 平移到屏幕中间 (width / 2, height / 2
) 然后旋转 270 度:
context.translate(canvas.width / 2, canvas.height / 2);
context.rotate(270 * Math.PI / 180);
除此之外,我建议进行一轮代码清理以避免不一致的变量名和硬编码数字(尝试使所有内容与 img.width
和 img.height
成正比,然后避免文字值。这使得它更容易动态调整您的代码,而无需重新键入所有值。您可以在 img.onload
函数触发后访问 img.width
和 img.height
。
另一个有用的函数是 context.measureText(text)
,它可以更简单地按比例缩放文本大小。
完整示例:
function init() {
var userInput = document.getElementById("user-input");
var elem = document.getElementById("elem");
var canvas = document.createElement("canvas");
var context = canvas.getContext("2d");
var img = new Image();
img.onload = function () {
canvas.width = img.width / 3;
canvas.height = img.height / 3;
context.drawImage(img, 0, 0, canvas.width, canvas.height);
context.fillStyle = "#000000";
context.textAlign = "center";
elem.appendChild(canvas);
userInput.oninput = function () {
var text = userInput.value;
var textSizePx = 50 - context.measureText(text).width / 10;
context.font = textSizePx + "px Righteous";
context.clearRect(0, 0, canvas.width, canvas.height);
context.drawImage(img, 0, 0, canvas.width, canvas.height);
context.save();
context.translate(canvas.width / 2, canvas.height / 2);
context.rotate(270 * Math.PI / 180);
context.fillText(text, 0, -canvas.width / 20);
context.restore();
}
};
img.src = "https://unblast.com/wp-content/uploads/2018/11/Vertical-Product-Box-Mockup-1.jpg";
}
init();
<div id="elem">
<input type="text" id="user-input" maxlength="15">
</div>
随着概念验证工作的进行,一个问题是在 canvas 上缩放图像会导致视觉伪影。这个问题可以通过with JS或者通过缩小源图像本身来解决,但是在这一点上,最好将图像作为一个元素来规避整个问题。
同样,也没有明显的理由在 canvas 上呈现文本;我们也可以为此制作一个元素。将文本移动到 HTML/CSS 可以更有效地改变它的外观(我在这里没有做太多样式,所以这是一个练习,可以让它更自然地融入图像)。
这是一个没有 canvas 的重写,看起来更干净并且应该更易于维护:
function init() {
var userInput = document.querySelector("#user-input");
var img = document.querySelector("#product-img");
var imgRect = img.getBoundingClientRect();
var overlayText = document.querySelector("#overlay-text");
var overlay = document.querySelector("#overlay");
overlay.style.width = (imgRect.width * 0.86) + "px";
overlay.style.height = imgRect.height + "px";
userInput.addEventListener("input", function () {
overlayText.innerText = userInput.value;
overlayText.style.fontSize = (50 - userInput.value.length * 2) + "px";
});
}
init();
#product-img {
position: absolute;
}
#overlay {
position: absolute;
display: flex;
}
#overlay-text {
font-family: Verdana, sans-serif;
color: #333;
transform: rotate(270deg);
margin: auto;
cursor: default;
}
<div>
<input type="text" id="user-input" maxlength="15">
</div>
<div id="product-container">
<img id="product-img" src="https://unblast.com/wp-content/uploads/2018/11/Vertical-Product-Box-Mockup-1.jpg" width=666 height=500 />
<div id="overlay">
<div id="overlay-text"></div>
</div>
</div>