【canvas學習筆記三】樣式和顏色

来源:http://www.cnblogs.com/-867259206/archive/2017/08/02/7275864.html
-Advertisement-
Play Games

上一節我們學習瞭如何用路徑繪製各種形狀,但我們只能用預設的顏色和線條。這節就來學習設置不同的顏色和線條樣式。 顏色 設置顏色主要有兩個屬性: fillStyle = color 設置填充顏色 strokeStyle = color 設置描邊顏色 顏色值可以用十六進位也可以用一些內置的顏色字元,還可以 ...


上一節我們學習瞭如何用路徑繪製各種形狀,但我們只能用預設的顏色和線條。這節就來學習設置不同的顏色和線條樣式。

顏色

設置顏色主要有兩個屬性:

fillStyle = color
設置填充顏色
strokeStyle = color
設置描邊顏色

顏色值可以用十六進位也可以用一些內置的顏色字元,還可以用rgb和rgba格式。

例子:

// these all set the fillStyle to 'orange'

ctx.fillStyle = 'orange';
ctx.fillStyle = '#FFA500';
ctx.fillStyle = 'rgb(255, 165, 0)';
ctx.fillStyle = 'rgba(255, 165, 0, 1)';

下麵來看看一個填充顏色的例子和一個描邊顏色的例子:

填充顏色示例

在下麵這個例子中,我們創建了6X6的方塊,每個方塊都填充了不同的顏色。根據i、j的值,生成R通道和G通道的值,而B通道的值為固定值0。

function draw() {
  var ctx = document.getElementById('canvas').getContext('2d');
  for (var i = 0; i < 6; i++) {
    for (var j = 0; j < 6; j++) {
      ctx.fillStyle = 'rgb(' + Math.floor(255 - 42.5 * i) + ', ' +
                       Math.floor(255 - 42.5 * j) + ', 0)';
      ctx.fillRect(j * 25, i * 25, 25, 25);
    }
  }
}

效果

image

描邊顏色示例

這個例子和上一個例子類似。在這個例子中,R通道的值固定,G和B通道的值根據i、j的值變化。

function draw() {
    var ctx = document.getElementById('canvas').getContext('2d');
    for (var i = 0; i < 6; i++) {
      for (var j = 0; j < 6; j++) {
        ctx.strokeStyle = 'rgb(0, ' + Math.floor(255 - 42.5 * i) + ', ' + 
                         Math.floor(255 - 42.5 * j) + ')';
        ctx.beginPath();
        ctx.arc(12.5 + j * 25, 12.5 + i * 25, 10, 0, Math.PI * 2, true);
        ctx.stroke();
      }
    }
  }

效果

image

Tips:

如果沒有設置fillStyle或strokeStyle,則預設的fillStyle或strokeStyle是黑色,如果設置了fillStyle或strokeStyle,則預設的顏色就變成設置的顏色。

透明

我們可以直接通過rgba的方式設置顏色從而實現透明的效果,如下:

// Assigning transparent colors to stroke and fill style

ctx.strokeStyle = 'rgba(255, 0, 0, 0.5)';
ctx.fillStyle = 'rgba(255, 0, 0, 0.5)';

我們還可以設置全局的透明度,設置了全局透明度,之後繪製的圖形都會是這個透明度。全局透明度的值是0~1。

globalAlpha = transparencyValue

例子

function draw() {
  var ctx = document.getElementById('canvas').getContext('2d');
  // draw background
  ctx.fillStyle = '#FD0';
  ctx.fillRect(0, 0, 75, 75);
  ctx.fillStyle = '#6C0';
  ctx.fillRect(75, 0, 75, 75);
  ctx.fillStyle = '#09F';
  ctx.fillRect(0, 75, 75, 75);
  ctx.fillStyle = '#F30';
  ctx.fillRect(75, 75, 75, 75);
  ctx.fillStyle = '#FFF';

  // set global transparency value
  ctx.globalAlpha = 0.2;

  // Draw semi transparent circles
  for (i = 0; i < 7; i++) {
    ctx.beginPath();
    ctx.arc(75, 75, 10 + 10 * i, 0, Math.PI * 2, true);
    ctx.fill();
  }
}

效果

image

線條樣式

有很多屬性和API可以設置線條的樣式。

lineWidth = value
設置線條的寬度。
lineCap = type
設置線條端點的樣式。
lineJoin = type
設置線條連接處的樣式。
miterLimit = value
設置或返回最大斜接長度。
getLineDash()
獲取當前虛線的樣式,返回設置虛線的線寬數組。
setLineDash(segments)
設置當前虛線樣式。
lineDashOffset = value
確定一條線從哪裡開始是虛線。

lineWidth

線寬這個屬性就是設置線的粗細。它的值不能是負數,單位是像素。預設值是1像素。
下麵我們先來看一個例子:

function draw() {
  var ctx = document.getElementById('canvas').getContext('2d');
  for (var i = 0; i < 10; i++) {
    ctx.lineWidth = 1 + i;
    ctx.beginPath();
    ctx.moveTo(5 + i * 14, 5);
    ctx.lineTo(5 + i * 14, 140);
    ctx.stroke();
  }
}

效果:
image
註意看的話會發現,奇數位置的線條邊緣有些模糊,這是因為位置不對,這就需要瞭解線生成的機制。
image
如圖,圖中一個方格表示一個像素。如果要在坐標(3,1)到坐標(3,5)之間畫一條1像素寬的直線,那麼線的寬度將會如圖中第一張圖的深藍部分所示,左右的寬度只占半個像素。半個像素是無法繪製的,所以實際繪製的線條是第二章圖所示的內容。它實際的位置並不正確。

lineCap

lineCap屬性設置了線段端點的樣式。它的值有三種:

butt (預設值)
端點是方的。
round
端點是圓的。
square
端點多出一個寬度和線寬一樣,長度是線寬一般的方塊。

三種樣式從左到右如圖:
image

lineJoin

這個屬性設置了線段連接處的樣式。
它的值有三種:

round
連接處是圓的。
bevel
連接處是一個三角形。
miter(預設值)
連接處是一個菱形。

從上到下效果如圖:
image

miterLimit

miterlimit屬性就是對上文miter作控制的一個屬性。簡單的說,miterlimit屬性就是控制miter的大小的。
下麵來簡單說明一下它的效果:
image
image
image
上面三張圖分別是miterlimit屬性值為1、5、10時的效果。miterlimit屬性實際上久時hi限制了連接處菱形的大小。

setLineDash(segments) && lineDashOffset

利用setLineDash(segments)方法和lineDashOffset屬性就可以自己設置虛線的樣式。
setLineDash(segments)接受一個數組作參數,數組的第一個元素規定了虛線中每一小段虛線的長度,第二個參數規定了虛線中每一小段虛線之間的間隔距離。
lineDashOffset設置了虛線樣式是從哪裡開始的。
下麵用一個螞蟻線的動畫例子來說明一下它們的用法:

var ctx = document.getElementById('canvas').getContext('2d');
var offset = 0;

function draw() {
  ctx.clearRect(0, 0, canvas.width, canvas.height);
  ctx.setLineDash([4, 2]);
  ctx.lineDashOffset = -offset;
  ctx.strokeRect(10, 10, 100, 100);
}

function march() {
  offset++;
  if (offset > 16) {
    offset = 0;
  }
  draw();
  setTimeout(march, 20);
}

march();

效果

image
通過間隔一段時間增加lineDashOffset的方法達到虛線移動的效果。這個效果經常用來表示選中。

漸變

canvas可以創建漸變對象,將漸變對象賦值給strokeStyle或fillStyle,就可以畫出漸變的顏色。
有兩種漸變對象,一種是線性漸變,一種是徑向漸變:

createLinearGradient(x1, y1, x2, y2)
創建線性漸變對象,從點(x1, y1)開始,至點(x2, y2)結束。
createRadialGradient(x1, y1, r1, x2, y2, r2)
創建徑向漸變對象,參數是兩個圓,一個圓圓心是(x1, y1),半徑是r1,另一個圓圓心是(x2, y2),半徑是r2。

例子:

var lineargradient = ctx.createLinearGradient(0, 0, 150, 150);
var radialgradient = ctx.createRadialGradient(75, 75, 0, 75, 75, 100);

這樣就創建了漸變對象。然後用addColorStop方法添加顏色:

gradient.addColorStop(position, color)
position的值是0~1,這決定了顏色相對於漸變對象的位置,color是表示顏色的字元串,只要CSS中用來表示的顏色的方法都可以,比如十六進位、rgb或rgba。

線性漸變例子

function draw() {
  var ctx = document.getElementById('canvas').getContext('2d');

  // Create gradients
  var lingrad = ctx.createLinearGradient(0, 0, 0, 150);
  lingrad.addColorStop(0, '#00ABEB');
  lingrad.addColorStop(0.5, '#fff');
  lingrad.addColorStop(0.5, '#26C000');
  lingrad.addColorStop(1, '#fff');

  var lingrad2 = ctx.createLinearGradient(0, 50, 0, 95);
  lingrad2.addColorStop(0.5, '#000');
  lingrad2.addColorStop(1, 'rgba(0, 0, 0, 0)');

  // assign gradients to fill and stroke styles
  ctx.fillStyle = lingrad;
  ctx.strokeStyle = lingrad2;
  
  // draw shapes
  ctx.fillRect(10, 10, 130, 130);
  ctx.strokeRect(50, 50, 50, 50);

}

效果

image

徑向漸變例子

function draw() {
  var ctx = document.getElementById('canvas').getContext('2d');

  // Create gradients
  var radgrad = ctx.createRadialGradient(45, 45, 10, 52, 50, 30);
  radgrad.addColorStop(0, '#A7D30C');
  radgrad.addColorStop(0.9, '#019F62');
  radgrad.addColorStop(1, 'rgba(1, 159, 98, 0)');
  
  var radgrad2 = ctx.createRadialGradient(105, 105, 20, 112, 120, 50);
  radgrad2.addColorStop(0, '#FF5F98');
  radgrad2.addColorStop(0.75, '#FF0188');
  radgrad2.addColorStop(1, 'rgba(255, 1, 136, 0)');

  var radgrad3 = ctx.createRadialGradient(95, 15, 15, 102, 20, 40);
  radgrad3.addColorStop(0, '#00C9FF');
  radgrad3.addColorStop(0.8, '#00B5E2');
  radgrad3.addColorStop(1, 'rgba(0, 201, 255, 0)');

  var radgrad4 = ctx.createRadialGradient(0, 150, 50, 0, 140, 90);
  radgrad4.addColorStop(0, '#F4F201');
  radgrad4.addColorStop(0.8, '#E4C700');
  radgrad4.addColorStop(1, 'rgba(228, 199, 0, 0)');
  
  // draw shapes
  ctx.fillStyle = radgrad4;
  ctx.fillRect(0, 0, 150, 150);
  ctx.fillStyle = radgrad3;
  ctx.fillRect(0, 0, 150, 150);
  ctx.fillStyle = radgrad2;
  ctx.fillRect(0, 0, 150, 150);
  ctx.fillStyle = radgrad;
  ctx.fillRect(0, 0, 150, 150);
}

效果

image

圖案

現在介紹的這個方法可以用圖片去填充圖形。

createPattern(image, type)  
這個方法創建並返回了一個pattern對象,image參數是CanvasImageSource,HTML圖片元素、canvas或

type參數有如下幾種值:

repeat
在垂直和水平方向上重覆平鋪圖片。
repeat-x
水平平鋪圖片。
repeat-y
垂直平鋪圖片。
no-repeat
不平鋪重覆圖片。

pattern對象的創建方法和漸變對象類似:

var img = new Image();
img.src = 'someimage.png';
var ptrn = ctx.createPattern(img, 'repeat');

註意

這個方法和drawImage類似,要確保圖片載入完,否則圖片不能顯示。

例子

function draw() {
  var ctx = document.getElementById('canvas').getContext('2d');

  // create new image object to use as pattern
  var img = new Image();
  img.src = 'https://mdn.mozillademos.org/files/222/Canvas_createpattern.png';
  img.onload = function() {

    // create pattern
    var ptrn = ctx.createPattern(img, 'repeat');
    ctx.fillStyle = ptrn;
    ctx.fillRect(0, 0, 150, 150);

  }
}

效果

image

陰影

陰影涉及四個屬性:

shadowOffsetX = float
陰影水平方向距離。預設值為0。不受transform變換矩陣影響。
shadowOffsetY = float
陰影垂直方向距離。預設值為0。不受transform變換矩陣影響。
shadowBlur = float
陰影模糊大小。預設值為0。模糊數值並不是模糊的像素的大小,是模糊的程度。不受transform變換矩陣影響。
shadowColor = color
陰影顏色。預設值是全透明黑色。

例子

function draw() {
  var ctx = document.getElementById('canvas').getContext('2d');

  ctx.shadowOffsetX = 2;
  ctx.shadowOffsetY = 2;
  ctx.shadowBlur = 2;
  ctx.shadowColor = 'rgba(0, 0, 0, 0.5)';
 
  ctx.font = '20px Times New Roman';
  ctx.fillStyle = 'Black';
  ctx.fillText('Sample String', 5, 30);  // 後面兩個參數是x, y坐標
}

效果

image

Canvas填充規則

如果兩個路徑交叉或重疊,我們可以設置填充的方式。
參數有兩種:

"nonzero": 預設值,按照non-zero winding rule規則填充。
"evenodd": 按照even-odd winding rule規則填充。

例子

function draw() {
  var ctx = document.getElementById('canvas').getContext('2d'); 
  ctx.beginPath(); 
  ctx.arc(50, 50, 30, 0, Math.PI * 2, true);
  ctx.arc(50, 50, 15, 0, Math.PI * 2, true);
  ctx.fill('evenodd');
}

效果

image


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 分散式系統中主要的問題就是如何保持節點狀態的一致性,不論發生任何failure,只要集群中大部分的節點可以正常工作,則這些節點具有相同的狀態,保持一致,在client看來相當於一臺機器。 一致性問題本質就是replicated state machines,即所有結點都從同一個state出發,都經過 ...
  • HashMap 簡介 Java為數據結構中的映射定義了一個介面java.util.Map,此介面主要有四個常用的實現類,分別是HashMap、Hashtable、LinkedHashMap和TreeMap,類繼承關係如下圖所示: 下麵針對各個實現類的特點做一些說明: (1) HashMap:它根據鍵 ...
  • 網頁中插入圖像 ================== 針對普通類圖片 IMG vs CSS background image 使用IMG 圖像是內容的一部分 網站logo如 "支付寶註冊頁面" 、圖表、照片人物等與上下文有關的,需要使用atl屬性 利於搜索引擎、屏幕閱讀器 對於輪播圖等需要JavaS ...
  • 閉包(Closure) 本文聚焦於回答2個問題: 1. 在全局作用域中,如何讀取函數內部的局部變數? 2. 在全局作用域中,如何修改函數內部的局部變數? 變數作用域 JavaScript語言的作用域,一句話概括就是:內層函數可以訪問外層函數的變數,而外層函 數不可以訪問內層函數的變數。 在內層函數中 ...
  • 1.正則表達式基本語法 兩個特殊的符號'^'和'$'。他們的作用是分別指出一個字元串的開始和結束。例子如下: "^The":表示所有以"The"開始的字元串("There","The cat"等); "of despair$":表示所以以"of despair"結尾的字元串; "^abc$":表示開 ...
  • 剛開始為了實現:篩選菜單彈出來:禁止頁面滑動,菜單收回去:允許頁面滑動,真是煞費苦心啊,以前在jquery/bootstrap上面用的老辦法都物是人非,哎…… 那些因為年輕犯的錯: ...
  • 前面的話 修飾器(Decorator)是一個函數,用來修改類的行為。本文將詳細介紹ES2017中的修飾器Decorator 概述 ES2017 引入了這項功能,目前 Babel 轉碼器已經支持Decorator 首先,安裝babel-core和babel-plugin-transform-decor ...
  • 前段時間在利用工作之餘開發了tomato timer這個蕃茄鐘,然後部署到github.io上,由於greatway太厲害,偶爾會有打不開的情況。上周末對比做了擴展和改進,使其成為chrome的插件,或者成為桌面app。 chrome插件的使用與開發 一、如何安裝與使用: 1、下載tomato ti ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...