中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Canvaskit快速入門實例代碼分析

發布時間:2023-03-15 16:38:13 來源:億速云 閱讀:307 作者:iii 欄目:開發技術

這篇“Canvaskit快速入門實例代碼分析”文章的知識點大部分人都不太理解,所以小編給大家總結了以下內容,內容詳細,步驟清晰,具有一定的借鑒價值,希望大家閱讀完這篇文章能有所收獲,下面我們一起來看看這篇“Canvaskit快速入門實例代碼分析”文章吧。

CanvasKit快速開始

CanvasKit 是一個 wasm 模塊,它使用 Skia 去繪制畫布元素,是一個比canvas API更高級的功能集。

一、最小應用

這個例子是一個最小的 Canvaskit 應用程序,它為一幀繪制一個圓角矩形。它從 unpkg.com 中提取 wasm 二進制文件,但您也可以自己構建和托管它。

<canvas id=foo width=300 height=300></canvas>

<script type="text/javascript"
  src="https://unpkg.com/canvaskit-wasm@0.19.0/bin/canvaskit.js"></script>
<script type="text/javascript">
  
  const ckLoaded = CanvasKitInit({
    locateFile: (file) => 'https://unpkg.com/canvaskit-wasm@0.19.0/bin/'+file});
  	ckLoaded.then((CanvasKit) => {
    	const surface = CanvasKit.MakeCanvasSurface('foo');
      const paint = new CanvasKit.Paint();
      paint.setColor(CanvasKit.Color4f(0.9, 0, 0, 1.0));
      paint.setStyle(CanvasKit.PaintStyle.Stroke);
      paint.setAntiAlias(true);
      const rr = CanvasKit.RRectXY(CanvasKit.LTRBRect(10, 60, 210, 260), 25, 15);
      function draw(canvas) {
        canvas.clear(CanvasKit.WHITE);
        canvas.drawRRect(rr, paint);
      }
      surface.drawOnce(draw);
  });
</script>

Canvaskit快速入門實例代碼分析

二、代碼解釋

<canvas id=foo width=300 height=300></canvas>

創建 CanvasKit 將繪制到的畫布。這個元素是我們控制繪圖緩沖區的寬度和高度的地方,而它的 css 樣式將控制在繪制到這些像素后應用的任何縮放。盡管使用了畫布元素,CanvasKit 并沒有調用 HTML 畫布自己的繪制方法。它使用此畫布元素獲取 WebGL2 上下文并使用編譯為 WebAssembly 的 C++ 代碼執行大部分繪圖工作,然后在每幀結束時向 GPU 發送命令。

<script type="text/javascript"
  src="https://unpkg.com/canvaskit-wasm@0.19.0/bin/canvaskit.js"></script>
const ckLoaded = CanvasKitInit({locateFile: (file) => 'https://unpkg.com/canvaskit-wasm@0.19.0/bin/'+file});

加載canvaskit和wasm相關的二進制文件

CanvasKitInit接受一個函數參數,允許您更改它將嘗試查找canvaskit.wasm的路徑,該函數的返回值是一個promise,解析為加載的模塊,通常將其命名為 CanvasKit。

const surface = CanvasKit.MakeCanvasSurface('foo');

創建一個與上面的 HTML canvas 元素關聯的 Surface。但可以通過調用 MakeSWCanvasSurface 來覆蓋。 MakeCanvasSurface 也是可以指定替代顏色空間或 gl 屬性的地方。這個Surface會硬件加速

const paint = new CanvasKit.Paint();
paint.setColor(CanvasKit.Color4f(0.9, 0, 0, 1.0));
paint.setStyle(CanvasKit.PaintStyle.Stroke);
paint.setAntiAlias(true);
const rr = CanvasKit.RRectXY(CanvasKit.LTRBRect(10, 60, 210, 260), 25, 15);

創建繪畫,描述如何在 canvaskit 中填充或描邊矩形、路徑、文本和其他幾何圖形。 rr 是一個圓角矩形,其角在 x 軸上的半徑為 25像素,在 y 軸上的半徑為 15 個像素。

function draw(canvas) {
  canvas.clear(CanvasKit.WHITE);
  canvas.drawRRect(rr, paint);
}

定義一個函數來繪制。函數參數需要提供一個 Canvas 對象,我們可以在該對象上進行繪制調用。先清除畫布再繪制圓角矩形。

我們還刪除了 paint 對象。必須刪除使用 new 創建的 CanvasKit 對象或以 make 為前綴的方法才能釋放 wasm 內存。 Javascript 的 GC 不會自動處理它。 rr 只是一個數組,不是用 new 創建的,也沒有指向任何 WASM 內存,所以我們不必對其調用 delete。

surface.drawOnce(draw);
paint.delete()

將繪圖函數交給 surface.drawOnce 進行調用并刷新表面。刷新后,Skia 將批處理并發送 WebGL 命令,使可見的變化出現在屏幕上。此示例繪制一次并處理表面,這就是一個一個canvaskit的最小應用程序。

三、基本繪制循環

如果我們需要每一幀都重繪到畫布上怎么辦?此示例像 90 年代的屏幕保護程序一樣彈跳圓角矩形。

ckLoaded.then((CanvasKit) => {
  const surface = CanvasKit.MakeCanvasSurface('foo');

  const paint = new CanvasKit.Paint();
  paint.setColor(CanvasKit.Color4f(0.9, 0, 0, 1.0));
  paint.setStyle(CanvasKit.PaintStyle.Stroke);
  paint.setAntiAlias(true);
  // const rr = CanvasKit.RRectXY(CanvasKit.LTRBRect(10, 60, 210, 260), 25, 15);
  const w = 100; // size of rect
  const h = 60;
  let x = 10; // initial position of top left corner.
  let y = 60;
  let dirX = 1; // box is always moving at a constant speed in one of the four diagonal directions
  let dirY = 1;

  function drawFrame(canvas) {
    // boundary check
    if (x < 0 || x+w > 300) {
      dirX *= -1; // reverse x direction when hitting side walls
    }
    if (y < 0 || y+h > 300) {
      dirY *= -1; // reverse y direction when hitting top and bottom walls
    }
    // move
    x += dirX;
    y += dirY;

    canvas.clear(CanvasKit.WHITE);
    const rr = CanvasKit.RRectXY(CanvasKit.LTRBRect(x, y, x+w, y+h), 25, 15);
    canvas.drawRRect(rr, paint);
    surface.requestAnimationFrame(drawFrame);
  }
  surface.requestAnimationFrame(drawFrame);
});

這里的主要區別是我們定義了一個在繪制每一幀之前要調用的函數,并將其傳遞給 surface.requestAnimationFrame(drawFrame);該回調被交給畫布并處理沖洗。

創建一個函數作為我們的主要繪圖循環。每次要渲染一幀(瀏覽器通常以 60fps 為目標)時,都會調用我們的函數,我們用白色清除畫布,重新繪制圓形矩形,然后調用 surface.requestAnimationFrame(drawFrame) 注冊要再次調用的函數在下一幀之前。

surface.requestAnimationFrame(drawFrame) 結合了 window.requestAnimationFrame 和 surface.flush() 并且應該以相同的方式使用。如果您的應用程序只會因鼠標事件而做出可見更改,請不要在 drawFrame 函數末尾調用 surface.requestAnimationFrame。僅在處理鼠標輸入后調用它。

四、變形文本

CanvasKit 通過 HTML Canvas API 提供的最大功能之一是段落整形。要在您的應用程序中使用文本,請提供字體文件并在 CanvasKit 和字體文件準備就緒后使用 Promise.all 運行您的代碼。

const loadFont = fetch('https://storage.googleapis.com/skia-cdn/misc/Roboto-Regular.ttf')
  .then((response) => response.arrayBuffer());

Promise.all([ckLoaded, loadFont]).then(([CanvasKit, robotoData]) => {
  const surface = CanvasKit.MakeCanvasSurface('foo3');
  const canvas = surface.getCanvas();
  canvas.clear(CanvasKit.Color4f(0.9, 0.9, 0.9, 1.0));

  const fontMgr = CanvasKit.FontMgr.FromData([robotoData]);
  const paraStyle = new CanvasKit.ParagraphStyle({
    textStyle: {
      color: CanvasKit.BLACK,
      fontFamilies: ['Roboto'],
      fontSize: 28,
    },
    textAlign: CanvasKit.TextAlign.Left,
  });
  const text = 'Any sufficiently entrenched technology is indistinguishable from Javascript';
  const builder = CanvasKit.ParagraphBuilder.Make(paraStyle, fontMgr);
  builder.addText(text);
  const paragraph = builder.build();
  paragraph.layout(290); // width in pixels to use when wrapping text
  canvas.drawParagraph(paragraph, 10, 10);
  surface.flush();
});
const fontMgr = CanvasKit.FontMgr.FromData([robotoData]);

創建一個對象,該對象按名稱為 CanvasKit 中的各種文本工具提供字體。如果需要,您可以在此語句中加載多種字體。

const paraStyle = new CanvasKit.ParagraphStyle({
  textStyle: {
    color: CanvasKit.BLACK,
    fontFamilies: ['Roboto'],
    fontSize: 28,
  },
  textAlign: CanvasKit.TextAlign.Left,
});

指定文本的樣式。字體名稱 Roboto 將用于從字體管理器中獲取它。您可以指定 (color) 或 (foregroundColor and backgroundColor) 以突出顯示。有關 API 的完整文檔,請查看 npm 包的類型/子文件夾或 Skia 存儲庫中的 Typescript 定義。

const builder = CanvasKit.ParagraphBuilder.Make(paraStyle, fontMgr);
builder.addText(text);
const paragraph = builder.build();

接下來,我們創建一個帶有樣式的 ParagraphBuilder,添加一些文本,并使用 build() 完成它。并且,我們可以在一個段落中使用多個 TextStyles

const builder = CanvasKit.ParagraphBuilder.Make(paraStyle, fontMgr);
builder.addText(text1);
const boldTextStyle = CanvasKit.TextStyle({
    color: CanvasKit.BLACK,
    fontFamilies: ['Roboto'],
    fontSize: 28,
    fontStyle: {'weight': CanvasKit.FontWeight.Bold},
})
builder.pushStyle(boldTextStyle);
builder.addText(text2);
builder.pop();
builder.addText(text3);
const paragraph = builder.build();

最后,我們對段落進行布局,將文本包裝到特定寬度,然后將其繪制到畫布上

paragraph.layout(290); // width in pixels to use when wrapping text
canvas.drawParagraph(paragraph, 10, 10); // (x, y) position of left top corner of paragraph.

以上就是關于“Canvaskit快速入門實例代碼分析”這篇文章的內容,相信大家都有了一定的了解,希望小編分享的內容對大家有幫助,若想了解更多相關的知識內容,請關注億速云行業資訊頻道。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

林口县| 桂阳县| 安泽县| 阳信县| 临沧市| 宁乡县| 新巴尔虎左旗| 分宜县| 通榆县| 上犹县| 青海省| 易门县| 巴林左旗| 乃东县| 台东市| 婺源县| 天等县| 晋城| 枞阳县| 新田县| 清涧县| 长白| 鸡东县| 交城县| 英吉沙县| 巴彦淖尔市| 遂昌县| 永泰县| 讷河市| 巴里| 台中市| 织金县| 惠东县| 滕州市| 晋中市| 万盛区| 霍林郭勒市| 新乐市| 林州市| 密云县| 龙川县|