在javascript中更新画布值

Updating canvas values in javascript

本文关键字:布值 更新 javascript      更新时间:2023-09-26

我用JavaScript使用Canvas编写了一个粒子动画。我要做的是改变画布绘制值,特别是radMax和radMin。我已经在这里编写了代码供您查看:https://jsfiddle.net/u3wwxg58/

现在发生的是,当我调用函数f()时,新的粒子被添加到正确的radMax和radMin值,而不是用新的radMax和radMin值更新当前的"绘图"。基本上,我要做的就是当函数f()被调用时,简单地使我的球体/动画变大。

我的drawParticle()代码
var cvs = document.createElement('canvas'),
context = cvs.getContext('2d');
document.body.appendChild(cvs);
var numDots = 500,
        n = numDots,
        currDot,
        maxRad = 100,
    minRad = 90,
    radDiff = maxRad-minRad,
    dots = [],
    PI = Math.PI,
    centerPt = {x:0, y:0};
    resizeHandler();
    window.onresize = resizeHandler;
    while(n--){
        currDot = {};
        currDot.radius = minRad+Math.random()*radDiff;
        currDot.radiusV = 10+Math.random()*50,
        currDot.radiusVS = (1-Math.random()*2)*0.005,
        currDot.radiusVP = Math.random()*PI,
        currDot.ang = (1-Math.random()*2)*PI;
        currDot.speed = 0;
        //currDot.speed = 1-Math.round(Math.random())*2;
        //currDot.speed = 1;
        currDot.intensityP = Math.random()*PI;
        currDot.intensityS = Math.random()*0.5;
        currDot.intensityO = 64+Math.round(Math.random()*64);
        currDot.intensityV = Math.min(Math.random()*255, currDot.intensityO);
        currDot.intensity = Math.round(Math.random()*255);
        currDot.fillColor = 'rgb('+currDot.intensity+','+currDot.intensity+','+currDot.intensity+')';
        dots.push(currDot);
    }
    function drawPoints(){
        var n = numDots;
        var _centerPt = centerPt,
            _context = context,
            dX = 0,
            dY = 0;
        _context.clearRect(0, 0, cvs.width, cvs.height);
        var radDiff,currDot;
        //draw dots
        while(n--) {
            currDot = dots[n];
            currDot.radiusVP += currDot.radiusVS;
            radDiff = currDot.radius+Math.sin(currDot.radiusVP)*currDot.radiusV;
            dX = _centerPt.x+Math.sin(currDot.ang)*radDiff;
            dY = _centerPt.y+Math.cos(currDot.ang)*radDiff;
            //currDot.ang += currDot.speed;
            currDot.ang += currDot.speed*radDiff/40000;
            currDot.intensityP += currDot.intensityS;
            currDot.intensity = Math.round(currDot.intensityO+Math.sin(currDot.intensityP)*currDot.intensityV);
            //console.log(currDot);
            _context.fillStyle= 'rgb('+currDot.intensity+','+currDot.intensity+','+currDot.intensity+')';
            _context.fillRect(dX, dY, 1, 1);
            console.log('draw dots');
        } //draw dot
        window.requestAnimationFrame(drawPoints);
    }
    function resizeHandler(){
        var box = cvs.getBoundingClientRect();
        var w = box.width;
        var h = box.height;
        cvs.width = w;
        cvs.height = h;
        centerPt.x = Math.round(w/2);
        centerPt.y = Math.round(h/2);
    }
 drawPoints();

和我更新值的代码:

var myi = 0, timex = 20;
         function f() {
         numDots =500+myi*10; maxRad = 300;minRad = 200 ; n=numDots;
         while(n--){
            currDot = {};
            currDot.radius = minRad+Math.random()*radDiff;
            currDot.radiusV = 10+Math.random()*500,
            currDot.radiusVS = (1-Math.random()*2)*0.005,
            currDot.radiusVP = Math.random()*PI,
            currDot.ang = (1-Math.random()*2)*PI;
            currDot.speed = (1-Math.random()*2);
            //currDot.speed = 1-Math.round(Math.random())*2;
            //currDot.speed = 1;
            currDot.intensityP = Math.random()*PI;
            currDot.intensityS = Math.random()*0.05;
            currDot.intensityO = 64+Math.round(Math.random()*64);
            currDot.intensityV = Math.min(Math.random()*255, currDot.intensityO);
            currDot.intensity = Math.round(Math.random()*255);
            currDot.fillColor = 'rgb('+currDot.intensity+','+currDot.intensity+','+currDot.intensity+')';
            dots.push(currDot);
            //setTimeout(function(){n++},1000);
        }
        myi++;
         if( myi < timex ){
        setTimeout( f, 500 );
    }}
    f();

图片显示我想做什么:https://postimg.org/image/9uhb3jda9/左图是调用函数f()之前,右图是调用函数f()时

函数f正在添加点,因为语句currDot = {};创建了一个新对象,而语句dots.push(currDot);将它添加到点数组中。

如果你把它改成:

currDot = dots[n];

并删除推,然后它将作用于现有的点。

然而,这只会在myi为零时起作用。

假设你打算随着时间的推移增加点的数量。也许你真正想要的只是完全取代现有的点?在这种情况下,只需在while循环之前粘贴dots = [];,其余部分保持原样。

再次迭代所有粒子只是为了改变效果的大小是没有意义的。在渲染粒子的时候进行。

从代码中添加变量radiusGrowAt,并在每次渲染时增加每个点半径。radiusGrowAt假设帧率不变,为60fps

   //just after document.body.appendChild(cvs) where you declare and define
    maxRad = 20,
    minRad = 10,
    radDiff = maxRad-minRad,
    //=================================================================
    radiusGrowAt = 20 / 60, //<<== add this  // grow 20 pixels every 60 frames (one second)
    //=================================================================
    dots = [],
    PI = Math.PI,
    centerPt = {x:0, y:0};       
    ... etc
然后

    //draw dots
    while(n--) {
        currDot = dots[n];
        //=================================================================
        currDot.radius += radiusGrowAt; //<<== add this line
        //=================================================================
        currDot.radiusVP += currDot.radiusVS;
        radDiff = currDot.radius+Math.sin(currDot.radiusVP)*currDot.radiusV;
        ... etc