Как масштабировать частицы из центра, используя HTML-холст - PullRequest
0 голосов
/ 21 декабря 2018

Добрый день Переполнение стека,

В настоящее время столкнулся с проблемой невозможности найти центр частиц, когда я масштабируюсь, я не уверен, где находится точка ctx.translate.

В функции «pixelOverlay.prototype.draw» это место, где установлена ​​точка регистрации ctx.translate, но, когда я анимирую, все частицы приходят из далека вправо, когда я надеюсь масштабировать от центра и по-прежнему анимировать x / yзначение.

Вот мой код для справки,

        var creative          = {};
        var fpsLabel          = {};

        window.addEventListener('load', function () {
          if(document.readyState === "complete") {
            init();
          }
        }, false);

      function init() {
          console.log('init');

          creative.canvas                 = document.getElementById('canvas_stage');
          creative.ctx                    = creative.canvas.getContext('2d');
          creative.ctx.canvas.width       = 728;
          creative.ctx.canvas.height      = 90;      
          creative.width                  = creative.ctx.canvas.width;
          creative.height                 = creative.ctx.canvas.height;

          fpsLabel.meter                  = new FPSMeter(
            document.getElementById('fpscounter'),
            {decimals:  1, theme: 'colorful', heat:  10, graph: 1, }
          );
        
          creative.particles              = [];
          creative.pixelSize              = 21; //all cells are sized from this variable 

          createRectangleCells();
      }

    function createRectangleCells () {
      var cellCounter = -1;

      for (var i = 0; i < creative.width; i+=creative.pixelSize) {
        for (var j = 0; j < creative.height; j+=creative.pixelSize) {

              cellCounter++; // cell index

          var color = random_rgba(random(300, 0), random(9, 226), random(9, 188), 1);

          var particle = new pixelOverlay(
            i,                                      //x
            j,                                      //y
            creative.pixelSize, creative.pixelSize, // w,h
            color,
            cellCounter,                            //index
            0,                                      //alpha
            1                                       //scale
          );           

          creative.particles.push(particle);
        }
      }
  
      addListeners(); //init loop
      rectangleCellsAnimIn();
    }
    
    function rectangleCellsAnimIn () {

      for (var i = 0; i < creative.particles.length; i++) {
        creative.particles[i].fadeIn(i);
      } 
    }

    pixelOverlay.prototype.fadeIn = function() {

          TweenMax.fromTo([this], Random(10), {
              x:this.x+random(50,-50),
              y:this.y+random(0, 1080),
              scaleX:10,
              scaleY:10
          },{
              x:this.lastX,
              y:this.lastY,
              scaleX:1,
              scaleY:1
          });
    }
  
    function addListeners () {
        TweenMax.ticker.useRAF(false);
        TweenMax.ticker.addEventListener("tick", handleTick);
        TweenMax.ticker.fps(60);
    }

    // -- loop handler -- //
    function handleTick() {
      fpsLabel.meter.tickStart();

      draw();

      fpsLabel.meter.tick();      
    }

    function draw () {
      creative.ctx.clearRect(0, 0, creative.canvas.width, creative.canvas.height);

      for (var i = 0, l = creative.particles.length; i < l; i++) {
          creative.particles[i].draw();
      }     
    }
  
    pixelOverlay.prototype.draw = function() {

            creative.ctx.save();
            creative.ctx.beginPath();
            // creative.ctx.translate(this.width/2, this.height/2);
            creative.ctx.scale(this.scaleX, this.scaleY);
            creative.ctx.rect(this.x, this.y, this.width, this.height);
            creative.ctx.fillStyle        = this.fill;
            creative.ctx.fill();             
            creative.ctx.closePath();
            creative.ctx.restore();            
    };

    // -- pixelOverlay Cell Constructor -- //
    function pixelOverlay(x, y, w, h, fill, index, alpha) {
        this.x                      = x;
        this.y                      = y;
        this.lastX                  = this.x;
        this.lastY                  = this.y;
        this.width                  = w;
        this.height                 = h;
        this.fadeTracker            = alpha;
        this.fill                   = fill;
        this.lastFill               = this.fill;
        this.index                  = index;
        this.hasAnimated            = false;
        this.scaleX                 = 1;
        this.scaleY                 = 1;
    }


    //  --   snippets -- //

    function random_rgba(r, g, b, a) {
        return 'rgba(' + r + ',' + g + ',' + b + ','+ a +')';
    }

    function random (min, max) {
        return Math.floor(Math.random() * (max - min + 1)) + min;
    }

    function Random (max) {
        return Math.random()*max;
    }
#container{
	position: absolute;
	cursor: pointer;
	left: 0px;
	top: 0px;
	width: 728px;
	height: 90px;
	background-color: white;
	/*background-color: blue;*/
	/*overflow: hidden;*/
}


#canvas_stage{
	position: absolute;
	overflow: hidden; 
	cursor: pointer;
}

#border{
	position: absolute;
	width: 100%;
	height: 100%;
	pointer-events: none;
	border: solid 1px black;
	-webkit-box-sizing: border-box; /* Safari/Chrome, other WebKit */
	-moz-box-sizing: border-box;    /* Firefox, other Gecko */
	box-sizing: border-box;         /* Opera/IE 8+ */
}

#fpscounter {
	left: 728px;
  position: relative;
}
	<!-- Greensock -->
	<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/2.0.2/TweenMax.min.js"></script>
	<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/2.0.2/plugins/RoundPropsPlugin.min.js"></script>
	<!-- Greensock -->

	<!-- FPS JS -->
	<script src="https://cdnjs.cloudflare.com/ajax/libs/fpsmeter/0.3.1/fpsmeter.min.js"></script>
	<!-- FPS JS -->

<div id="container">
  <canvas id="canvas_stage"></canvas>
  <div id="border"></div>		
  <div id="fpscounter"></div>  
</div>
...