diff --git a/.gitignore b/.gitignore index b461350..dfa9169 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ +node_modules/* screenshots/* .DS_Store diff --git a/README.md b/README.md index c57852b..c722e35 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Responsive Mockups via PhantomJS 2.0 -Small PhantomJS based script that allows you to automatically create mockup graphics, providing only a URL. +Small Nightmare.js/Electron based script that allows you to automatically create mockup graphics, providing only a URL. ![mockup 1](https://i.imgur.com/IUEHBcI.png) ![mockup 2](https://i.imgur.com/kolyLwL.png) @@ -8,28 +8,12 @@ Small PhantomJS based script that allows you to automatically create mockup grap ## How To +* Make sure you have a current node version installed * Clone this repo +* `npm install` all dependencies * Edit `example.js` to choose mockup template and target url -* Call `phantomjs example.js` (for an example with a single URL) -* Or call `phantomjs example-mobile-multiple.js` (for an example with multiple URLs) - -## Requirements - -The only external requirement is PhantomJS in version >= 2.0.0. - -`brew install phantomjs` - -Double check the version of PhantomJS - -`phantomjs -v` - -## Known issues with SSL - -PhantomJS seems to have problems with some SSL certficates. In case you get errors like `Unable to load the address for layer [...]` - you can get a more verbose output by running PhantomJS in debug mode, e.g. `phantomjs --debug=true example.js`. - -If the output says something like `SSL Error: "The issuer certificate of a locally looked up certificate could not be found"`, but you still want to take screenshots via HTTPS, you can deactivate SSL checks using `phantomjs --ignore-ssl-errors=true example.js`. - -Please be aware that this disables SSL certificate validations, so don't pass credentials or other data to the script that would require a verified secure connection. +* Call `node example.js` (for an example with a single URL) +* Or call `node example-mobile-multiple.js` (for an example with multiple URLs) ## Credits for provided mockup templates diff --git a/index.js b/index.js index 33ecbdb..a7cdb0a 100644 --- a/index.js +++ b/index.js @@ -1,61 +1,43 @@ -var webpage = require('webpage'); - -function takeScreenshot(url, screenshotsDir, layer, done) { - var page = webpage.create(); - - var output = screenshotsDir + '/' + layer.type + '.png'; - - page.viewportSize = { width: layer.viewport.width, height: layer.viewport.height }; - page.clipRect = { top: 0, left: 0, width: page.viewportSize.width, height: page.viewportSize.height }; - - console.info('Now loading: layer ' + layer.type + '...'); - - page.open(url, function(status) { - if (status !== 'success') console.error('Unable to load the address for layer ' + layer.type); - - window.setTimeout(function() { +var Nightmare = require('nightmare'); +var mkdirp = require('mkdirp'); + +function renderInNightmare(options, url, output, clipRect, done) { + return Nightmare(options) + .goto(url) + .wait(500) + .evaluate(function () { + document.documentElement.style.overflow = 'hidden'; // hide scrollbars + }) + .wait(100) + .screenshot(output, clipRect) + .end(function(err, result) { + if (err) throw('Unable to render ' + url + ' to ' + output); console.info('Generated: ' + output); - page.render(output); done(); - }, 1000); - - }); + }); } -function renderMockup(path, output, metadata) { - var page = webpage.create(); - - page.viewportSize = { - width: metadata.mockup.width, - height: metadata.mockup.height - }; - - page.clipRect = { - top: 0, - left: 0, - width: metadata.mockup.width, - height: metadata.mockup.height - }; - - page.open(path, function(status) { - if (status !== 'success') console.error('Unable to load mockup!'); +function takeScreenshot(url, screenshotsDir, layer, done) { + var output = screenshotsDir + '/' + layer.type + '.png'; + var options = { width: layer.viewport.width, height: layer.viewport.height, overlayScrollbars: true }; + var clipRect = { x: 0, y: 0, width: options.width, height: options.height }; - page.onConsoleMessage = function(msg) { - console.warn('[render] ' + msg); - }; + console.info('Now loading: layer ' + layer.type + '...'); + renderInNightmare(options, url, output, clipRect, done); +} - window.setTimeout(function() { - console.info('Saved responsive mockup to: ' + output); - page.render(output); - phantom.exit(); - }, 500); +function renderMockup(path, output, metadata, done) { + var url = 'file:///' + path; + var options = { width: metadata.mockup.width, height: metadata.mockup.height }; + var clipRect = { width: metadata.mockup.width, height: metadata.mockup.height, x: 0, y: 0 }; - }); + console.info('Now loading: mockup...'); + renderInNightmare(options, url, output, clipRect, done); } function create(options) { ['output', 'template', 'url'].forEach(function(requiredOption) { - if (!options[requiredOption]) throw(requiredOption + ' option missing'); + if (!options[requiredOption]) throw(requiredOption + ' option missing'); }); var output = options.output; @@ -63,17 +45,20 @@ function create(options) { var url = options.url; var metadata = require('./templates/' + template + '/metadata'); - var mockupPath = './templates/' + template + '/render.html'; - var screenshotsDir = './screenshots/' + template; + var mockupPath = __dirname + '/templates/' + template + '/render.html'; + var screenshotsDir = __dirname + '/screenshots/' + template; var tasks = []; + // assure the screenshots directory exists + mkdirp.sync(screenshotsDir); + function next() { var task = tasks.shift(); if (task) { task(); } else { - phantom.exit(); + console.info("DONE!"); } } @@ -87,7 +72,7 @@ function create(options) { tasks.push(function() { takeScreenshot(newUrl, screenshotsDir, layer, next); }); }); - tasks.push(function() { renderMockup(mockupPath, output, metadata); }); + tasks.push(function() { renderMockup(mockupPath, output, metadata, next); }); next(); } diff --git a/package.json b/package.json index 8bc04f8..31a37e4 100644 --- a/package.json +++ b/package.json @@ -1,8 +1,12 @@ { "name": "responsive_mockups", - "version": "0.0.1", + "version": "1.0.0", "description": "Takes screenshots of a webpage in different resolutions and automatically applies it to mockups.", "main": "index.js", "author": "Christian Bäuerlein", - "license": "MIT" + "license": "MIT", + "dependencies": { + "mkdirp": "^0.5.1", + "nightmare": "^2.1.1" + } }