动态调整 pixi 舞台的大小及其在窗口调整大小和窗口加载时的内容

Posted

技术标签:

【中文标题】动态调整 pixi 舞台的大小及其在窗口调整大小和窗口加载时的内容【英文标题】:Dynamically resize the pixi stage and it's contents on window resize and window load 【发布时间】:2015-08-13 19:02:06 【问题描述】:

我正在尝试在调整窗口大小时动态调整 pixi 舞台(画布和内容)的大小。并且还让它最初以浏览器窗口的大小加载而不改变比例。

我使用以下方法将初始大小设置为window.innerWidth & window.innerHeight

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

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 函数 - 它正在调整画布的大小,而不是内容。

我认为它正在更新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);

【问题讨论】:

你想保持什么比例?或者,默认的画布尺寸是多少? 这是一个非常好的问题 :D 现在是 1920x1080,所以是 16x9。但这可能需要稍后改变。我编辑了上面的仅供参考。 我的回答有帮助吗? 【参考方案1】:

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

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

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

【讨论】:

这有效,但不会重绘元素位置 - 只是画布大小。我为此创建了一个功能请求:github.com/pixijs/pixi.js/issues/6081【参考方案2】:

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

另外,请注意我没有运行renderer.resize。我只是在调整绘图区域的大小。

这里有一个小提琴供你看:http://jsfiddle.net/2wjw043f/

这是小提琴代码:

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;

【讨论】:

几天前我为您的 JSFiddle 添加了书签,现在它不再起作用了。控制台说明 PIXI 未定义。请你修好吗?编辑:没关系,看起来托管外部 pixi (goodboydigital) 的域已关闭。【参考方案3】:

我使用 Pixi.js 已经有几个星期了,并且解决了调整画布大小的相同问题。这个类创建了一个精灵,它有一个方法“applyResize”来完成大部分工作。画布背景的大小将与构造函数中的父“domElement”相同。初始化后,您必须将“调整大小”事件侦听器添加到精灵。或者你可以做一些其他的事情来改进它。

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>

【讨论】:

【参考方案4】:
app.renderer.resize(window.innerWidth, window.innerHeight);
window.onresize = function()

    app.renderer.resize(window.innerWidth, window.innerHeight);

【讨论】:

【参考方案5】:

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

【讨论】:

以上是关于动态调整 pixi 舞台的大小及其在窗口调整大小和窗口加载时的内容的主要内容,如果未能解决你的问题,请参考以下文章

允许窗口在转换后动态调整大小

为啥 Scrolltrigger 在调整窗口大小时不更新我的动态 x 值?

根据窗口大小动态调整闪亮绘图输出的高度和/或宽度

Kineticjs如何在舞台上居中图像并根据浏览器调整大小

如何将电子窗口附加到应用程序屏幕并动态调整大小

如何在css中动态调整图像大小?