Анимация точки холста в исходном положении при отпускании мыши - PullRequest
1 голос
/ 01 апреля 2020

Я создал анимацию холста, в которой линии зависают при наведении на холст. 1 точка тянется к мышке, а другая отталкивается.

Есть несколько аспектов анимации, с которыми я борюсь, я хотел бы анимировать линии, которые тянутся к мышке, сейчас это просто очень мгновенно и наоборот, когда мышь покидает холст, они просто получают свои начальные координаты, что делает его очень мгновенным. Я попробовал это с помощью gsap.to, но я не могу понять, как использовать это, чтобы установить две отдельные точки в линии.

Еще одна вещь, которую я хотел бы добавить, это то, что чем дальше мышь находится от определенной линии, тем короче я бы хотел, чтобы линия была. Прямо сейчас все строки равны по длине, как только мышь наводит курсор на холст.

$(document).ready(function () {
    initContainerCanvas();
});

$(window).resize(function () {
    initContainerCanvas();
});

function initContainerCanvas() {
    var canvas = document.querySelector('.container-animation');

    canvas.setAttribute('width', window.getComputedStyle(canvas, null).getPropertyValue("width"));
    canvas.setAttribute('height', window.getComputedStyle(canvas, null).getPropertyValue("height"));


    var Line = function() {
        this.point1x = 0;
        this.point1y = 0;

        this.point2x = 0;
        this.point2y = 0;

        this.initialpoint1x = 0;
        this.initialpoint1y = 0;

        this.initialpoint2x = 0;
        this.initialpoint2y = 0;

        this.lineWidth = 0;

        this.color = 0;
    };

    Line.prototype.draw = function (context) {
        context.save();
        context.beginPath();

        context.moveTo(this.point1x, this.point1y);
        context.lineTo(this.point2x, this.point2y);

        context.strokeStyle = this.color;
        context.lineWidth = this.lineWidth;
        context.lineCap = "round";
        context.stroke();

        context.closePath();
        context.restore();
    };

    var context = canvas.getContext('2d');

    var lines = [];
    var mouse = {x: 0, y: 0};

    var mouseOver = false;
    var mouseMoved = false;
    var column = 4;

    for ( var i = 1; i < 10; i++) {
        lines[i] = [];
        var xa = 0;
        var ya = 0;

        for ( var j = 0; j < column; j++ ) {
            xa += 20;
            ya = (i * 20);

            var line = new Line();
            line.point1x = xa;
            line.point1y = ya;

            line.initialpoint1x = xa;
            line.initialpoint1y = ya;

            line.point2x = xa;
            line.point2y = ya;

            line.initialpoint2x = xa;
            line.initialpoint2y = ya;

            line.color = '#19FDB7';
            line.lineWidth = 10;
            lines[i][j] = line;
        }

        column++;
    }
    console.log(lines);

    gsap.ticker.add(draw);

    function draw() {
        context.clearRect(0, 0, canvas.width, canvas.height);

        if(mouseOver && mouseMoved){
            calculateLinePosition();
            mouseMoved = false;
        }
        var column = 4;
        for (var i = 1; i < 10; i++) {
            for (var j = 0; j < column; j++) {
                var line = lines[i][j];
                line.draw(context);
            }

            column++;
        }
    }

    function calculateLinePosition() {
        var column = 4;
        for (var i = 1; i < 10; i++) {
            for (var j = 0; j < column; j++) {
                var line = lines[i][j];
                var radius = 20;
                var dx = mouse.x - line.initialpoint1x;
                var dy = mouse.y - line.initialpoint1y;
                var dist = Math.sqrt(dx * dx + dy * dy) || 1;
                var angle = Math.atan2(dy, dx);

                line.point1x = line.initialpoint1x - Math.cos(angle) * radius;
                line.point1y = line.initialpoint1y - Math.sin(angle) * radius;

                line.point2x = line.initialpoint2x + Math.cos(angle) * radius;
                line.point2y = line.initialpoint2y + Math.sin(angle) * radius;
            }

            column++;
        }
    }

    $(canvas).mousemove(function (e) {
        var rect = canvas.getBoundingClientRect();
        mouse.x = e.clientX - rect.left;
        mouse.y  = e.clientY - rect.top;

        mouseMoved = true;
    });

    $(canvas).mouseenter(function () {
        mouseOver = true;
    });

    $(canvas).mouseleave(function () {
        mouseOver = false;

        var column = 4;
        for (var i = 1; i < 10; i++) {
            for (var j = 0; j < column; j++) {
                var line = lines[i][j];

                line.point1x = line.initialpoint1x;
                line.point1y = line.initialpoint1y;
                line.point2x = line.initialpoint2x;
                line.point2y = line.initialpoint2y;

            }

            column++;
        }
    });
}

Вот что у меня есть: https://codepen.io/geordi-feijens/pen/abOMKKY

1 Ответ

0 голосов
/ 01 апреля 2020

Ключ использует твины внутри функций рисования и отпускания мыши вместо того, чтобы просто устанавливать значение. Убедитесь, что вы установили overwrite на true или auto, потому что значение по умолчанию false не будет содержать ошибки.

Например, это то, как вы настроили бы его в функции рисования :

gsap.to(line, {
  duration: 0.2, 
  overwrite: 'auto',
  point1x: line.initialpoint1x - Math.cos(angle) * radius,
  point1y: line.initialpoint1y - Math.sin(angle) * radius,
  point2x: line.initialpoint2x + Math.cos(angle) * radius,
  point2y: line.initialpoint2y + Math.sin(angle) * radius
});

https://codepen.io/GreenSock/pen/oNXOvoy?editors=0010

Нет необходимости в jQuery:)

Дополнительное замечание о производительности: циклы довольно медленные. Обычно это не имеет большого значения, но когда вы перебираете множество элементов на каждом такте, это может повредить вашей производительности. Для получения дополнительной информации о том, как повысить производительность, ознакомьтесь с CodeReview.SE - некоторые действительно полезные люди ответят на вопросы там.

Кстати, если вы разместите подобные вопросы GSAP на на форумах GreenSock вы, вероятно, получите ответ быстрее и от большего количества людей.

Существует также множество существующих тем , подобных этому , которые очень похожи на то, что вы ' снова хочу.

...