【问题标题】:Pixi.js images jump when draggedPixi.js 图像在拖动时会跳转
【发布时间】:2017-10-26 13:08:35
【问题描述】:

我在使用 pixi.js 时遇到问题 我正在创建一个类似 http://www.wolverineunleashed.com/#muscles 的页面图像在屏幕上抖动,我在想这可能是渲染问题?但目前我正在拔头发,所以任何帮助都会非常感激。我的代码是:

var w = window.innerWidth;
var h = window.innerHeight;
var images = [];
var stage = new PIXI.Container();
var renderer = new PIXI.autoDetectRenderer(w, h,{transparent:true},true);
document.body.appendChild(renderer.view);

var background = new PIXI.Container();
background.parent = background;
background.interactive = true;

background.on('mousedown', onDragStart)
        .on('touchstart', onDragStart)
        .on('mouseup', onDragEnd)
        .on('mouseupoutside', onDragEnd)
        .on('touchend', onDragEnd)
        .on('touchendoutside', onDragEnd)
        .on('mousemove', onDragMove)
        .on('touchmove', onDragMove);

loadImages();

requestAnimationFrame(animate);

function animate() {
    requestAnimationFrame(animate);
    renderer.render(background);
}

function onDragStart(event)
{
    this.data = event.data;
    this.mousePressPoint = [];
    this.dragging = true;
    this.mousePressPoint[0] = this.data.getLocalPosition(this.parent).x - this.position.x;
    this.mousePressPoint[1] = this.data.getLocalPosition(this.parent).y - this.position.y;
}

function onDragEnd()
{
    this.dragging = false;
    this.data = null;
}

function onDragMove()
{
    if (this.dragging)
    {
        var position = this.data.getLocalPosition(this.parent);
        this.position.x = parseInt(position.x - this.mousePressPoint[0]);
        this.position.y = parseInt(position.y - this.mousePressPoint[1]);
    }
}

【问题讨论】:

    标签: pixi.js


    【解决方案1】:

    这是一个非常古老的问题,自 OP 以来 PIXI 库已经发生了变化,但我自己也遇到了这个问题,我觉得这个问题还没有很好的答案......

    自 OP 以来,部分 PIXI API 发生了变化,但请参阅dragging bunnies example 的 PIXI 文档。

    精灵第一次开始拖动时的跳跃性是因为精灵总是相对于锚点/枢轴点定位。正因为如此,锚点的位置在拖动时跟随鼠标的位置(至少在上面的代码中)。如果单击兔子的中心,您不会注意到,但单击边缘会产生非常明显的跳跃。当使用大得多的精灵时(如 OP 中链接的示例),这种跳跃会变得非常明显。

    这是我修复它的方法:

    PIXI 演示几乎不需要更改。 onDragEnd 和 onDragMove 保持不变:

    function onDragEnd(){
        this.dragging=false;
        this.data = null;
    }
    
    
    function onDragMove(){
        if (this.dragging){
            let newPosition = this.data.getLocalPosition(this.parent);
                this.x = newPosition.x;
                this.y = newPosition.y;
            }
    }
    

    但是,我们需要将轴心点更新为 onDragStart 函数中点击事件的位置,如下所示:

    function onDragStart(event){
        this.data = event.data;
    
        //store this variable for convenience           
        let position = this.data.getLocalPosition(this);
    
        // Set the pivot point to the new position
        this.pivot.set(position.x, position.y)
    
        // update the new position of the sprite to the position obtained through 
        // the global data. This ensures the position lines up with the location of 
        // the mouse on the screen. I'm not certain why, but this is necessary. 
        this.position.set(this.data.global.x, this.data.global.y)
        this.dragging = true;
    }   
    

    通过此设置,无论大小如何,拖动精灵都将是平滑的。非常适合创建单击并拖动以探索的环境,如 OP 中所链接的那样。

    希望这对未来两年的其他人有所帮助。

    【讨论】:

      【解决方案2】:

      我确实希望你已经想出了如何解决这个问题,但是由于这里没有答案,我将引导你朝着正确的方向前进。

      您给我们的代码缺少 loadImages() 函数,但我相信无论如何我们应该能够解决它。

      问题似乎出在这段代码sn-p:

      var background = new PIXI.Container();
      background.parent = background;
      background.interactive = true;
      
      background.on('mousedown', onDragStart)
          .on('touchstart', onDragStart)
          .on('mouseup', onDragEnd)
          .on('mouseupoutside', onDragEnd)
          .on('touchend', onDragEnd)
          .on('touchendoutside', onDragEnd)
          .on('mousemove', onDragMove)
          .on('touchmove', onDragMove);
      

      在这里,您正在使后台容器交互并为其提供所有事件处理程序。

      您应该做的是让每个单独的精灵/图像具有交互性,并为它们提供移动它的事件处理程序。

      我在您的代码中添加了以下代码: // 从一些图像创建一个精灵 var sprite = new PIXI.Sprite.fromImage('some_image.png');

      // Make the sprite interactive. should be done to each individual sprite
      sprite.interactive = true;
      
      // Set the anchor in the center of our sprite 
      sprite.anchor.x = 0.5;
      sprite.anchor.y = 0.5;
      
      // Position our sprite in the center of the renderer
      sprite.position.x = renderer.width / 2;
      sprite.position.y = renderer.height / 2;
      
      
      sprite.on('mousedown', onDragStart)
              .on('touchstart', onDragStart)
              .on('mouseup', onDragEnd)
              .on('mouseupoutside', onDragEnd)
              .on('touchend', onDragEnd)
              .on('touchendoutside', onDragEnd)
              .on('mousemove', onDragMove)
              .on('touchmove', onDragMove);
      
      
      background.addChild(sprite);
      

      你应该把它放在你的 loadImages 函数中。然后让该函数遍历每个图像,为它们提供工作所需的事件处理程序和选项。

      这是基于您的有效代码。

      var w = window.innerWidth;
      var h = window.innerHeight;
      var images = [];
      var stage = new PIXI.Container();
      var renderer = new PIXI.autoDetectRenderer(w, h,{transparent:true},true);
      document.body.appendChild(renderer.view);
      
      var background = new PIXI.Container();
      
      // Create a sprite from some image
      var sprite = new PIXI.Sprite.fromImage('some_image.png');
      
      // Make the sprite interactive. should be done to each individual sprite
      sprite.interactive = true;
      
      // Set the anchor in the center of our sprite 
      sprite.anchor.x = 0.5;
      sprite.anchor.y = 0.5;
      
      // Position our sprite in the center of the renderer
      sprite.position.x = renderer.width / 2;
      sprite.position.y = renderer.height / 2;
      
      
      sprite.on('mousedown', onDragStart)
              .on('touchstart', onDragStart)
              .on('mouseup', onDragEnd)
              .on('mouseupoutside', onDragEnd)
              .on('touchend', onDragEnd)
              .on('touchendoutside', onDragEnd)
              .on('mousemove', onDragMove)
              .on('touchmove', onDragMove);
      
      
      background.addChild(sprite);
      
      requestAnimationFrame(animate);
      
      function animate() {
          requestAnimationFrame(animate);
          renderer.render(background);
      }
      
      function onDragStart(event)
      {
          this.data = event.data;
          this.mousePressPoint = [];
          this.dragging = true;
      }
      
      function onDragEnd()
      {
          this.dragging = false;
          this.data = null;
      }
      
      function onDragMove()
      {
          if (this.dragging)
          {
              var position = this.data.getLocalPosition(this.parent);
              this.position.x = position.x;
              this.position.y = position.y;
          }
      }
      

      【讨论】:

        猜你喜欢
        • 2015-09-29
        • 1970-01-01
        • 1970-01-01
        • 2019-05-03
        • 1970-01-01
        • 2018-10-29
        • 2015-07-01
        • 2016-02-12
        • 1970-01-01
        相关资源
        最近更新 更多