ホームページ >ウェブフロントエンド >CSSチュートリアル >Canvasにマウスを押したまま移動して軌跡を描くメソッド例を実装

Canvasにマウスを押したまま移動して軌跡を描くメソッド例を実装

小云云
小云云オリジナル
2018-02-02 14:01:142059ブラウズ

要件

キャンバスの初期状態では何もありません。次に、いくつかのマウスイベントをキャンバスに追加し、マウスを使用してキャンバスに書き込みたいと考えています。具体的な効果としては、マウスをキャンバス上の任意の点に移動し、マウスを押したままマウスの位置を移動すると、書き込みを開始できるようになります。

この記事は、キャンバスを学習することで得られる最初の利点です。キャンバスを学習するときに多くの人が行う最初のデモは、もちろん私も実装しましたが、これについては説明しません。もっと面白いもの、そしてもっとシンプルなもの。

マウスを押したままにして軌跡を描きます

Canvasにマウスを押したまま移動して軌跡を描くメソッド例を実装

原理

まず、キャンバスが必要で、キャンバス上のマウスの位置を計算し、onmousedown イベントをバインドしましょう。 onmousemove イベントをマウスに渡します。移動中にパスが描画され、マウスが放されると描画が終了します。

このアイデアは非常にシンプルですが、実装するにはいくつかのコツが必要な部分があります。

1. Canvas 要素を含む HTML ファイルが必要です。

これは幅800、高さ400のキャンバスです。なぜpxと書かなかったのですか?ああ、まだわかりませんが、キャンバスのドキュメントで推奨されています。

<!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. 現在の環境がキャンバスをサポートしているかどうかを確認します。

main.js では、互換性判定のためのコードスニペットを記述します。「コード本体」が実装要件の中核となります。

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

3. 2D オブジェクトを取得します。

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

4. キャンバスに対する現在のマウスの座標を取得します。

なぜこの座標を取得する必要があるのでしょうか?マウスはデフォルトで現在のウィンドウの相対座標を取得し、キャンバスはページ上のどこにでも配置できるため、実際のマウス座標を取得するには計算が必要です。

キャンバスに対するマウスの実際の座標の取得を関数にカプセル化します。抽象的だと感じる場合は、この操作が必要な理由をメモ用紙に描くと理解できます。

通常は、x-rect.left と y-rect.top になります。しかし、実際にはなぜ x -rect.left * (canvas.width/rect.width) なのでしょうか?

canvas.width/rect.width は、canvas 内のスケーリング動作を決定し、スケーリング倍数を見つけることを意味します。

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. 手順4のツール機能を使用して、キャンバスにマウスイベントを追加できます。

まず、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. マウスを動かすときにマウスの長押しイベントがありません。それを監視するにはどうすればよいですか?

ここで使用されているちょっとしたトリックは、onmousedown 内で onmousemove (マウス移動) イベントを実行して、マウスを監視して移動できるようにすることです。

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 イベントで上記で監視されている 2 つのイベントを防ぐ方法はありますか? onmousedown と onmousemove を null に設定する方法はたくさんありますが、ここでは「switch」を使用しました。 isAllowDrawLine はブール値に設定され、関数が実行されるかどうかを制御します。具体的なコードについては、以下の完全なソース コードを参照してください。

ソースコード

は、index.html、main.js、utils.jsの3つのファイルに分かれています。ここではparcleを使用して開発環境を構築しています。コードを直接コピーします。コードの実行中にエラーが発生します。ブラウザをアップグレードできない場合は、es6 の構文を es5.

1、index.html
に変更できます。上記の説明は繰り返しません。

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
}

関連推奨事項:

美しい星空の軌跡モーション効果を実現するためのCSSとJS

canvas Bessel公式の導出とオブジェクト複雑な曲線軌跡をたどる

CSS3アニメーションで円運動軌跡を実現


以上がCanvasにマウスを押したまま移動して軌跡を描くメソッド例を実装の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。