动态调整 pixi 阶段及其内容 window resize and window load

Dynamically resize the pixi stage and it's contents on window resize and window load

我正在尝试在 window 调整大小时动态调整 pixi 阶段(canvas 和内容)的大小。并且还让它最初以浏览器 window 的大小加载,而不改变比率。

我正在使用以下内容将初始大小基本上设置为 window.innerWidth & window.innerHeight

但它做了一些奇怪的事情,它以较小的尺寸加载(但不是 html 中指定的 canvas 的尺寸),然后扩展以适应 window。

var w;
var h;
    
window.onload = function() {
    var w = window.innerWidth;
    var h = window.innerHeight;

    //this part resizes the canvas but keeps ratio the same
    renderer.view.style.width = w + "px";
    renderer.view.style.height = h + "px"

//  init();
}; 

这是我的 onresize 函数 - 它正在调整 canvas 的大小,但不是内容。

我以为它正在更新 renderer.view,它会调整内容的大小,但它并没有这样做。

如何调整 stage/renderer.view 内容的大小?

window.onresize = function (event){
    var w = window.innerWidth;
    var h = window.innerHeight;

    //this part resizes the canvas but keeps ratio the same
    renderer.view.style.width = w + "px";
    renderer.view.style.height = h + "px";

    //this part adjusts the ratio:
    renderer.resize(w,h);
}

    // create an new instance of a pixi stage
    var stage = new PIXI.Stage(0xff00ff);
    var renderer = PIXI.autoDetectRenderer(window.innerWidth, window.innerHeight);

    // add the renderer view element to the DOM
   var mypixiStage = document.body.appendChild(renderer.view);

您需要设置大小和比例,供调整大小事件函数参考。然后,您需要一个调整大小函数来检查 window 大小,以便在调整大小时保持比例。我也在 运行 手动调整大小功能以启动初始页面加载。

此外,请注意我不是 运行 renderer.resize。我只是调整绘图区域的大小。

这里有一个fiddle给你看看:http://jsfiddle.net/2wjw043f/

这是 fiddle 代码:

var size = [1920, 1080];
var ratio = size[0] / size[1];
var stage = new PIXI.Stage(0x333333, true);
var renderer = PIXI.autoDetectRenderer(size[0], size[1], null);
document.body.appendChild(renderer.view);
var texture = new PIXI.RenderTexture();
r1 = new PIXI.Graphics();
r1.beginFill(0x00ffff);
r1.drawRect(0, 0, 100, 100);
r1.endFill();
texture.render(r1);
var block = new PIXI.Sprite(texture);
block.position.x = 100;
block.position.y = 100;
block.anchor.x = .5;
block.anchor.y = .5;
stage.addChild(block);
requestAnimFrame(animate);
resize();
function animate() {
    requestAnimFrame(animate);
    block.rotation += .01;
    renderer.render(stage);
}
function resize() {
    if (window.innerWidth / window.innerHeight >= ratio) {
        var w = window.innerHeight * ratio;
        var h = window.innerHeight;
    } else {
        var w = window.innerWidth;
        var h = window.innerWidth / ratio;
    }
    renderer.view.style.width = w + 'px';
    renderer.view.style.height = h + 'px';
}
window.onresize = resize;

我已经使用 Pixi.js 几个星期了,并解决了调整 canvas 大小的相同问题。此 class 创建了一个精灵,该精灵具有完成大部分工作的方法 "applyResize"。 canvas 背景的大小将与构造函数中的父级 "domElement" 相同。你必须在初始化后给精灵添加 'resize' 事件监听器。或者您可以做其他事情来改进它。

class PixiBackground {

    constructor(type = 'cover', domElement, imgUrl) {
        this.domElement = domElement;
        this.imgUrl = imgUrl;
        this.parent = new PIXI.Container();
        this.sprite = new PIXI.Sprite.fromImage(this.imgUrl);
        this.parent.addChild(this.sprite);
        this.type = type;
    }

    addTo(container) {
        container.addChild(this.parent);
        this.applyResize();
    }

