国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

【30分鐘學完】canvas動畫|游戲基礎(extra1-1):美圖我也行

G9YH / 3364人閱讀

摘要:前言本文是接續系列教程的,主要是介紹顏色系統在中的應用。本來是與一起成文的,因為莫名其妙的字數限制只能分割放送了。提供可以獲取畫布上任何一個像素,并可以自由的操作他們。繪制指定的位置繪制對象的內容。

前言

本文是接續系列教程的extra1,主要是介紹顏色系統在canvas中的應用。
本來是與extra1一起成文的,因為segmentfault莫名其妙的字數限制bug只能分割放送了。

canvas操縱像素

你如果認為canvas只是畫圖工具,那接下來的操作會顛覆你的認知。canvas提供api可以獲取畫布上任何一個像素,并可以自由的操作他們。

獲取像素

直接訪問像素的功能由canvas上下文中的ImageData對象提供,它提供了以下一組方法,都會返回ImageData對象。

getImageData()接受x軸坐標、y軸坐標、寬度、高度四個參數,獲取畫布上這個矩形區域的像素數據;

createImageData()可憑空創建指定寬高的矩形區域,初始是黑色,也可以輸入一個ImageData對象用于創建一個同樣大小的區域,但注意不會復制像素數據

context.getImageData(x, y, width, height);
context.createImageData(width, height);
context.createImageData(anothorImageData);

獲取到的ImageData對象中data屬性是一個一維數組,乍看亂糟糟的,但細看你會發現其實這就是RGBA的顏色數據,也就是數組中每個四位就是一個像素的顏色數據,這里注意一下透明度A也是0~255,不是CSS里簡化過的0~1

*

舉個例子
現在假定在一個純紅色區域取一塊2*2的矩形,我們得到的像素數據是:

let pixels = [255, 0, 0, 255, 255, 0, 0, 255,
              255, 0, 0, 255, 255, 0, 0, 255]

他們與圖像的對應關系是從左到右,從上到下,大概就像上面代碼格式化這樣,如圖所示:

根據4對1的對應關系,我們很容易就能寫出遍歷的辦法,offset就相當于指針,每次移動4位,代碼如下:

for (let offset = 0, len = pixels.length; offset < len; offset += 4) {
  r = pixels[offset];
  g = pixels[offset + 1];
  b = pixels[offset + 2];
  a = pixels[offset + 3];
}

當需要訪問特定坐標的像素時,可以使用如下公式,其中xpos是像素點在該區域的x坐標;ypos是像素點在該區域的y坐標,imagedata.width是指區域橫向有多少像素。

let offset = (xpos + ypos * imagedata.width) * 4;
let r = pixels[offset];
let g = pixels[offset + 1];
let b = pixels[offset + 2];
let a = pixels[offset + 3];
繪制像素

可以將修改過的ImageData對象重新用上下文的putImageData()方法繪制到指定區域,該方法接受三個參數:ImageData對象、x軸坐標、y軸坐標。繪制指定的位置繪制ImageData對象的內容。直接看下面例子的核心代碼。
先繪制鋪滿畫布的色塊,點擊按鈕觸發change事件處理器可改變顏色,過程見注釋。
完整例子:演示反色變化

【PS】對js了解不深的朋友可能會有疑問,遍歷過程操作的是pixels,imageData怎么會改變呢?  
這是因為js中對象都是地址傳遞的特點,也就是pixels = imageData.data操作只是將pixels變量的指向到imageData.data所指向的內存空間,所以操作pixels就是操作imageData.data。
window.onload = function () {
  const canvas = document.getElementById("canvas");
  const context = canvas.getContext("2d");
  // 繪制色塊,每個色塊寬10像素,高等于畫布高,鋪滿畫布
  for (let i = 0; i < canvas.width; i += 10) {
    context.fillStyle = (i % 20 === 0) ? "#f00" : ((i % 30 === 0) ? "#0f0" : "#00f");
    context.fillRect(i, 0, 10, canvas.height);
  }
};

function change() {
  const canvas = document.getElementById("canvas");
  const context = canvas.getContext("2d");
  // 獲取整個畫布的ImageData對象
  const imageData = context.getImageData(0, 0, canvas.width, canvas.height);
  // 取出顏色數據
  const pixels = imageData.data;
  // 遍歷顏色數據求每個顏色的反色
  for (let offset = 0, len = pixels.length; offset < len; offset += 4) {
    pixels[offset] = 255 - pixels[offset];
    pixels[offset + 1] = 255 - pixels[offset + 1];
    pixels[offset + 2] = 255 - pixels[offset + 2];
    // 這里沒有操作透明度
  }
  // 將ImageData重新繪制到畫布上
  context.putImageData(imageData, 0, 0);
}
更多有趣的例子

