跳到內容

色彩循環

本教學將探索「認識 Canvas」中色彩循環範例的一些變體。它包含動畫說明和一些基本使用者控制項。

此特效由填充整個 canvas 並隨時間改變顏色的矩形組成。使用者可以編輯色彩轉換的速度。

<head>
<title>Generic</title>
<meta description="Template"/>
<meta publisher="WhirlwindFX" />
<!-- 1. 建立數字滑桿以編輯動畫速度 -->
<meta property="speed" label="Cycle Speed" type="number" min="1" max="10" default="2">
</head>
<body style="margin: 0; padding: 0;">
<!-- 2. 在 body 標籤內建立 canvas 元素 -->
<canvas id="exCanvas" width="320" height="200"></canvas>
</body>
<script>
// 3. 從 DOM 取得 canvas 元素
var c = document.getElementById("exCanvas");
var ctx = c.getContext("2d");
// 4. 宣告腳本變數
var width = 320;
var height = 200;
var hue = 0;
// 5. 撰寫 update 函式以渲染每個影格
function update() {
// 6. 設定 fillstyle,色相隨時間可變
ctx.fillStyle = 'hsl('+ hue + ', 100%, 50%)';
// 7. 使用 fillRect 方法在同一個命令中建立路徑並繪製
ctx.fillRect(0, 0, width , height);
// 8. 以使用者設定的速度迭代色相。為了更好的使用者滑桿體驗進行了小幅調整。
hue+=(speed / 4);
// 9. 將色相限制在 0-360 範圍內以用於 hsl
if (hue > 360) { hue = hue % 360; }
// 10. 在每次更新結束時重新呼叫 update 函式
window.requestAnimationFrame(update);
}
// 11. 初始更新呼叫
window.requestAnimationFrame(update);
</script>

結果色彩豐富但基本。我們可以用 canvas 做更多!

在這裡,我用一個隨時間移動的漸層替換了單一顏色。使用者可以編輯色彩轉換的速度以及每個漸層點與其他點的距離。

<head>
<title>Generic</title>
<meta description="Template"/>
<meta publisher="WhirlwindFX" />
<meta property="speed" label="Cycle Speed" type="number" min="1" max="10" default="2">
<!-- 1. 建立數字滑桿以編輯漸層的色彩寬度 -->
<meta property="distance" label="Color Distance" type="number" min="1" max="160" default="50">
</head>
<body style="margin: 0; padding: 0;">
<canvas id="exCanvas" width="320" height="200"></canvas>
</body>
<script>
var c = document.getElementById("exCanvas");
var ctx = c.getContext("2d");
var width = 320;
var height = 200;
// 2. 初始色相設定為 0
var hue1 = 0;
function update() {
// 3. 透過添加使用者的色彩寬度來建立另外兩種顏色以用於漸層。
hue1+=(speed / 4);
hue2 = hue1 + distance;
hue3 = hue2 + distance;
// 4. 將每個單獨的色相限制在 0-360 範圍內
if (hue1 > 360) { hue1 = hue1 % 360; }
if (hue2 > 360) { hue2 = hue2 % 360; }
if (hue3 > 360) { hue3 = hue3 % 360; }
// 5. 建立線性漸層。我的漸層從 (0, 0) 開始,沿寬度方向水平平移。將最後一個 0 更改為整數會為漸層添加垂直分量。
var grd = ctx.createLinearGradient(0, 0, width, 0);
// 6. 用色相設定漸層色標。左端、中間和右端各一個。
grd.addColorStop(0, `hsl(${hue1}, 100%, 50%)`);
grd.addColorStop(.5, `hsl(${hue2}, 100%, 50%)`);
grd.addColorStop(1, `hsl(${hue3}, 100%, 50%)`);
// 7. 設定 fillstyle 並繪製矩形
ctx.fillStyle = grd;
ctx.fillRect(0, 0, width , height);
window.requestAnimationFrame(update);
}
window.requestAnimationFrame(update);
</script>

這個有點複雜,請耐心跟上數學部分。我們最後的色彩循環是一個像素化的蛇形色彩爬行。

<head>
<title>Generic</title>
<meta description="Template"/>
<meta publisher="WhirlwindFX" />
<meta property="speed" label="Cycle Speed" type="number" min="1" max="10" default="2">
<meta property="distance" label="Color Distance" type="number" min="1" max="10" default="2">
<!-- 1. 建立數字滑桿以編輯循環的像素密度 -->
<meta property="density" label="Pixel Density" type="number" min="0" max="2" default="1">
</head>
<body style="margin: 0; padding: 0;">
<canvas id="exCanvas" width="320" height="200"></canvas>
</body>
<script>
var c = document.getElementById("exCanvas");
var ctx = c.getContext("2d");
var width = 320;
var height = 200;
var hue = 0;
function update() {
// 2. 繪製白色背景以覆寫之前的影格
ctx.fillStyle = "white"
ctx.fillRect(0, 0, width, height)
hue += (speed/4);
if(hue > 360) {
hue = hue % 360;
}
// 3. 從使用者輸入計算正方形大小。基於我們的 320x200 螢幕比例,我的 4 個可能值是 5px、10px、20px 和 40px 的正方形。您可以用方程式 10 * 2 ^ density 計算大小。
var size = 10 * Math.pow(2, density);
// 4. 透過將螢幕像素面積 (320 * 200) 除以正方形像素面積來計算正方形總數。
var goal = 64000 / (size * size);
// 5. while 迴圈將執行到我們達到指定數量的正方形
var i = 0;
while(i < goal){
// 6. 計算行和列乘數,與 HTML5+JS 中的網格範例相同
var iRow = Math.floor(i / (width / size));
var iCol = i % (width / size);
// 7. 根據行和列乘數計算每個正方形的 (x, y)
var ix = iCol * size;
var iy = iRow * size;
// 8. 根據使用者輸入計算每個正方形的可變顏色。確保在計算中包含索引,使每個正方形與下一個不同。
var iHue = hue + (i * distance);
if(iHue > 360){
iHue = iHue % 360;
}
// 9. 如果 iRow 計算為奇數,翻轉水平繪製方向。
if(iRow % 2 != 0){
ix = (width - size) - iCol * size;
}
ctx.beginPath();
ctx.rect(ix, iy, size, size);
ctx.fillStyle = `hsl(${iHue}, 100%, 50%)`;
ctx.fill();
i++;
}
window.requestAnimationFrame(update);
}
window.requestAnimationFrame(update);
</script>

希望您在製作色彩循環時玩得開心!如需涉及基於類別的行為和一些基本物理的教學,請查看 Ball Class 頁面。