拖动时,Pixi.js图像跳转

时间:2015-08-03 12:09:32

标签: pixi.js

我在使用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]);
    }
}

2 个答案:

答案 0 :(得分: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函数中click事件的位置,如下所示:

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中链接。

希望这将在未来两年帮助别人。

答案 1 :(得分:0)

我希望您已经找到了解决此问题的方法,但由于此处没有答案,我将指导您朝着正确的方向前进。

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

问题似乎在于此代码段:

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;
    }
}