成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

使用Canvas和JavaScript做一個畫板

asce1885 / 881人閱讀

摘要:本文同步于個人博客前些天學(xué)習(xí)了的元素,今天就來實(shí)踐一下,用做一個畫板。實(shí)現(xiàn)一個簡單的畫板實(shí)現(xiàn)思路監(jiān)聽鼠標(biāo)事件,用方法把記錄的數(shù)據(jù)畫出來。為時,移動鼠標(biāo)使用剪裁擦除畫布。

本文同步于個人博客:https://zhoushuo.me/blog/2018/03/11/drawing-borad/

前些天學(xué)習(xí)了HTML5元素,今天就來實(shí)踐一下,用canvas做一個畫板。

首先說一下要實(shí)現(xiàn)的功能:

切換畫筆顏色

調(diào)整筆刷粗細(xì)

清空畫布

橡皮擦擦除

撤銷操作

保存成圖片

兼容移動端(支持觸摸)

好了,廢話少說,先看最終效果:https://zhoushuozh.github.io/drawingborad

準(zhǔn)備工作

首先,準(zhǔn)備個容器,也就是畫板了。

然后初始化js:

let canvas = document.getElementById("drawing-board");
let ctx = canvas.getContext("2d");

我想把畫板做成全屏的,所以接下來設(shè)置一下canvas的寬高。

let pageWidth = document.documentElement.clientWidth;
let pageHeight = document.documentElement.clientHeight;

canvas.width = pageWidth;
canvas.height = pageHeight;

由于部分IE不支持canvas,如果要兼容IE,我們可以創(chuàng)建一個canvas,然后使用excanvas初始化,針對IE加上exCanvas.js,這里我們暫時先不考慮IE。

實(shí)現(xiàn)一個簡單的畫板

實(shí)現(xiàn)思路:監(jiān)聽鼠標(biāo)事件,用drawCircle()方法把記錄的數(shù)據(jù)畫出來。

設(shè)置初始化當(dāng)前畫布功能為畫筆狀態(tài),painting = false,

當(dāng)鼠標(biāo)按下時(mousedown),把painting設(shè)為true,表示正在畫,鼠標(biāo)沒松開。把鼠標(biāo)點(diǎn)記錄下來。

當(dāng)按下鼠標(biāo)的時候,鼠標(biāo)移動(mousemove)就把點(diǎn)記錄下來并畫出來。

如果鼠標(biāo)移動過快,瀏覽器跟不上繪畫速度,點(diǎn)與點(diǎn)之間會產(chǎn)品間隙,所以我們需要將畫出的點(diǎn)用線連起來(lineTo())。

鼠標(biāo)松開的時候(mouseup),把painting設(shè)為false。

代碼:

let painting = false;
let lastPoint = {x: undefined, y: undefined};

//鼠標(biāo)按下事件
canvas.onmousedown = function (e) {
    painting = true;
    let x = e.clientX;
    let y = e.clientY;
    lastPoint = {"x": x, "y": y};
    drawCircle(x, y, 5);
};

//鼠標(biāo)移動事件
canvas.onmousemove = function (e) {
    if (painting) {
        let x = e.clientX;
        let y = e.clientY;
        let newPoint = {"x": x, "y": y};
        drawLine(lastPoint.x, lastPoint.y, newPoint.x, newPoint.y,clear);
        lastPoint = newPoint;
    }
};

//鼠標(biāo)松開事件
canvas.onmouseup = function () {
    painting = false;
}

// 畫點(diǎn)函數(shù)
function drawCircle(x, y, radius) {
    ctx.save();
    ctx.beginPath();
    ctx.arc(x, y, radius, 0, Math.PI * 2);
    ctx.fill();
}

// 劃線函數(shù)
function drawLine(x1, y1, x2, y2) {
    ctx.lineWidth = 3;
    ctx.lineCap = "round";
    ctx.lineJoin = "round";
    ctx.moveTo(x1, y1);
    ctx.lineTo(x2, y2);
    ctx.stroke();
    ctx.closePath();
}
橡皮擦功能

實(shí)現(xiàn)思路

獲取橡皮擦元素

設(shè)置橡皮擦初始狀態(tài),clear = false。

監(jiān)聽橡皮擦click事件,點(diǎn)擊橡皮擦,改變橡皮擦狀態(tài),clear = true。

cleartrue時,移動鼠標(biāo)使用canvas剪裁(clip())擦除畫布。

let eraser = document.getElementById("eraser");
let clear = false;

eraser.onclick = function () {
    clear = true;
};

...
if (clear) {
    ctx.save();
    ctx.globalCompositeOperation = "destination-out";
    ctx.stroke();
    ctx.closePath();
    ctx.clip();
    ctx.clearRect(0,0,canvas.width,canvas.height);
    ctx.restore();
}
...

注意,在canvas中的裁剪和平時的裁剪功能不一樣在這里,裁剪是指在裁剪區(qū)域去顯示我們所畫的圖

兼容移動端

實(shí)現(xiàn)思路:

判斷設(shè)備是否支持觸摸

true,則使用touch事件;false,則使用mouse事件

代碼:

...
if (document.body.ontouchstart !== undefined) {
    // 使用touch事件
    anvas.ontouchstart = function (e) {
        // 開始觸摸
    }
    canvas.ontouchmove = function (e) {
        // 開始滑動
    }
    canvas.ontouchend = function () {
        // 滑動結(jié)束
    }
}else{
    // 使用mouse事件
    ...
}
...