    applyResize() {
        const domSize = {
            x: this.domElement.clientWidth,
            y: this.domElement.clientHeight
        };
        const imageSize = {
            x: this.sprite.texture.width,
            y: this.sprite.texture.height
        };
        const domElementRatio = domSize.x / domSize.y;
        const imageRatio = imageSize.x / imageSize.y;
        var scale = 1;
        var position = new PIXI.Point(0, 0);

        if (this.type == 'cover' ? domElementRatio > imageRatio : domElementRatio < imageRatio) {
            //photo is taller than background
            scale = domSize.x / imageSize.x;
            position.y = -(imageSize.y * scale - domSize.y) / 2;
            position.x = 0;
        } else {
            //photo is wider than background
            scale = domSize.y / imageSize.y;
            position.x = -(imageSize.x * scale - domSize.x) / 2;
            position.y = 0;
        }
        this.sprite.scale = new PIXI.Point(scale, scale);
        this.sprite.position = position;
        return this;
    }
}

const imgUrl = 'https://images.unsplash.com/photo-1528723624453-3e53a413b392?ixlib=rb-0.3.5&q=85&fm=jpg&crop=entropy&cs=srgb&ixid=eyJhcHBfaWQiOjE0NTg5fQ&s=b44ae61a30e1a05f5defbf48cb5956eb';
const canvasParentElement = document.getElementById('canvasParentElement');
const renderer = PIXI.autoDetectRenderer({
    width: canvasParentElement.clientWidth,
    height: canvasParentElement.clientHeight
});
canvasParentElement.appendChild(renderer.view);

const stage = new PIXI.Container();
const pixiTestObject = new PixiBackground('cover', canvasParentElement, imgUrl);

PIXI.loader.add(imgUrl).load(function() {
    pixiTestObject.addTo(stage)
    requestAnimationFrame(animate);

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

window.addEventListener('resize', debounce(() => onResizeWindow(), 250));
window.addEventListener('resize', debounce(() => pixiTestObject.applyResize(), 250));

// From underscrore.js
function debounce(func, wait, immediate) {
    let timeout;
    return function() {
        let args = arguments;
        let later = () => {
            timeout = null;
            if (!immediate) func.apply(this, args);
        };
        let callNow = immediate && !timeout;
        clearTimeout(timeout);
        timeout = setTimeout(later, wait);
        if (callNow) func.apply(this, args);
    }
}

function onResizeWindow() {
    const canvas = renderer.view;
    const w = canvasParentElement.clientWidth;
    const h = canvasParentElement.clientHeight;
    canvas.style.width = w + 'px';
    canvas.style.height = h + 'px';
    canvas.width = w;
    canvas.height = h;
    renderer.resize(w, h);
}
  #canvasParentElement {
    background: black;
    width: 100vw;
    height: 100vh;
    overflow: hidden;
  }
<script src="https://cdnjs.cloudflare.com/ajax/libs/pixi.js/4.8.1/pixi.min.js"></script>
<div id="canvasParentElement"></div>

从 PixiJS 5.0 开始,您可以简单地使用应用程序的 resizeTo 属性:

let app = new PIXI.Application({ resizeTo: window });

文档:http://pixijs.download/release/docs/PIXI.Application.html#Application

adaptive-scale 对于调整大小和缩放事物非常有用

app.renderer.resize(window.innerWidth, window.innerHeight);
window.onresize = function()
{
    app.renderer.resize(window.innerWidth, window.innerHeight);
}

对于我的用例,我只需要根据精灵的宽度缩放精灵。我使用 scale 函数并将其限制为最大值 1:

sprite.scale.set(Math.min(app.screen.width / sprite.texture.width, 1))

从 PixiJS 5.3.0 开始,渲染器上会发出一个 resize 事件。这要感谢 Fabian von Ellerts 在他的评论中提到的 issue #6081 打开。

app.renderer.on('resize', (width, height) => {
  sprite.scale.set(Math.min(width / sprite.texture.width, 1))
})

⚠️ 这只会设置精灵的尺寸。您仍然需要以类似的方式将其定位在 canvas 上,即也缩放其位置。