├── .editorconfig ├── .gitattributes ├── .gitignore ├── .jshintrc ├── .travis.yml ├── demo.gif ├── index.js ├── license ├── package.json ├── public └── index.html ├── readme.md └── test.js /.editorconfig: -------------------------------------------------------------------------------- 1 | # editorconfig.org 2 | root = true 3 | 4 | [*] 5 | indent_style = space 6 | indent_size = 2 7 | end_of_line = lf 8 | charset = utf-8 9 | trim_trailing_whitespace = true 10 | insert_final_newline = true 11 | 12 | [*.md] 13 | trim_trailing_whitespace = false 14 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | screens 3 | -------------------------------------------------------------------------------- /.jshintrc: -------------------------------------------------------------------------------- 1 | { 2 | "node": true, 3 | "esnext": true, 4 | "bitwise": true, 5 | "camelcase": true, 6 | "curly": true, 7 | "eqeqeq": true, 8 | "immed": true, 9 | "indent": 2, 10 | "latedef": true, 11 | "newcap": true, 12 | "noarg": true, 13 | "quotmark": "single", 14 | "regexp": true, 15 | "undef": true, 16 | "unused": true, 17 | "strict": true, 18 | "trailing": true, 19 | "smarttabs": true 20 | } 21 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - '0.10' 4 | - '0.12' 5 | - 'iojs-v1.0.4' 6 | notifications: 7 | email: false 8 | -------------------------------------------------------------------------------- /demo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/danielhusar/gulp-local-screenshots/f47dee538b46f4e03d5875c12e1e93b30dc4069c/demo.gif -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | var gutil = require('gulp-util'); 3 | var through = require('through2'); 4 | var phantom = require('phantom'); 5 | var http = require('http'); 6 | var st = require('st'); 7 | 8 | // Core screenshot function using phamtonJS 9 | var browser = function (file, opts, cb) { 10 | var width = opts.width.slice(0); 11 | var filename = file.replace(opts.path, ''); 12 | var url = opts.protocol + '://' + opts.host + ':' + opts.port + '/' + filename; 13 | 14 | phantom.create(function (ph) { 15 | ph.createPage(function (page) { 16 | page.set('zoomFactor', opts.zoom); 17 | var screenshot = function (w) { 18 | if (!w) { 19 | ph.exit(); 20 | setTimeout(cb, opts.timeout); 21 | width = opts.width * opts.zoom; 22 | return; 23 | } 24 | page.set('viewportSize', { 25 | width: w * opts.zoom, 26 | height: opts.height * opts.zoom 27 | }); 28 | 29 | page.open(url, function() { 30 | var dest; 31 | if ( opts.suffix ){ 32 | dest = filename.replace('.html', '') + '-' + opts.suffix + '.' + opts.type; 33 | }else if ( opts.zoom > 1 ) { 34 | dest = filename.replace('.html', '') + '-' + w + '-zoom-' + opts.zoom + '.' + opts.type; 35 | } else { 36 | dest = filename.replace('.html', '') + '-' + w + '.' + opts.type; 37 | } 38 | 39 | // Background problem under self-host server 40 | page.evaluate(function () { 41 | var style = document.createElement('style'); 42 | var text = document.createTextNode('body { background: #fff }'); 43 | style.setAttribute('type', 'text/css'); 44 | style.appendChild(text); 45 | document.head.insertBefore(style, document.head.firstChild); 46 | }); 47 | page.render(opts.folder + '/' + dest, function () { 48 | gutil.log('gulp-local-screenshots:', gutil.colors.green('✔ ') + dest); 49 | screenshot(width.pop()); 50 | }); 51 | }); 52 | }; 53 | screenshot(width.pop()); 54 | }); 55 | }); 56 | }; 57 | 58 | module.exports = function (options) { 59 | var opts = { 60 | local: {} 61 | }; 62 | var server; 63 | options = options ? options : {}; 64 | 65 | //defaults 66 | opts.path = options.path || 'public/'; 67 | opts.port = options.port || '8080'; 68 | opts.width = options.width || ['1024']; 69 | opts.height = options.height || '10'; 70 | opts.zoom = options.zoom || '1'; 71 | opts.type = options.type || 'jpg'; 72 | opts.folder = options.folder || 'screens'; 73 | opts.timeout = options.timeout || 200; 74 | opts.protocol = options.protocol || 'http'; 75 | opts.host = options.host || 'localhost'; 76 | opts.suffix = options.suffix || false; 77 | opts.server = typeof options.server === 'undefined' ? true : options.server; 78 | 79 | //start local webserver 80 | if (opts.server) { 81 | server = http.createServer(st({ path: opts.path })).listen(opts.port); 82 | } 83 | 84 | return through.obj(function (file, enc, cb) { 85 | if (file.isNull()) { 86 | this.push(file); 87 | return cb(); 88 | } 89 | 90 | if (file.isStream()) { 91 | this.emit('error', new gutil.PluginError('gulp-local-screenshots', 'Streaming not supported')); 92 | return cb(); 93 | } 94 | 95 | this.push(file); 96 | browser(file.relative, opts, cb); 97 | 98 | }, function (cb) { 99 | if (opts.server) { 100 | server.close(); 101 | } 102 | cb(); 103 | }); 104 | }; 105 | -------------------------------------------------------------------------------- /license: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) Daniel Husar 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "gulp-local-screenshots", 3 | "version": "2.2.0", 4 | "description": "Make the screenshots of your static html files using phantomjs.", 5 | "license": "MIT", 6 | "repository": "danielhusar/gulp-local-screenshots", 7 | "author": { 8 | "name": "Daniel Husar", 9 | "email": "dano.husar@gmail.com", 10 | "url": "https://github.com/danielhusar" 11 | }, 12 | "engines": { 13 | "node": ">=0.10.0" 14 | }, 15 | "scripts": { 16 | "test": "mocha -R spec --timeout 10000" 17 | }, 18 | "files": [ 19 | "index.js" 20 | ], 21 | "keywords": [ 22 | "gulpplugin", 23 | "phantom", 24 | "screenshots", 25 | "testing" 26 | ], 27 | "dependencies": { 28 | "gulp-util": "^3.0.4", 29 | "through2": "^0.6.3", 30 | "phantom": "^0.7.2", 31 | "st": "^0.5.3" 32 | }, 33 | "devDependencies": { 34 | "mocha": "*", 35 | "image-size": "^0.3.5" 36 | }, 37 | "readmeFilename": "readme.md" 38 | } 39 | -------------------------------------------------------------------------------- /public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Example 5 | 6 | 7 | 28 |
29 |

An example title

30 |

Paragraph 1

31 |

Paragraph 2

32 |
33 | 34 | 35 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # [gulp](http://gulpjs.com)-local-screenshots [![Build Status](https://secure.travis-ci.org/danielhusar/gulp-local-screenshots.svg?branch=master)](http://travis-ci.org/danielhusar/gulp-local-screenshots) 2 | 3 | This plugin will make the screenshots of your static html files using phantomjs. 4 | (make sure you have phantomjs installed on your machine) 5 | 6 | 7 | ## Install 8 | 9 | ``` 10 | npm install --save-dev gulp-local-screenshots 11 | ``` 12 | 13 | ## Example 14 | 15 | ```javascript 16 | var gulp = require('gulp'); 17 | var localScreenshots = require('gulp-local-screenshots'); 18 | 19 | gulp.task('screens', function () { 20 | gulp.src('./public/*.html') 21 | .pipe(localScreenshots({ 22 | width: ['1600', '1000', '480', '320'] 23 | })) 24 | .pipe(gulp.dest('./public/')); 25 | }); 26 | ``` 27 | 28 | ## Options 29 | 30 | 31 | #### path 32 | 33 | Type: `String` 34 | Default: 'public/' 35 | 36 | Path from which the static files are served (Trailing slash at the end is required.) 37 | 38 | 39 | #### port 40 | 41 | Type: `Number` 42 | Default: '8080' 43 | 44 | Port for the static web server 45 | 46 | #### width 47 | 48 | Type: `Array` 49 | Default: ['1024'] 50 | 51 | Array of page widths to make screenshots (for the responsive website) 52 | 53 | #### height 54 | 55 | Type: `String` 56 | Default: '10' 57 | 58 | Height of the page, if the actual page heights is more than that it, iamge will have actual page height. 59 | (specifing height is good for testing) 60 | 61 | #### type 62 | 63 | Type: `String` 64 | Default: 'jpg' 65 | 66 | Output image extension 67 | 68 | #### folder 69 | 70 | Type: `String` 71 | Default: 'screens' 72 | 73 | Folder where to put images 74 | 75 | #### timeout 76 | 77 | Type: `Number` 78 | Default: '200' 79 | 80 | Timeout between files, in most cases you dont need to change that 81 | 82 | #### protocol 83 | 84 | Type: `String` 85 | Default: 'http' 86 | 87 | Protocol that will be used in phantom.js 88 | 89 | #### host 90 | 91 | Type: `String` 92 | Default: 'localhost' 93 | 94 | Host that will be used in phantom.js 95 | 96 | #### server 97 | 98 | Type: `Boolean` 99 | Default: 'true' 100 | 101 | If plugin should start local web server (otherwise you should start your web server by yourself, or specify host option for some remote server) 102 | 103 | #### zoom 104 | 105 | Type: `Number` 106 | Default: '1' 107 | 108 | Zoom level to set the phantom.js browser viewport. Can be used to take 2x, 3x, etc. screen shots. Widths, heights and output file name remain as specified, but the resulting image will be * 'zoom' pixels. E.g. specify 320 width, zoom level 2: output file will be 320px of page content, but at twice the resolution (640px wide). 109 | 110 | #### suffix 111 | 112 | Type: `String` 113 | Default: 'false' 114 | 115 | A custom suffix for output file name, you can use -thumb, -shot, etc. And the output file will named source-file-name + custom-suffix. If no suffix set, will use default suffix. 116 | 117 | ## Demo 118 | 119 | ![Demo](demo.gif) 120 | 121 | ## License 122 | 123 | MIT © [Daniel Husar](https://github.com/danielhusar) 124 | -------------------------------------------------------------------------------- /test.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var fs = require('fs'); 4 | var assert = require('assert'); 5 | var gutil = require('gulp-util'); 6 | var sizeOf = require('image-size'); 7 | var localScreenshots = require('./index'); 8 | var dimensions; 9 | 10 | it('It should generate properly screenshot', function (cb) { 11 | var stream = localScreenshots({height: 500}); 12 | 13 | stream.on('data', function(){ 14 | }); 15 | 16 | stream.on('end', function(){ 17 | console.log('\r\n'); 18 | dimensions = sizeOf('screens/index-1024.jpg'); 19 | assert.equal(dimensions.width, 1024); 20 | assert.equal(dimensions.height, 500); 21 | fs.unlinkSync('screens/index-1024.jpg'); 22 | fs.rmdirSync('screens'); 23 | cb(); 24 | }); 25 | 26 | stream.write(new gutil.File({ 27 | base: __dirname, 28 | path: __dirname + '/public/index.html', 29 | contents: new Buffer('unicorns') 30 | })); 31 | 32 | stream.end(); 33 | }); 34 | --------------------------------------------------------------------------------