iT邦幫忙

2022 iThome 鐵人賽

DAY 11
0
Modern Web

從新開始學習p5.js畫出一片天系列 第 11

D11_文字與字型操作

  • 分享至 

  • xImage
  •  

文字與字型操作

今天來整理一下在p5.js中,有關字型的操作
主要分為字體的載入,設定,大小,對齊,長度,換行的功能

載入字型檔與字型設定

第1種利用 loadFont("assets/Noto_Sans_TC/NotoSansTC-Light.otf"); 載入字型檔
字型檔的格式 支援 .otf, .ttf

網路上有一些免費的字型檔可以先行下載。
Google Fonts
https://fonts.google.com/

一般來說載入字型的順序,會先在 preload() 的程式區段,執行loadFont();

let can;
let font1;
let font2;
function preload() {
	font1 = loadFont("assets/Noto_Sans_TC/NotoSansTC-Light.otf");
	font2 = loadFont("assets/Noto_Serif_TC/NotoSerifTC-Regular.otf");
}

function setup() {

	can = createCanvas(400, 400); 
	can.id("can1");
	can.class("c1");
	can.position(0, 0);
	background(0);

	noFill();
	stroke(255, 255, 0);
	rect(0, 0, 64*3, 64);
	rect(0, 0, 64*3, 64*2);

	fill(255);
	//noStroke();
	textSize(64);
	textAlign(LEFT, TOP);

	textFont(font1);
	text("鐵人賽", 0, 0);
	//text("鐵人賽", 0, 0-17);
	
	textFont(font2);
	text("鐵人賽", 0, 64);
	//text("鐵人賽", 0, 64-17);
	
}

textFont(font1); //-- 設定字型
textSize(64); //-- 設定字型大小
textAlign(LEFT, TOP); //-- 設定字型對齊方式
text("鐵人賽", 0, 0); //-- 在canvas中,在座標(0, 0)顯示文字

text(str, x, y); 在座標(x, y)顯示文字
文字的預設基準點在左下角
textAlign(LEFT, BASELINE);

textAlign(horizAlign, vertAlign);
horizAlign 水平對齊:LEFT, CENTER, or RIGHT
vertAlign 垂直對齊:TOP, BOTTOM, CENTER, or BASELINE

若要設定基準點在左上角
textAlign(LEFT, TOP);

若要設定基準點在中間,置中對齊
textAlign(CENTER, CENTER);

目前 Google Fonts 支援的中文字型有
Noto Sans Traditional Chinese (思源黑體)
https://fonts.google.com/noto/specimen/Noto+Sans+TC?subset=chinese-traditional

Noto Serif Traditional Chinese (思源宋體)
https://fonts.google.com/noto/specimen/Noto+Serif+TC?subset=chinese-traditional

https://ithelp.ithome.com.tw/upload/images/20220925/201520986tGORUNX5r.png

文字間隔偏移

Google Fonts的中文字,在字的上方會預留一些padding間隔

假設 textSize(64); 字型大小設定為64,代表每個字的寬高大小是 64px,
若設定字型對齊為 textAlign(LEFT, TOP); 代表靠左上對齊,
當畫了一個方形 rect(0, 0, 192, 64); 原則上字應該要完全呈現在方形中,
結果是字有點向下偏移,大約有17px的偏移,因此,在字的y軸座標上就要 -17,
這樣就會順利讓字出現在方形中

noFill();
stroke(255, 255, 0);
rect(0, 0, 64*3, 64);
rect(0, 0, 64*3, 64*2);

textSize(64);
textAlign(LEFT, TOP);

textFont(font1);
text("鐵人賽", 0, 0);

textFont(font2);
text("鐵人賽", 0, 64);

文字間隔偏移1
文字間隔偏移1

noFill();
stroke(255, 255, 0);
rect(0, 0, 64*3, 64);
rect(0, 0, 64*3, 64*2);

textSize(64);
textAlign(LEFT, TOP);
    
textFont(font1);
text("鐵人賽", 0, 0-17);

textFont(font2);
text("鐵人賽", 0, 64-17);

文字間隔偏移2
文字間隔偏移2

取得文字得方形外框

另外,可以利用 let bbox = font.textBounds(textString, x, y, fontSize) 來取得文字方形外框

let font1 = loadFont("assets/Noto_Sans_TC/NotoSansTC-Light.otf");
let textString = "鐵人賽";
textSize(64);
textAlign(LEFT, TOP);
textFont(font1);
text(textString, 0, 0-17);
let bbox = font1.textBounds(textString, 0, 0-17, 64);
rect(bbox.x, bbox.y, bbox.w, bbox.h);

文字方形外框
文字方形外框

取得文字輪廓線座標點

利用 let points = font.textToPoints(txt, x, y, fontSize);

let font1 = loadFont("assets/Noto_Sans_TC/NotoSansTC-Light.otf");
textSize(64);
textAlign(LEFT, TOP);
textFont(font1);
textString = "鐵人賽";

points = font1.textToPoints(textString, 0, 0-17, 64);
fill(0, 255, 255);
stroke(0, 0, 255);

translate(0, 64+10);
for(let p of points) {
    rect(p.x-2, p.y-2, 4, 4);
}

translate(0, 64);
beginShape();
for(let p of points) {
    vertex(p.x, p.y);
}
endShape(CLOSE);

文字輪廓線座標點
文字輪廓線座標點

文字的本身如果需要換行,可以使用 '\n' 換行字元
textString = "鐵\n人\n賽";

textFont(font1);
text("鐵\n人\n賽", 0, 0-17);

如果要取的文字的寬度,可以用 textWidth(textString)

textSize(64);
console.log(textWidth("鐵"));  //-- 64  
console.log(textWidth("1"));   //--  34.24
console.log(textWidth("2022")); //--  136.96
console.log(textWidth("鐵人賽")); //--  192
console.log(textWidth("2022鐵人賽")); //--  328.96

//---------------------

利用 index.html 匯入字型檔連結

第2種是 在index.html匯入字型檔連結

https://fonts.googleapis.com/css2?family=Noto+Sans+TC&display=swap
https://fonts.googleapis.com/css2?family=Noto+Serif+TC&display=swap

其中 Noto+Sans+TC 及 Noto+Serif+TC是字型名稱

<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Noto+Sans+TC&display=swap">
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Noto+Serif+TC&display=swap">

在 p5.js中 設定字型名稱程式碼如下
let font1 = "Noto Sans TC";
textFont(font1);

let can;
let font1;
let font2;
function preload() {
	font1 = "Noto Sans TC";
	font2 = "Noto Serif TC";
}

function setup() {
    can = createCanvas(400, 400); 
    can.id("can1");
    can.class("c1");
    can.position(10, 10);
    background(0);

    let textString = "鐵人賽";
    fill(255);
    noStroke();
    textSize(64);
    textAlign(LEFT, TOP);

    textFont(font1);
    text("鐵人賽", 0, 0);

    textFont(font2);
    text("鐵人賽", 0, 64);
}

使用 index.html 匯入的字型的方式,
在文字顯示的結果,沒有上方會預留一些padding間隔,算是比較準確的字型大小。
### 設定 DOM 的字型設定
將index.html中的div元件的id設定為a1,
接著利用 select("#a1").style('font-family', 'Noto Serif TC'); 設定字型

<div id="a1">鐵人賽</div>
select("#a1").style('font-family', 'Noto Serif TC');
select("#a1").style('font-size', '64px');
select("#a1").position(10, -17);

也可以在style.css設定字型

#a1 {
	font-family: "Noto Serif TC";
	font-size: 64px;
	position: absolute;
	left: 10px;
	top: -17px;
}
select("#a1").style("font-family", "Noto Serif TC");
select("#a1").style("font-size", "64px");
select("#a1").position(10, -17);

#a1 {
	font-family: "Noto Serif TC";
	font-size: 64px;
	position: absolute;
	left: 10px;
	top: -17px;
}

css的樣式屬性名稱及數值,不用特別加上引號,不過字型檔的名稱要特別加註引號
p5.js中的 style('font-family', 'Noto Serif TC'); 屬性名稱及數值都要加註引號

style.css設定字型
style.css設定字型

Sans-serif 無襯線體 (黑體):Noto Sans TC
Serif 襯線體:Noto Serif TC

參考資料
Google Fonts
https://fonts.google.com/
loadFont()
https://p5js.org/reference/#/p5/loadFont
p5.Font
https://p5js.org/reference/#/p5.Font
字體領域
https://www.twfont.com/
CSS Fonts
https://www.w3schools.com/css/css_font.asp


上一篇
D10_Graphics圖層操作
下一篇
D12_Audio聲音操作(聲音檔)
系列文
從新開始學習p5.js畫出一片天40
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言