Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CPU占用略大 & 抖动的问题 #2

Open
chenxuuu opened this issue Dec 19, 2015 · 36 comments
Open

CPU占用略大 & 抖动的问题 #2

chenxuuu opened this issue Dec 19, 2015 · 36 comments

Comments

@chenxuuu
Copy link

chenxuuu commented Dec 19, 2015

No description provided.

@hustcc
Copy link
Owner

hustcc commented Dec 21, 2015

可以按照情况配置count数量,当然越大就越耗费了。

@chenxuuu
Copy link
Author

小了效果不好。。。大了占用高= =

@hustcc
Copy link
Owner

hustcc commented Dec 21, 2015

这个确实是问题,不过在这种canvas动画,都会有这样的问题。你那边有比较好的解决方案吗?

@chenxuuu
Copy link
Author

@hustcc
Copy link
Owner

hustcc commented Dec 21, 2015

这个文章之前看过翻译版本,按照这个进行优化,在我的电脑上,可以把cpu从20降到15,但是动画的效果会差很多。

@hustcc
Copy link
Owner

hustcc commented Dec 21, 2015

可以看看其他相关canvas的优化,或着从代码中寻找优化,减少计算量的方法,欢迎讨论和pr~

@git-lt
Copy link

git-lt commented Jul 20, 2016

当鼠标点不动的时候,线连的多的时候,抖动太明显了,是可有方法可以减少抖动

@hustcc
Copy link
Owner

hustcc commented Dec 12, 2016

@git-lt 之前没有 watch 这个项目,一直没有看到这个回复,我抽时间看看这个问题。

@beiping96
Copy link

@hustcc 同问抖动的问题。。

@hustcc hustcc changed the title CPU占用略大。。。 CPU占用略大 & 抖动的问题 Dec 29, 2016
@yumy-wang
Copy link

抖动问题很尴尬23333

@hustcc
Copy link
Owner

hustcc commented Jun 25, 2018

抖动问题其实还好,可以当做 feature,如果有大牛能解决的,欢迎 pr。

@chenxuuu
Copy link
Author

当做feature hhhhh,你是苹果吗

@hustcc
Copy link
Owner

hustcc commented Jun 25, 2018

是的,苹果!

@stefenson
Copy link

抖动问题解决终极办法:去掉窗体的鼠标监听事件www

@stefenson
Copy link

stefenson commented Jun 25, 2018

哦对,还有个方法是把点聚集收缩的部分逻辑去掉,nest.min.js里面对应着一段:

i.x-=0.01*B,i.y-=0.01*z

0.01应该是被我修改过了,把它改成0,去掉粘附加速就不抖动了233。

@hustcc
Copy link
Owner

hustcc commented Jun 25, 2018

加速效果还是需要的!可以做成如果达到稳定的距离,就不计算了,这样也可以提高计算的性能!

@chenxuuu
Copy link
Author

喂喂这是两年前的issue,我的Outlook一直在弹窗😂

@hustcc
Copy link
Owner

hustcc commented Jun 25, 2018

@chenxuuu 两年半之后,重构一把,关闭十几个 issue,唯独这个还是关不掉,哈哈!

@yumy-wang
Copy link

被我唤醒了2333333

@stefenson
Copy link

stefenson commented Jun 25, 2018

我貌似搞定了……刚好今天上午公司事少就自己想了想这个问题。
基本思路:记录一个加速度变量,加速度的方向和取值根据到鼠标点的距离计算,然后点位置重绘方法放到后面,重新计算位置时加上加速度就好了。

主要是这几处:

t.forEach(function(i){
    for(v=0;v<w.length;v++){
        x=w[v];
        savex=null;
        if(i!==x&&null!==x.x&&null!==x.y){
            B=i.x-x.x,
            z=i.y-x.y,
            prex=i.x+i.xa-x.x,
            prey=i.y+i.ya-x.y;
            y=B*B+z*z;
            if (x===f) {
                if(y<x.max) {
                    i.xd=(Math.abs(prex) > Math.abs(B) ? -1 : 1)*y/x.max*2*i.xa,
                    i.yd=(Math.abs(prey) > Math.abs(z) ? -1 : 1)*y/x.max*2*i.ya;
                } else {
                    i.xd=0;i.yd=0;
                }
            }
            if(y<x.max){
                A=(x.max-y)/x.max,e.beginPath(),e.lineWidth=A/2,e.strokeStyle="rgba("+s.c+","+(A+0.2)+")",e.moveTo(i.x,i.y),e.lineTo(x.x,x.y),e.stroke();
            }
        }
    }
    i.x+=i.xa+i.xd,
    i.y+=i.ya+i.yd,
    i.xa*=i.x>r||i.x<0?-1:1,
    i.ya*=i.y>n||i.y<0?-1:1;
    e.fillRect(i.x-0.5,i.y-0.5,1,1);
    w.splice(w.indexOf(i),1)
}),

