Javascript 画布设置指向鼠标上原始位置的点的动画

Javascript 画布设置指向鼠标上原始位置的点的动画,javascript,jquery,gsap,Javascript,Jquery,Gsap,我创建了一个画布动画,其中线在画布上悬停时会扭曲。一个点拉向鼠标,另一个点推开 动画有几个方面我正在努力,我想动画的线被拉向鼠标,现在它只是非常即时,反之亦然,鼠标离开画布,他们只是收到他们的初始协调,这使它非常即时。我使用gsap.to尝试了这个方法,但我似乎不知道如何使用它在一条直线上设置两个独立的点 我还想补充一点,鼠标离某一行越远,我希望该行越短。现在,鼠标悬停在画布上时,所有线条的长度都相等 $(document).ready(function () { initContain

我创建了一个画布动画,其中线在画布上悬停时会扭曲。一个点拉向鼠标,另一个点推开

动画有几个方面我正在努力,我想动画的线被拉向鼠标,现在它只是非常即时,反之亦然,鼠标离开画布,他们只是收到他们的初始协调,这使它非常即时。我使用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++;
        }
    });
}
$(文档).ready(函数(){
initContainerCanvas();
});
$(窗口)。调整大小(函数(){
initContainerCanvas();
});
函数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”);
变量行=函数(){
该点1X=0;
该点1y=0;
该点2x=0;
该点2y=0;
此参数为0.initialpoint1x=0;
此参数为0.initialpoint1y=0;
此参数为0.initialpoint2x=0;
此参数为0.initialpoint2y=0;
此参数为0.lineWidth=0;
这个颜色=0;
};
Line.prototype.draw=函数(上下文){
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”;
stroke();
closePath();
restore();
};
var context=canvas.getContext('2d');
var行=[];
变量鼠标={x:0,y:0};
var mouseOver=false;
var mouseMoved=false;
var列=4;
对于(变量i=1;i<10;i++){
行[i]=[];
var-xa=0;
var-ya=0;
对于(var j=0;j

到目前为止,我所掌握的是:

关键是在draw和mouseleave函数中使用tweens,而不仅仅是设置值。确保将
overwrite
设置为
true
auto
,因为
false
的默认值不会出现错误

例如,这是如何在draw函数中进行设置的:

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
});

不需要jQuery:)

关于性能的旁注:循环非常慢。这通常没什么大不了的,但是当你在很多元素中循环时,每一个滴答声都会开始影响你的表现。有关如何提高绩效的更多反馈,请查看-一些真正有帮助的人在那里回答问题

顺便说一句,如果你在网站上发布这样的GSAP问题,你可能会得到更快的回复,也会得到更多人的回复


还有一组现有的线程,它们的功能与您想要的非常相似。

关键是在draw和mouseleave函数中使用tweens,而不仅仅是设置值。确保将
overwrite
设置为
true