Maison > interface Web > tutoriel CSS > Canvas implémente un exemple de méthode consistant à maintenir la souris enfoncée et à se déplacer pour tracer une trajectoire

Canvas implémente un exemple de méthode consistant à maintenir la souris enfoncée et à se déplacer pour tracer une trajectoire

小云云
Libérer: 2018-02-02 14:01:14
original
2064 Les gens l'ont consulté

Exigences

Sur un canevas, l'état initial du canevas n'a rien. Maintenant, je souhaite ajouter quelques événements de souris au canevas et utiliser la souris pour écrire sur le canevas. L'effet spécifique est de déplacer la souris vers n'importe quel point du canevas, puis de maintenir la souris enfoncée, de déplacer la position de la souris et vous pouvez commencer à écrire !

Cet article est le premier gain de l'apprentissage de Canvas. La première démonstration que beaucoup de gens font lorsqu'ils apprennent Canvas est d'implémenter une "horloge". Parlons de cela. Parlons d’une chose plus intéressante et plus simple.

Maintenez la souris enfoncée pour tracer la trajectoire

Canvas implémente un exemple de méthode consistant à maintenir la souris enfoncée et à se déplacer pour tracer une trajectoire

Principe

Analysons brièvement l'idée .Tout d'abord, nous avons besoin d'un canevas, puis calculons la position de la souris sur le canevas, lions l'événement onmousedown et onmousemove à la souris et dessinons le chemin pendant le mouvement. Lorsque la souris est relâchée, le dessin se termine.

Bien que cette idée soit très simple, certaines parties nécessitent quelques astuces pour être mises en œuvre.

1. Un fichier html est requis, contenant des éléments de canevas.

Il s'agit d'une toile d'une largeur de 800 et d'une hauteur de 400. Pourquoi n'as-tu pas écrit px ? Oh, je ne comprends pas encore, c'est recommandé par le document canevas.

<!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>
Copier après la connexion

2. Déterminez si l'environnement actuel prend en charge le canevas.

Dans main.js, nous écrivons une fonction auto-exécutable. Ce qui suit est l'extrait de code pour le jugement de compatibilité. Le « corps du code » sera au cœur des exigences d'implémentation.

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

3. Récupérez l'objet 2D.

   let context = theCanvas.getContext('2d')
Copier après la connexion

4. Obtenez les coordonnées de la souris actuelle par rapport au canevas.

Pourquoi devons-nous obtenir ces coordonnées ? Étant donné que la souris obtient par défaut les coordonnées relatives de la fenêtre actuelle et que le canevas peut être situé n'importe où sur la page, des calculs sont nécessaires pour obtenir les coordonnées réelles de la souris.

Encapsule les coordonnées réelles de la souris par rapport au canevas dans une fonction. Si vous vous sentez abstrait, vous pouvez dessiner une image sur un papier brouillon pour comprendre pourquoi cette opération est nécessaire.

Normalement, cela peut être x - rect.left et y - rect.top. Mais pourquoi est-ce réellement x - rect.left * (canvas.width/rect.width) ?

canvas.width/rect.width signifie déterminer le comportement de mise à l'échelle dans le canevas et trouver le multiple de mise à l'échelle.

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)
    }
}
Copier après la connexion

5. Avec la fonction outil de l'étape 4, nous pouvons ajouter des événements de souris au canevas !

Liez d'abord l'événement onmousedown à la souris et utilisez moveTo pour dessiner le point de départ des coordonnées.

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

6. Lorsque vous déplacez la souris, il n'y a pas d'événement d'appui long de la souris, comment dois-je le surveiller ?

La petite astuce utilisée ici est d'exécuter un événement onmousemove (mouvement de la souris) à l'intérieur de onmousedown, afin que la souris puisse être surveillée et déplacée.

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()
    }
}
Copier après la connexion

7. Lorsque la souris est relâchée, le chemin ne sera plus tracé.

Existe-t-il un moyen d'empêcher les deux événements surveillés ci-dessus dans l'événement onmouseup ? Il existe de nombreuses méthodes. Définir onmousedown et onmousemove sur null en est une. J'ai utilisé "switch" ici. isAllowDrawLine est défini sur une valeur booléenne pour contrôler si la fonction est exécutée. Pour le code spécifique, veuillez consulter le code source complet ci-dessous.

Le code source

est divisé en 3 fichiers, index.html, main.js, utils.js La syntaxe d'es6 est utilisée ici pour configurer l'environnement de développement, donc non Il y aura une erreur. Si vous copiez le code directement et qu'une erreur se produit lors de l'exécution, si le navigateur ne peut pas être mis à niveau, vous pouvez changer la syntaxe es6 en es5.

1. html
Il a été montré ci-dessus et ne sera plus répété.

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
        }
    }
})()
Copier après la connexion

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
}
Copier après la connexion

Recommandations associées :

CSS et JS obtiennent un bel effet de mouvement de trajectoire de ciel étoilé

Dérivation de la formule Canvas Bessel et objets suivant une trajectoire de courbe complexe

Implémentation de trajectoire de mouvement circulaire en animation CSS3


Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Étiquettes associées:
source:php.cn
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal