五、Canvas基本繪圖

Canvas繪圖(四)

本章將介紹Canvas渲染文本方面的操作垦搬,而對(duì)于瀏覽器的支持度參差不齊网严,可以使用modernizr.js這個(gè)庫(kù)提供支持识樱,注意Canvas的文本不能使用css樣式,但是它的屬性與css屬性相似震束。

本章內(nèi)容較少

  • 基本文本
  • 文本漸變動(dòng)畫(huà)

一怜庸、基本文本

要在Canvas上顯示文本,首先需要通過(guò) font 設(shè)置文本的屬性

  • font-style[normal | italic | oblique ]
  • font-weight [normal | bold | border | lighter | 100~900 | auto | inherit | auto ]
  • font-size
  • font-face [serif | sans-serif | cursive | fantasy | monospace ]

例如

drawText() {
    this.context.font = "50px serif";
    this.context.font = "normal bold 50px serif";
    this.context.fillStyle = "#ff0000";
    this.context.fillText("Hellow World", 100, 80);
}

A. 表單與畫(huà)布通信

與DOM綁定事件沒(méi)有什么不同垢村,綁定事件需要重繪整個(gè)Canvas

setup() {
    this.bindEvent();
}

bindEvent() {
    const formElement = document.getElementById("textBox");
    formElement.addEventListener(
        "keyup",
        this._textBoxChange.bind(this),
        false
    );
}

_textBoxChange(e) {
    this.message = e.target.value;
    this.drawScreen();
}

drawScreen() {
    this.context.fillStyle = "#ff0000";
    this.context.fillText(this.message, 100, 80);
}

B. MeasureText

Canvas有一個(gè)用于返回字體在當(dāng)前環(huán)境的文本屬性

接口 說(shuō)明
measureText(str) 返回一個(gè)TextMetrics對(duì)象割疾,該對(duì)象包含文本的屬性

a . 居中地輸入文本

drawScreen() {
    this.context.fillStyle = "#ff0000";
    const metrics = this.context.measureText(this.message);
    const textWidth = metrics.width;
    const xPosition = this.theCanvas.width / 2 - textWidth / 2;
    this.context.fillText(this.message, xPosition, 80);
}

b. 計(jì)算文本高度

TextMetrics對(duì)象并不包含高度屬性,我們現(xiàn)階段只能簡(jiǎn)單的將文本渲染在畫(huà)布中央

const yPosition = this.theCanvas.height / 2;
this.context.fillText(this.message, xPosition, yPosition);

C. StrokeText

strokeText()這個(gè)方法與fillText()類似嘉栓,但前者是描邊的效果宏榕,方法如下

接口 說(shuō)明
strokeText(text,x,y,maxWidth) 在畫(huà)布上使用文本筆觸進(jìn)行描邊

還可以使用strokeStyle()方法設(shè)置描邊的顏色

this.context.strokeStyle = '#66ccff'
this.context.strokeText(this.message, xPosition, yPosition);

D. 基線與對(duì)齊

a. 垂直對(duì)齊

可以通過(guò)設(shè)置context.textBaseline來(lái)對(duì)基線進(jìn)行設(shè)置,例如 :

  • top : 文本頂端
  • hanging : 比top稍低
  • middle : 絕對(duì)垂直居中于基線
  • alphabetic : 垂直書(shū)寫(xiě)字體的底部侵佃,例如阿拉伯文麻昼、拉丁文與西伯來(lái)文
  • bottom : 文本底部

b. 水平對(duì)齊

context.textAlign設(shè)置關(guān)于x軸的文本位置,它有以下屬性

  • center : 文本絕對(duì)水平居中
  • start : 從y軸前端開(kāi)始顯示
  • end : 從y軸末尾開(kāi)始顯示
  • left : 文本最左端從y軸位置開(kāi)始
  • right : 文本最右端從y軸位置開(kāi)始

E. 全局陰影趣钱、漸變涌献、圖案

陰影與透明度對(duì)文字也是有效的

this.context.shadowOffsetX = this.shadowOffsetX;
this.context.shadowOffsetY = this.shadowOffsetY;
this.context.shadowColor = this.shadowColor;
this.context.shadowBlur = this.shadowBlur;

文本漸變應(yīng)用前幾章的學(xué)習(xí)的漸變效果胚宦,需要注意的是首有,在創(chuàng)建線性漸變時(shí)燕垃,起點(diǎn)需要位于文本開(kāi)始處并結(jié)束于文本寬度。例如 :

const metrics = this.context.measureText(this.message)
const textWidth = metrics.width 
const gradient = this.context.createLinerGradient(100,100,textWidth,100)
gradient.addColorStop(0,'#000')
gradient.addColorStop(.5,'#fff')
this.context.fillStyle = gradient

若要使用圖案填充井联,則需要調(diào)用Canvas環(huán)境的createPattern卜壕,再

const pattern = this.context.createPattern(patternImg,'repeat')
this.context.fillStyle = pattern

實(shí)例 : 文本處理器

1601784040135.png

代碼貼在另外一篇文章

二、文字動(dòng)畫(huà)

Canvas的動(dòng)畫(huà)比HTML強(qiáng)得多烙常,例如在使用漸變效果時(shí)轴捎,不僅能編輯文本,還能動(dòng)態(tài)創(chuàng)建文本蚕脏,例如做一個(gè)漸變的文字動(dòng)畫(huà)

import "@s/assets/style/normalize.scss";
import helloworld from "@s/assets/images/helloworld.jpg";

class CanvasApp {
  constructor() {
    this.theCanvas = document.getElementById("canvasOne");
    this.context = this.theCanvas.getContext("2d");
    this.fadeIn = true;
    this.text = "Hello World";
    this.alpha = 0;
    this.colorStops = [
      {
        color: "#ff0000",
        stopPercent: 0,
      },
      {
        color: "#ffff00",
        stopPercent: 0.125,
      },
      {
        color: "#00ff00",
        stopPercent: 0.375,
      },
      {
        color: "#0000ff",
        stopPercent: 0.625,
      },
      {
        color: "#ff00ff",
        stopPercent: 0.875,
      },
      {
        color: "#ff0000",
        stopPercent: 1,
      },
    ];
  }
  setup() {
    const helloWorldImage = new Image();
    helloWorldImage.onload = () => {
      this.context.drawImage(helloWorldImage, 0, 0, 720, 300);
    };
    helloWorldImage.src = helloworld;
    this.gameLoop(this.drawScreen);
  }
  gameLoop(callback) {
    window.requestAnimationFrame(this.gameLoop.bind(this, callback));
    callback.call(this);
  }
  drawScreen() {
    const gradient = this.context.createLinearGradient(
      this.theCanvas.width / 2,
      0,
      this.theCanvas.width / 2,
      this.theCanvas.height
    );

    this.colorStops.forEach((stop) => {
      const tempColor = stop.color;
      let tempStopPercent = stop.stopPercent;
      gradient.addColorStop(tempStopPercent, tempColor);
      tempStopPercent += 0.015;
      if (tempStopPercent > 1) {
        tempStopPercent = 0;
      }
      stop.stopPercent = tempStopPercent;
    });
    this.context.globalAlpha = 1;
    this.context.fillStyle = gradient;
    this.context.fillRect(0, 0, 720, 300);
    this.context.font = "72px Sans-Serif";
    this.context.textBaseline = "top";
    this.context.fillStyle = "#ffffff";
    this.context.fillText(this.text, 150, 120);
  }
}

new CanvasApp().setup();
1601809888796.png
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末侦副,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子驼鞭,更是在濱河造成了極大的恐慌秦驯,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,576評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件挣棕,死亡現(xiàn)場(chǎng)離奇詭異译隘,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)洛心,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,515評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門(mén)固耘,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人词身,你說(shuō)我怎么就攤上這事厅目。” “怎么了偿枕?”我有些...
    開(kāi)封第一講書(shū)人閱讀 168,017評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵璧瞬,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我渐夸,道長(zhǎng)嗤锉,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 59,626評(píng)論 1 296
  • 正文 為了忘掉前任墓塌,我火速辦了婚禮瘟忱,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘苫幢。我一直安慰自己访诱,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,625評(píng)論 6 397
  • 文/花漫 我一把揭開(kāi)白布韩肝。 她就那樣靜靜地躺著触菜,像睡著了一般。 火紅的嫁衣襯著肌膚如雪哀峻。 梳的紋絲不亂的頭發(fā)上涡相,一...
    開(kāi)封第一講書(shū)人閱讀 52,255評(píng)論 1 308
  • 那天哲泊,我揣著相機(jī)與錄音,去河邊找鬼催蝗。 笑死切威,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的丙号。 我是一名探鬼主播先朦,決...
    沈念sama閱讀 40,825評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼犬缨!你這毒婦竟也來(lái)了喳魏?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 39,729評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤怀薛,失蹤者是張志新(化名)和其女友劉穎截酷,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體乾戏,經(jīng)...
    沈念sama閱讀 46,271評(píng)論 1 320
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡迂苛,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,363評(píng)論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了鼓择。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片三幻。...
    茶點(diǎn)故事閱讀 40,498評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖呐能,靈堂內(nèi)的尸體忽然破棺而出念搬,到底是詐尸還是另有隱情,我是刑警寧澤摆出,帶...
    沈念sama閱讀 36,183評(píng)論 5 350
  • 正文 年R本政府宣布朗徊,位于F島的核電站,受9級(jí)特大地震影響偎漫,放射性物質(zhì)發(fā)生泄漏爷恳。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,867評(píng)論 3 333
  • 文/蒙蒙 一象踊、第九天 我趴在偏房一處隱蔽的房頂上張望温亲。 院中可真熱鬧,春花似錦杯矩、人聲如沸栈虚。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,338評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)魂务。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間粘姜,已是汗流浹背蚣驼。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,458評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留相艇,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,906評(píng)論 3 376
  • 正文 我出身青樓纯陨,卻偏偏與公主長(zhǎng)得像坛芽,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子翼抠,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,507評(píng)論 2 359