点的结构体里面添加xd,yd定义:

t.push({x:h,y:g,xa:q,ya:d,xd:0,yd:0,max:6000})

不过我的博客是拿min版本用的,非min版本的话应该位置差不多,找一下就好啦 ^_^)/

具体效果可以查看stefenson.github.io

人家才不会说这是顺便给自己blog打广告呢

@hustcc
Copy link
Owner

hustcc commented Jun 25, 2018

@stefenson 大牛 Pr 上来吧!代码尽量优美一点咯~

还可以在 readme 中把你的博客加进来!

@chenxuuu
Copy link
Author

@stefenson 都是大佬,我只会反馈问题不会修

@flyerH
Copy link
Contributor

flyerH commented Oct 15, 2018

抖动的问题我最近试着解决了一下,目前达到的效果是到达鼠标半径的点,停止运动,也就不再抖动。
但考虑到还有一种效果,就是到达鼠标半径的点,围绕鼠标做圆周运动,而不是内外的抖动,但也不停止运动,不知道最终要做成哪种效果?

@ShellyCoder
Copy link

我貌似搞定了……刚好今天上午公司事少就自己想了想这个问题。
基本思路:记录一个加速度变量,加速度的方向和取值根据到鼠标点的距离计算,然后点位置重绘方法放到后面,重新计算位置时加上加速度就好了。

主要是这几处:

t.forEach(function(i){
    for(v=0;v<w.length;v++){
        x=w[v];
        savex=null;
        if(i!==x&&null!==x.x&&null!==x.y){
            B=i.x-x.x,
            z=i.y-x.y,
            prex=i.x+i.xa-x.x,
            prey=i.y+i.ya-x.y;
            y=B*B+z*z;
            if (x===f) {
                if(y<x.max) {
                    i.xd=(Math.abs(prex) > Math.abs(B) ? -1 : 1)*y/x.max*2*i.xa,
                    i.yd=(Math.abs(prey) > Math.abs(z) ? -1 : 1)*y/x.max*2*i.ya;
                } else {
                    i.xd=0;i.yd=0;
                }
            }
            if(y<x.max){
                A=(x.max-y)/x.max,e.beginPath(),e.lineWidth=A/2,e.strokeStyle="rgba("+s.c+","+(A+0.2)+")",e.moveTo(i.x,i.y),e.lineTo(x.x,x.y),e.stroke();
            }
        }
    }
    i.x+=i.xa+i.xd,
    i.y+=i.ya+i.yd,
    i.xa*=i.x>r||i.x<0?-1:1,
    i.ya*=i.y>n||i.y<0?-1:1;
    e.fillRect(i.x-0.5,i.y-0.5,1,1);
    w.splice(w.indexOf(i),1)
}),

点的结构体里面添加xd,yd定义:

t.push({x:h,y:g,xa:q,ya:d,xd:0,yd:0,max:6000})

不过我的博客是拿min版本用的,非min版本的话应该位置差不多,找一下就好啦 ^_^)/

具体效果可以查看stefenson.github.io

人家才不会说这是顺便给自己blog打广告呢

请教一下,关于动画速度怎么能修改呢谢谢大佬

@flyerH
Copy link
Contributor

flyerH commented Apr 18, 2019

我貌似搞定了……刚好今天上午公司事少就自己想了想这个问题。
基本思路:记录一个加速度变量,加速度的方向和取值根据到鼠标点的距离计算,然后点位置重绘方法放到后面,重新计算位置时加上加速度就好了。
主要是这几处:

