Skip to content

Instantly share code, notes, and snippets.

@motsu0
Created April 19, 2023 09:27
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save motsu0/83d6fe73aeca48b15e096646f1aeffa8 to your computer and use it in GitHub Desktop.
Save motsu0/83d6fe73aeca48b15e096646f1aeffa8 to your computer and use it in GitHub Desktop.
canvas text centering
const width_canvas = 400;
const height_canvas = 214;
drawText1();
function drawText1(){
//canvasを取得 ※ document.createElement('canvas') で作成しても可
const canvas = document.getElementById('canvas1');
canvas.width = width_canvas;
canvas.height = height_canvas;
const ctx = canvas.getContext('2d');
//フォント指定
ctx.font = '24px sans-selif';
//テキストを水平中央揃えに
ctx.textAlign= 'center';
//テキストを指定
const text = '1行の場合';
//x座標を計算
const x_pos = width_canvas / 2;
//テキストの高さを取得
const measure = ctx.measureText(text);
const height_text = measure.actualBoundingBoxAscent + measure.actualBoundingBoxDescent;
//y座標を計算
const y_pos = (height_canvas / 2) + (height_text / 2);
//テキストを描画
ctx.fillText(text, x_pos, y_pos);
/*
※以下はデモ用
*/
const height_line = height_canvas / 2;
ctx.strokeStyle = 'rgb(255 0 0 / .7)';
ctx.beginPath();
ctx.moveTo(0, height_line);
ctx.lineTo(width_canvas, height_line);
ctx.stroke();
}
const array_text2_o = new Array(3).fill('奇数行テキスト');
drawText2('canvas2-o', array_text2_o);
const array_text2_e = new Array(4).fill('偶数行テキスト');
drawText2('canvas2-e', array_text2_e);
function drawText2(id_canvas, array_text){
//canvasを取得 ※ document.createElement('canvas') で作成しても可
const canvas = document.getElementById(id_canvas);
canvas.width = width_canvas;
canvas.height = height_canvas;
const ctx = canvas.getContext('2d');
//フォント指定
ctx.font = '24px sans-selif';
//テキストを水平中央揃えに
ctx.textAlign= 'center';
//x座標を計算
const x_pos = width_canvas / 2;
//行数取得
const rows = array_text.length * 2 + 1;
//テキスト配列にそれぞれ計算・描画処理
array_text.forEach((text,i)=>{
//テキストの高さを取得
const measure = ctx.measureText(text);
const height_text = measure.actualBoundingBoxAscent + measure.actualBoundingBoxDescent;
//y座標を計算
const y_pos = (height_canvas * (i*2+1.5) / rows) + (height_text / 2);
//テキストを描画
ctx.fillText(text, x_pos, y_pos);
/*
※以下はデモ用
*/
const height_line = y_pos;
ctx.fillStyle = 'rgb(255 0 0 / .2)';
ctx.fillRect(0, y_pos, width_canvas, -height_text);
ctx.fillStyle = '#000';
});
}
const array_text3_o = new Array(3).fill('奇数行テキスト');
drawText3('canvas3-o', array_text3_o);
const array_text3_e = new Array(4).fill('偶数行テキスト');
drawText3('canvas3-e', array_text3_e);
function drawText3(id_canvas, array_text){
//canvasを取得 ※ document.createElement('canvas') で作成しても可
const canvas = document.getElementById(id_canvas);
canvas.width = width_canvas;
canvas.height = height_canvas;
const ctx = canvas.getContext('2d');
//フォント指定
ctx.font = '24px sans-selif';
//テキストを水平中央揃えに
ctx.textAlign= 'center';
//x座標を計算
const x_pos = width_canvas / 2;
//行数取得
const rows = array_text.length * 2;
//高さを取得
//テキスト配列にそれぞれ計算・描画処理
array_text.forEach((text,i)=>{
//テキストの高さを取得
const measure = ctx.measureText(text);
const height_text = measure.actualBoundingBoxAscent + measure.actualBoundingBoxDescent;
//y座標を計算
const y_pos = (height_canvas * (i*2+1) / rows) + (height_text / 2);
//テキストを描画
ctx.fillText(text, x_pos, y_pos);
/*
※以下はデモ用
*/
const height_line = y_pos;
ctx.fillStyle = 'rgb(255 0 0 / .2)';
ctx.fillRect(0, y_pos, width_canvas, -height_text);
ctx.fillStyle = '#000';
});
}
const array_text4_o = new Array(3).fill('奇数行テキスト');
drawText4('canvas4-o', array_text4_o);
const array_text4_e = new Array(4).fill('偶数行テキスト');
drawText4('canvas4-e', array_text4_e);
function drawText4(id_canvas, array_text){
//canvasを取得 ※ document.createElement('canvas') で作成しても可
const canvas = document.getElementById(id_canvas);
canvas.width = width_canvas;
canvas.height = height_canvas;
const ctx = canvas.getContext('2d');
//フォント指定
ctx.font = '24px sans-selif';
//テキストを水平中央揃えに
ctx.textAlign= 'center';
//x座標を計算
const x_pos = width_canvas / 2;
//行数取得
const rows = array_text.length;
//テキスト配列にそれぞれ計算・描画処理
array_text.forEach((text,i)=>{
//テキストの高さを取得
const measure = ctx.measureText(text);
const height_text = measure.actualBoundingBoxAscent + measure.actualBoundingBoxDescent;
//y座標を計算
const y_pos = (height_canvas * (i+1) / (rows+1)) + (height_text / 2);
//テキストを描画
ctx.fillText(text, x_pos, y_pos);
/*
※以下はデモ用
*/
const height_line = height_canvas * (i+1) / (rows+1);
ctx.strokeStyle = 'rgb(255 0 0 / .7)';
ctx.beginPath();
ctx.moveTo(0, height_line);
ctx.lineTo(width_canvas, height_line);
ctx.stroke();
});
}
const array_text5_o = new Array(3).fill('奇数行テキスト');
drawText5('canvas5-o-0', array_text5_o, 0);
drawText5('canvas5-o-20', array_text5_o, 20);
const array_text5_e = new Array(4).fill('偶数行テキスト');
drawText5('canvas5-e-0', array_text5_e, 0);
drawText5('canvas5-e-20', array_text5_e, 20);
function drawText5(id_canvas, array_text, gap){
//canvasを取得 ※ document.createElement('canvas') で作成しても可
const canvas = document.getElementById(id_canvas);
canvas.width = width_canvas;
canvas.height = height_canvas;
const ctx = canvas.getContext('2d');
//フォント指定
ctx.font = '24px sans-selif';
//テキストを水平中央揃えに
ctx.textAlign= 'center';
//x座標を計算
const x_pos = width_canvas / 2;
//行数取得
const rows = array_text.length;
//中央の行の順番を取得 ※偶数行の場合は中央すぐ上の行
const center_row = Math.ceil(rows / 2) - 1;
console.log('center_row',center_row);
//テキスト配列にそれぞれ計算・描画処理
array_text.forEach((text,i)=>{
//テキストの高さを取得
const measure = ctx.measureText(text);
const height_text = measure.actualBoundingBoxAscent + measure.actualBoundingBoxDescent;
//y座標を計算
//中央に対する差分を計算
const diff_y_single = (i - center_row) * height_text;
//奇数行の場合はテキストを半分ずらす
const diff_y_half = (rows%2===0) ? 0 : height_text/2;
//gapにより差分を計算
const diff_y_gap = (()=>{
//奇数行の中央の場合
if(rows%2===1&&center_row===i) return 0;
//奇数行の場合
if(rows%2===1){
return (i - center_row) * gap;
}
//偶数行の場合
return (i - center_row - .5) * gap;
})();
const y_pos = (height_canvas / 2 ) + (diff_y_single + diff_y_half + diff_y_gap);
//テキストを描画
ctx.fillText(text, x_pos, y_pos);
});
/*
※以下はデモ用
*/
const height_line = height_canvas / 2;
ctx.strokeStyle = 'rgb(255 0 0 / .7)';
ctx.beginPath();
ctx.moveTo(0, height_line);
ctx.lineTo(width_canvas, height_line);
ctx.stroke();
ctx.textAlign= 'left';
ctx.fillStyle = '#e00000';
ctx.font = '20px sans-selif';
const text_demo = `gap: ${gap}px`;
const measure_demo = ctx.measureText(text_demo);
const height_demo = measure_demo.actualBoundingBoxAscent + measure_demo.actualBoundingBoxDescent;
ctx.fillText(text_demo, 4, height_demo);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment