Skip to content

Instantly share code, notes, and snippets.

@only-cliches
Last active March 14, 2024 12:07
Show Gist options
  • Save only-cliches/581823db9cdc8d94ed3f78c1a548f50d to your computer and use it in GitHub Desktop.
Save only-cliches/581823db9cdc8d94ed3f78c1a548f50d to your computer and use it in GitHub Desktop.
PixiJS Background Cover & Background Container
/*
* PixiJS Background Cover/Contain Script
* Returns object
* . {
* container: PixiJS Container
* . doResize: Resize callback
* }
* ARGS:
* bgSize: Object with x and y representing the width and height of background. Example: {x:1280,y:720}
* inputSprite: Pixi Sprite containing a loaded image or other asset. Make sure you preload assets into this sprite.
* type: String, either "cover" or "contain".
* forceSize: Optional object containing the width and height of the source sprite, example: {x:1280,y:720}
*/
function background(bgSize, inputSprite, type, forceSize) {
var sprite = inputSprite;
var bgContainer = new PIXI.Container();
var mask = new PIXI.Graphics().beginFill(0x8bc5ff).drawRect(0,0, bgSize.x, bgSize.y).endFill();
bgContainer.mask = mask;
bgContainer.addChild(mask);
bgContainer.addChild(sprite);
function resize() {
var sp = {x:sprite.width,y:sprite.height};
if(forceSize) sp = forceSize;
var winratio = bgSize.x/bgSize.y;
var spratio = sp.x/sp.y;
var scale = 1;
var pos = new PIXI.Point(0,0);
if(type == 'cover' ? (winratio > spratio) : (winratio < spratio)) {
//photo is wider than background
scale = bgSize.x/sp.x;
pos.y = -((sp.y*scale)-bgSize.y)/2
} else {
//photo is taller than background
scale = bgSize.y/sp.y;
pos.x = -((sp.x*scale)-bgSize.x)/2
}
sprite.scale = new PIXI.Point(scale,scale);
sprite.position = pos;
}
resize();
return {
container: bgContainer,
doResize: resize
}
}
@only-cliches
Copy link
Author

only-cliches commented Nov 22, 2016

Example:

var containerSize = {x:800,y:600};

var renderer = PIXI.autoDetectRenderer(containerSize.x,containerSize.y);
document.body.appendChild(renderer.view);

var stage = new PIXI.Container();
var container = new PIXI.Container();

stage.addChild(container);

PIXI.loader.add("some-image.jpg").load(function () {   
    var slide = background(containerSize, new PIXI.Sprite.fromImage("some-image.jpg"),'cover');        
    container.addChild(slide.container);
    // force resize: slide.doResize();
    renderer.render(stage);
});

@dnecklesportfolio
Copy link

dnecklesportfolio commented Jan 7, 2017

Hi Click Simply, you have "container" declared twice, once as an object and once as a sprite..
once that was fixed, it seemed to work..

@only-cliches
Copy link
Author

Ah yes, didn't notice that in my example. 👍

Update made.

@michaelgrc
Copy link

Hi Click Simply, I try to use your function with a displacementFilter effect but it's not working.
I don't see what I'm missing.
Is that because I'm using Texture for the Sprite ?
My script works without your function but it's not 'cover'.

Any idea ? Thank you very much

    var containerSize = {x:window.innerWidth,y:window.innerHeight};
    var renderer = PIXI.autoDetectRenderer(containerSize.x, containerSize.y, {transparent:true});
    document.body.appendChild(renderer.view);

    var stage = new PIXI.Container();
    var container = new PIXI.Container();

    stage.addChild(container);

    var texture2 = PIXI.Texture.fromImage('./img_home.jpg');
    var logo = new PIXI.Sprite(texture2);

    var displacementSprite = PIXI.Sprite.fromImage("http://i.imgur.com/2yYayZk.png");
    displacementSprite.texture.baseTexture.wrapMode = PIXI.WRAP_MODES.REPEAT;

    var displacementFilter = new PIXI.filters.DisplacementFilter(displacementSprite);

    displacementSprite.scale.y = 0.3;
    displacementSprite.scale.x = 0.3;

    stage.addChild(displacementSprite);

    PIXI.loader.add("./img_home.jpg").load(function () {   
        var slide = background(container, logo, 'cover');        
        container.addChild(slide);
        
        animate();
    });


    function animate() {
        requestAnimationFrame(animate);
        
        displacementSprite.x -= .5; // current_value
        displacementSprite.y -= .5; // current_value

        stage.filters = [displacementFilter];
        renderer.render(stage);
    }`

@schneider-simon
Copy link

Very nice. Such behaviour should be offered by the core 👍

@thibka
Copy link

thibka commented Nov 4, 2018

Great, thanks!
Correct me if I'm wrong but you do not need line 15
bgContainer.addChild(mask);
And you could simplify line 13 to
var mask = new PIXI.Graphics().drawRect(0, 0, bgSize.x, bgSize.y);

@martifenosa
Copy link

Hi,
Great job thanks for sharing!
I want ask, is there a correct way to force a refresh in case the window is resized?

Thank's again!

@thibka
Copy link

thibka commented Aug 25, 2019

I want ask, is there a correct way to force a refresh in case the window is resized?

+1 :)

Also, is it possible to change the anchor position without offsetting the whole sprite ? Just like we would do in CSS

background-size: cover;
background-position: center bottom;

@only-cliches
Copy link
Author

Not sure how to do the background position stuff, might get a chance later to dig into that.

I updated the gist to have a resize callback, should take care of things for you. 👍

@thibka
Copy link

thibka commented Aug 26, 2019

Hey thanks!
Not sure you need line 19 bgContainer.addChild(mask); though.
Besides, the resize function doesn't work when you actually change the sprite container size.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment