DOM 和 Canvas 如何實現文字豎向排列的效果

前言

開發 H5 遇到過幾回豎排文字的需求,把實現思路梳理一下。javascript

關於豎排文字的一些需求

  1. 輸入框樣式需作成豎排樣式;
  2. 使用 Canvas 生成圖片供用戶保存,圖片中的文字方向爲豎排;
  3. 非漢字需與漢字垂直。

項目地址

DOM 實現文字豎排

<input> 標籤沒有豎排的屬性,最早嘗試修改 <input> 的樣式來實現效果,可是效果不理想。最後使用 HTML 的 contenteditable 屬性。css

嘗試修改 input 樣式(失敗)

想經過限定 輸入框的寬度文字的大小 ,讓文字自動換行。html

關鍵代碼

input{
    width: 30px;
    height: 250px;
    font-size: 30px;
}
複製代碼

放棄緣由

  • 英文字符寬度小,會出現換行失敗的狀況

使用 HTML 的 contenteditable 屬性代替 <input> (推薦)

HTML 的 contenteditable 屬性規定元素內容是否可編輯。java

關鍵代碼

<div contenteditable="true" style="writing-mode: vertical-lr; writing-mode: tb-lr; "></div>
複製代碼
  • 使用 div 代替 input
  • 使用 contenteditable 屬性使 div 可編輯
  • 使用 CSS 的 writing-mode 屬性讓文字垂直排列

使用緣由

  • 非中文自動旋轉,排版更好看(實現了需求中的第三點)

Canvas 實現文字豎排

Canvas 一樣沒有豎排文字的屬性,我經過遍歷文字的方式進行繪製。web

關鍵代碼

let name; // 文本內容
let x = 657,y=170; // 文字開始的座標
let letterSpacing = 10; // 設置字間距
for(let i = 0; i < this.name.length; i++){
    const str = this.name.slice(i,i+1).toString();
    if(str.match(/[A-Za-z0-9]/)&&(y<576)){ // 非漢字 旋轉
        ctx.save();
        ctx.translate(x,y);
        ctx.rotate(Math.PI/180*90);
        ctx.textBaseline = 'bottom';
        ctx.fillText(str,0,0);
        ctx.restore();
        y+=ctx.measureText(str).width+letterSpacing; // 計算文字寬度
    }else if(str.match(/[\u4E00-\u9FA5]/)&&(y<576)){
        ctx.save();
        ctx.textBaseline = 'top';
        ctx.fillText(str,x,y);
        ctx.restore();
        y+=ctx.measureText(str).width+letterSpacing; // 計算文字寬度
    }
}

複製代碼

推薦緣由

  • 非中文自動旋轉,排版更好看(實現了需求中的第三點)
  • 使用 measureText() 計算字符寬度,使中英文字間距更和諧
相關文章
相關標籤/搜索