計算 Canvas 帶邊框文字最大字體
是的,當文字有邊框(使用 ctx.strokeText 繪製)時,文字的實際渲染大小會受到 lineWidth 的影響。你需要考慮到邊框的寬度,以確保文字和邊框都在 Canvas 的固定尺寸內完整顯示。
<html>
<head>
<title>計算 Canvas 帶邊框文字最大字體</title>
<style>
#myCanvas {
border: 1px solid black;
}
</style>
</head>
<body>
<head>
<title>計算 Canvas 帶邊框文字最大字體</title>
<style>
#myCanvas {
border: 1px solid black;
}
</style>
</head>
<body>
<div>
<label for="inputText">輸入文字:</label>
<input type="text" id="inputText" value="Hello">
</div>
<div>
<label for="canvasWidth">Canvas 寬度:</label>
<input type="number" id="canvasWidth" value="300">
</div>
<div>
<label for="lineWidth">邊框寬度:</label>
<input type="number" id="lineWidth" value="2">
</div>
<button id="calculateBtn">計算並繪製</button>
<canvas id="myCanvas" width="300" height="100"></canvas>
<label for="inputText">輸入文字:</label>
<input type="text" id="inputText" value="Hello">
</div>
<div>
<label for="canvasWidth">Canvas 寬度:</label>
<input type="number" id="canvasWidth" value="300">
</div>
<div>
<label for="lineWidth">邊框寬度:</label>
<input type="number" id="lineWidth" value="2">
</div>
<button id="calculateBtn">計算並繪製</button>
<canvas id="myCanvas" width="300" height="100"></canvas>
<script>
const canvas = document.getElementById('myCanvas');
const ctx = canvas.getContext('2d');
const inputText = document.getElementById('inputText');
const calculateBtn = document.getElementById('calculateBtn');
const canvasWidthInput = document.getElementById('canvasWidth');
const lineWidthInput = document.getElementById('lineWidth');
function calculateMaxFontSizeWithStroke(text, maxWidth, lineWidth) {
let fontSize = 10;
ctx.font = `${fontSize}px sans-serif`;
ctx.lineWidth = lineWidth;
while (ctx.measureText(text).width + lineWidth * 2 < maxWidth) {
fontSize++;
ctx.font = `${fontSize}px sans-serif`;
ctx.lineWidth = lineWidth;
}
return fontSize - 1;
}
function drawTextWithStrokeToCanvas(text, fontSize, canvasWidth, canvasHeight, lineWidth) {
ctx.clearRect(0, 0, canvasWidth, canvasHeight);
ctx.font = `${fontSize}px sans-serif`;
ctx.lineWidth = lineWidth;
const textWidth = ctx.measureText(text).width;
const x = (canvasWidth - textWidth) / 2;
const y = canvasHeight / 2 + fontSize / 3; // 垂直居中
ctx.strokeStyle = 'blue'; // 邊框顏色
ctx.strokeText(text, x, y);
ctx.fillStyle = 'black'; // 文字顏色
ctx.fillText(text, x, y);
}
calculateBtn.addEventListener('click', function() {
const text = inputText.value;
const canvasWidth = parseInt(canvasWidthInput.value);
const lineWidth = parseInt(lineWidthInput.value);
canvas.width = canvasWidth;
const maxFontSize = calculateMaxFontSizeWithStroke(text, canvasWidth, lineWidth);
drawTextWithStrokeToCanvas(text, maxFontSize, canvasWidth, canvas.height, lineWidth);
});
// 初始繪製
const initialText = inputText.value;
const initialWidth = parseInt(canvasWidthInput.value);
const initialLineWidth = parseInt(lineWidthInput.value);
const initialFontSize = calculateMaxFontSizeWithStroke(initialText, initialWidth, initialLineWidth);
drawTextWithStrokeToCanvas(initialText, initialFontSize, initialWidth, canvas.height, initialLineWidth);
</script>
const canvas = document.getElementById('myCanvas');
const ctx = canvas.getContext('2d');
const inputText = document.getElementById('inputText');
const calculateBtn = document.getElementById('calculateBtn');
const canvasWidthInput = document.getElementById('canvasWidth');
const lineWidthInput = document.getElementById('lineWidth');
function calculateMaxFontSizeWithStroke(text, maxWidth, lineWidth) {
let fontSize = 10;
ctx.font = `${fontSize}px sans-serif`;
ctx.lineWidth = lineWidth;
while (ctx.measureText(text).width + lineWidth * 2 < maxWidth) {
fontSize++;
ctx.font = `${fontSize}px sans-serif`;
ctx.lineWidth = lineWidth;
}
return fontSize - 1;
}
function drawTextWithStrokeToCanvas(text, fontSize, canvasWidth, canvasHeight, lineWidth) {
ctx.clearRect(0, 0, canvasWidth, canvasHeight);
ctx.font = `${fontSize}px sans-serif`;
ctx.lineWidth = lineWidth;
const textWidth = ctx.measureText(text).width;
const x = (canvasWidth - textWidth) / 2;
const y = canvasHeight / 2 + fontSize / 3; // 垂直居中
ctx.strokeStyle = 'blue'; // 邊框顏色
ctx.strokeText(text, x, y);
ctx.fillStyle = 'black'; // 文字顏色
ctx.fillText(text, x, y);
}
calculateBtn.addEventListener('click', function() {
const text = inputText.value;
const canvasWidth = parseInt(canvasWidthInput.value);
const lineWidth = parseInt(lineWidthInput.value);
canvas.width = canvasWidth;
const maxFontSize = calculateMaxFontSizeWithStroke(text, canvasWidth, lineWidth);
drawTextWithStrokeToCanvas(text, maxFontSize, canvasWidth, canvas.height, lineWidth);
});
// 初始繪製
const initialText = inputText.value;
const initialWidth = parseInt(canvasWidthInput.value);
const initialLineWidth = parseInt(lineWidthInput.value);
const initialFontSize = calculateMaxFontSizeWithStroke(initialText, initialWidth, initialLineWidth);
drawTextWithStrokeToCanvas(initialText, initialFontSize, initialWidth, canvas.height, initialLineWidth);
</script>
</body>
</html>
</html>
在 while 迴圈的判斷條件中,我們將 ctx.measureText(text).width 加上了 lineWidth * 2。這是因為邊框會向文字的左右兩側擴展 lineWidth 的寬度。
加入了設定 ctx.lineWidth = lineWidth;。 使用了 ctx.strokeText(text, x, y); 來繪製邊框。 為了讓文字顯示在邊框內部,我們仍然使用 ctx.fillText(text, x, y); 繪製了填充的文字。你可以根據需要調整顏色。
留言
張貼留言