canvas強大的像素操作可以給我們帶來更多的可能,也許你會想開始做一個網頁版的美圖工具了吧(笑)。
這里還有一些有趣的demo可以玩玩:

演示灰度變化

有趣的色彩波紋

綜合案例

有關顏色的番外部分到這里就基本完結了,最后有個綜合題,會應用這些技術。
將系列第二篇中的鼠標畫圖工具改造成鼠標噴漆工具,這里建議自己動手實踐一下。
下面例子基本思路就是取得畫布像素數據,每當鼠標點下并移動(執行onMouseMove)就隨機改變鼠標周圍一定范圍的像素點的顏色。
完整案例:鼠標噴漆工具

window.onload = function () {
  const canvas = document.getElementById("canvas");
  const context = canvas.getContext("2d");
  // 獲得整個畫布區域的ImageData對象
  const imageData = context.getImageData(0, 0, canvas.width, canvas.height);
  // 取出像素數據
  const pixels = imageData.data;
  // 設定筆刷大小
  const brush_size = 25;
  // 設定筆刷密度
  const brush_density = 80;
  // 筆刷的顏色變量
  let brush_color;

  function onMouseMove() {
    // 根據設定的筆刷密度生成隨機像素點
    for (let i = 0; i < brush_density; i++) {
      // 隨機像素點角度相對于鼠標的角度
      const angle = Math.random() * Math.PI * 2;
      // 根據設定的筆刷大小,隨機像素點以鼠標為圓心的半徑
      const radius = Math.random() * brush_size;
      // 計算出像素點的x軸相對坐標
      const xpos = (mouse.x + Math.cos(angle) * radius) | 0;
      // 計算出像素點的y軸相對坐標
      const ypos = (mouse.y + Math.sin(angle) * radius) | 0;
      // 算出該像素點在pixels中的偏移量
      const offset = (xpos + ypos * imageData.width) * 4;
      // 對這個像素點的顏色數據進行操作,將顏色分解成三基色
      pixels[offset] = brush_color >> 16 & 0xff;
      pixels[offset + 1] = brush_color >> 8 & 0xff;
      pixels[offset + 2] = brush_color & 0xff;
      pixels[offset + 3] = 255;
    }
    // 重新繪制區域
    context.putImageData(imageData, 0, 0);
  }
  canvas.addEventListener("mousedown", () => {
    // 隨機一個顏色
    brush_color = utils.parseColor(Math.random() * 0xffffff, true);
    canvas.addEventListener("mousemove", onMouseMove, false);
  }, false);
  canvas.addEventListener("mouseup", () => {
    canvas.removeEventListener("mousemove", onMouseMove, false);
  }, false);
};

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/54518.html

相關文章

  • 30分鐘學完canvas動畫|游戲基礎(extra1-1):美圖也行

    摘要:前言本文是接續系列教程的,主要是介紹顏色系統在中的應用。本來是與一起成文的,因為莫名其妙的字數限制只能分割放送了。提供可以獲取畫布上任何一個像素,并可以自由的操作他們。繪制指定的位置繪制對象的內容。 前言 本文是接續系列教程的extra1,主要是介紹顏色系統在canvas中的應用。 本來是與extra1一起成文的,因為segmentfault莫名其妙的字數限制bug只能分割放送了。 ...

    Hydrogen 評論0 收藏0
  • 30分鐘學完canvas動畫|游戲基礎(1):理論先行

    摘要:所建議的刷新率是秒幀,大部分瀏覽器是遵循這一標準的。基于時間的動畫其實無論是還是定時器,都不能保證以特定速率播放。將物體每幀移動距離,轉變為物體每秒移動距離。 前言 本文雖說是基礎教程,但這是相對動畫/游戲領域來說,在前端領域算是中級教程了,不適合前端小白或萌新。閱讀前請確保自己對前端三大件(JavaScript+CSS+HTML)的基礎已經十分熟悉,而且有高中水平的數學和物理知識。d...

    wind5o 評論0 收藏0
  • 30分鐘學完canvas動畫|游戲基礎(1):理論先行

    摘要:所建議的刷新率是秒幀,大部分瀏覽器是遵循這一標準的。基于時間的動畫其實無論是還是定時器,都不能保證以特定速率播放。將物體每幀移動距離,轉變為物體每秒移動距離。 前言 本文雖說是基礎教程,但這是相對動畫/游戲領域來說,在前端領域算是中級教程了,不適合前端小白或萌新。閱讀前請確保自己對前端三大件(JavaScript+CSS+HTML)的基礎已經十分熟悉,而且有高中水平的數學和物理知識。d...

    wemall 評論0 收藏0

發表評論

0條評論

最新活動
閱讀需要支付1元查看
<