2016-10-29 4 views
-1

캔버스를 사용하여 자바 스크립트로 작성된 입자 애니메이션이 있습니다. 내가하려는 것은 캔버스 드로잉 값, 특히 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(); 

과 값을 업데이트하는 내 코드에 대한 나의 코드 : https://postimg.org/image/9uhb3jda9/ 그래서 왼쪽 하나는 함수를 호출하기 전에입니다 : 내가하고 싶은 것을 보여

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

사진을 f(), 오른쪽 하나는 f()가 호출 될 때입니다.

+0

에서 가정합니다. 따라 가기가 어렵습니다. 작동하지 않는 것은 무엇입니까? – Soviut

+0

죄송합니다, 설명을 업데이트하고 그림을 추가했습니다. Thanks @Soviut – OhNoThatsBad

+0

그냥 부작용이 있습니다 - 난수 생성시 Math.round 대신 Math.floor를 사용하는 것이 일반적입니다. 왜냐하면 후자가 비 균일 분포를 제공하기 때문입니다 (http://stackoverflow.com/a/). 7377769/6854845). – Jon

답변

0

함수 f는 도트를 추가합니다. currDot = {}; 문은 새 개체를 만들고, dots.push(currDot); 문은 점의 배열에 추가합니다.

당신은 그것을 변경하는 경우 :

currDot = dots[n]; 

하고 기존의 점에 역할을 할 다음 푸시를 제거합니다.

그러나 myi이 0 인 경우에만 작동합니다.

아마도 시간이 지남에 따라 점의 수를 늘리려는 것입니다. 아마도 당신이 정말로 원하는 것은 기존 점들을 완전히 대체하는 것일뿐입니다. 어떤 경우에는 while 루프 앞에 dots = [];을 붙이고 나머지는 그대로 두십시오.

0

효과의 크기를 변경하기 위해 모든 입자를 다시 반복하지 않습니다. 입자를 렌더링하는 동안 그것을하십시오.

코드에서 radiusGrowAt 변수를 추가하고 렌더링 할 때마다 점 반지름을 늘리십시오. radiusGrowAt 프레임 속도는 질문을 단순화하십시오 일정하고 그리고 초당 60 프레임

//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 
관련 문제