twolfson / gulp.spritesmith

Convert a set of images into a spritesheet and CSS variables via gulp
The Unlicense
1.07k stars 81 forks source link

Support for retina devices with a pixel ratio of 3 #95

Open rigoli07 opened 8 years ago

rigoli07 commented 8 years ago

Using spritesmith for @3x sprite files or any pixel ratio. Thoughts?

twolfson commented 8 years ago

Currently we don't have support for 3x spritesheets but are open to it. For more immediate support, here are some options:

I'm not too familiar with 3x support (e.g. devices, usage %). Can you provide us with information on that?

rigoli07 commented 8 years ago

Thanks for the info.

A few of the new devices which have been released in the past year, have a pixel density of 3. This includes, the iPhone 6 plus, Samsung Galaxy S4+ and Nexus 6, to name a few.

twolfson commented 8 years ago

Ah, k. Thanks =) To add support for this will be a large undertaking (likely restructuring our API syntax to handle infinite scaled spritesheets (albeit I doubt we will ever go past 4x spritesheets, human eyes have limits) and our spritesheet schema). I don't have any available time in the immediate future but I will leave this issue open for now.

adgvan commented 7 years ago

Here is a table pointing to pixel densities in different devices: https://material.io/devices/ There are densities from x1 to x4

Some gulp plugins already have support for x3 like this one https://github.com/weixin/gulp-tmtsprite Any news on x3 / x4 support in gulp.spritesmith?

twolfson commented 7 years ago

@adgvan Are there any tables that show market share as well? It would help to know how many users are being affected

I'm still considering this on the backburner due to not seeing any blog posts on major channels about 3x/4x sprites (e.g. web newsletters, Reddit, Hacker News, Lobsters) as well as having workarounds and alternatives

https://github.com/twolfson/gulp.spritesmith/issues/95#issuecomment-233904152

adgvan commented 7 years ago

I tried to find some info on that, but didn't succeed. To think logically, because x3 and x4 density is present so little number of devices, of course its market share is tiny. But however, a developer should have a possibility to ship users with maximum possible quality, shipping to users on all types of devices the best they can get. And the issue of how quickly density of other devices will progress up to x3 and x4 is just a matter of time. So it is very desirable for all developers to have this possibility. Another question is, that one has to include each source image in all resolutions, according to number of densities (2 images for x1 & x2, 3 images for x1, x2 and x3, etc). Is there any possibility that one can include just the biggest resolution image (say x2) and get the plugin to automatically create an x1 image out of it (losslessly lowering its resolution) ? So that instead of dealing with duplicate images we'll have to have just 1 high-res source?

twolfson commented 7 years ago

Alright, going to keep on hedging my bets against 3x and 4x. I have a feeling the higher retina displays are going to unnecessarily drain battery without providing much better aesthetics. Additionally, 3x and 4x images would require even more bandwidth which also leads to more battery usage

As mentioned, there are still workarounds available for now for any developer who definitely wants 3x support now:

https://github.com/twolfson/gulp.spritesmith/issues/95#issuecomment-233904152

My resistance is mostly from not being convinced that it's going to become widely adopted as well as other items having higher priority for me.

With respect to downsizing images, we recommend using another gulp plugin (e.g. gulp-image-resize):

https://www.npmjs.com/package/gulp-image-resize/

twolfson commented 7 years ago

This is still low on our priorities list but we thought of a nice format for Gulp if we do implement this:

Non-retina:

spritesmith({
  src: gulp.src(['path/to/sprites/*@1x.png']),
  imgName: 'spritesheet.png',
  cssName: 'sprites.css'
});

2x/3x:

spritesmith({
  src: {
    '1x': gulp.src(['path/to/sprites/*@1x.png']),
    '2x': gulp.src(['path/to/sprites/*@2x.png'])
    '3x': gulp.src(['path/to/sprites/*@3x.png'])
  },
  imgName: {
    '1x': 'spritesheet@1x.png',
    '2x': 'spritesheet@2x.png',
    '3x': 'spritesheet@3x.png'
  }
  cssName: 'sprites.css'
});

This new syntax is partially in retaliation to the confusion around filtering out retina images from src.

In addition to this, we would throw out a lot of retina specific options due to them being redundant to normal options. We should be able to reuse them instead of requiring double configuration.

We should also consider an all-in-one object for configuring a spritesheet:

sheets: [{
    src: gulp.src(['path/to/sprites/*@1x.png']),
    imgName: 'spritesheet@1x.png'
}]

Notes:

We are uncertain about how this would look in Grunt -- maybe an array of src objects with flags on them?

http://gruntjs.com/configuring-tasks#files-array-format

{
  spritesmith: {
    all: {
      files: [
        {type: '1x', src: 'path/to/sprites/*@1x.png', dest: 'path/to/spritesheet@1x.png'}
        {type: '2x', src: 'path/to/sprites/*@2x.png', dest: 'path/to/spritesheet@1x.png'}
      ],
      options: {
        // Options go here
      }
    }
  }
}

Whatever the choice is, it must be compatible with grunt-contrib-watch

Attribution:

The intent at keeping things elegant yet robust was inspired by:

https://github.com/glebmachine/postcss-easysprites

adgvan commented 7 years ago

This is still low on our priorities list but we thought of a nice format for Gulp if we do implement this

Great! Can't wait to implement it in the existent gulp front-end workflow. Would be also very grateful if you include besides x3, support for x4 as well, herewith preserving the ability to have in output separate sprite.png files for every pixel density (in order not to oblige users on corresponding pixel ratio to load images from another ratio within the sprite image).

Thanks!

fantasy525 commented 7 years ago

in windows:there is some errors: cmd log: C:\GTK\bin\libfreetype-6.dll E:\PHPStudy\WWW\H5Mobile\iosapp\spritesTest\node_modules\canvas\build\binding.s ln : error MSB3411: 未能加载 Visual C++ 组件“VCBuild.exe”。如果未安装该组件, 请执行下列操作之一: 1) 安装 M icrosoft Windows SDK for Windows Server 2008 和 .NET Framework 3.5;或 2) 安装 M icro soft Visual Studio 2008。 gyp ERR! build error gyp ERR! stack Error: C:\Windows\Microsoft.NET\Framework\v3.5\msbuild.exe fail ed with exit code: 1 gyp ERR! stack at ChildProcess.onExit (D:\node\node_modules\npm\node_modules \node-gyp\lib\build.js:276:23) gyp ERR! stack at emitTwo (events.js:106:13) gyp ERR! stack at ChildProcess.emit (events.js:191:7) gyp ERR! stack at Process.ChildProcess._handle.onexit (internal/child_proces s.js:204:12) gyp ERR! System Windows_NT 6.1.7600 gyp ERR! command "D:\node\node.exe" "D:\node\node_modules\npm\node_modules \node-gyp\bin\node-gyp.js" "rebuild" gyp ERR! cwd E:\PHPStudy\WWW\H5Mobile\iosapp\spritesTest\node_modules\canvas gyp ERR! node -v v6.2.0 gyp ERR! node-gyp -v v3.3.1 gyp ERR! not ok npm WARN install:canvas@1.1.6 canvas@1.1.6 install: node-gyp rebuild npm WARN install:canvas@1.1.6 Exit status 1

twolfson commented 7 years ago

@fantasy525 That is unrelated to this issue. It's being caused by missing dependencies for node-canvas. Please see its documentation:

https://github.com/Automattic/node-canvas/wiki/Installation---Windows

If you're still having issues, please open another issue

tsteuwer-accesso commented 6 years ago

Not sure if this is still active, but we should really be getting away from image files. Instead, we should use font-files or some form of vector/svg that will autoscale and is future-proof.