Heim  >  Artikel  >  Web-Frontend  >  Canvas implementiert ein Methodenbeispiel für das Gedrückthalten der Maus und Bewegen, um eine Flugbahn zu zeichnen

Canvas implementiert ein Methodenbeispiel für das Gedrückthalten der Maus und Bewegen, um eine Flugbahn zu zeichnen

小云云
小云云Original
2018-02-02 14:01:142004Durchsuche

Anforderungen

Auf einer Leinwand hat der Anfangszustand der Leinwand nichts. Jetzt möchte ich der Leinwand einige Mausereignisse hinzufügen und mit der Maus auf die Leinwand schreiben. Der konkrete Effekt besteht darin, die Maus an einen beliebigen Punkt auf der Leinwand zu bewegen, dann die Maus gedrückt zu halten, die Mausposition zu verschieben und schon können Sie mit dem Schreiben beginnen!

Dieser Artikel ist der erste Gewinn von Learning Canvas. Die erste Demo, die viele Leute machen, wenn sie Canvas lernt, ist die Implementierung einer „Uhr“, aber das werde ich nicht tun Sprechen wir darüber. Lassen Sie uns über eine interessantere und einfachere Sache sprechen.

Halten Sie die Maus gedrückt, um die Flugbahn zu zeichnen

Canvas implementiert ein Methodenbeispiel für das Gedrückthalten der Maus und Bewegen, um eine Flugbahn zu zeichnen

Prinzip

Lassen Sie uns die Idee kurz analysieren Zuerst benötigen wir eine Leinwand, berechnen dann die Position der Maus auf der Leinwand, binden die Ereignisse onmousedown und onmousemove an die Maus, zeichnen während der Bewegung einen Pfad und beenden die Zeichnung, wenn Sie die Maus loslassen.

Obwohl diese Idee sehr einfach ist, gibt es einige Teile, für deren Umsetzung einige Tricks erforderlich sind.

1. Es ist eine HTML-Datei erforderlich, die Canvas-Elemente enthält.

Dies ist eine Leinwand mit einer Breite von 800 und einer Höhe von 400. Warum hast du nicht px geschrieben? Oh, ich verstehe es noch nicht, es wird im Canvas-Dokument empfohlen.

<!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. Bestimmen Sie, ob die aktuelle Umgebung Canvas unterstützt.

In main.js schreiben wir eine selbstausführende Funktion. Das Folgende ist ein Codeausschnitt zur Beurteilung der Kompatibilität. Der „Codekörper“ wird der Kern der Implementierungsanforderungen sein.

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

3. Holen Sie sich das 2D-Objekt.

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

4. Ermitteln Sie die Koordinaten der aktuellen Maus relativ zur Leinwand.

Warum müssen wir diese Koordinate erhalten? Da die Maus standardmäßig die relativen Koordinaten des aktuellen Fensters ermittelt und sich die Leinwand an einer beliebigen Stelle auf der Seite befinden kann, sind Berechnungen erforderlich, um die tatsächlichen Mauskoordinaten zu ermitteln.

Kapselt die tatsächlichen Koordinaten der Maus relativ zur Leinwand in einer Funktion. Wenn Sie sich abstrakt fühlen, können Sie ein Bild auf ein Notizpapier zeichnen, um zu verstehen, warum dieser Vorgang erforderlich ist.

Normalerweise kann dies x - rect.left und y - rect.top sein. Aber warum ist es eigentlich x - rect.left * (canvas.width/rect.width)?

canvas.width/rect.width bedeutet, das Skalierungsverhalten im Canvas zu bestimmen und das Skalierungsmultiplikator zu ermitteln.

const windowToCanvas = (canvas, x, y) => {
    //获取canvas元素距离窗口的一些属性,MDN上有解释
    let rect = canvas.getBoundingClientRect()
    //x和y参数分别传入的是鼠标距离窗口的坐标,然后减去canvas距离窗口左边和顶部的距离。
    return {
        x: x - rect.left * (canvas.width/rect.width),
        y: y - rect.top * (canvas.height/rect.height)
    }
}

5. Mit der Werkzeugfunktion in Schritt 4 können wir Mausereignisse zur Leinwand hinzufügen!

Binden Sie zunächst das onmousedown-Ereignis an die Maus und zeichnen Sie mit moveTo den Startpunkt der Koordinaten.

theCanvas.onmousedown = function(e) {
    //获得鼠标按下的点相对canvas的坐标。
    let ele = windowToCanvas(theCanvas, e.clientX, e.clientY)
    //es6的解构赋值
    let { x, y } = ele
    //绘制起点。
    context.moveTo(x, y)
}

6. Beim Bewegen der Maus gibt es kein langes Drücken der Maus. Wie soll ich das überwachen?

Der hier verwendete kleine Trick besteht darin, ein onmousemove (Mausbewegung)-Ereignis innerhalb von onmousedown auszuführen, damit die Maus überwacht und bewegt werden kann.

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. Beim Loslassen der Maus wird der Pfad nicht mehr gezeichnet.

Gibt es eine Möglichkeit, die beiden oben überwachten Ereignisse im onmouseup-Ereignis zu verhindern? Es gibt viele Methoden. Das Setzen von onmousedown und onmousemove auf Null ist eine davon. isAllowDrawLine wird auf einen Bool-Wert gesetzt, um zu steuern, ob die Funktion ausgeführt wird. Den spezifischen Code finden Sie unten im vollständigen Quellcode.

Der Quellcode

ist in 3 Dateien unterteilt: index.html, main.js, utils.js. Hier wird die Syntax von es6 verwendet, um die Entwicklungsumgebung zu konfigurieren. also nein. Wenn Sie den Code direkt kopieren und beim Ausführen ein Fehler auftritt, können Sie die es6-Syntax in es5 ändern.

1. html
Es wurde oben gezeigt und wird nicht noch einmal wiederholt.

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
}

Verwandte Empfehlungen:

CSS und JS erzielen einen wunderschönen Bewegungseffekt der Flugbahn des Sternenhimmels

Ableitung der Canvas-Bessel-Formel und Objekte, die einer komplexen Kurvenbahn folgen

Implementierung der kreisförmigen Bewegungsbahn in der CSS3-Animation


Das obige ist der detaillierte Inhalt vonCanvas implementiert ein Methodenbeispiel für das Gedrückthalten der Maus und Bewegen, um eine Flugbahn zu zeichnen. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn