欧美一区二区三区老妇人-欧美做爰猛烈大尺度电-99久久夜色精品国产亚洲a-亚洲福利视频一区二区

怎么利用canvas實現(xiàn)按住鼠標移動繪制出軌跡

這篇文章主要介紹怎么利用canvas實現(xiàn)按住鼠標移動繪制出軌跡,文中介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們一定要看完!

創(chuàng)新互聯(lián)2013年開創(chuàng)至今,先為勃利等服務建站,勃利等地企業(yè),進行企業(yè)商務咨詢服務。為勃利企業(yè)網(wǎng)站制作PC+手機+微官網(wǎng)三網(wǎng)同步一站式服務解決您的所有建站問題。

概要

工作以來,寫過vue、react、正則、算法、小程序等知識,唯獨沒有寫過canvas,因為實在不會?。?/p>

2018年,給自己設定一個小目標:學會canvas,達到的效果是能用canvas實現(xiàn)一些css3不容易實現(xiàn)的動畫。

本文作為學習canvas的第一篇收獲,很多人初學canvas做的第一個demo是實現(xiàn)一個“鐘”,當然,我也實現(xiàn)了一個,不過不講這個,而是講講一個更有趣、也更簡單的玩意。

鼠標按住繪制軌跡

需求

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

怎么利用canvas實現(xiàn)按住鼠標移動繪制出軌跡

原理

先簡單分析下思路,首先我們需要一個canvas畫布,然后計算鼠標在畫布上的位置,給鼠標綁定onmousedown事件和onmousemove事件,在移動過程中繪制出路徑,松開鼠標的時候,繪制結束。

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

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

這是一個寬度800,高度400的畫布。為什么沒有寫px呢?哦,暫時沒搞懂,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學習</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、判斷當前環(huán)境是否支持canvas。

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

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

3、獲取2d對象。

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

4、獲取當前鼠標相對于canvas的坐標。

為什么要獲取這個坐標呢?因為鼠標默認是獲取當前窗口的相對坐標,而canvas可以位于頁面上的任何位置,所以需要通過計算才能得到真實的鼠標坐標。

將獲取鼠標相對于canvas的真實坐標封裝成了一個函數(shù),如果你覺得抽象,可以在草稿紙上畫圖來理解為什么要這么運算。

通常情況下,可以是x - rect.left和y - rect.top。但為什么實際上卻是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ù)分別傳入的是鼠標距離窗口的坐標,然后減去canvas距離窗口左邊和頂部的距離。
    return {
        x: x - rect.left * (canvas.width/rect.width),
        y: y - rect.top * (canvas.height/rect.height)
    }
}

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

先給鼠標綁定按下onmousedown事件,用moveTo繪制坐標起點。

theCanvas.onmousedown = function(e) {
    //獲得鼠標按下的點相對canvas的坐標。
    let ele = windowToCanvas(theCanvas, e.clientX, e.clientY)
    //es6的解構賦值
    let { x, y } = ele
    //繪制起點。
    context.moveTo(x, y)
}

6、移動鼠標的時候,沒有鼠標長按事件,又該怎么監(jiān)聽呢?

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

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

7、鼠標松開的時候,不再繪制路徑。

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

源碼

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

1、index.html

上面已經(jīng)展示了,不再復述。

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

/*
* 獲取鼠標在canvas上的坐標
* */
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
}

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

以上是怎么利用canvas實現(xiàn)按住鼠標移動繪制出軌跡的所有內容,感謝各位的閱讀!希望分享的內容對大家有幫助,更多相關知識,歡迎關注創(chuàng)新互聯(lián)行業(yè)資訊頻道!

文章名稱:怎么利用canvas實現(xiàn)按住鼠標移動繪制出軌跡
本文地址:http://chinadenli.net/article2/gphdoc.html

成都網(wǎng)站建設公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站導航網(wǎng)站建設、品牌網(wǎng)站設計外貿建站、服務器托管電子商務

廣告

聲明:本網(wǎng)站發(fā)布的內容(圖片、視頻和文字)以用戶投稿、用戶轉載內容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內容未經(jīng)允許不得轉載,或轉載時需注明來源: 創(chuàng)新互聯(lián)

外貿網(wǎng)站建設
精品欧美国产一二三区| 爱草草在线观看免费视频| 大伊香蕉一区二区三区| 一区二区日韩欧美精品| 成人国产激情在线视频| 欧美色婷婷综合狠狠爱| 欧美精品女同一区二区| 欧美日韩一区二区综合| 午夜色午夜视频之日本| 国产又色又爽又黄又大| 亚洲国产av一二三区| 国产不卡一区二区四区| 亚洲av成人一区二区三区在线| 99久久国产精品亚洲| 中国美女草逼一级黄片视频| 乱女午夜精品一区二区三区| 亚洲欧美天堂精品在线| 午夜福利大片亚洲一区| 在线观看免费无遮挡大尺度视频| 国产美女精品午夜福利视频 | 日本在线高清精品人妻| 草草视频精品在线观看| 在线观看免费无遮挡大尺度视频 | 亚洲一区二区三区免费的视频| 日本深夜福利在线播放| 免费黄色一区二区三区| 熟女乱一区二区三区丝袜| 视频一区二区黄色线观看| 日韩女优视频国产一区| 国产免费一区二区不卡| 日韩丝袜诱惑一区二区| 亚洲精品中文字幕在线视频| 婷婷色香五月综合激激情| 日本国产欧美精品视频| 中文字幕一区二区熟女| 欧美一级日韩中文字幕| 日韩专区欧美中文字幕| 亚洲精品国产主播一区| 国产一区二区不卡在线视频| 欧美小黄片在线一级观看 | 四十女人口红哪个色好看|