欧美成人午夜免费全部完,亚洲午夜福利精品久久,а√最新版在线天堂,另类亚洲综合区图片小说区,亚洲欧美日韩精品色xxx

扣丁學(xué)堂HTML5培訓(xùn)簡(jiǎn)述canvas實(shí)現(xiàn)按住鼠標(biāo)移動(dòng)繪制出軌跡的示例代碼

2019-09-09 10:34:43 4497瀏覽

本篇文章扣丁學(xué)堂HTML5培訓(xùn)小編給讀者們介紹一下canvas實(shí)現(xiàn)按住鼠標(biāo)移動(dòng)繪制出軌跡的示例代碼,文中有代碼列出供小伙伴們參考,現(xiàn)在小編分享給大家,感興趣的小伙伴就來(lái)了解一下吧。


扣丁學(xué)堂HTML5培訓(xùn)簡(jiǎn)述canvas實(shí)現(xiàn)按住鼠標(biāo)移動(dòng)繪制出軌跡的示例代碼


需求


在一塊canvas畫(huà)布上,初始狀態(tài)畫(huà)布什么都沒(méi)有,現(xiàn)在,我們想給畫(huà)布加一點(diǎn)鼠標(biāo)事件,用鼠標(biāo)在畫(huà)布上寫(xiě)字。具體的效果是鼠標(biāo)移動(dòng)到畫(huà)布上任意一點(diǎn),然后按住鼠標(biāo),移動(dòng)鼠標(biāo)的位置,就可以開(kāi)始寫(xiě)字啦。



原理


先簡(jiǎn)單分析下思路,首先我們需要一個(gè)canvas畫(huà)布,然后計(jì)算鼠標(biāo)在畫(huà)布上的位置,給鼠標(biāo)綁定onmousedown事件和onmousemove事件,在移動(dòng)過(guò)程中繪制出路徑,松開(kāi)鼠標(biāo)的時(shí)候,繪制結(jié)束。

這個(gè)思路雖然很簡(jiǎn)單,但是里面有些地方需要小技巧實(shí)現(xiàn)。


1、需要一個(gè)html文件,包含canvas元素。


這是一個(gè)寬度800,高度400的畫(huà)布。為什么沒(méi)有寫(xiě)px呢?哦,暫時(shí)沒(méi)搞懂,canvas文檔推薦的。


<!doctype html>
<html class="no-js" lang="zh">
    <head>
        <meta charset="utf-8">
        <meta http-equiv="x-ua-compatible" content="ie=edge">
        <title>canvas學(xué)習(xí)</title>
        <meta name="description" content="">
        <meta name="viewport" content="width=device-width, initial-scale=1">

        <link rel="manifest" href="site.webmanifest">
        <link rel="apple-touch-icon" href="icon.png">
        <link rel="stylesheet" href="css/main.css">
    </head>
    <body>
        <canvas id="theCanvas" width="800" height="400"></canvas>
        <script src="js/main.js"></script>
    </body>
</html>

2、判斷當(dāng)前環(huán)境是否支持canvas。


在main.js中,我們寫(xiě)一個(gè)自執(zhí)行函數(shù),下面是兼容性判斷的代碼片段,“代碼主體”中將會(huì)是實(shí)現(xiàn)需求的核心。


(function() {
    let theCanvas = document.querySelector('#theCanvas')
    if (!theCanvas || !theCanvas.getContext) {
        //不兼容canvas
        return false
    } else {
        //代碼主體
    }
})()


3、獲取2d對(duì)象。


let context = theCanvas.getContext('2d')


4、獲取當(dāng)前鼠標(biāo)相對(duì)于canvas的坐標(biāo)。


為什么要獲取這個(gè)坐標(biāo)呢?因?yàn)槭髽?biāo)默認(rèn)是獲取當(dāng)前窗口的相對(duì)坐標(biāo),而canvas可以位于頁(yè)面上的任何位置,所以需要通過(guò)計(jì)算才能得到真實(shí)的鼠標(biāo)坐標(biāo)。


將獲取鼠標(biāo)相對(duì)于canvas的真實(shí)坐標(biāo)封裝成了一個(gè)函數(shù),如果你覺(jué)得抽象,可以在草稿紙上畫(huà)圖來(lái)理解為什么要這么運(yùn)算。


通常情況下,可以是x - rect.left和y - rect.top。但為什么實(shí)際上卻是x - rect.left * (canvas.width/rect.width)呢?


canvas.width/rect.width表示判斷canvas中存在的縮放行為,求出縮放的倍數(shù)。


const windowToCanvas = (canvas, x, y) => {
    //獲取canvas元素距離窗口的一些屬性,MDN上有解釋
    let rect = canvas.getBoundingClientRect()
    //x和y參數(shù)分別傳入的是鼠標(biāo)距離窗口的坐標(biāo),然后減去canvas距離窗口左邊和頂部的距離。
    return {
        x: x - rect.left * (canvas.width/rect.width),
        y: y - rect.top * (canvas.height/rect.height)
    }
}


5、有了第4步的利器函數(shù),我們可以給canvas加上鼠標(biāo)事件了!


先給鼠標(biāo)綁定按下onmousedown事件,用moveTo繪制坐標(biāo)起點(diǎn)。


theCanvas.onmousedown = function(e) {
    //獲得鼠標(biāo)按下的點(diǎn)相對(duì)canvas的坐標(biāo)。
    let ele = windowToCanvas(theCanvas, e.clientX, e.clientY)
    //es6的解構(gòu)賦值
    let { x, y } = ele
    //繪制起點(diǎn)。
    context.moveTo(x, y)
}


6、移動(dòng)鼠標(biāo)的時(shí)候,沒(méi)有鼠標(biāo)長(zhǎng)按事件,又該怎么監(jiān)聽(tīng)呢?


這里用到的小技巧是在onmousedown內(nèi)部再執(zhí)行一個(gè)onmousemove(鼠標(biāo)移動(dòng))事件,這樣就能監(jiān)聽(tīng)按住鼠標(biāo)并且移動(dòng)了。


theCanvas.onmousedown = function(e) {
    //獲得鼠標(biāo)按下的點(diǎn)相對(duì)canvas的坐標(biāo)。
    let ele = windowToCanvas(theCanvas, e.clientX, e.clientY)
    //es6的解構(gòu)賦值
    let { x, y } = ele
    //繪制起點(diǎn)。
    context.moveTo(x, y)
    //鼠標(biāo)移動(dòng)事件
    theCanvas.onmousemove = (e) => {
        //移動(dòng)時(shí)獲取新的坐標(biāo)位置,用lineTo記錄當(dāng)前的坐標(biāo),然后stroke繪制上一個(gè)點(diǎn)到當(dāng)前點(diǎn)的路徑
        let ele = windowToCanvas(theCanvas, e.clientX, e.clientY)
        let { x, y } = ele
        context.lineTo(x, y)
        context.stroke()
    }
}


7、鼠標(biāo)松開(kāi)的時(shí)候,不再繪制路徑。


有什么辦法可以讓onmouseup事件中阻止掉上面監(jiān)聽(tīng)的2種事件呢?方法挺多的,設(shè)置onmousedown和onmousemove為null算是一種,我這里用到了“開(kāi)關(guān)”。isAllowDrawLine設(shè)置為bool值,來(lái)控制函數(shù)是否執(zhí)行,具體代碼可以看下面完整的源碼。



源碼


分為3個(gè)文件,index.html、main.js、utils.js,這里用到了es6的語(yǔ)法,我是使用parcle配置好了開(kāi)發(fā)環(huán)境,所以不會(huì)有報(bào)錯(cuò),如果你直接復(fù)制代碼,運(yùn)行的時(shí)候出現(xiàn)錯(cuò)誤,在無(wú)法升級(jí)瀏覽器的情況下,可以將es6語(yǔ)法改成es5。


1、index.html

上面已經(jīng)展示了,不再?gòu)?fù)述。


2、main.js

import { windowToCanvas } from './utils'
(function() {
    let theCanvas = document.querySelector('#theCanvas')
    if (!theCanvas || !theCanvas.getContext) {
        return false
    } else {
        let context = theCanvas.getContext('2d')
        let isAllowDrawLine = false
        theCanvas.onmousedown = function(e) {
            isAllowDrawLine = true
            let ele = windowToCanvas(theCanvas, e.clientX, e.clientY)
            let { x, y } = ele
            context.moveTo(x, y)
            theCanvas.onmousemove = (e) => {
                if (isAllowDrawLine) {
                    let ele = windowToCanvas(theCanvas, e.clientX, e.clientY)
                    let { x, y } = ele
                    context.lineTo(x, y)
                    context.stroke()
                }
            }
        }
        theCanvas.onmouseup = function() {
            isAllowDrawLine = false
        }
    }
})()


3、utils.js

/*
* 獲取鼠標(biāo)在canvas上的坐標(biāo)
* */
const windowToCanvas = (canvas, x, y) => {
    let rect = canvas.getBoundingClientRect()
    return {
        x: x - rect.left * (canvas.width/rect.width),
        y: y - rect.top * (canvas.height/rect.height)
    }
}

export {
    windowToCanvas
}


總結(jié)


這里有個(gè)誤區(qū),我們用的是canvas對(duì)象綁定事件 theCanvas.onmouseup,其實(shí)canvas不能綁定事件,真正綁定的是document和window。但是由于瀏覽器會(huì)自動(dòng)幫你判斷并且移交事件處理,所以完全不用擔(dān)心。


想要了解更多內(nèi)容的小伙伴可以登錄扣丁學(xué)堂官網(wǎng)咨詢(xún)。想要學(xué)好HTML5開(kāi)發(fā)小編給大家推薦口碑良好的扣丁學(xué)堂,扣丁學(xué)堂有專(zhuān)業(yè)老師制定的HTML5學(xué)習(xí)路線圖輔助學(xué)員學(xué)習(xí),此外還有與時(shí)俱進(jìn)的HTML5課程體系和HTML5視頻教程供大家學(xué)習(xí),想要學(xué)好HTML5開(kāi)發(fā)技術(shù)的小伙伴快快行動(dòng)吧??鄱W(xué)堂H5技術(shù)交流群:673883249。


                           【掃碼進(jìn)入HTML5VIP免費(fèi)公開(kāi)課】  


     【關(guān)注微信公眾號(hào)獲取更多學(xué)習(xí)資料】        【掃碼進(jìn)入HTML5前端開(kāi)發(fā)VIP免費(fèi)公開(kāi)課】  



查看更多關(guān)于“HTML5開(kāi)發(fā)技術(shù)資訊”的相關(guān)文章>>


標(biāo)簽: HTML5培訓(xùn) HTML5視頻教程 HTML5學(xué)習(xí)視頻 HTML5在線視頻 HTML5培訓(xùn)班 微信小程序

熱門(mén)專(zhuān)區(qū)

暫無(wú)熱門(mén)資訊

課程推薦

微信
微博
15311698296

全國(guó)免費(fèi)咨詢(xún)熱線

郵箱:codingke@1000phone.com

官方群:148715490

北京千鋒互聯(lián)科技有限公司版權(quán)所有   北京市海淀區(qū)寶盛北里西區(qū)28號(hào)中關(guān)村智誠(chéng)科創(chuàng)大廈4層
京ICP備2021002079號(hào)-2   Copyright ? 2017 - 2022
返回頂部 返回頂部