近期工作用到了map相關(guān)的一些知識(shí),有些資料找起來(lái)著實(shí)費(fèi)勁奔滑。忙里偷閑,順手整理一下啦顺少。(≧▽≦)/啦啦啦朋其。
首先呢,是canvas脆炎。
?先來(lái)個(gè)simple demo
?實(shí)現(xiàn)功能:
- 選擇畫(huà)筆顏色
- 繪畫(huà)
- 橡皮擦
- 清空畫(huà)板
?核心技能:
- 獲取鼠標(biāo)在畫(huà)板中的位置
- canvas繪畫(huà)
?canvas相關(guān)
- canvas是一個(gè)可以使用腳本在其中繪制圖形的HTML元素梅猿。注意:無(wú)論canvas 上畫(huà)多少東西膜眠,canvas都始終是單個(gè)元素统诺。
- canvas標(biāo)簽只有兩個(gè)非通用屬性width和height,canvas默認(rèn)的大小為300*150.
- canvas元素也和普通的元素一樣逾一,有margin几蜻,border喇潘,background等屬性。
- 如果在canvas繪制出來(lái)的圖像是扭曲的梭稚,嘗試在<canvas>的屬性中明確規(guī)定寬和高颖低,而不是使用CSS。
-
基本用法
- 元素引入
<canvas id="canvas" width="600" height="400">
<p>瀏覽器不支持canvas</p>
</canvas> - 渲染上下文
- canvas本身不具備畫(huà)圖形的功能哨毁,一切都是由canvas內(nèi)部的CanvasRenderingContext2D對(duì)象來(lái)做的。
- 繪制矩形
canvas只支持一種原生的圖形繪制:矩形源武。所有其他圖形的繪制都至少需要生成一條路徑扼褪。
-
canvas提供三種繪制矩形的方法
-
fillRect(x,y,width,height)
繪制一個(gè)填充的矩形 -
strokeRect(x,y,width,height)
繪制一個(gè)矩形的邊框 -
clearRect(x,y,width,height)
清除指定矩形矩形,讓清除部分完全透明
-
繪制線段
1.開(kāi)始路徑ctx.beginPath()
2.設(shè)置起點(diǎn)ctx.moveTo(x,y)
3.設(shè)置終點(diǎn)ctx.lineTo(x,y)
4.繪制ctx.stroke()
5.結(jié)束路徑ctx.closePath()
-
繪制三角形
- 利用繪制線段的原理繪制三角形
繪制弧形
-
繪制弧形的參數(shù)分別是:弧形圓心x坐標(biāo)粱栖、y坐標(biāo)话浇、半徑、起始角(以三點(diǎn)鐘的位置開(kāi)始)闹究、結(jié)束角幔崖、方向(true表示逆時(shí)針,false表示順時(shí)針)
- ctx.arc(600,200,100,0,Math.PI*2,false);
-
繪制貝塞爾曲線:
二次貝塞爾曲線:
ctx.quadraticCurveTo (cpx, cpy, x, y)
參數(shù)是控制點(diǎn)x坐標(biāo),控制點(diǎn)y坐標(biāo),結(jié)束點(diǎn)x坐標(biāo)和結(jié)束點(diǎn)y坐標(biāo)三次貝塞爾曲線
ctx.bezierCurveTo (cp1x, cp1y, cp2x, cp2y, x, y)
參數(shù)是控制點(diǎn)1的x坐標(biāo)和控制點(diǎn)1的y坐標(biāo)赏寇、控制點(diǎn)2的x坐標(biāo)和控制點(diǎn)2的y坐標(biāo)吉嫩、結(jié)束點(diǎn)x坐標(biāo)和結(jié)束點(diǎn)y坐標(biāo)
?完整代碼如下,注釋有詳解
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<style type="text/css">
*{
margin: 0;
padding: 0;
}
#box{
width: 600px;
height: 500px;
margin: 100px auto;
border: 1px solid black;
}
#box .control{
height: 100px;
}
#box .control div{
height: 50px;
line-height: 50px;
}
#box .control .changeColor{
padding-left: 15px;
}
#box .control .changeColor input{
width: 30px;
height: 30px;
margin: 0 15px;
font-size: 0;
/*background-color: orange;*/
vertical-align: middle;
}
#box .control .changeColor input:nth-of-type(1){
background-color: black;
}
#box .control .changeColor input:nth-of-type(2){
background-color: pink;
}
#box .control .changeColor input:nth-of-type(3){
background-color: red;
}
#box .control .changeColor input:nth-of-type(4){
background-color: orange;
}
#box .control .changeColor input:nth-of-type(5){
background-color: brown;
}
#box .control .changeColor input:nth-of-type(6){
background-color: purple;
}
#box .control .clear{
height: 50px;
}
#box .control .clear input{
width: 100px;
height: 50px;
margin: 0 15px;
font-size: 20px;
background-color: #FDF5E5;
}
#canvas{
background-color: #FFEBCB;
}
b{
font-size: 20px;
}
</style>
</head>
<body>
<div id="box">
<div class="control">
<div class="changeColor">
選擇畫(huà)筆顏色:
<input type="button" value="黑色" />
<input type="button" value="粉色" />
<input type="button" value="紅色"/>
<input type="button" value="橘色"/>
<input type="button" value="棕色" />
<input type="button" value="紫色" />
</div>
<div class="clear">
<input type="button" value="清空畫(huà)布" id="clearAllBtn" />
當(dāng)前選中的顏色:<b>黑色</b>
<input type="button" value="橡皮擦" id="rubberBtn" />
</div>
</div>
<canvas id="canvas" width="600" height="400"></canvas>
</div>
<script type="text/javascript">
var cvs = document.querySelector("#canvas");
var ctx = canvas.getContext("2d");
//記錄坐標(biāo)的對(duì)象(用來(lái)給move使用)
var pointerObj = {
}
//切換橡皮擦的狀態(tài)
var isRubber = false;
//按下
cvs.addEventListener('mousedown', function (e) {
var x = e.offsetX;
var y = e.offsetY;
console.log(x + " : " + y);
pointerObj.x = x;
pointerObj.y = y;
if (isRubber) {
//橡皮擦
rubberFn(x, y);
} else {
//畫(huà)畫(huà)
draw(x, y);
}
//移動(dòng)和抬起
this.addEventListener('mousemove', move);
this.addEventListener('mouseup', up);
})
//移動(dòng)
function move (e) {
var x = e.offsetX;
var y = e.offsetY;
if (isRubber) {
//橡皮擦
rubberFn(x, y);
} else {
//畫(huà)畫(huà)
draw(x, y);
}
//在移動(dòng)的時(shí)候把之前的存儲(chǔ)起來(lái)
pointerObj.x = x;
pointerObj.y = y;
}
//抬起
function up () {
cvs.removeEventListener('mousemove', move);
}
//畫(huà)畫(huà)
function draw (x, y) {
ctx.beginPath();
ctx.lineWidth = 5;
//設(shè)置樣式為圓頭
ctx.lineCap = "round";
ctx.moveTo(x, y);
ctx.lineTo(pointerObj.x, pointerObj.y);
ctx.stroke();
ctx.closePath();
}
var colorBtns = document.querySelectorAll('.changeColor input');
for (var i = 0; i < colorBtns.length; i++) {
colorBtns[i].onclick = changeColor;
}
//改變畫(huà)筆顏色
function changeColor () {
ctx.strokeStyle = getComputedStyle(this, null).backgroundColor;
var b = document.querySelector("b");
b.style.color = ctx.strokeStyle;
b.innerHTML = this.value;
//改變橡皮擦的狀態(tài)
isRubber = false;
}
var clearAllBtn = document.querySelector("#clearAllBtn");
var rubberBtn = document.querySelector("#rubberBtn");
//清空畫(huà)布
clearAllBtn.onclick = function () {
ctx.clearRect(0, 0, cvs.width, cvs.height);
}
//橡皮擦按鈕
rubberBtn.onclick = function () {
//開(kāi)啟橡皮擦功能
isRubber = true;
}
//橡皮擦功能
function rubberFn (x, y) {
ctx.beginPath();
//裁剪之前先把當(dāng)前場(chǎng)景保存下來(lái)
ctx.save();
//裁剪區(qū)域
ctx.arc(x, y, 20, 0, Math.PI * 2, false);
//裁剪
ctx.clip();
//在裁剪之后畫(huà)一個(gè)清空矩形嗅定,但根據(jù)裁剪的原理自娩,只有在裁剪區(qū)域才生效
ctx.clearRect(0, 0, cvs.width, cvs.height);
//然后在還原之前的場(chǎng)景
ctx.restore();
ctx.closePath();
}
</script>
</body>
</html>