Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Multiple image sizes #9

Open
s3ththompson opened this issue Apr 22, 2018 · 14 comments
Open

Multiple image sizes #9

s3ththompson opened this issue Apr 22, 2018 · 14 comments

Comments

@s3ththompson
Copy link

I've been trying to figure out an elegant way to support multiple image sizes with hypha, but perhaps there's an opportunity for nanopage to smooth this over.

Is there any way to associate multiple files with a single identifier? E.g. image.jpg and image@2x.jpg?

Understood if this is out of scope.

@jongacnik
Copy link
Collaborator

jongacnik commented Apr 25, 2018

This might not be quite what you're talking about since it seems like you are wanting to resolve multiple files to a single key via hypha, but nonetheless this might give some ideas? I've been using multiple image sizes with a hypha-ish content structure (using Kirby to spit this out). My content is shaped a little something like (only showing the bare minimum of keys here):

{
  '/some-page': {
    files: {
      'some-file.jpg': {
        sizes: {
          500: '/path/to/some-page/some-file-500.jpg',
          1000: '/path/to/some-page/some-file-1000.jpg',
          1500: '/path/to/some-page/some-file-1500.jpg'
        }
      }
    }
  }
}

This pattern seems to work pretty well for consolidating image sizes. You could do something like:

var sizes = page('/some-page').file('some-file.jpg').value('sizes')

fwiw, I use this with a little nanocomponent to render an appropriate image size based on it's parent's size (kinda like a context aware srcset). I'll try to get a repo up for that after current build I'm working on is wrapped.

@jondashkyle
Copy link
Owner

jondashkyle commented Apr 25, 2018

That’s pretty solid @jongacnik, hmm. Perhaps we could structure that simply by checking to see if there is a file appended with filename-{INT}.jpg the same way we check for metadata by checking by seeing if there is filename.jpg.txt.

@s3ththompson
Copy link
Author

@jongacnik yeah, that's absolutely perfect
@jondashkyle that would be great.

I'm using gulp-responsive to generate different sizes with a known naming pattern. I also use gulp to write out the aspect ratio to a metadata file:

var probe = require('probe-image-size')

var size = probe.sync(file.contents)
if (size !== null) {
  metadata = merge(metadata, {
    data: {
      aspect: (size.width / size.height)
    }
  })
}

Then I've hacked hypha/transform to run the site object through this function:

module.exports = removeResponsiveImages

function removeResponsiveImages(site) {
  for (var href in site) {
    var files = site[href].files
    for (var file in files) {
      if (isResponsive(files[file])) delete files[file]
    }
  }
  return site
}

function isResponsive(file) {
  if (file.extension == '.webp') return true
  var suffixes = ['-md', '-l', '-xl']
  for (var suffix of suffixes) {
    if (file.name.endsWith(suffix)) return true
  }
  return false
}

And then I basically reconstruct the sizes dynamically when I'm formatting them.

But it would definitely be preferable for hypha to append the different sizes to the file object.

@jongacnik also, I totally agree that there should be a nanocomponent to render images intelligently. There are a lot of nice ideas in lazysizes.

Right now my component constructs a picture element with srcset for webp and jpg, fades in the image once it's loaded, and adds padding based on the aspect ratio to keep intrinsic sizes:

function calcPadding (aspect) {
  return `padding-bottom: ${100 / aspect}%;`
}

Would def be curious to see what you've come up with.

@jondashkyle
Copy link
Owner

@s3ththompson nice, i’m thinking about this for the Enoki Panel too, but entirely clientside within the panel and using canvas to resize, get metadata, etc… @jongacnik could be cool to throw that little nanocomponent into a repo and we could spec this out a bit more.

@jondashkyle
Copy link
Owner

Btw this makes me want file data stored alongside pages as per #7 even more.

1 similar comment
@jondashkyle
Copy link
Owner

Btw this makes me want file data stored alongside pages as per #7 even more.

@s3ththompson
Copy link
Author

Yep totally. Although I do worry about ballooning size of the site object. My index.js (which contains the site object) for this choo app is now 1/2 the size of my total bundle. I probably need to figure out some sort of async loading for site data...

@jongacnik
Copy link
Collaborator

jongacnik commented Apr 26, 2018

@jondashkyle I think the filename pattern matching for hypha is cool. Perhaps it could catch different dimension formats: /-\d*x?\d*\./ for things like: filename-500.jpg, filename-500x500.jpg, filename-500x.jpg, filename-x500.jpg

@s3ththompson I had the same thought re: site object size, but might be ok. I'll drop this thought into #7 though so we don't get sidetracked here.

Will try to package up that nanocomponent late today/ tomorrow!

@jongacnik jongacnik mentioned this issue Apr 26, 2018
Closed
@jongacnik
Copy link
Collaborator

@s3ththompson heads up I pushed that image component up https://github.com/jongacnik/monoimage. It assumes the file object is shaped like what is above with the sizes field.

@s3ththompson
Copy link
Author

@jondashkyle monoimage looks great. just to confirm, you're getting the sizes part of the file object from Kirby, not hypha, right?

@s3ththompson
Copy link
Author

err sorry meant @jongacnik

@jongacnik
Copy link
Collaborator

@s3ththompson correct. Ya, that is still an open q in regards to the best way to generate via hypha, or enoki, or etc.

@jondashkyle
Copy link
Owner

jondashkyle commented May 4, 2018

yeah, to do that in a unified way both client and server side requires a bit of thinking. seeing as hypha accepts fs as a param, we could simply see if the relevant function is available, and if so we can read meta information like dimensions. that also enables you to pass in any arbitrary function of your choosing via fs to get the job done.

where that gets a little hairy is when running client side within beaker. the only way to obtain (i can think of) dimension like that is via reading the image buffer into canvas. that’s obviously a super slow operation, hahah.

anyway, could be cool to add support for this if the environment enables it, and progressively fall back if not.

@s3ththompson
Copy link
Author

anyway, could be cool to add support for this if the environment enables it, and progressively fall back if not.

👍

@jongacnik jongacnik mentioned this issue May 17, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants