您好,登錄后才能下訂單哦!
這篇“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>
<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快速入門實例代碼分析”這篇文章的內容,相信大家都有了一定的了解,希望小編分享的內容對大家有幫助,若想了解更多相關的知識內容,請關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。