javascriptruby-on-rails

How to parse a dynamic image path in Rails 8 inside Stimulus controller (Popshaft Asset Pipeline)?


I am trying to run a .png sequence inside a canvas with scrolling as the trigger of changing the current displayed image from Ring_00001.png to Ring_00002.png and so on.

In Popshaft Rails GitHub page it was taught that you may reference a path inside a javascript using pseudo-method:

export default class extends Controller {
    init() {
    this.img = RAILS_ASSET_URL("/icons/trash.svg")
  }
}

However I can not wrap my head around my case on how to properly reference an image URL if the file name is changing depending on the scroll action.

I tried

const currentFrame = index => (
    `${index.toString().padStart(5, '0')}.png`);

const animation = new Image();
    animation.src = RAILS_ASSET_URL(`/RingSeq/Ring_${currentFrame}`);
    animation.onload = function(){
      context.drawImage(animation, 0, 0)
    };

I would like to add that trying to load RAILS_ASSET_URL("/RingSeq/Ring_00001.png") is working so the only trouble here is how to reference this helper correctly with javascript variable.

Thank you very much!


Solution

  • RAILS_ASSET_URL() is not an actual function, it's only used by propshaft as a placeholder to find image paths and replace them with digested path.

    You'll have to preconstruct all of the necessary images ahead of time:

    const images = {
      1: RAILS_ASSET_URL("/RingSeq/Ring_00001.png"),
      2: RAILS_ASSET_URL("/RingSeq/Ring_00002.png"),
      3: RAILS_ASSET_URL("/RingSeq/Ring_00003.png"),
      4: RAILS_ASSET_URL("/RingSeq/Ring_00004.png"),
    }
    
    const animation = new Image();
    animation.src = images[index]
    

    You could also put these images into public directory, that way you won't need to dance around rails' assets digest path, but responsibility of invalidating cache if those images ever change falls on you (appending ?v=2 to the path).