t.forEach(function(i){
    for(v=0;v<w.length;v++){
        x=w[v];
        savex=null;
        if(i!==x&&null!==x.x&&null!==x.y){
            B=i.x-x.x,
            z=i.y-x.y,
            prex=i.x+i.xa-x.x,
            prey=i.y+i.ya-x.y;
            y=B*B+z*z;
            if (x===f) {
                if(y<x.max) {
                    i.xd=(Math.abs(prex) > Math.abs(B) ? -1 : 1)*y/x.max*2*i.xa,
                    i.yd=(Math.abs(prey) > Math.abs(z) ? -1 : 1)*y/x.max*2*i.ya;
                } else {
                    i.xd=0;i.yd=0;
                }
            }
            if(y<x.max){
                A=(x.max-y)/x.max,e.beginPath(),e.lineWidth=A/2,e.strokeStyle="rgba("+s.c+","+(A+0.2)+")",e.moveTo(i.x,i.y),e.lineTo(x.x,x.y),e.stroke();
            }
        }
    }
    i.x+=i.xa+i.xd,
    i.y+=i.ya+i.yd,
    i.xa*=i.x>r||i.x<0?-1:1,
    i.ya*=i.y>n||i.y<0?-1:1;
    e.fillRect(i.x-0.5,i.y-0.5,1,1);
    w.splice(w.indexOf(i),1)
}),

点的结构体里面添加xd,yd定义:

t.push({x:h,y:g,xa:q,ya:d,xd:0,yd:0,max:6000})

不过我的博客是拿min版本用的,非min版本的话应该位置差不多,找一下就好啦 ^_^)/
具体效果可以查看stefenson.github.io
人家才不会说这是顺便给自己blog打广告呢

请教一下,关于动画速度怎么能修改呢谢谢大佬

我上条回复就是这么做的,做完后感觉静止还不如抖动的效果好,就想着让点做圆周运动,但要计算圆周加速度方向,就一直懒得做,你有兴趣可以这么改改
动画速度应该是修改初始时的加速度

@Justsoos
Copy link

Justsoos commented Feb 6, 2020

这个 js 在很多个人网站上如同挖矿脚本一样占用cpu/gpu,烧电脑浏览器,费电!
可以用 ublock/adblock plus等禁止加载,如下写规则:

*/canvas-nest.min.js$script
*/canvas-nest.js$script

@warmonipa
Copy link

warmonipa commented Sep 29, 2020

这个 js 在很多个人网站上如同挖矿脚本一样占用cpu/gpu,烧电脑浏览器,费电!
可以用 ublock/adblock plus等禁止加载,如下写规则:

*/canvas-nest.min.js$script
*/canvas-nest.js$script

mac电脑只能这么干,否者容易炸了

@hustcc
Copy link
Owner

hustcc commented Sep 29, 2020

