Search code examples
javascriptarraysglobal-variablesphoto-gallerypixi.js

How to get around issues with global variables when creating image gallery?


I am trying to create a click through image gallery for a project in pixi.js. You can see in my fiddle when you click on the right side of the screen it adds the next image. The problem is when you click on the left to delete the image it will only delete one and not the rest.

I know why this is happening, its because "image" is a global variable , its holding only the last image that was added. There's no way for my function to get images that were added before it. However I am stuck trying to think of a work around. Could anyone help me adjust my code? My JS and a fiddle are below.

  const bodyTag = document.querySelector("body")
  const nextTag = document.querySelector("div.right")
  const backTag = document.querySelector("div.left")

  let type = "WebGL"
  if(!PIXI.utils.isWebGLSupported()){
    type = "canvas"
  }

  // Aliases
  let Application = PIXI.Application,
      loader = PIXI.loader,
      resources = PIXI.loader.resources,
      Sprite = PIXI.Sprite;

  //Create a pixi application
  let app = new PIXI.Application({
    width: 2000,
    height: 2000,
    transparent: false,
    antialias: true,
    resolution: 1

  })

  //Add the canvas that Pixi automatically created for you to the html document
  bodyTag.appendChild(app.view);

  let image = null
  let image2 = null
  let imageCreated = false
  let step = 0
  let left = 0

  var images = [
    "https://i.imgur.com/HEwZDoW.jpg",
    "https://i.imgur.com/F5XOYH7.jpg",
    "https://i.imgur.com/e29HpQj.jpg",
    "https://i.imgur.com/2FaU2fI.jpg",
    "https://i.imgur.com/fsyrScY.jpg"
  ]


  loader
    .add([
      images
    ])

    const createSprite = function() {
      imageCreated = true
      image = new Sprite(resources[images[step]].texture)
      image.width = 400;
      image.height = 300;
      image.x = left
      app.stage.addChild(image)
      step += 1
      left += 40
    }

    const removeSprite = function() {
      app.stage.removeChild(image)
      step -= 1
    }


    loader.load((loader, resources) => {
        createSprite()
      })


    nextTag.addEventListener("click", function() {
      console.log("next")
      createSprite()
    })

    backTag.addEventListener("click", function() {
      console.log("back")
      removeSprite()
    })
* {
  padding: 0;
  margin: 0;
}

body {
  margin:0;
  padding:0;
  overflow:hidden;
}

canvas {
  display:block;
}

div.left {
  position: fixed;
  top: 0;
  left: 0;
  width: 50vw;
  height: 100vh;
  cursor: pointer;
}

div.right {
  position: fixed;
  top: 0;
  right: 0;
  width: 50vw;
  height: 100vh;
  cursor: pointer;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/pixi.js/4.8.6/pixi.js"></script>
<div class="left"></div>
  <div class="right"></div>


Solution

  • Use array to hold images that are added to screen instead of holding each image into single variable and

    on click on left div perform pop on image array it will give last image added and remove it

    const bodyTag = document.querySelector("body")
      const nextTag = document.querySelector("div.right")
      const backTag = document.querySelector("div.left")
    
      let type = "WebGL"
      if(!PIXI.utils.isWebGLSupported()){
        type = "canvas"
      }
    
      // Aliases
      let Application = PIXI.Application,
          loader = PIXI.loader,
          resources = PIXI.loader.resources,
          Sprite = PIXI.Sprite;
    
      //Create a pixi application
      let app = new PIXI.Application({
        width: 2000,
        height: 2000,
        transparent: false,
        antialias: true,
        resolution: 1
    
      })
    
      //Add the canvas that Pixi automatically created for you to the html document
      bodyTag.appendChild(app.view);
    
      //use array for storing images
      let imageSet = []
      let image2 = null
      let imageCreated = false
      let step = 0
      let left = 0
    
      var images = [
        "https://i.imgur.com/HEwZDoW.jpg",
        "https://i.imgur.com/F5XOYH7.jpg",
        "https://i.imgur.com/e29HpQj.jpg",
        "https://i.imgur.com/2FaU2fI.jpg",
        "https://i.imgur.com/fsyrScY.jpg"
      ]
    
    
      loader
        .add([
          images
        ])
    
        const createSprite = function() {
          imageCreated = true
          //create an image
          let image = new Sprite(resources[images[step]].texture)
          image.width = 400;
          image.height = 300;
          image.x = left
          
          //push created images reference into images array
          imageSet.push(image)
          app.stage.addChild(image)
          step += 1
          left += 40
          
        }
    
        const removeSprite = function() {
        
          //get the last element from image array
          let image = imageSet.pop();
          
          app.stage.removeChild(image)
          step -= 1
          
        //reset left
          left -= 40
        }
    
    
        loader.load((loader, resources) => {
            createSprite()
          })
    
    
        nextTag.addEventListener("click", function() {
          console.log("next")
          createSprite()
        })
    
        backTag.addEventListener("click", function(event) {
          console.log("back")
          removeSprite()
        })
    * {
      padding: 0;
      margin: 0;
    }
    
    body {
      margin:0;
      padding:0;
      overflow:hidden;
    }
    
    canvas {
      display:block;
    }
    
    div.left {
      position: fixed;
      top: 0;
      left: 0;
      width: 50vw;
      height: 100vh;
      cursor: pointer;
    }
    
    div.right {
      position: fixed;
      top: 0;
      right: 0;
      width: 50vw;
      height: 100vh;
      cursor: pointer;
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/pixi.js/4.8.6/pixi.js"></script>
    <div class="left"></div>
      <div class="right"></div>