2createStudio / postcss-sprites

Generate sprites from stylesheets.
MIT License
413 stars 50 forks source link

How to config the background-image? #84

Closed yutucc closed 7 years ago

yutucc commented 7 years ago

hardcoded:

.test-sprite {
  background-image: url(../../build/images/sprite.png);
  background-position: -60px 0px;
  background-size: 89px 86px;}

And I want to custom the background-image, but I don't know how to do.

vvasilev- commented 7 years ago

Hey @NicholasNC,

Can you paste some expected output so I can help you?

vvasilev- commented 7 years ago

Also, you can check onUpdateRule hook.

yutucc commented 7 years ago

Thank you for your enthusiastic help.

output:

.test-sprite {
  background-image: url(../../build/images/sprite.png); /* this is not my want */
  background-position: -60px 0px;
  background-size: 89px 86px;
  width: 29px;
  height: 28px;
  background-image: url(../images/sprite.png); /*this is my want*/
}

I use the hooks to realize it , but I hope have a simple method.

I don't know if this is a unreasonable request.

gulpfile.js

var gulp = require('gulp');
var plugins = require('gulp-load-plugins')();
var postcss = require('postcss');
var gulpPostcss = require('gulp-postcss');
var sprites = require('postcss-sprites');
var updateRule = require('postcss-sprites/lib/core').updateRule;
var autoprefixer = require('autoprefixer');
var sass = require('gulp-sass');

var processors = [
    // autoprefixer,
    sprites({
         spritePath: './build/images', // 指定生成的雪碧图的存放路径
         filterBy: function(image) {
            var reg = /\/\bslice\b\/\w*\.\w*/; // 匹配图片url中有*/slice/*.*的图片(即雪碧图的存放路径)

            if (!reg.test(image.url)) {
                return Promise.reject();
            }

            return Promise.resolve();
        },
         hooks: {
            onUpdateRule: function(rule, token, image) {
                // Use built-in logic for background-image & background-position
                updateRule(rule, token, image);

                ['width', 'height'].forEach(function(prop) {
                    rule.insertAfter(rule.last, postcss.decl({
                        prop: prop,
                        value: image.coords[prop] + 'px'
                    }));
                });

                // 实在迫不得已才用这种方法
                rule.insertAfter(rule.last, postcss.decl({
                    prop: 'background-image',
                    value: 'url(../images/sprite.png)'
                }));
            }
        },
    })
];

gulp.task('css', function () {
  return gulp.src('./src/sass/application.scss')
    .pipe(sass().on('error', sass.logError))
    .pipe(gulpPostcss(processors))
    .pipe(gulp.dest('./build/styles'));
});

gulp.task('default', ['css']);
vvasilev- commented 7 years ago

Setting the stylesheetPath option should do the trick, but if doesn't help use the hooks as an escape hatch.

yutucc commented 7 years ago

Thank you very much.

I got it.

Set stylesheetPath: './build/styles',. It can realize what I want. (The compiled css is in ./build/styles, and the sprite.png is in ./build/images)

Now my gulpfile.js:

var gulp = require('gulp');
var plugins = require('gulp-load-plugins')();
var postcss = require('postcss');
var gulpPostcss = require('gulp-postcss');
var sprites = require('postcss-sprites');
var updateRule = require('postcss-sprites/lib/core').updateRule;
var autoprefixer = require('autoprefixer');
var sass = require('gulp-sass');

var processors = [
    sprites({
        stylesheetPath: './build/styles', // 告诉插件,生成的css文件存放在哪里,让插件可以正确设定css文件中的background-image
        spritePath: './build/images', // 指定生成的雪碧图的存放路径
        filterBy: function(image) {
            var reg = /\/\bslice\b\/\w*\.\w*/; // 匹配图片url中有*/slice/*.*的图片(即雪碧图的存放路径)

            if (!reg.test(image.url)) {
                return Promise.reject();
            }

            return Promise.resolve();
        },
        hooks: {
            onUpdateRule: function(rule, token, image) {
                // Use built-in logic for background-image & background-position
                updateRule(rule, token, image);

                ['width', 'height'].forEach(function(prop) {
                    rule.insertAfter(rule.last, postcss.decl({
                        prop: prop,
                        value: image.coords[prop] + 'px'
                    }));
                });
            }
        },
    })
];

gulp.task('css', function () {
  return gulp.src('./src/sass/application.scss')
    .pipe(sass().on('error', sass.logError))
    .pipe(gulpPostcss(processors))
    .pipe(gulp.dest('./build/styles'));
});

gulp.task('default', ['css']);
hycript commented 7 years ago

@NicholasNC have you try multiple style file which images render to the same target sprites file ?

yutucc commented 7 years ago

@ND-linwei sorry, I haven't try it.