Canvas 相當有趣的一項功能就是可以引入圖像,它可以用於圖片合成或製作背景等。而目前僅可在影像中加入文字(標準說明中並沒有包含繪製文字的功能)。只要是Gecko支援的圖像(如 PNG,GIF,JPEG等)都可以引入到 canvas 中,而且其它的 canvas 元素也可以作為圖像的來源。
引入圖像 importing images
引入圖像只需要簡單的兩步:
第一個當然是來源圖片,不是簡單的 URL 路徑,但可以是一個 JavaScript 的 Image 物件引用,或者其它的 canvas 元素。
然後用drawImage方法將影像插入 canvas 中。
先來看看第一步,基本上有四種可選方式:
引用頁面內的圖片Using images which are on the same page
我們可以透過document.images集合、document.getElementsByTagName方法又或者document.getElementById方法來取得頁面內的圖片(如果已知圖片元素的ID)。
使用其它 canvas 元素 Using other canvas elements和引用頁面內的圖片類似地,用document.getElementsByTagName或 document.getElementById方法來獲取其它 canvas 元素。但你引入的應該是已經準備好的 canvas。一個常用的應用是為另一個大的 canvas 做縮圖。
由零開始創建圖像Creating an image from scratch
另外,我們可以用腳本創建一個新的Image
對象,但這種方法的主要缺點是如果不希望腳本因為等待圖片裝置而暫停,還得需要突破預裝載。我們可以透過下面簡單的方法來建立圖片:
var img = new Image(); // Create new Image object img.src = 'myImage.png'; // Set source path
當腳本執行後,圖片開始裝載。若呼叫drawImage時,圖片沒裝載完,腳本會等待直至裝載完畢。如果不希望這樣,可以使用onload
事件:
var img = new Image(); // Create new Image object img.onload = function(){ // executedrawImage statements here } img.src = 'myImage.png'; // Set source path
如果你只用到一張圖片的話,這已經夠了。但一旦需要不只一張圖片,那就需要更複雜的處理方法,但圖片預載策略超出本教學的範圍,有興趣的話可以參考JavaScript Image Preloader。
透過 data: url 方式嵌入圖像 Embedding an image via data: url
我們也可以透過 data: url 方式來引用圖像。 Data urls 允許以一串 Base64 編碼的字串的方式來定義一個圖片。其優點就是圖片內容即時可用,無須再到伺服器兜一圈。 (還有一個優點是,可以將CSS,JavaScript,HTML 和圖片全部封裝在一起,遷移起來十分方便。)缺點就是圖像沒法緩存,圖片大的話內嵌的url 數據會相當的長:
var img_src = 'data:image/gif;base64,R0lGODlhCwALAIAAAAAA3pn/ZiH5BAEAAAEALAAAAAALAAsAAAIUhA+hkcuO4lmNVindo7 qyrIXiGBYAOw==';
drawImage
一旦獲得了來源圖對象,我們就可以使用drawImage方法將它渲染到canvas 裡。 drawImage方法有三種形態,以下是最基礎的一種。
drawImage(image, x, y)
其中image是 image 或 canvas 對象,x和y 是其在目標 canvas 的起始座標。
drawImage
範例 1
下面一個範例我用一個外部影像作為第一線性圖的背景。用背景圖我們就不需要繪製負責的背景,省下不少程式碼。這裡只用到一個 image 對象,於是就在它的onload
事件回應函數中觸發繪製動作。 drawImage
方法將背景圖放置在 canvas 的左上角 (0,0) 處。
function draw() { var ctx = document.getElementById('canvas').getContext('2d'); var img = new Image(); img.onload = function(){ ctx.drawImage(img,0,0); ctx.beginPath(); ctx.moveTo(30,96); ctx.lineTo(70,66); ctx.lineTo(103,76); ctx.lineTo(170,15); ctx.stroke(); } img.src = 'images/backdrop.png'; }
缩放Scaling
drawImage
方法的又一变种是增加了两个用于控制图像在 canvas 中缩放的参数。
drawImage(image, x, y, width, height)
切片Slicing
drawImage方法的第三个也是最后一个变种有8个新参数,用于控制做切片显示的。
drawImage(image, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight)
第一个参数和其它的是相同的,都是一个图像或者另一个 canvas 的引用。其它8个参数最好是参照下边的图解,前4个是定义图像源的切片位置和大小,后4个则是定义切片的目标显示位置和大小。
切片是个做图像合成的强大工具。假设有一张包含了所有元素的图像,那么你可以用这个方法来合成一个完整图像。例如,你想画一张图表,而手上有一个包含所有 必需的文字的 PNG 文件,那么你可以很轻易的根据实际数据的需要来改变最终显示的图表。这方法的另一个好处就是你不需要单独装载每一个图像。
drawImage
示例2
在这个例子里面我用到上面已经用过的犀牛图像,不过这次我要给犀牛头做个切片特写,然后合成到一个相框里面去。相框带有阴影效果,是一个以 24-bit PNG 格式保存的图像。我用一个与上面用到的不同的方法来装载图像,直接将图像插入到 HTML 里面,然后通过 CSS 隐藏(display:none)它。两个图像我都赋了id,方便后面使用。看下面的脚本,相当简单,首先犀牛头做好切片(第一个drawImage)放在 canvas 上,然后再上面套个相框(第二个drawImage)。
function draw() { var canvas = document.getElementById('canvas'); var ctx = canvas.getContext('2d'); // Draw slice ctx.drawImage(document.getElementById('source'), 33,71,104,124,21,20,87,104); // Draw frame ctx.drawImage(document.getElementById('frame'),0,0); }
示例:画廊 Art gallery example
我这一章最后的示例是弄一个小画廊。画廊由挂着几张画作的格子组成。当页面装载好之后,为每张画创建一个 canvas 元素并用加上画框然后插入到画廊中去。在我这个例子里面,所有“画”都是固定宽高的,画框也是。你可以做些改进,通过脚本用画的宽高来准确控制围绕它的画框的大小。下面的代码应该是蛮自我解释的了。就是遍历图像对象数组,依次创建新的 canvas 元素并添加进去。可能唯一需要注意的,对于那些并不熟悉 DOM 的朋友来说,是 insertBefore 方法的用法。insertBefore是父节点(单元格)的方法,用于将新节点(canvas 元素)插入到我们想要插入的节点之前
function draw() { // Loop through all images for (i=0;i<document.images.length;i++){ // Don't add a canvas for the frame image if (document.images[i].getAttribute('id')!='frame'){ // Create canvas element canvas = document.createElement('CANVAS'); canvas.setAttribute('width',132); canvas.setAttribute('height',150); // Insert before the image document.images[i].parentNode.insertBefore(canvas,document.images[i]); ctx = canvas.getContext('2d'); // Draw image to canvas ctx.drawImage(document.images[i],15,20); // Add frame ctx.drawImage(document.getElementById('frame'),0,0); } } }
以上就是canvas游戏开发学习之四:应用图像的内容,更多相关内容请关注PHP中文网(m.sbmmt.com)!