diff --git a/inputs/back.svg b/inputs/back.svg deleted file mode 100755 index bed89f9..0000000 --- a/inputs/back.svg +++ /dev/null @@ -1,5 +0,0 @@ - - - diff --git a/inputs/bottom.svg b/inputs/bottom.svg deleted file mode 100755 index fda87d1..0000000 --- a/inputs/bottom.svg +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - diff --git a/inputs/front.svg b/inputs/front.svg deleted file mode 100755 index e2a3cbe..0000000 --- a/inputs/front.svg +++ /dev/null @@ -1,5 +0,0 @@ - - - diff --git a/inputs/left.svg b/inputs/left.svg deleted file mode 100755 index d3a94ad..0000000 --- a/inputs/left.svg +++ /dev/null @@ -1,5 +0,0 @@ - - - diff --git a/inputs/right.svg b/inputs/right.svg deleted file mode 100755 index 9810390..0000000 --- a/inputs/right.svg +++ /dev/null @@ -1,5 +0,0 @@ - - - diff --git a/inputs/top.svg b/inputs/top.svg deleted file mode 100755 index 7472516..0000000 --- a/inputs/top.svg +++ /dev/null @@ -1,5 +0,0 @@ - - - diff --git a/package.json b/package.json index 9249ff3..e37558f 100755 --- a/package.json +++ b/package.json @@ -1,20 +1,21 @@ { - "name": "gen-svg-cube", - "version": "0.0.5", - "description": "Render and download svg cubes using webdriver", - "main": "render.js", + "name": "svg2cube", + "version": "0.0.6", + "description": "Fold a svg panel into a cube and take images at isometric angles", + "main": "svg2cube.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1", - "start": "node render.js svgCube.html", - "debug": "NODE_DEBUG=request,webdriver,chromedriver DEBUG=true node render.js svgCube.html" + "start": "node svg2cube.js inputs/panels.svg", + "debug": "NODE_DEBUG=request,webdriver,chromedriver DEBUG=true node svg2cube.js inputs/panels.svg" }, "repository": "git@gitlab.com:wassname/svg2Cube.git", "author": "wassname@wassname.org", "private": true, - "license": "ISC", + "license": "MIT", "dependencies": { "chromedriver": "^2.20.0", "fs": "0.0.2", + "gm": "^1.21.1", "jquery": "^2.2.0", "path": "^0.12.7", "system": "^1.0.4", diff --git a/readme.md b/readme.md index cb430b8..d3e721a 100755 --- a/readme.md +++ b/readme.md @@ -1,40 +1,39 @@ gen-svg-cube -This package makes isometric cubes. It takes in svg's and renders them from a given side -at a given resolution. +This package makes isometric cubes. It takes in svg's and renders them from a given side at a given resolution. # Quickstart - TODO # Screenshots ## Input: - ## Output: - ## GUI # Installation - `npm i` # Usage +From the command line: -`npm start` +```sh +nde svg2cube-cli.js inputs/panels.svg +``` -# TODO +Or in node: +```js +var svg2cube = require('./svg2cube.js'); +svg2cube('inputs/panels.svg',{rotateY: 45, size:256}); +``` # Author - wassname.org - # License - -ISC +MIT diff --git a/render.js b/render.js deleted file mode 100755 index 510bf67..0000000 --- a/render.js +++ /dev/null @@ -1,128 +0,0 @@ -'use strict'; -/** - * Node js script to render and download svg cubes using webdriver - */ - -var webdriverio = require('webdriverio'); -var path = require('path'); -var globby = require('globby'); -var gm = require('gm'); - -var SvgCube = require('./SvgCube.js'); -// var $ = require('jquery'); - -var chromedriver = require('chromedriver'); -var childProcess = require('child_process'); - -// get inputs -if (process.argv.length < 3 || process.argv.length > 4) { - console.log('Command: ', process.argv); - console.log('Usage: node rasterize.js svgCube.html panel.svg'); - return; -} else { - var input = process.argv[2]; - var outfile = process.argv[3]; - console.log('input:', input); -} - -// see if we are in debug mode -var debug = process.env.DEBUG || false; - -// start server chromedriver for selenium -var binPath = chromedriver.path; -var childArgs = ['--url-base=/wd/hub', '--whitelisted-ips="*"']; -if (debug){childArgs.push('--verbose');} - -var chromeInstance = childProcess.execFile(binPath, childArgs, function (err, stdout, stderr) { - if (err) { - console.error('[webdriver]', err, stdout, stderr); - } else { - console.log('[webdriver]', stdout, stderr); - } -}); - -// define client -var options = { - host: "localhost", - port: 9515, - desiredCapabilities: { - browserName: 'chrome', - chromeOptions: { - binary: '/usr/bin/chromium' - } - } -}; -var client = webdriverio.remote(options); - - -var bounds; - -// get input file and components -var file = input; -var address = path.join(process.cwd(), file); -var ext = path.extname(file); -var url = 'file://' + path.join(process.cwd(), file); -var outfile = outfile? outfile:address.replace(ext, '.png'); - -console.info('Converting ', file, url, '->', outfile); - -// start client -client.init() - .url(url) - // inject code into page - .execute(function () { - var cube1, text; - cube1 = new SvgCube.SvgCube({ - rotateX: 45, - svgPanel: 'inputs/panels.svg', - clipCircle: false, - stroke: { - 'stroke': 'black', // stroke color for outline - 'stroke-width': 0, // outline width - }, - size: 444, - }); - text = cube1.getBounds(); - - // Get dimensions of each pane and make it accesable to webdriver - $('#dimensions').attr('value', 1); - $('#dimensions').text(JSON.stringify(text)); - }) - .waitForVisible('.front', 5000) - // get image boundries from html - .execute(function () { - return $('#dimensions').text(); - }) - .then(text => { - console.info('[svg2Cube] dimensions', text); - try { - bounds = JSON.parse(text.value); - } catch (e) { - console.warn(text); - } - }) - // take a screen shot crop using graphics magic - .screenshot() - .then(res => { - var imgBuffer = new Buffer(res.value, 'base64'); - - /** Crop it using graphicks magic */ - gm(imgBuffer) - .crop( - bounds.right.max - bounds.left.min, - bounds.bottom.max - bounds.top.min, - bounds.left.min, - bounds.top.min - ) - .write(outfile, function (err) { - if (!err) {console.log('done');} - }); - - }) - .end() - .then(function(){ - // close the browser server - if (chromeInstance !== null){ - chromeInstance.kill(); - } - }); diff --git a/svg2cube-cli.js b/svg2cube-cli.js new file mode 100755 index 0000000..6e3e7ce --- /dev/null +++ b/svg2cube-cli.js @@ -0,0 +1,13 @@ +/** command line interface for svg2cube. Usage `node svg2cube panel.svg` **/ +var svg2cube = require('./svg2cube.js'); + +if (process.argv.length < 3 || process.argv.length > 4) { + console.log('Command: ', process.argv); + console.log('Usage: node rasterize.js panel.svg'); + return; +} else { + var input = process.argv[2]; + var outfile = process.argv[3]; + console.log('input:', input, 'output:', outfile); +} +svg2cube(input,outfile); diff --git a/svg2cube-frontend.js b/svg2cube-frontend.js new file mode 100755 index 0000000..e0e48a6 --- /dev/null +++ b/svg2cube-frontend.js @@ -0,0 +1,302 @@ +'use strict'; +/** + * Frontend js file to generate an cube of svg's + */ + +(function (exports) { + exports.SvgCube = function (svgPanel, options) { + + // Inputs and options + var defaultOptions = { + rotateX: 30, // isometric angle + rotateY: 45, + rotateZ: 0, + perspective: 0, // doesn't do anything usefull + scaleX: 1.00, + scaleY: 1.00, // flatten + scaleZ: 1.00, // push face + + size: 400, + verbose: false, + // outline + drawOutline: false, + drawShading: false, + borderRadius: 0, + stroke: { + "stroke": 'black', // stroke color for outline + "stroke-width": 0, // outline width + }, + // cube + topRot: 0, // rotation of top image in degrees + topShad: 0, // shading for top + leftRot: 0, + leftShad: 0.0, + rightRot: 0, + rightShad: 0.0, + backRot: 0, + backShad: 0.0, + bottomRot: 0, + bottomShad: 0.0, + frontRot: 0, + frontShad: 0.0, + }; + + // add defaults, 2 levels deep + options = options || {}; + for (var opt in defaultOptions) { + if (defaultOptions.hasOwnProperty(opt) && !options.hasOwnProperty(opt)) { + options[opt] = defaultOptions[opt]; + } + for (var opt2 in defaultOptions[opt]) { + if (defaultOptions[opt].hasOwnProperty(opt2) && !options[opt].hasOwnProperty(opt2)) { + options[opt][opt2] = defaultOptions[opt][opt2]; + } + } + } + options.svgPanel = svgPanel; + this.options = options; + console.log(svgPanel); + + + // legacy compat + if (options.flatten !== undefined) { + options.scaleY = 1 - options.flatten; + } + if (options.angle !== undefined) { + options.rotateX = options.angle; + } + + if (!options.drawOutline) { + options.stroke['stroke-width'] = 0; + } + + this.init(); + + }; + + exports.SvgCube.prototype.init = function () { + + this.rotateX = this.options.rotateX; + + this.w = this.options.size; // input image width + this.h = this.options.size; + this.f = 1 - this.options.scaleY; + + this.rot = this.rotateX * Math.PI / 180; + this.padding = this.options.padding || 0; // pading fraction + + + this.cw = this.w; // we will keep same width but change height + this.ch = this.h * 5; //(this.h + Math.sqrt(2)*this.h * Math.tan(this.rot)) - this.h / 2 * (this.f); //canvas height full + + // create SVG element + var o = this.options; + + /** Write sides if they have not already been written **/ + if ($('body>.cube').length === 0) { + var cube = $('
'); + + var imageFront = $('' + + '' + + '' + + ' ' + + '' + + ''); + cube.append(imageFront); + + var imageL = $('' + + '' + + '' + + ' ' + + '' + + ''); + cube.append(imageL); + + var imageRight = $('' + + '' + + ' ' + + ' ' + + ' ' + + ''); + cube.append(imageRight); + + var imageTop = $('' + + '' + + '' + + ' ' + + '' + + ''); + cube.append(imageTop); + + var imageBack = $('' + + '' + + '' + + ' ' + + '' + + ''); + cube.append(imageBack); + + var imageBottom = $('' + + '' + + '' + + ' ' + + '' + + ''); + cube.append(imageBottom); + + $('body').append(cube); + + } + // Now we generate some css to put everything in good positions + var transitions = 0.1; + var styleStr = '' + + ''; + $('head>#projection').remove(); + $('head').append($(styleStr)); + + }; + + /** + * Get the bounds of the images for a screenshot + * uses $.position to get min,max of each side of the image + * @return {object} object.dimension.[min|max] e.g. object.left.min + */ + exports.SvgCube.prototype.getBounds = function () { + var bounds = {}; + $('.cube>b').each(function () { + var pos = this.getBoundingClientRect(); + for (var dim in pos) { + if (dim in pos) { + + // init + if (bounds[dim] === undefined) { + bounds[dim] = { + 'max': pos[dim], + 'min': pos[dim] + }; + } else { + // get max and min + bounds[dim].max = Math.max(bounds[dim].max, pos[dim]); + bounds[dim].min = Math.min(bounds[dim].min, pos[dim]); + } + } + } + }); + return bounds; + }; + + exports.SvgCube.prototype.update = function () { + this.init(); + console.log(this.getBounds()); + }; +})(typeof exports === 'undefined' ? this['SvgCube'] = {} : exports); diff --git a/svg2cube.js b/svg2cube.js new file mode 100755 index 0000000..cff8c92 --- /dev/null +++ b/svg2cube.js @@ -0,0 +1,131 @@ +'use strict'; +/** + * Node js script to render and download svg cubes using webdriver + */ + +var webdriverio = require('webdriverio'); +var path = require('path'); +var gm = require('gm'); + +var chromedriver = require('chromedriver'); +var childProcess = require('child_process'); + +var SvgCube = require('./svgcube.js'); + + +var debug = process.env.DEBUG || false; +const converterFileName = 'file://'+path.resolve(__dirname, "./svgCube.html"); +console.log(converterFileName); +const binPath = chromedriver.path; +var childArgs = ['--url-base=/wd/hub', '--whitelisted-ips="*"']; +if (debug) { + childArgs.push('--verbose'); +} + +/** + * Convert an svg panel with 6 sides into a image of the folded cube. The out + * images are png. + * @param {string} svgPanel file name of svgpanel + * @param {string} outfile output filename + * @param {object} options See svgCube.js for full options + * @return {undefined} + */ +module.exports = function (svgPanel, outfile, options) { + + // start server chromedriver for selenium + var chromeInstance = childProcess.execFile(binPath, childArgs, function (err, stdout, stderr) { + if (err) { + console.error('[webdriver]', err, stdout, stderr); + } else { + console.log('[webdriver]', stdout, stderr); + } + }); + + // define client + var webdriverOptions = { + host: "localhost", + port: 9515, + desiredCapabilities: { + browserName: 'phantonjs', + } + }; + var client = webdriverio.remote(webdriverOptions); + + var bounds; + + // get input file and components + var address = path.join(process.cwd(), svgPanel); + var ext = path.extname(svgPanel); + outfile = outfile ? outfile : address.replace(ext, '.png'); + svgPanel = 'file://'+path.resolve(__dirname,svgPanel); + console.info('Converting ', svgPanel, '->', outfile); + + options = options ? options: {}; + + + // start client + client.init() + .windowHandleMaximize() + .getViewportSize() + .then(function(size) { + // set a reasonable size based on viewport size + var minSize = Math.min(size.width, size.height)/2; + if (!options.size){ + options.size = minSize; + } else if (options.size && options.size > minSize){ + console.warn('Pane size '+options.size+' to big for viewport '+size+', setting to '+minSize); + options.size = minSize; + } + }) + .url(converterFileName) + // inject code into page + .execute(function (svgPanel,options) { + var cube1 = new SvgCube.SvgCube(svgPanel, options); + return cube1.getBounds(); + },svgPanel,options) + .then(text => { + // rendered dimensions are returned + console.info('[svg2Cube] dimensions', text); + bounds = text.value; + }) + // take a screen shot crop using graphics magic + .screenshot() + .then(res => { + var imgBuffer = new Buffer(res.value, 'base64'); + + /** Crop it using GraphicsMagick */ + gm(imgBuffer) + .crop( + bounds.right.max - bounds.left.min, + bounds.bottom.max - bounds.top.min, + bounds.left.min, + bounds.top.min + ) + .write(outfile, function (err) { + if (!err) { + console.log('done'); + } + }); + + }) + .end() + .then(function () { + // close the browser server + if (chromeInstance !== null) { + chromeInstance.kill(); + } + }); +}; + + +// get inputs +if (process.argv.length < 3 || process.argv.length > 4) { + console.log('Command: ', process.argv); + console.log('Usage: node rasterize.js panel.svg'); + return; +} else { + var input = process.argv[2]; + var outfile = process.argv[3]; + console.log('input:', input, 'output:', outfile); +} +module.exports(input,outfile); diff --git a/svgCube.html b/svgCube.html index 310cbbb..1778fbd 100755 --- a/svgCube.html +++ b/svgCube.html @@ -1,40 +1,20 @@ - + - - svg2Cube - + diff --git a/svgCube_gui.html b/svgCube_gui.html index d2b3005..da06828 100755 --- a/svgCube_gui.html +++ b/svgCube_gui.html @@ -21,7 +21,7 @@ - +