Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.2k views
in Technique[技术] by (71.8m points)

javascript - 来自base64编码的png的纯Javascript粒子排斥器(Pure Javascript particle repeller from base64 encoded png)

I have some js code that i copied from a youtube tutorial and adapted for my own project to fill the header, the code works as intended and it works when the viewport is smaller than around 1200px, however when i put firefox into full screen the animation does not play & the image is being stretched, not retaining its aspect ratio.

(我有一些js代码,这些代码是我从youtube教程中复制的,并适合我自己的项目以填充标题,该代码可以按预期工作,并且当视口小于1200px时可以正常工作,但是当我将Firefox放到全屏动画中时无法播放且图像正在拉伸,因此不保留其纵横比。)

I do have a 10/15 year old gpu so i'm guessing thats half my issue.

(我确实有10/15岁的GPU,所以我猜那是我问题的一半。)

The script uses a png image file of 100x100 pixels, which it then converts into particle color values.

(该脚本使用100x100像素的png图像文件,然后将其转换为粒子颜色值。)

Can this be optimized or made to run better.

(是否可以对其进行优化或使其运行得更好。)

it seems that the wider the viewport the longer the animation takes to kick in, until it finally stops & doesn't work.

(视口越宽,动画开始播放所需的时间就越长,直到最终停止并且不起作用为止。)

full screen= [2550x1440]...

(全屏= [2550x1440] ...)

The original tutorial is here: Pure Javascript Particle Animations & to convert an image to base64 encoding is here: Image to base64 .

(原始教程在这里: Pure Javascript Particle Animations和将图像转换为base64编码的位置在这里: Image to base64 。)

HTML:

(HTML:)

        <html>
          <body>
            <canvas id="CanV"></canvas>
          </body>
        </html>

CSS:

(CSS:)

    #Canv{
        position:absolute;
        top:-1px;left:-2px;
        z-index:67;
        width:100vw !important;
        max-height: 264px !important;
        min-height: 245px !important;
        filter:blur(2.27px);
        }

Javascript:

(Javascript:)

        window.addEventListener("DOMContentLoaded",(e)=>{
          const canv = document.getElementById('Canv');
          const ctx = canv.getContext('2d');
          canv.width = window.innerWidth;
          canv.height = window.innerHeight/ 3.85;

        let particleArray = [];
        let mouse = {
            x: null,
            y: null,
            radius: 74
        }

        window.addEventListener('mousemove',(e)=>{
            mouse.x = event.x + canv.clientLeft/2;
            mouse.y = event.y + canv.clientTop/1.2;
        });

        function drawImage(){
            let imageWidth = png.width;         //These to values crop if / sum no.
            let imageHeight = png.height;
            const data = ctx.getImageData(0, 0, imageWidth, imageHeight); //Gets img data for particles
            ctx.clearRect(0,0, canv.width, canv.height); // Clears the original img as its now being stored in the variable data.

            class Particle {
                  constructor(x, y, color, size){
                      this.x = x + canv.width/2 - png.width * 174,      //Chngd Ok:74
                      this.y = y + canv.height/2 - png.height * 32,         //Ch<2  Ok:16
                      this.color = color,
                      this.size = 2.28, // Particle Size > Changed this value. from 2 i think!.
                      this.baseX = x + canv.width/1.8 - png.width * 3.1,    //Chngd ok:5.1
                      this.baseY = y + canv.height/1.2 - png.height * 2.8,
                      this.density = (Math.random() * 14) + 2;
                      }
            draw() {
               ctx.beginPath();  // this creates the sort of force field around the mouse pointer.
               ctx.arc(this.x, this.y, this.size, 0, Math.PI * 2);
               ctx.closePath();
               ctx.fill();
               }
            update() {
               ctx.fillStyle = this.color;

            // Collision detection
                let dx = mouse.x - this.x;
                let dy = mouse.y - this.y;
                let distance = Math.sqrt(dx * dx + dy * dy);
                let forceDirectionX = dx / distance;
                let forceDirectionY = dy / distance;
            // Max distance, past that the force will be 0
                const maxDistance = 144;
                   let force = (maxDistance - distance) / maxDistance;
                      if (force < 0) force = 0;
                   let directionX = (forceDirectionX * force * this.density * 0.6);
                   let directionY = (forceDirectionY * force * this.density * 8.7); //Ch.this

               if (distance < mouse.radius + this.size) {
                    this.x -= directionX;
                    this.y -= directionY;
               } else {
                   if (this.x !== this.baseX){
                       let dx = this.x - this.baseX;
                       this.x -= dx/54;  // Speed Particles return to ori
                 } if (this.y !== this.baseY){
                       let dy = this.y - this.baseY;
                       this.y -= dy/17;  // Speed Particles return to ori
                   }
             }
             this.draw();
         }
     }
    function init(){
        particleArray = [];
        for(let y = 0, y2 = data.height; y<y2; y++){
            for(let x =0, x2 = data.width; x<x2; x++){
                if(data.data[(y * 4 * data.width) + (x*4) + 3] > 128){
                    let positionX = x + 25;
                    let positionY = y + 45; // Co-ords on Canv
                    let color = "rgb(" + data.data[(y * 4 * data.width) + (x * 4)] + "," +
                                         data.data[(y * 4 * data.width) + (x * 4) + 1] + "," +
                                         data.data[(y * 4 * data.width) + (x * 4) + 2] + ")";
                                    particleArray.push(new Particle(positionX * 2, positionY * 2, color));
                }           /* These number effect png size but its to high */
            }
        }
    }
    function animate(){
        requestAnimationFrame(animate);
        ctx.fillStyle = 'rgba(0,0,0,.07)';
        ctx.fillRect(0,0, innerWidth, innerHeight);

        for(let i =0; i < particleArray.length; i++){
            particleArray[i].update();
        }
    }
    init();
    animate();
    }

    const png = new Image();

    png.src = "RemovedBase64StringToBig";

    window.addEventListener('load',(e)=>{
        console.log('page has loaded');
        ctx.drawImage(png, 0, 0);
        drawImage();
    })

    });

have managed to shorten it by about 100 characters by shortening all the variable names > PartArr, ImgWidth, DirX, DirY etc, but apart from minifying it is there any other ways to optimize this?

(通过缩短所有变量名称> PartArr,ImgWidth,DirX,DirY等,已经设法将其缩短了约100个字符,但是除了最小化它之外,还有其他方法可以对此进行优化吗?)

and fix the full screen issue?

(并解决全屏问题?)

I tried to add it to a JSfiddle, So I could link to it here, but I don't think this is allowing the base64 string, its not loading anything anyway.

(我试图将其添加到JSfiddle中,因此可以在此处链接到它,但是我认为这不允许base64字符串,无论如何它都不会加载任何东西。)

The canvas loads, with the bg just no image or animation.

(画布加载,而bg仅没有图像或动画。)

I've found out what part of the problem is with full screen, the cursor position is actually about 300px to the right of where the actual cursor is, but I still have no idea how to fix this or fix the major lagging performance issues.

(我发现全屏问题的一部分,光标位置实际上是实际光标所在位置的右侧约300px,但是我仍然不知道如何解决此问题或解决主要的性能滞后问题。)

Guessing its alot to compute even just with 100x100.

(猜测很多即使使用100x100进行计算。)

I'm adding these links only for future reference, when I come back to this later on:

(我添加这些链接仅是为了将来参考,稍后再回到此:)

MDN Canvas Optimizations

(MDN画布优化)


Html5Rocks Canvas Performance

(HTML5Rocks画布性能)


Stack Question.

(堆栈问题。)

Canv ~ Opti

(Canv?Opti)

  ask by Ryan Stone translate from so

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)
等待大神答复

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

2.1m questions

2.1m answers

60 comments

57.0k users

...