Heim  >  Artikel  >  Web-Frontend  >  Implementieren Sie beweglichen Objektcode über JavaScript

Implementieren Sie beweglichen Objektcode über JavaScript

零下一度
零下一度Original
2017-04-17 17:56:452611Durchsuche

Ein Hauptziel interaktiver Animationen besteht darin, ein reibungsloses Benutzererlebnis zu schaffen, bei dem der größte Teil der Benutzerinteraktion über die Maus und den Touchscreen erfolgt.

In diesem Blogbeitrag möchte ich einige häufige Verwendungsmöglichkeiten von JS zum Bewegen von Objekten vorstellen, einschließlich Zieh- und Wurfeffekten.

1. Mithilfe von Mausereignissen

kann ein Mausklickereignis in zwei Ereignisse zerlegt werden: ein Maus-Down-Ereignis und ein Button-Up-Ereignis. Typischerweise treten diese beiden Ereignisse gleichzeitig auf. Manchmal bewegt sich die Maus jedoch nach dem Drücken eine Weile, bevor sie auftaucht. Dieser Vorgang wird als Ziehen bezeichnet, d. h. Drücken, Bewegen und Loslassen.

In der Canvas-Animation können Mausereignisse nur von Canvas-Elementen im HTML-DOM-Baum erfasst werden. Daher müssen wir manuell berechnen, wo das Mausereignis auf der Canvas auftritt, und bestimmen, ob es in welchem ​​Zeichenbereich auftritt Leinwandobjekt. Die Mausereignisse, die Aufmerksamkeit erfordern, sind: Mousedown, MouseMove und MouseUp. Spezifische Details finden Sie in meinem zugehörigen Blog-Beitrag „Detaillierte Erläuterung der JavaScript-Animation (1) – Schleifen und Ereignisüberwachung“.

2. Verwendung von Berührungsereignissen

Angesichts der Beliebtheit von Touchscreen-Geräten müssen wir die Berührungsereignisse des Benutzers wahrscheinlich in Animationen erfassen. Obwohl ein Touchscreen und eine Maus unterschiedliche Geräte sind, unterscheidet sich die Erfassung von Berührungsereignissen im DOM-Baum glücklicherweise nicht wesentlich von der Erfassung von Mausereignissen.

Die Berührungsereignisse, die den Mausereignissen Mousedown, Mousemove und Mouseup entsprechen, sind Touchstart, Touchend und Touchmove.

Ein großer Unterschied zwischen der Verwendung von Fingern und einer Maus besteht darin, dass die Maus immer auf dem Bildschirm erscheint, die Finger jedoch nicht immer in Berührung sind. Ein gängiger Ansatz besteht darin, ein benutzerdefiniertes Attribut isPressed einzuführen, um uns mitzuteilen, ob ein Finger den Bildschirm berührt. Spezifische Details finden Sie in meinem zugehörigen Blog-Beitrag „Detaillierte Erläuterung der JavaScript-Animation (1) – Schleifen und Ereignisüberwachung“.

3. Drag-Ereignis

Drag-Ereignis enthält drei Unterereignisse: Mausdrücken, Bewegen und Loslassen. Indem Sie die Koordinatenposition des Objekts kontinuierlich aktualisieren, um der Position des Mauszeigers zu folgen, können Sie das Objekt auf dem Canvas-Element ziehen. Darüber hinaus ist ein benutzerdefiniertes Attribut isPressed erforderlich, um anzugeben, ob die Maus derzeit gedrückt ist. Der Standardwert ist false, was bedeutet, dass sich die Maus im oberen Zustand befindet. Der Implementierungscode umfasst den folgenden Prozess:

1. Erfassen Sie das Mousedown-Ereignis und bestimmen Sie, ob sich die aktuelle Maus innerhalb des Objekts befindet. Wenn die Maus innerhalb des Objekts gedrückt wird, setzen Sie isPressed = true; Mauszeiger. Position zum Simulieren des Mauszieheffekts; Erfassen Sie das Mouseup-Ereignis und setzen Sie es auf „false“. >

Der JavaScript-Code lautet wie folgt:

Dieses Beispiel weist jedoch Fehler auf! Sie werden schnell feststellen, dass sich der Mittelpunkt des Balls beim Ziehen an der Mausposition befindet. Insbesondere wenn Sie mit der Maus auf den Rand des Balls klicken, werden Sie feststellen, dass der Mittelpunkt des Balls plötzlich an die Position des Mauszeigers springt. An. Offensichtlich wirkt das etwas abrupt.
<canvas id="canvas" width="400" height="400"></canvas>

