今天來整理一下在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
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
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
另外,可以利用 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
//---------------------
第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設定字型
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