一个特效,变成了网络噩梦(´・_・`)

@phantom0174
Copy link

phantom0174 commented Feb 20, 2023

近期写了个类似的替代性专案,从基本上舍弃了爆搜,改用chunks与draw buffer解决掉大部分的效能瓶颈。
目前还不是很完整,但核心代码写好了。
https://github.com/phantom0174/canvas-nice.js

@wufujie2000
Copy link

wufujie2000 commented Feb 20, 2023 via email

@Chant00
Copy link

Chant00 commented Feb 20, 2023 via email

@chenxuuu
Copy link
Author

chenxuuu commented Feb 21, 2023 via email

@phantom0174
Copy link

遍历算法应该不是重点(10^4个点以内应该都不会差太多);关于瓶颈的绘图过程,作者有打算实作类似缓冲区的东西解决吗?

@cniter
Copy link

cniter commented May 12, 2024

抖动的问题我最近试着解决了一下,目前达到的效果是到达鼠标半径的点,停止运动,也就不再抖动。 但考虑到还有一种效果,就是到达鼠标半径的点,围绕鼠标做圆周运动,而不是内外的抖动,但也不停止运动,不知道最终要做成哪种效果?

最近在用这个库的时候,想到了吸附鼠标的点能不能均匀分布在一个圆上,也想到了能不能让这个圆自动旋转,不过个人认为抖动是 feature,还特意加上了抖动 :D,改写了 drawCanvas 函数(无分号结尾代码是改写的部分):

this.stableAngleTolerance = Math.PI/180 * 2
this.roundAngle = Math.PI/180 / 3

drawCanvas() {
        const context = this.context;
        const width = this.canvas.width;
        const height = this.canvas.height;
        const current = this.current;
        const points = this.points;
        const all = this.all;

        context.clearRect(0, 0, width, height);
        // 随机的线条和当前位置联合数组
        let e, i, d, x_dist, y_dist, dist; // 临时节点
        let roundCurrPoints = []
        // 遍历处理每一个点
        points.forEach((r, idx) => {
            r.x += r.xa / 3;
            r.y += r.ya / 3; // 移动
            r.xa *= r.x > width || r.x < 0 ? -1 : 1;
            r.ya *= r.y > height || r.y < 0 ? -1 : 1; // 碰到边界,反向反弹
            context.fillStyle = `rgba(${this.c.pointColor})`;
            context.fillRect(r.x - 1.5, r.y - 1.5, 3, 3); // 绘制一个宽高为1的点

            if (r.xa == 0 && r.ya == 0) {
                r.xa = 2 * Math.random() - 1
                r.ya = 2 * Math.random() - 1
            }

            if (r.x > width+100 || r.x < 0-100 || r.y > height+100 || r.y < 0-100) {
                if (current.x !== null && current.y !== null) {
                    r.xa = current.x - r.x
                    r.ya = current.y - r.y
                }
            }
            
            // 从下一个点开始
            for (i = idx + 1; i < all.length; i++) {
                e = all[i];
                // 当前点存在
                if (null !== e.x && null !== e.y) {
                    x_dist = r.x - e.x; // x轴距离 l
                    y_dist = r.y - e.y; // y轴距离 n
                    dist = x_dist * x_dist + y_dist * y_dist; // 总距离, m

                    dist < e.max && (e === current && dist >= e.max / 2 && (r.x -= 0.03 * x_dist, r.y -= 0.03 * y_dist), // 靠近的时候加速
                        d = (e.max - dist) / e.max,
                        context.beginPath(),
                        context.lineWidth = d * 1.5,
                        context.strokeStyle = `rgba(${this.c.color},${d + 0.2})`,
                        context.moveTo(r.x, r.y),
                        context.lineTo(e.x, e.y),
                        context.stroke());
                    
                    if (e === current && e.max*0.5 <= dist && dist <= e.max*0.53) {
                        // 获取环绕点
                        let rad = Math.atan2(y_dist, x_dist)
                        roundCurrPoints.push([r, rad])
                    }
                }
            }
        });

        const radDelta = 2 * Math.PI / Math.max(roundCurrPoints.length, 1)
        const radTolerance = this.stableAngleTolerance*(1+(roundCurrPoints.length-1)/(this.c.count-1)*0.36)
        const radRange = [radDelta-radTolerance, radDelta+radTolerance]
        // 所有环绕点的角度差值稳定在 radRange 之内,则开始旋转
        if (roundCurrPoints.map((val, idx) => idx > 0 ? val[1] - roundCurrPoints[idx-1][1] : val[1]).slice(1).every(val => [val, val+2*Math.PI].some(v => radRange[0]<=v && v<=radRange[1]))) {
            roundCurrPoints.forEach((item, idx) => {
                // 旋转动画
                let [r, rad] = item
                rad += this.roundAngle // 旋转动画,每一帧前进 Math.PI/180 / 3
                let radius = Math.sqrt(current.max) * (0.02 * Math.random() + 0.7072) // 沿半径方向随机抖动 [sqrt(0.5), sqrt(0.53)]
                r.x = current.x + radius * Math.cos(rad) // 旋转动画,下一帧圆上点坐标x
                r.y = current.y + radius * Math.sin(rad) // 旋转动画,下一帧圆上点坐标y
                r.xa = 0 // 去除直线运动
                r.ya = 0 // 去除直线运动
            })
        } else {
            roundCurrPoints.forEach((item, idx) => {
                // 均匀分布动画
                let [r, rad] = item
                rad = Math.min(Math.max(rad, -Math.PI), Math.PI)
                if (rad >= Math.PI) {
                    rad = -Math.PI
                }
                rad += (-Math.PI + radDelta*idx - rad) * 0.01 // 均匀分布移动动画,以 0.01 的比例系数慢慢逼近均匀分布所在的理想角度 (-Math.PI + radDelta*idx)
                rad += (2*Math.random()-1) * this.roundAngle // 沿角度随机抖动
                rad = Math.min(Math.max(rad, -Math.PI), Math.PI)
                let radius = Math.sqrt(current.max) * (0.02 * Math.random() + 0.7072) // 沿半径方向随机抖动 [sqrt(0.5), sqrt(0.53)]
                r.x = current.x + radius * Math.cos(rad) // 旋转动画,下一帧圆上点坐标x
                r.y = current.y + radius * Math.sin(rad) // 旋转动画,下一帧圆上点坐标y
                r.xa = 0 // 去除直线运动
                r.ya = 0 // 去除直线运动
            })
        }
        
        this.requestFrame(this.drawCanvas);
    }

具体效果可看:https://cniter.github.io/

@wufujie2000
Copy link

wufujie2000 commented May 12, 2024 via email

@Chant00
Copy link

Chant00 commented May 12, 2024 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests