JS地下城-2F時鐘
新手JS-地下城:2F-時鐘
紀錄一下這次使用的Canvas
不知道Canvas如何使用的人可以參考六角學院-使用Canvas製作遊戲並搭配MDN會加深很大的印象
前置作業:
首先在html使用
接著輸入你畫布的尺寸,在這邊是要全部瀏覽器都是畫布,所以使用
這邊要提醒,繪製一個圖形我們需要以下步驟:
1.ctx.save();儲存
2.ctx.beginPath();開始繪圖
3.ctx.restore();復原上一階段
當開始繪畫後,首先我們要先儲存當前狀態,畫完後使用
在這邊介紹幾個常見功能
1.填色:
fillStyle實心顏色、SrokeStyle空心顏色,有使用填色後面要記得使用
2.lineWidth(線寬):
3.moveTo(x,y):移動到哪個座標
4.lineTo(x,y):畫一條線到哪個座標
5.arc(x,y,半徑,起點位置,終點位置,true):畫圓(弧度)
x,y為中心座標
起點位置是你想從圓的哪個位置開始畫,通常會以0開始
中點位置:假如你要畫個圓可以使用Math.PI*2 (Math.PI是180度所以乘2就是360度)
最後的true表示為順時鐘畫圓,假如要使用逆時鐘可以改成false
6.rect(x, y, 寬度, 高度):畫矩形
7.ctx.rotate(角度):旋轉角度
以上面時鐘為範例,當你有個物件想要重複執行變成圓圈就可以使用
製作鐘錶:
我們分三個階段
1.外層
2.四方圓角
3.圓形
第二步:移到瀏覽器中心點製作四方型圓角,這邊我們使用二次曲線製作
第三部:設定顏色會,在0,0的座標為圓點中心畫一個圓,使用半徑150,起點從0轉Math.PI*2度也就是360度,之後上色,而圓框的部分則是使用
刻度:
這邊介紹白色點點
橘色線條和星星也是這樣操作,星星製作則是使用貝茲曲線
時間數字則是:
指針:
這邊最主要的是製作指針樣式前要加入
再來是重頭戲時鐘的指針走動:
接著為了避免前面移動的會殘留所以要使用
最後把參數放進控制指針的
最後我們在外面放
以上第一次使用
只是邏輯要很夠(笑)
參考來源:
https://developer.mozilla.org/zh-TW/docs/Web/API/Canvas_API/Tutorial/Basic_usage
https://medium.com/@ruby30336/%E4%BD%BF%E7%94%A8canvas%E8%88%87js%E5%81%9A%E5%9C%93%E5%BD%A2%E6%99%82%E9%90%98-c400e0f51d3f
https://www.youtube.com/watch?v=sOHcx9jekzs
https://medium.com/@cos214159/canvas-%E7%AD%86%E8%A8%98-8-%E8%B2%9D%E8%8C%B2%E6%9B%B2%E7%B7%9Abeziercurveto-93b8f5257c86
紀錄一下這次使用的Canvas
不知道Canvas如何使用的人可以參考六角學院-使用Canvas製作遊戲並搭配MDN會加深很大的印象
前置作業:
首先在html使用
canvas
標籤,像是再瀏覽器產生一個固定大小的繪圖畫布,當瀏覽器抓到canvas
了,再來就是要告知它要使用何種方式渲染環境,在這邊我們是使用平面繪圖,所以getContext
就要輸入2d。接著輸入你畫布的尺寸,在這邊是要全部瀏覽器都是畫布,所以使用
widow.innerWidth
、window.innerHeight
var mycanvas=document.querySelector('#canvas');
var ctx = mycanvas.getContext("2d");
var ww=window.innerWidth;
var wh=window.innerHeight;
mycanvas.width=ww;
mycanvas.height=wh;
這邊要提醒,繪製一個圖形我們需要以下步驟:
1.ctx.save();儲存
2.ctx.beginPath();開始繪圖
3.ctx.restore();復原上一階段
當開始繪畫後,首先我們要先儲存當前狀態,畫完後使用
ctx.restore()
還原狀態,才不會導致之後的圖會因為剛剛的動作導致重複或者飄移,再來每當要畫一個地方就要使用beginPath
產生一個新路徑,告訴JS說我要開始畫圖了,那有一個ctx.closePath()
關閉路徑,這個方法會在現在所在點到起始點間畫一條直線以閉合圖形,如果圖形已經閉合或是只含一個點,這個方法不會有任何效果。在這邊介紹幾個常見功能
1.填色:
fillStyle實心顏色、SrokeStyle空心顏色,有使用填色後面要記得使用
fill()
、stroke()
表示結束2.lineWidth(線寬):
lineWidth=2
表示你要使用的線寬是23.moveTo(x,y):移動到哪個座標
4.lineTo(x,y):畫一條線到哪個座標
5.arc(x,y,半徑,起點位置,終點位置,true):畫圓(弧度)
x,y為中心座標
起點位置是你想從圓的哪個位置開始畫,通常會以0開始
中點位置:假如你要畫個圓可以使用Math.PI*2 (Math.PI是180度所以乘2就是360度)
最後的true表示為順時鐘畫圓,假如要使用逆時鐘可以改成false
6.rect(x, y, 寬度, 高度):畫矩形
7.ctx.rotate(角度):旋轉角度
以上面時鐘為範例,當你有個物件想要重複執行變成圓圈就可以使用
ctx.rotate()
製作鐘錶:
我們分三個階段
1.外層
2.四方圓角
3.圓形
ctx.fillStyle="#293B29";
ctx.fillRect(0,0,ww,wh);
//儲存
ctx.save();
//移至中心點
ctx.translate(ww/2,wh/2);
//開始繪圖
ctx.beginPath();
//填滿顏色
ctx.fillStyle="#3d5a45";
ctx.moveTo(145,175);//移動到145,175
ctx.quadraticCurveTo(175,175,175,145);//二次曲線
ctx.lineTo(175,-145);//畫條線到175,-145
ctx.quadraticCurveTo(175,-175,145,-175);//二次曲線
ctx.lineTo(-145,-175);
ctx.quadraticCurveTo(-175,-175,-175,-145);
ctx.lineTo(-175,145);
ctx.quadraticCurveTo(-175,175,-145,175);
ctx.lineTo(145,175);
ctx.fill();
//圓形鐘面
ctx.beginPath();//開始繪圖
ctx.fillStyle="#293b29";//顏色
ctx.arc(0,0,150,0,Math.PI*2,true);//圓形
ctx.fill();//填滿
ctx.strokeStyle="#212f0b";//框顏色
ctx.lineWidth=3;//寬度
ctx.stroke();//填滿
首先第一步:外表我們只要單色填滿所以使用ctx.fillStyle="#293B29";
接下來使用方形把你要填色的大小框出,在這邊因為是整個瀏覽器都要填滿所以使用ctx.fillRect();
第二步:移到瀏覽器中心點製作四方型圓角,這邊我們使用二次曲線製作
ctx.quadraticCurveTo(cp1x, cp1y, x, y)
不了解貝茲曲線和二次曲線的可以查貝茲曲線和AI、PS軟體的貝茲曲線一樣cp1x,cp1y是給你設定無形的控制點,而x,y則指定的終點第三部:設定顏色會,在0,0的座標為圓點中心畫一個圓,使用半徑150,起點從0轉Math.PI*2度也就是360度,之後上色,而圓框的部分則是使用
strokeStyle
勾勒框圖形,給予寬度,最後上色刻度:
這邊介紹白色點點
for(var i=0;i<72 ath.pi="" code="" ctx.arc="" ctx.beginpath="" ctx.fill="" ctx.fillstyle="white" ctx.rotate="" else="" i="" if="" true="">72>
以範例來說以小時來說,一個小時會有4個點點,中間還參雜橘色部分,所以首我們要先計算一個點點和另一個點點的距離是多少,我們假如全部都是白色點點的話一共有72個點點,所以就是Math*2/72,接著我們發現只要是三的倍數都是橘色區域,所以我們可以使用if
假設若能被3整除就轉角度,若不行則是填上白色點點並轉角度橘色線條和星星也是這樣操作,星星製作則是使用貝茲曲線
ctx.bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y)
時間數字則是:
ctx.fillStyle="white";
ctx.font = '10px serif';
var ang;
let innum=[6,7,8,9,10,11,12,1,2,3,4,5];
for(var num = 0; num < innum.length; num++){
ang=Math.PI*2/12*num;
ctx.rotate(ang);//旋轉角度
ctx.translate(0,90);//從原點移動半徑距離r
ctx.rotate(-ang);//為了防止打印出來的數字跟著轉,這時候將座標轉回來
ctx.fillText(innum[num].toString(),0,0);//使用原點位置當成打印座標,把數字印出來
ctx.textBaseline = "middle";//基線對齊設置
ctx.textAlign="center";//文字對齊設置
ctx.rotate(ang);//接著轉回原位
ctx.translate(0,-90);//倒退回到時鐘圓心
ctx.rotate(-ang);//轉回最開始的角度
}
指針:
這邊最主要的是製作指針樣式前要加入
ctx.rotate(item);
告知需要多少角度
//時針
function hourHand(item){
ctx.save();//儲存狀態
ctx.translate(ww/2,wh/2);//移到中心
ctx.rotate(item);//旋轉角度
ctx.lineWidth=7;
ctx.strokeStyle="white";
ctx.beginPath();
ctx.moveTo(0,0);
ctx.lineTo(0,-55);
ctx.stroke();
//白色內的黑線
ctx.lineWidth=2;
ctx.strokeStyle="black";
ctx.beginPath();
ctx.moveTo(0,-30);
ctx.lineTo(0,-50);
ctx.stroke();
ctx.restore();//復原
}
以時針為例子,首先因為是額外開啟一個function
所以要增加ctx.save()
,接著移動到中心,告知你的角度(參數),接著設定顏色、樣式,最後復原狀態再來是重頭戲時鐘的指針走動:
function update(){
var now=new Date();
var sec=now.getSeconds();
var min=now.getMinutes();
var hour=now.getHours();
hour=hour>12?hour-12:hour;//計算小時是否大於12,是的話扣12小時,否正常輸出
var secrot=Math.PI*2/60*sec;
var minrot=(Math.PI*2/60*min)+(Math.PI*2/60)/60*sec;//計算一分鐘可以走6度,在乘已經走了幾分鐘,加上在一分鐘以內一秒走了0.2度,再乘走了60秒
var hourrot=(Math.PI*2/12*hour)+(Math.PI*2/12/60*min)+(Math.PI*2/12/60/60*sec);//計算12小時一小時需要走30度,乘已走了幾個小時,加上一小時需走60分鐘(一小時一分鐘需要0.5度),乘共走了幾分鐘,加上一分鐘需要走60秒(一小時一分鐘一秒需要0.00833333333度),乘已共走了幾秒
ctx.clearRect(0,0,500,500);
draw();
hourHand(hourrot);
secHand(secrot);
minuteHand(minrot);
}
首先抓取我們的目前時間,之後抓去秒數,分數,時數,接下來計算每秒、每分、每小時都需要走的角度,畢竟沒有一個時鐘是直接大幅度跳角度的吧,所以當秒針走到這裡時,分針和時針也要移動接著為了避免前面移動的會殘留所以要使用
ctx.clearRect(0,0,width,height);
清除指定位置矩形內的內容,使他變透明。最後把參數放進控制指針的
function
就大功造成最後我們在外面放
setInterval(update,1000);
讓我們的時鐘能1000毫秒跑一次流程以及使用requestAnimationFrame(draw);
通知瀏覽器我們想要產生動畫,並且要求瀏覽器在下次重繪畫面前呼叫特定函數更新動畫。這個方法接受一個引數作為下次重繪前調用的回呼函數。以上第一次使用
canvas
還有很多不清楚也沒做好的部分,也參考許多前輩,但不得不說還蠻好玩的~只是邏輯要很夠(笑)
參考來源:
https://developer.mozilla.org/zh-TW/docs/Web/API/Canvas_API/Tutorial/Basic_usage
https://medium.com/@ruby30336/%E4%BD%BF%E7%94%A8canvas%E8%88%87js%E5%81%9A%E5%9C%93%E5%BD%A2%E6%99%82%E9%90%98-c400e0f51d3f
https://www.youtube.com/watch?v=sOHcx9jekzs
https://medium.com/@cos214159/canvas-%E7%AD%86%E8%A8%98-8-%E8%B2%9D%E8%8C%B2%E6%9B%B2%E7%B7%9Abeziercurveto-93b8f5257c86
留言
張貼留言