diff --git a/.jshintrc b/.jshintrc new file mode 100755 index 0000000..f9f8501 --- /dev/null +++ b/.jshintrc @@ -0,0 +1,92 @@ +{ + // JSHint Default Configuration File (as on JSHint website) + // See http://jshint.com/docs/ for more details + + "maxerr" : 50, // {int} Maximum error before stopping + + // Enforcing + "bitwise" : true, // true: Prohibit bitwise operators (&, |, ^, etc.) + "camelcase" : false, // true: Identifiers must be in camelCase + "curly" : true, // true: Require {} for every new block or scope + "eqeqeq" : true, // true: Require triple equals (===) for comparison + "forin" : true, // true: Require filtering for..in loops with obj.hasOwnProperty() + "freeze" : true, // true: prohibits overwriting prototypes of native objects such as Array, Date etc. + "immed" : false, // true: Require immediate invocations to be wrapped in parens e.g. `(function () { } ());` + "latedef" : false, // true: Require variables/functions to be defined before being used + "newcap" : false, // true: Require capitalization of all constructor functions e.g. `new F()` + "noarg" : true, // true: Prohibit use of `arguments.caller` and `arguments.callee` + "noempty" : true, // true: Prohibit use of empty blocks + "nonbsp" : true, // true: Prohibit "non-breaking whitespace" characters. + "nonew" : false, // true: Prohibit use of constructors for side-effects (without assignment) + "plusplus" : false, // true: Prohibit use of `++` and `--` + "quotmark" : false, // Quotation mark consistency: + // false : do nothing (default) + // true : ensure whatever is used is consistent + // "single" : require single quotes + // "double" : require double quotes + "undef" : true, // true: Require all non-global variables to be declared (prevents global leaks) + "unused" : true, // Unused variables: + // true : all variables, last function parameter + // "vars" : all variables only + // "strict" : all variables, all function parameters + "strict" : true, // true: Requires all functions run in ES5 Strict Mode + "maxparams" : false, // {int} Max number of formal params allowed per function + "maxdepth" : false, // {int} Max depth of nested blocks (within functions) + "maxstatements" : false, // {int} Max number statements per function + "maxcomplexity" : false, // {int} Max cyclomatic complexity per function + "maxlen" : false, // {int} Max number of characters per line + "varstmt" : false, // true: Disallow any var statements. Only `let` and `const` are allowed. + + // Relaxing + "asi" : false, // true: Tolerate Automatic Semicolon Insertion (no semicolons) + "boss" : false, // true: Tolerate assignments where comparisons would be expected + "debug" : false, // true: Allow debugger statements e.g. browser breakpoints. + "eqnull" : false, // true: Tolerate use of `== null` + "es5" : true, // true: Allow ES5 syntax (ex: getters and setters) + "esnext" : true, // true: Allow ES.next (ES6) syntax (ex: `const`) + "moz" : false, // true: Allow Mozilla specific syntax (extends and overrides esnext features) + // (ex: `for each`, multiple try/catch, function expression…) + "evil" : false, // true: Tolerate use of `eval` and `new Function()` + "expr" : false, // true: Tolerate `ExpressionStatement` as Programs + "funcscope" : false, // true: Tolerate defining variables inside control statements + "globalstrict" : false, // true: Allow global "use strict" (also enables 'strict') + "iterator" : false, // true: Tolerate using the `__iterator__` property + "lastsemic" : false, // true: Tolerate omitting a semicolon for the last statement of a 1-line block + "laxbreak" : false, // true: Tolerate possibly unsafe line breakings + "laxcomma" : false, // true: Tolerate comma-first style coding + "loopfunc" : false, // true: Tolerate functions being defined in loops + "multistr" : false, // true: Tolerate multi-line strings + "noyield" : false, // true: Tolerate generator functions with no yield statement in them. + "notypeof" : false, // true: Tolerate invalid typeof operator values + "proto" : false, // true: Tolerate using the `__proto__` property + "scripturl" : false, // true: Tolerate script-targeted URLs + "shadow" : false, // true: Allows re-define variables later in code e.g. `var x=1; x=2;` + "sub" : false, // true: Tolerate using `[]` notation when it can still be expressed in dot notation + "supernew" : false, // true: Tolerate `new function () { ... };` and `new Object;` + "validthis" : false, // true: Tolerate using this in a non-constructor function + + // Environments + "browser" : true, // Web Browser (window, document, etc) + "browserify" : false, // Browserify (node.js code in the browser) + "couch" : false, // CouchDB + "devel" : true, // Development/debugging (alert, confirm, etc) + "dojo" : false, // Dojo Toolkit + "jasmine" : false, // Jasmine + "jquery" : true, // jQuery + "mocha" : true, // Mocha + "mootools" : false, // MooTools + "node" : true, // Node.js + "nonstandard" : false, // Widely adopted globals (escape, unescape, etc) + "phantom" : true, // PhantomJS + "prototypejs" : false, // Prototype and Scriptaculous + "qunit" : false, // QUnit + "rhino" : false, // Rhino + "shelljs" : false, // ShellJS + "typed" : false, // Globals for typed array constructions + "worker" : false, // Web Workers + "wsh" : false, // Windows Scripting Host + "yui" : false, // Yahoo User Interface + + // Custom Globals + "globals" : {} // additional predefined global variables +} diff --git a/images/result.png b/images/result.png index 08df8c9..63abc74 100755 Binary files a/images/result.png and b/images/result.png differ diff --git a/package.json b/package.json index f654c18..cd2804d 100755 --- a/package.json +++ b/package.json @@ -5,17 +5,21 @@ "main": "render.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1", - "start": "node render.js" + "start": "node render.js svgCube.html" }, "repository": "git@gitlab.com:wassname/svg2Cube.git", "author": "wassname@wassname.org", "private": true, "license": "ISC", "dependencies": { + "chromedriver": "^2.20.0", "fs": "0.0.2", "globby": "^4.0.0", + "jquery": "^2.2.0", + "mustache": "^2.2.1", "path": "^0.12.7", "snapsvg": "^0.4.0", - "webdriverio": "^3.4.0" + "system": "^1.0.4", + "webdriverio": "^3" } } diff --git a/projectSVG.js b/projectSVG.js index 074f40e..67af214 100755 --- a/projectSVG.js +++ b/projectSVG.js @@ -3,9 +3,35 @@ * Frontend js file to generate an cube of svg's */ // http://cssdeck.com/labs/pure-css-animated-isometric-boxes -try { - var Snap = require('snapsvg'); -} catch (e) {}; + + + +// polyfill for bind https://github.com/ariya/phantomjs/issues/11281 +if (!Function.prototype.bind) { + console.log("Using polyfill of Function.prototype.bind"); + Function.prototype.bind = function (oThis) { + if (typeof this !== "function") { + // closest thing possible to the ECMAScript 5 + // internal IsCallable function + throw new TypeError("Function.prototype.bind - what is trying to be bound is not callable"); + } + + var aArgs = Array.prototype.slice.call(arguments, 1), + fToBind = this, + fNOP = function () {}, + fBound = function () { + return fToBind.apply(this instanceof fNOP && oThis + ? this + : oThis, + aArgs.concat(Array.prototype.slice.call(arguments))); + }; + + fNOP.prototype = this.prototype; + fBound.prototype = new fNOP(); + + return fBound; + }; +} var SvgCube = function (options) { @@ -48,7 +74,7 @@ var SvgCube = function (options) { frontUrl: '', frontRot: 0, frontShad: 0.0, - } + }; // add defaults, 2 levels deep options = options || {}; @@ -62,14 +88,14 @@ var SvgCube = function (options) { } } } - this.options = options + this.options = options; // legacy compat - if (options.flatten!==undefined){ - options.scaleY=1-options.flatten; + if (options.flatten !== undefined) { + options.scaleY = 1 - options.flatten; } - if (options.angle!==undefined){ - options.rotateX=options.angle; + if (options.angle !== undefined) { + options.rotateX = options.angle; } if (!options.drawOutline) { @@ -78,161 +104,149 @@ var SvgCube = function (options) { this.init(); -} +}; SvgCube.prototype.init = function () { - this.rotateX = this.options.rotateX + 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.f = 1 - this.options.scaleY; - this.rot = this.rotateX * Math.PI / 180 - this.padding = this.options.padding||0; // pading fraction + 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 + 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; - //var style = document.createElement('style'); - //this.paper.defs.appendChild(style) - var styleStr = ` ` + // Now we generate some css to put everything in good positions + var transitions = 0; + var styleStr = '' + + ''; if ($('body>.cube').length === 0) { - var cube = $('
') + var cube = $('
'); - var imageFront = $(``) + var imageFront = $(''); cube.append(imageFront); - var imageL = $(``) + var imageL = $(''); cube.append(imageL); - var imageRight = $(``) + var imageRight = $(''); cube.append(imageRight); - var imageTop = $(``) + var imageTop = $(''); cube.append(imageTop); - var imageBack = $(``) + var imageBack = $(''); cube.append(imageBack); - var imageBottom = $(``) + var imageBottom = $(''); cube.append(imageBottom); $('body').append(cube); @@ -254,10 +268,10 @@ SvgCube.prototype.init = function () { } - $('head>#projection').remove() + $('head>#projection').remove(); $('head').append($(styleStr)); -} +}; /* draw cube from urls in options and outline according to options */ SvgCube.prototype.drawCube = function () { @@ -281,38 +295,65 @@ SvgCube.prototype.drawCube = function () { // class: 'face top', // }) -} +}; -// svg2png -SvgCube.prototype.toPNG = function () { - try { - var dataUrl = svg2png(this.paper.node); - img = document.createElement("img"); - document.body.appendChild(img) - img.src = dataUrl - img.id = "toPNG" - } catch (e) { - console.log(e) - }; -} +/** + * Get the bounds of the images for a screenshot + * uses $.position to get min,max of each side of the image + * @return {[type]} [description] + */ +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; +}; + +/** + * Get the bounds of the images for a screenshot + * uses $.position to get min,max of each side of the image + * @return {[type]} [description] + */ +SvgCube.prototype.getAllBounds = 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] = []; + } + // get max and min + bounds[dim].push(pos[dim]); + } + } + }); + return bounds; +}; -// svg2png -SvgCube.prototype.toPNG2 = function () { - var dataUrl = svg2png(this.paper.node); - img = document.createElement("img"); - document.body.appendChild(img) - img.src = dataUrl - img.id = "toPNG" -} -// svg2png SvgCube.prototype.update = function () { //this.paper.remove(); this.init(); this.drawCube(); -} - - -try { - module.exports = SvgCube -} catch (e) {}; + console.log(this.getBounds()); +}; diff --git a/render.js b/render.js index 32302eb..34a2254 100755 --- a/render.js +++ b/render.js @@ -5,45 +5,40 @@ var webdriverio = require('webdriverio'); var path = require('path'); -var fs = require('fs'); -var system = require('system') +// var fs = require('fs'); +// var system = require('system') var globby = require('globby'); +var gm = require('gm'); + +// start chromedriver for selenium +var chromedriver = require('chromedriver'); +chromedriver.start(); var options = { + host: "localhost", + port: 9515, desiredCapabilities: { - browserName: 'chrome' + browserName: 'chrome', + chromeOptions: { + binary: '/usr/bin/chromium' + } } }; +var client = webdriverio.remote(options); -/** TODO - * Need to look at clien bounding box for all parts of cube, then get minLeft, maxRight etc, then crop the screenshot there - * - **/ - -// get config -var config = { - debug: false -} - // get inputs -var input = process.argv[2]; -console.log('input:', input); - - -/** - * Screenshot for debug and notification of screenshots - */ -var screenHandler = function (err, screenshot, response) { - if (config.debug) { - console.log({ - err, screenshot, response - }); - } else if (err) { - console.log('saveScreenshot', err); - } +if (process.argv.length < 3 || process.argv.length > 3) { + console.log('Command: ', process.argv); + console.log('Usage: rasterize.js filename'); + return; +} else { + var input = process.argv[2]; + console.log('input:', input); } + +var bounds; globby(input).then(inputs => { console.log('glob(', input, ') ->', inputs); @@ -57,19 +52,45 @@ globby(input).then(inputs => { var url = 'file://' + path.join(process.cwd(), file); var outfile = address.replace(ext, '.png'); + // create panel elements temporarily + console.log('Converting ', file, url, '->', outfile); - webdriverio - .remote(options) - .init() + client.init() .url(url) - .getTitle().then(title => { - console.log('Title is: ' + title); + .waitForVisible('.front', 5000) + // get image boundries from html + .execute(function () { + return $('#dimensions').text(); + }) + .then(text => { + try { + bounds = JSON.parse(text.value); + } catch (e) { + console.warn(text); + } + }) + // take a screen shot + .screenshot() + // crop using graphics magic + .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'); + }); + }) - .waitForVisible('.front', 1000) //.then(callback); - .saveScreenshot( - outfile, screenHandler - ) .end(); + } }, this) +chromedriver.stop(); diff --git a/svgCube.html b/svgCube.html index 31bf8e4..c020ffc 100755 --- a/svgCube.html +++ b/svgCube.html @@ -3,27 +3,22 @@ - Snap.js isometric SVG + svg2Cube +