Wir können leichte Verbesserungen vornehmen:

// 创建画球函数
function Ball() {
    this.x = 0;
    this.y = 0;
    this.radius = 20;
    this.fillStyle = "#f85455";
    this.draw = function(cxt) {
        cxt.fillStyle = this.fillStyle;
        cxt.beginPath();
        cxt.arc(this.x, this.y, this.radius,  0, 2 * Math.PI, true);
        cxt.closePath();
        cxt.fill();
    }
}
// 获得当前鼠标位置
function getMouse(ev) {
    var mouse = {
        x: 0,
        y: 0
    };
    var event = ev || window.event;
    if(event.pageX || event.pageY) {
        x = event.x;
        y = event.y;
    }else {
        var scrollLeft = document.documentElement.scrollLeft || document.body.scrollLeft;
        var scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
        x = event.clientX + scrollLeft;
        y = event.clientY + scrollTop;
    }
    mouse.x = x;
    mouse.y = y;

    return mouse;
}

var canvas = document.getElementById("canvas"),
        context = canvas.getContext("2d"),
        ball = new Ball(),
        mouse = {x: 0, y: 0},
        isPressed = false;
ball.x = 20;
ball.y = 20;

// 渲染小球
ball.draw(context);

// 小球拖拽事件
canvas.addEventListener("mousedown", mouseDown, false);
canvas.addEventListener("mousemove", mouseMove, false);
canvas.addEventListener("mouseup", mouseUp, false);

function mouseDown(ev) {
    // 判断当前鼠标是否在小球内
    mouse = getMouse(ev);
    if(Math.pow(mouse.x - ball.x, 2) + Math.pow(mouse.y - ball.y, 2) <= Math.pow(ball.radius, 2)) {
        isPressed = true;
    }
}

function mouseMove(ev) {
    if(isPressed) {
        mouse = getMouse(ev);

        ball.x = mouse.x;
        ball.y = mouse.y;
        context.clearRect(0, 0, canvas.width, canvas.height);
        ball.draw(context);
    }
}

function mouseUp(ev) {
    // 标示鼠标弹起事件
    isPressed = false;
}
Erfassen Sie den Versatz zwischen der aktuellen Mausposition und dem Mittelpunkt des Balls, wenn die Maus gedrückt wird; >

Wenn sich die Maus bewegt, subtrahieren Sie den beim Drücken der Maus aufgezeichneten Offset von der aktuellen Position der Maus

4. Wurfereignis

// 记录鼠标按下时,鼠标与小球圆心的偏移量
dx = mouse.x - ball.x;
dy = mouse.y - ball.y;

Wie drückt man das Werfen in einer Animation aus? Wählen Sie mit der Maus ein Objekt aus und ziehen Sie es, um es in eine bestimmte Richtung zu bewegen. Nach dem Loslassen der Maus bewegt sich das Objekt weiter in die gezogene Richtung.

Beim Werfen eines Objekts muss der Geschwindigkeitsvektor des Objekts während des Ziehvorgangs berechnet werden und dieser Geschwindigkeitsvektor muss dem Objekt beim Loslassen des Objekts zugewiesen werden. Tatsächlich ist die Berechnung des Geschwindigkeitsvektors eines Objekts beim Ziehen genau das Gegenteil der Anwendung des Geschwindigkeitsvektors auf das Objekt. Beim Anwenden eines Geschwindigkeitsvektors auf ein Objekt wird die Geschwindigkeit zur ursprünglichen Position des Objekts addiert, um die neue Position des Objekts zu berechnen. Diese Formel kann wie folgt geschrieben werden:

alte Position + Geschwindigkeitsvektor = neue Position
ball.x = mouse.x - dx;
ball.y = mouse.y - dy;
, das heißt

Geschwindigkeitsvektor = neue Position – alte Position

.

Um das Wurfverhalten zu implementieren, müssen einige Änderungen am vorherigen Code vorgenommen werden. Überprüfen Sie zunächst, ob die Maus gedrückt wird. Verwenden Sie die Variablen oldX und oldY, um die alten x- und y-Koordinatenpositionen des Balls zu speichern und die Ziehgeschwindigkeit des Balls zu aktualisieren.

Der spezifische JavaScript-Code wird wie folgt implementiert:

Es gibt noch einige Fehler in der Grenzbeurteilung dieser Demo, die wird in ein paar Tagen behoben.

5. Zusammenfassung

// 创建画球函数
function Ball() {
    this.x = 0;
    this.y = 0;
    this.radius = 20;
    this.fillStyle = "#f85455";
    this.draw = function(cxt) {
        cxt.fillStyle = this.fillStyle;
        cxt.beginPath();
        cxt.arc(this.x, this.y, this.radius,  0, 2 * Math.PI, true);
        cxt.closePath();
        cxt.fill();
    }
}
// 获得当前鼠标位置
function getMouse(ev) {
    var mouse = {
        x: 0,
        y: 0
    };
    var event = ev || window.event;
    if(event.pageX || event.pageY) {
        x = event.x;
        y = event.y;
    }else {
        var scrollLeft = document.documentElement.scrollLeft || document.body.scrollLeft;
        var scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
        x = event.clientX + scrollLeft;
        y = event.clientY + scrollTop;
    }
    mouse.x = x;
    mouse.y = y;

    return mouse;
}

var canvas = document.getElementById("canvas"),
        context = canvas.getContext("2d"),
        ball = new Ball(),
        mouse = {x: 0, y: 0},
        isPressed = false,
        oldX = 0,
        oldY = 0,
        currentX = 0,
        currentY = 0,
        vx = 0,
        vy = 0;
ball.x = 200;
ball.y = 200;

// 声明鼠标按下时,鼠标与小球圆心的距离
var dx = 0,
        dy = 0;

// 渲染小球
ball.draw(context);

// 小球拖拽事件
canvas.addEventListener("mousedown", mouseDown, false);
canvas.addEventListener("mousemove", mouseMove, false);
canvas.addEventListener("mouseup", mouseUp, false);

function mouseDown(ev) {
    // 判断当前鼠标是否在小球内
    mouse = getMouse(ev);
    if(Math.pow(mouse.x - ball.x, 2) + Math.pow(mouse.y - ball.y, 2) <= Math.pow(ball.radius, 2)) {
        isPressed = true;
        // 记录鼠标按下时,鼠标与小球圆心的距离
        dx = mouse.x - ball.x;
        dy = mouse.y - ball.y;
        // 获得小球拖拽前的位置
        mouse = getMouse(ev);
        oldX = mouse.x;
        oldY = mouse.y;
    }
}

function mouseMove(ev) {
    if(isPressed) {
        mouse = getMouse(ev);
        ball.x = mouse.x - dx;
        ball.y = mouse.y - dy;
        context.clearRect(0, 0, canvas.width, canvas.height);
        ball.draw(context);
    }
}

function mouseUp(ev) {
    // 标示鼠标弹起事件
    isPressed = false;
    // 把鼠标与圆心的距离位置恢复初始值
    dx = 0;
    dy = 0;
    // 获得小球拖拽后的位置
    mouse = getMouse(ev);
    currentX = mouse.x;
    currentY = mouse.y;

    // 更新速度向量:速度向量 = 新的位置 - 旧的位置
    vx = (currentX - oldX) * 0.05;
    vy = (currentY - oldY) * 0.05;

    drawFrame();
}

// 缓动动画
function drawFrame() {
    animRequest = window.requestAnimationFrame(drawFrame, canvas);
    context.clearRect(0, 0, canvas.width, canvas.height);
    if(ball.x >= canvas.width - 30 || ball.x <= 30 || ball.y >= canvas.height - 30 || ball.y <= 30) {
        window.cancelAnimationFrame(animRequest);
    }
    ball.x += vx;
    ball.y += vy;
    ball.draw(context);
}
Objektbewegungsereignisse können viele Formen der Gesamtbewegung haben, sie können jedoch alle zur Steuerung in drei separate Ereignisse zerlegt werden: Drücken, Bewegen, Loslassen , die bei Mausereignissen jeweils „mousedown“, „mousemove“ und „mouseup“ und bei Berührungsereignissen „touchstart“, „touchmove“ und „touchend“ entsprechen. Indem die Koordinatenposition des Objekts ständig aktualisiert wird, um der Position des Mauszeigers zu folgen, kann der Effekt des Ziehens und Werfens auf dem Canvas-Element erzielt werden.

Das obige ist der detaillierte Inhalt vonImplementieren Sie beweglichen Objektcode über JavaScript. 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