這里需要注意的一點(diǎn)是,在touch事件里,是通過.touches[0].clientX.touches[0].clientY來獲取坐標(biāo)的,這點(diǎn)要和mouse事件區(qū)別開。

切換畫筆顏色

實(shí)現(xiàn)思路:

獲取顏色元素節(jié)點(diǎn)。

點(diǎn)擊顏色返回其顏色值,并賦給畫布的ctx.strokeStyle

代碼:

let aColorBtn = document.getElementsByClassName("color-item");

for (let i = 0; i < aColorBtn.length; i++) {
    aColorBtn[i].onclick = function () {
    for (let i = 0; i < aColorBtn.length; i++) {
        activeColor = this.style.backgroundColor;
        ctx.strokeStyle = activeColor;
    }
}
清空畫布

實(shí)現(xiàn)思路:

獲取元素節(jié)點(diǎn)。

點(diǎn)擊清空按鈕清空canvas畫布。

代碼:

let reSetCanvas = document.getElementById("clear");

reSetCanvas.onclick = function () {
    ctx.clearRect(0, 0, canvas.width, canvas.height);
};
調(diào)整筆刷粗細(xì)

實(shí)現(xiàn)思路:

創(chuàng)建input[type=range]

滑動range獲取其value值,并賦給ctx.lineWidth

代碼:

let range = document.getElementById("range");

range.onchange = function(){
    lWidth = this.value;
};
保存成圖片

實(shí)現(xiàn)思路:

獲取canvas.toDateURL

在頁面里創(chuàng)建并插入一個a標(biāo)簽

a標(biāo)簽href等于canvas.toDateURL,并添加download屬性

點(diǎn)擊保存按鈕,a標(biāo)簽觸發(fā)click事件

代碼:

let save = document.getElementById("save");

save.onclick = function () {
    let imgUrl = canvas.toDataURL("image/png");
    let saveA = document.createElement("a");
    document.body.appendChild(saveA);
    saveA.href = imgUrl;
    saveA.download = "zspic" + (new Date).getTime();
    saveA.target = "_blank";
    saveA.click();
};
撤銷

實(shí)現(xiàn)思路:

準(zhǔn)備一個數(shù)組記錄歷史操作

每次使用畫筆前將當(dāng)前繪圖表面儲存進(jìn)數(shù)組

點(diǎn)擊撤銷時,恢復(fù)到上一步的繪圖表面

代碼:

canvas.ontouchstart = function (e) {
     // 在這里儲存繪圖表面
    this.firstDot = ctx.getImageData(0, 0, canvas.width, canvas.height);
    saveData(this.firstDot);
    ...
}

let undo = document.getElementById("undo");
let historyDeta = [];

function saveData (data) {
    (historyDeta.length === 10) && (historyDeta.shift()); // 上限為儲存10步,太多了怕掛掉
    historyDeta.push(data);
}
undo.onclick = function(){
    if(historyDeta.length < 1) return false;
    ctx.putImageData(historyDeta[historyDeta.length - 1], 0, 0);
    historyDeta.pop()
};

因?yàn)槊看蝺Υ娑际菍⒁粡垐D片存入內(nèi)存,對性能影響較大,所以在這里設(shè)置了儲存上限。

總結(jié)

這里用的知識點(diǎn)主要有:監(jiān)聽mouse、touch事件,以及canvasmoveTo()、lineTo()、stroke()、clip()、clearRect()等方法。其實(shí)還有很多效果可以實(shí)現(xiàn),比如說噴霧效果,蠟筆效果,藝術(shù)畫效果等等。日后有時間我會繼續(xù)對這個畫板進(jìn)行優(yōu)化,增加一些新的功能,同時歡迎大家留言提問或者提出批評建議。

最終代碼:https://github.com/zhoushuozh/drawingborad

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/93455.html

相關(guān)文章

  • JavaScript中的圖片處理與合成(一)

    摘要:中的圖片處理與合成一引言圖片處理現(xiàn)在已經(jīng)成為了我們生活中的剛需,想必大家也經(jīng)常有這方面的需求。實(shí)際前端業(yè)務(wù)中,也經(jīng)常會有很多的項目需要用到圖片加工和處理。 JavaScript中的圖片處理與合成(一) 引言: 圖片處理現(xiàn)在已經(jīng)成為了我們生活中的剛需,想必大家也經(jīng)常有這方面的需求。實(shí)際前端業(yè)務(wù)中,也經(jīng)常會有很多的項目需要用到圖片加工和處理。由于過去一段時間公司的業(yè)務(wù)需求,讓我在這方面積累...

    Charles 評論0 收藏0
  • Day08 - HTML5 Canvas 實(shí)現(xiàn)彩虹畫筆繪畫板指南

    摘要:實(shí)現(xiàn)彩虹畫筆繪畫板指南作者簡介是推出的一個天挑戰(zhàn)。這部分不涉及內(nèi)容,全部由來實(shí)現(xiàn)。實(shí)現(xiàn)彩虹畫筆繪畫板效果圖項目源碼分析源碼獲取節(jié)點(diǎn)支持不支持彩虹效控制筆觸大小控制繪制路徑源碼分析寬高設(shè)置屬性筆觸的形狀,有圓平方三種。 Day08 - HTML5 Canvas 實(shí)現(xiàn)彩虹畫筆繪畫板指南 作者:?liyuechun 簡介:JavaScript30 是 Wes Bos 推出的一個 30 天挑...

    Ajian 評論0 收藏0

發(fā)表評論

0條評論

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