init
@@ -0,0 +1,43 @@
|
||||
|
||||
.grass {
|
||||
background-image: url(2c_css_svgs.png);
|
||||
background-position: 0px 0px;
|
||||
width: 256px;
|
||||
height: 256px;
|
||||
}
|
||||
|
||||
.manual_good_30 {
|
||||
background-image: url(2c_css_svgs.png);
|
||||
background-position: 0px -256px;
|
||||
width: 1128px;
|
||||
height: 1128px;
|
||||
}
|
||||
|
||||
.manualcss_v2 {
|
||||
background-image: url(2c_css_svgs.png);
|
||||
background-position: 0px -431px;
|
||||
width: 1128px;
|
||||
height: 1128px;
|
||||
}
|
||||
|
||||
.manualcss_v2c {
|
||||
background-image: url(2c_css_svgs.png);
|
||||
background-position: 0px -606px;
|
||||
width: 1128px;
|
||||
height: 1128px;
|
||||
}
|
||||
|
||||
.manualcss_v2d {
|
||||
background-image: url(2c_css_svgs.png);
|
||||
background-position: 0px -1734px;
|
||||
width: 1128px;
|
||||
height: 1128px;
|
||||
}
|
||||
|
||||
.manuallcss_2b {
|
||||
background-image: url(2c_css_svgs.png);
|
||||
background-position: 0px -2862px;
|
||||
width: 1128px;
|
||||
height: 1128px;
|
||||
}
|
||||
|
||||
|
After Width: | Height: | Size: 73 KiB |
|
After Width: | Height: | Size: 73 KiB |
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"name": "2c_css_svgs",
|
||||
"description": "",
|
||||
"main": "",
|
||||
"moduleType": [],
|
||||
"license": "Unlicences",
|
||||
"homepage": "",
|
||||
"private": true,
|
||||
"ignore": [
|
||||
"**/.*",
|
||||
"node_modules",
|
||||
"bower_components",
|
||||
"test",
|
||||
"tests"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
cairosvg manual_good_30.svg -o manual_good_30.png
|
||||
|
||||
|
||||
for i in *.svg; do cairosvg $i -o `echo $i | sed -e 's/\.svg$/1.png/'`; done
|
||||
for i in *.svg; do rsvg-convert -a $i -o `echo $i | sed -e 's/\.svg$/2.png/'`; done
|
||||
for i in *.svg; do phantomjs rasterise.js $i `echo $i | sed -e 's/\.svg$/3.png/'`; done
|
||||
|
After Width: | Height: | Size: 78 KiB |
|
After Width: | Height: | Size: 86 KiB |
|
After Width: | Height: | Size: 75 KiB |
|
After Width: | Height: | Size: 29 KiB |
@@ -0,0 +1,41 @@
|
||||
<svg height="1128" style="overflow: hidden; position: relative; left: 0px; top: 0px;" version="1.1" width="1128" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg" >
|
||||
<foreignObject>
|
||||
<style>
|
||||
.cube, .cube .face, .cube .face * {
|
||||
height: 170px;
|
||||
width: 170px;
|
||||
}
|
||||
.cube {
|
||||
transform: translate(50%, 50%);
|
||||
}
|
||||
.cube2 .face, .cube2 .face * {
|
||||
transform-origin: 50% 50%;
|
||||
}
|
||||
.cube2 .top {
|
||||
transform: rotate(-45deg) skew(15deg, 15deg);
|
||||
}
|
||||
.cube2 .left {
|
||||
transform: rotate(15deg) skew(15deg, 15deg) translate(-50%, 100%);
|
||||
}
|
||||
.cube2 .right {
|
||||
transform: rotate(-15deg) skew(-15deg, -15deg) translate(50%, 100%);
|
||||
}
|
||||
</style>
|
||||
</foreignObject>
|
||||
|
||||
<g class="cube cube2" id="c2notnested" >
|
||||
<image
|
||||
class="face top"
|
||||
xlink:href="grass.svg"
|
||||
/>
|
||||
<image
|
||||
class="face left"
|
||||
xlink:href="grass.svg"
|
||||
/>
|
||||
<image
|
||||
class="face right"
|
||||
xlink:href="grass.svg"
|
||||
/>
|
||||
</g>
|
||||
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.2 KiB |
|
After Width: | Height: | Size: 30 KiB |
@@ -0,0 +1,56 @@
|
||||
<svg height="1128" version="1.1" width="1128" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg" >
|
||||
<desc>https://en.wikipedia.org/wiki/Isometric_projection </desc>
|
||||
<foreignObject>
|
||||
<style>
|
||||
.cube, .cube .face, .cube .face * {
|
||||
height: 170px;
|
||||
width: 170px;
|
||||
}
|
||||
.cube {
|
||||
position: relative;
|
||||
-webkit-transform: translate(11em,11em)
|
||||
}
|
||||
|
||||
.cube * {
|
||||
transform-origin: 0% 100%;
|
||||
}
|
||||
|
||||
.cube2 .top {
|
||||
position: relative;
|
||||
-webkit-transform: rotateX(45deg) rotateZ(-45deg) rotateX(0deg);
|
||||
-webkit-transform-style: preserve-3d;
|
||||
-webkit-transition: .25s;
|
||||
|
||||
}
|
||||
.cube2 .left {
|
||||
-webkit-transform: rotateX(45deg) rotateZ(-45deg) rotateX(90deg);
|
||||
-webkit-transform-style: preserve-3d;
|
||||
-webkit-transition: .25s;
|
||||
position: absolute;
|
||||
|
||||
}
|
||||
.cube2 .right {
|
||||
-webkit-transform: rotateX(45deg) rotateZ(-45deg) rotateY(90deg);
|
||||
-webkit-transform-style: preserve-3d;
|
||||
-webkit-transition: .25s;
|
||||
position: absolute;
|
||||
}
|
||||
</style>
|
||||
</foreignObject>
|
||||
|
||||
<g class="cube cube2" id="c2notnested" >
|
||||
<image
|
||||
class="face top"
|
||||
xlink:href="grass.svg"
|
||||
/>
|
||||
<image
|
||||
class="face left"
|
||||
xlink:href="grass.svg"
|
||||
/>
|
||||
<image
|
||||
class="face right"
|
||||
xlink:href="grass.svg"
|
||||
/>
|
||||
</g>
|
||||
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.7 KiB |
@@ -0,0 +1,457 @@
|
||||
'use strict';
|
||||
|
||||
try{
|
||||
var Snap = require('snapsvg');
|
||||
} catch(e) {};
|
||||
var SvgCube = function (options) {
|
||||
|
||||
// Inputs and options
|
||||
var defaultOptions = {
|
||||
angle: 30,
|
||||
size: 64,
|
||||
verbose: false,
|
||||
// outline
|
||||
drawOutline: true,
|
||||
drawShading: true,
|
||||
clipCircle: false,
|
||||
stroke: {
|
||||
"arrow-end": 'none',
|
||||
"stroke": 'black', // stroke color for outline
|
||||
"stroke-width": Math.sqrt(options.size)/2, // outline width
|
||||
"stroke-linecap": "round",
|
||||
"stroke-linejoin": "round",
|
||||
"fill": "none",
|
||||
},
|
||||
// cube
|
||||
flatten: 0, // fraction to vertically flatten the cube
|
||||
topUrl: '', // url for image in top of cuve
|
||||
topRot: 0, // rotation of top image in degrees
|
||||
topShad: 0, // shading for top
|
||||
leftUrl: '',
|
||||
leftRot: 0,
|
||||
leftShad: 0.1,
|
||||
rightUrl: '',
|
||||
rightRot: 0,
|
||||
rightShad: 0.3,
|
||||
svgNS: "http://www.w3.org/2000/svg",
|
||||
padding: 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];
|
||||
}
|
||||
}
|
||||
}
|
||||
this.options = options
|
||||
|
||||
this.angle = options.angle
|
||||
|
||||
this.w = options.size; // input image width
|
||||
this.h = options.size;
|
||||
this.f = options.flatten
|
||||
|
||||
this.rot = this.angle * Math.PI / 180
|
||||
this.padding = options.padding; // pading fraction
|
||||
|
||||
|
||||
this.cw = this.w; // we will keep same width but change height
|
||||
this.ch = (1 + this.padding) * (this.h / 2 + this.h * Math.tan(this.rot)) -this.h/2*(1-this.f); //canvas height full
|
||||
|
||||
// create SVG element
|
||||
this.paper = Snap(this.cw, this.ch);
|
||||
this.svg=this.paper.node
|
||||
var o = this.options;
|
||||
|
||||
var style = document.createElement('style');
|
||||
this.paper.defs.appendChild(style)
|
||||
var styleStr = ` <style>
|
||||
.cube, .cube .face, .cube .face * {
|
||||
height: ${o.size}px;
|
||||
width: ${o.size}px;
|
||||
}
|
||||
.cube {
|
||||
position: absolute;
|
||||
background-color: #f66;
|
||||
-webkit-transform-style: preserve-3d;
|
||||
-webkit-transition: .25s;
|
||||
transform: translate(${o.size/2}px,${0}px) rotateX(${o.angle}deg) ;
|
||||
}
|
||||
|
||||
.cube * {
|
||||
transform-origin: 0% 100%;
|
||||
}
|
||||
|
||||
.cube2 .top {
|
||||
position: relative;
|
||||
-webkit-transform: rotateX(45deg) rotateZ(-45deg) rotateX(0deg);
|
||||
-webkit-transform-style: preserve-3d;
|
||||
-webkit-transition: .25s;
|
||||
|
||||
}
|
||||
.cube2 .right {
|
||||
-webkit-transform: rotateX(45deg) rotateZ(-45deg) rotateX(90deg) scaleY(${o.flatten}) ;
|
||||
-webkit-transform-style: preserve-3d;
|
||||
-webkit-transition: .25s;
|
||||
position: absolute;
|
||||
|
||||
}
|
||||
.cube2 .left {
|
||||
-webkit-transform: rotateX(45deg) rotateZ(-45deg) rotateY(90deg) scaleX(${o.flatten}) ;
|
||||
-webkit-transform-style: preserve-3d;
|
||||
-webkit-transition: .25s;
|
||||
position: absolute;
|
||||
}
|
||||
</style>`
|
||||
console.log(styleStr);
|
||||
style.innerHTML= styleStr
|
||||
|
||||
}
|
||||
|
||||
/* drawing measurements as a function of padding */
|
||||
SvgCube.prototype.measurements= function(p){
|
||||
if (p===undefined){
|
||||
p=0;
|
||||
}
|
||||
|
||||
var f = this.options.flatten
|
||||
|
||||
var tBox = this.imageT.getBBox()
|
||||
var lBox = this.imageL.getBBox()
|
||||
var rBox = this.imageR.getBBox()
|
||||
|
||||
return {
|
||||
// measurements
|
||||
uf : 1-f,
|
||||
p : 0, // lw/2, // padding
|
||||
|
||||
tw: this.cw-p/2, // right side. adjust by half line thickness to keep line in canvas
|
||||
th: tBox.height-p/2, // height of square, and dist to middle
|
||||
|
||||
mw: this.cw/2, // middle x
|
||||
mh: tBox.height/2, // middle of top square
|
||||
|
||||
bh: 0+p/2, // top of picture, bottom y
|
||||
bw: 0+p/2, // left of picture, bottom of x
|
||||
|
||||
sw: this.cw-p/2,// bottom of cube
|
||||
sh: this.ch-p/2, // right of cube
|
||||
|
||||
lq: -tBox.height/2+this.ch-p/2, // lower quarter of height
|
||||
uq: tBox.height/2+p/2 // upper quarter
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Adds a svg transform to an element, the transform has the origin of
|
||||
* xi,yi fraction of the element, so 0.5,0.5 is the middle,
|
||||
* unlike normalsvg it adds transforms in order of application not reverse order
|
||||
* Usage: svgTransform(elementImage,'rotate',[45],0.5,0.5)
|
||||
* This would rotate 45 degrees around center of image
|
||||
*/
|
||||
SvgCube.prototype.svgTransform = function (element, op, inputs, xi, yi) {
|
||||
if (isNaN(xi)) {
|
||||
xi = 0.5;
|
||||
}
|
||||
if (isNaN(yi)) {
|
||||
yi = 0.5;
|
||||
}
|
||||
var svgBox = this.svg.getClientRects()[0]
|
||||
// this.paper.getBBox()
|
||||
var cbox = element.getBoundingClientRect();
|
||||
var x = cbox.left + xi * cbox.width -svgBox.left;
|
||||
var y = cbox.top + yi * cbox.height -svgBox.top;
|
||||
//
|
||||
var matrix = this.svg.createSVGMatrix()
|
||||
matrix = matrix.translate(x, y)
|
||||
matrix = matrix[op].apply(matrix, inputs);
|
||||
matrix = matrix.translate(-x, -y);
|
||||
|
||||
var transform = this.svg.createSVGTransform();
|
||||
transform.setMatrix(matrix);
|
||||
//element.transform.baseVal.appendItem(transform); // for reverse order
|
||||
element.transform.baseVal.insertItemBefore(transform, 0) // normal order
|
||||
}
|
||||
|
||||
/*
|
||||
* transform an element to be the left of an isometric cube
|
||||
* Inputs: dom element, angle in degrees, and xi,yi which
|
||||
* are the transform origin as a fraction of element size
|
||||
*/
|
||||
SvgCube.prototype.toLeft = function (element, angle, xi, yi) {
|
||||
// half it's width
|
||||
xi = 0
|
||||
yi = 1
|
||||
if (this.f>0){
|
||||
this.svgTransform(element, 'scaleNonUniform', [1,this.f],0.5,0.5)
|
||||
}
|
||||
this.svgTransform(element, 'translate', [-1, -1]) // pixel adjustment HACK
|
||||
this.svgTransform(element, 'scaleNonUniform', [1 / 2, 1 / 2], xi, yi)
|
||||
// skew it, in degrees
|
||||
this.svgTransform(element, 'skewY', [angle], xi, yi)
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* transform an element to be the right of an isometric cube
|
||||
* Inputs: dom element, angle in degrees, and xi,yi which
|
||||
* are the transform origin as a fraction of element size
|
||||
*/
|
||||
SvgCube.prototype.toRight = function (element, angle, xi, yi) {
|
||||
xi = 1
|
||||
yi = 1
|
||||
if (this.f>0){
|
||||
this.svgTransform(element, 'scaleNonUniform', [1,this.f],0.5,0.5)
|
||||
}
|
||||
this.svgTransform(element, 'translate', [-1, -2]) // pixel adjustment HACK
|
||||
// half it's width to fiit in canvas
|
||||
this.svgTransform(element, 'scaleNonUniform', [1 / 2, 1 / 2], xi, yi)
|
||||
// skew it
|
||||
this.svgTransform(element, 'skewY', [-angle], xi, yi)
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* transform an element to be the top of an isometric cube
|
||||
* Inputs: dom element, angle in degrees, and xi,yi which
|
||||
* are the transform origin as a fraction of element size
|
||||
*/
|
||||
SvgCube.prototype.toTop = function (element, angle, xi, yi) {
|
||||
var rot = angle * Math.PI / 180;
|
||||
this.svgTransform(element, 'translate', [-2, -1]) // pixel adjustment HACK
|
||||
|
||||
// rotate so it's a diamond
|
||||
this.svgTransform(element, 'rotate', [45], xi, yi)
|
||||
// squish - along x axis to fit in canvas, along y axis for perspective change
|
||||
this.svgTransform(element, 'scaleNonUniform', [Math.sin(45 * Math.PI / 180), Math.tan(rot) * Math.sin(45 * Math.PI / 180)], xi, yi)
|
||||
}
|
||||
|
||||
SvgCube.prototype.moveTop = function (element) {
|
||||
// align top of cube with top of canvas
|
||||
var cbox = element.getBoundingClientRect();
|
||||
this.svgTransform(element, 'translate', [-cbox.left + this.pPx, -cbox.top + this.pPx])
|
||||
}
|
||||
|
||||
/*
|
||||
* align left of cube with top,
|
||||
* fit upper-left of left panel with middle-left of top panel
|
||||
*/
|
||||
SvgCube.prototype.moveLeft = function (elem, elemT) {
|
||||
var cboxL = elem.getBoundingClientRect();
|
||||
var cboxT = elemT.getBoundingClientRect();
|
||||
// align left
|
||||
var x = cboxT.left - cboxL.left
|
||||
// align top of left with half height of
|
||||
var y = cboxT.top - cboxL.top + cboxT.height / 2
|
||||
this.svgTransform(elem, 'translate', [x, y])
|
||||
}
|
||||
|
||||
/*
|
||||
* align right of cube with top,
|
||||
* fit upper-right of right panel with middle-right of top panel
|
||||
*/
|
||||
SvgCube.prototype.moveRight = function (elem, elemT) {
|
||||
// line up left with top, move to half tops height, and to align left
|
||||
var cboxL = elem.getBoundingClientRect();
|
||||
var cboxT = elemT.getBoundingClientRect();
|
||||
|
||||
// align right with right
|
||||
var x = cboxT.right - cboxL.right
|
||||
|
||||
// align top of left with half height of
|
||||
var y = cboxT.top - cboxL.top + cboxT.height / 2
|
||||
this.svgTransform(elem, 'translate', [x, y])
|
||||
}
|
||||
|
||||
/* draw outline get line color from option.strokeColor, and width from options.stroke-width */
|
||||
SvgCube.prototype.drawOutline = function(lw){
|
||||
lw=lw||this.options.stroke["stroke-width"];
|
||||
var ms = this.measurements(lw/2)
|
||||
|
||||
|
||||
var tb = this.imageT.getBBox()
|
||||
var lb = this.imageL.getBBox()
|
||||
var rb = this.imageR.getBBox()
|
||||
|
||||
// Draw outline of top
|
||||
var strTop=
|
||||
'M'+ms.mw +' '+ms.th +' '+ // Move to bottom
|
||||
'L'+ms.bw +' '+ms.mh+' '+ // left
|
||||
'L'+ms.mw +' '+ms.bh+ ' '+ // top
|
||||
'L'+ms.tw +' '+ms.mh+' '+ // right
|
||||
'Z' // close
|
||||
var pathTop = this.paper.path(strTop);
|
||||
|
||||
// // outline of left
|
||||
var strLeft=
|
||||
'M'+ms.mw +' '+ms.th+' '+ // middle
|
||||
'L'+ms.bw +' '+ms.uq+' '+ // left top
|
||||
'L'+ms.bw +' '+ms.lq+' '+ // left bottom
|
||||
'L'+ms.mw +' '+ms.sh+' '+ // middle bottom
|
||||
'Z'
|
||||
var pathLeft = this.paper.path(strLeft);
|
||||
//
|
||||
// right
|
||||
var strRight=
|
||||
'M'+ms.mw +' '+ms.th+' '+ // middle
|
||||
'L'+ms.mw +' '+ms.sh +' '+ // middle bottom
|
||||
'L'+ms.tw +' '+ms.lq+' '+ // right bottom
|
||||
'L'+ms.tw +' '+ms.uq+' '+ // right top
|
||||
'Z' // close
|
||||
var pathRight = this.paper.path(strRight);
|
||||
|
||||
// join into set
|
||||
var pathGroup = this.paper.group();
|
||||
pathGroup.append(pathTop);
|
||||
pathGroup.append(pathLeft);
|
||||
pathGroup.append(pathRight);
|
||||
|
||||
// set attrs from options
|
||||
// ref http://raphaeljs.com/reference.html#Element.attr
|
||||
var blackList = ['url','target','src','title']
|
||||
for (var a in this.options.stroke){
|
||||
if (this.options.stroke.hasOwnProperty(a) && blackList.indexOf(a)<0){
|
||||
pathGroup.attr(a,this.options.stroke[a]);
|
||||
}
|
||||
}
|
||||
this.outline=pathGroup;
|
||||
}
|
||||
|
||||
|
||||
/* draw outline get line color from option.strokeColor, and width from options.stroke-width */
|
||||
SvgCube.prototype.drawShading = function(lw){
|
||||
lw=lw||this.options.stroke["stroke-width"];
|
||||
var ms = this.measurements(0);
|
||||
var pathGroup = this.paper.g();
|
||||
|
||||
var strTop=
|
||||
'M'+ms.mw +' '+ms.th +' '+ // Move to bottom
|
||||
'L'+ms.bw +' '+ms.mh+' '+ // left
|
||||
'L'+ms.mw +' '+ms.bh+ ' '+ // top
|
||||
'L'+ms.tw +' '+ms.mh+' '+ // right
|
||||
'Z' // close
|
||||
var pathTop = this.paper.path(strTop);
|
||||
pathGroup.append(pathTop);
|
||||
|
||||
// outline of left
|
||||
var strLeft=
|
||||
'M'+ms.mw +' '+ms.th+' '+ // middle
|
||||
'L'+ms.bw +' '+ms.uq+' '+ // left top
|
||||
'L'+ms.bw +' '+ms.lq+' '+ // left bottom
|
||||
'L'+ms.mw +' '+ms.sh+' '+ // middle bottom
|
||||
'Z'
|
||||
var pathLeft = this.paper.path(strLeft);
|
||||
pathGroup.append(pathLeft);
|
||||
|
||||
// last line from middle down
|
||||
var strRight=
|
||||
'M'+ms.mw +' '+ms.th+' '+ // middle
|
||||
'L'+ms.mw +' '+ms.sh +' '+ // middle bottom
|
||||
'L'+ms.tw +' '+ms.lq+' '+ // right bottom
|
||||
'L'+ms.tw +' '+ms.uq+' '+ // right top
|
||||
'Z' // close
|
||||
var pathRight = this.paper.path(strRight);
|
||||
pathGroup.append(pathRight);
|
||||
|
||||
|
||||
// style the set
|
||||
pathGroup.attr({
|
||||
'stroke': 'none',
|
||||
'fill': 'black',
|
||||
'stroke-width': 0,
|
||||
'stroke-opacity': 0,
|
||||
'stroke-linecap': 'round',
|
||||
'stroke-linejoin': 'round'
|
||||
});
|
||||
// shade each side, 0 is no shading, 1 is black
|
||||
pathTop.attr({'fill-opacity': this.options.topShad});
|
||||
pathLeft.attr({'fill-opacity': this.options.leftShad});
|
||||
pathRight.attr({'fill-opacity': this.options.rightShad});
|
||||
this.shading=pathGroup;
|
||||
|
||||
}
|
||||
|
||||
/*clip the cube using an elipse to give rounded corners */
|
||||
SvgCube.prototype.clipCircle = function(amount){
|
||||
var cp = document.createElementNS("http://www.w3.org/2000/svg","clipPath")
|
||||
cp.id="cp";
|
||||
var rxc=51+4*(1-this.f)*(1-this.f);
|
||||
var ryc=50-2/Math.sqrt(1-this.f);
|
||||
cp.innerHTML = '<ellipse xmlns="http://www.w3.org/2000/svg" cx="50%" cy="50%" rx="'+rxc+'%" ry="'+ryc+'%" fill="white"/>'
|
||||
this.paper.node.getElementsByTagName("defs")[0].appendChild(cp);
|
||||
this.paper.node.setAttribute("clip-path","url(#cp)");
|
||||
}
|
||||
|
||||
|
||||
/* returns svg string */
|
||||
SvgCube.prototype.toSVG = function(){
|
||||
var svg3 = this.paper.toString();
|
||||
//var svg = this.paper.node.outerHTML;
|
||||
//var svg2 = xmlserializer.serializeToString(this.paper.node);
|
||||
if (this.paper.node.attributes.getNamedItem("clip-path")){
|
||||
// patch svg export to add clip
|
||||
// HACK I have to add these manually to the export sadly as raphael.export doesn't handle them and also misses some recent change to canvas
|
||||
svg3=svg3.replace("<svg",'<svg clip-path="url(#cp)"')
|
||||
svg3=svg3.replace("<image",this.paper.node.getElementsByTagName("defs")[0].outerHTML+"<image")
|
||||
svg3=svg3.replace("clippath","clipPath")
|
||||
svg3=svg3.replace("clippath","clipPath")
|
||||
|
||||
}
|
||||
return svg3
|
||||
}
|
||||
|
||||
/* draw cube from urls in options and outline according to options */
|
||||
SvgCube.prototype.drawCube = function (){
|
||||
|
||||
var imgS = this.options.size / Math.sqrt(2);
|
||||
this.cube = this.paper.g();
|
||||
this.cube.attr({
|
||||
class: 'cube cube2',
|
||||
id: "c2notnested",
|
||||
});
|
||||
this.leftImg = this.cube.image(this.options.leftUrl,0,0,imgS,imgS);
|
||||
this.leftImg.attr({
|
||||
class: 'face left',
|
||||
})
|
||||
this.rightImg = this.cube.image(this.options.rightUrl,0,0,imgS,imgS);
|
||||
this.rightImg.attr({
|
||||
class: 'face right',
|
||||
})
|
||||
this.topImg = this.cube.image(this.options.topUrl,0,0,imgS,imgS);
|
||||
this.topImg.attr({
|
||||
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)};
|
||||
}
|
||||
|
||||
// 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"
|
||||
}
|
||||
|
||||
|
||||
try{
|
||||
module.exports=SvgCube
|
||||
} catch(e){};
|
||||
@@ -0,0 +1,477 @@
|
||||
'use strict';
|
||||
// http://cssdeck.com/labs/pure-css-animated-isometric-boxes
|
||||
try{
|
||||
var Snap = require('snapsvg');
|
||||
} catch(e) {};
|
||||
|
||||
var SvgCube = function (options) {
|
||||
|
||||
// Inputs and options
|
||||
var defaultOptions = {
|
||||
angle: 30,
|
||||
size: 64,
|
||||
verbose: false,
|
||||
// outline
|
||||
drawOutline: true,
|
||||
drawShading: true,
|
||||
clipCircle: false,
|
||||
stroke: {
|
||||
"arrow-end": 'none',
|
||||
"stroke": 'black', // stroke color for outline
|
||||
"stroke-width": Math.sqrt(options.size)/2, // outline width
|
||||
"stroke-linecap": "round",
|
||||
"stroke-linejoin": "round",
|
||||
"fill": "none",
|
||||
},
|
||||
// cube
|
||||
flatten: 0, // fraction to vertically flatten the cube
|
||||
topUrl: '', // url for image in top of cuve
|
||||
topRot: 0, // rotation of top image in degrees
|
||||
topShad: 0, // shading for top
|
||||
leftUrl: '',
|
||||
leftRot: 0,
|
||||
leftShad: 0.1,
|
||||
rightUrl: '',
|
||||
rightRot: 0,
|
||||
rightShad: 0.3,
|
||||
svgNS: "http://www.w3.org/2000/svg",
|
||||
padding: 0,
|
||||
rotateX: 0,
|
||||
rotateY: 0,
|
||||
rotateZ: 0,
|
||||
perspective: 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];
|
||||
}
|
||||
}
|
||||
}
|
||||
this.options = options
|
||||
|
||||
this.init();
|
||||
|
||||
}
|
||||
|
||||
SvgCube.prototype.init = function(){
|
||||
|
||||
this.angle = this.options.angle
|
||||
|
||||
this.w = this.options.size; // input image width
|
||||
this.h = this.options.size;
|
||||
this.f = this.options.flatten
|
||||
|
||||
this.rot = this.angle * Math.PI / 180
|
||||
this.padding = this.options.padding; // pading fraction
|
||||
|
||||
|
||||
this.cw = this.w; // we will keep same width but change height
|
||||
this.ch = (1 + this.padding) * (this.h / 2 + this.h * Math.tan(this.rot)) -this.h/2*(1-this.f); //canvas height full
|
||||
|
||||
// create SVG element
|
||||
this.paper = Snap(this.cw, this.ch);
|
||||
this.svg=this.paper.node
|
||||
var o = this.options;
|
||||
|
||||
var style = document.createElement('style');
|
||||
this.paper.defs.appendChild(style)
|
||||
var styleStr = ` <style>
|
||||
.cube, .cube .face, .cube .face * {
|
||||
height: ${o.size}px;
|
||||
width: ${o.size}px;
|
||||
}
|
||||
.cube {
|
||||
position: absolute;
|
||||
background-color: #f66;
|
||||
|
||||
-webkit-transform: translate(${this.cw/2}px,${0*this.ch/2}px) perspective(${o.perspective}px) rotateX(${o.angle}deg) rotateX(${o.rotateX}deg) rotateY(${o.rotateY}deg) rotateZ(${o.rotateZ}deg);
|
||||
-webkit-transform-style: preserve-3d;
|
||||
-webkit-transition: .25s;
|
||||
}
|
||||
|
||||
|
||||
.cube * {
|
||||
transform-origin: 0% 100%;
|
||||
}
|
||||
|
||||
.cube2 .top {
|
||||
position: relative;
|
||||
-webkit-transform: rotateX(45deg) rotateZ(-45deg) rotateX(0deg);
|
||||
-webkit-transform-style: preserve-3d;
|
||||
-webkit-transition: .25s;
|
||||
|
||||
}
|
||||
.cube2 .left {
|
||||
-webkit-transform: rotateX(45deg) rotateZ(-45deg) rotateX(90deg);
|
||||
-webkit-transform-style: preserve-3d;
|
||||
-webkit-transition: .25s;
|
||||
position: absolute;
|
||||
|
||||
}
|
||||
.cube2 .right {
|
||||
-webkit-transform: rotateX(45deg) rotateZ(-45deg) rotateY(90deg);
|
||||
-webkit-transform-style: preserve-3d;
|
||||
-webkit-transition: .25s;
|
||||
position: absolute;
|
||||
}
|
||||
</style>`
|
||||
console.log(styleStr);
|
||||
style.innerHTML= styleStr
|
||||
|
||||
}
|
||||
|
||||
/* drawing measurements as a function of padding */
|
||||
SvgCube.prototype.measurements= function(p){
|
||||
if (p===undefined){
|
||||
p=0;
|
||||
}
|
||||
|
||||
var f = this.options.flatten
|
||||
|
||||
var tBox = this.imageT.getBBox()
|
||||
var lBox = this.imageL.getBBox()
|
||||
var rBox = this.imageR.getBBox()
|
||||
|
||||
return {
|
||||
// measurements
|
||||
uf : 1-f,
|
||||
p : 0, // lw/2, // padding
|
||||
|
||||
tw: this.cw-p/2, // right side. adjust by half line thickness to keep line in canvas
|
||||
th: tBox.height-p/2, // height of square, and dist to middle
|
||||
|
||||
mw: this.cw/2, // middle x
|
||||
mh: tBox.height/2, // middle of top square
|
||||
|
||||
bh: 0+p/2, // top of picture, bottom y
|
||||
bw: 0+p/2, // left of picture, bottom of x
|
||||
|
||||
sw: this.cw-p/2,// bottom of cube
|
||||
sh: this.ch-p/2, // right of cube
|
||||
|
||||
lq: -tBox.height/2+this.ch-p/2, // lower quarter of height
|
||||
uq: tBox.height/2+p/2 // upper quarter
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Adds a svg transform to an element, the transform has the origin of
|
||||
* xi,yi fraction of the element, so 0.5,0.5 is the middle,
|
||||
* unlike normalsvg it adds transforms in order of application not reverse order
|
||||
* Usage: svgTransform(elementImage,'rotate',[45],0.5,0.5)
|
||||
* This would rotate 45 degrees around center of image
|
||||
*/
|
||||
SvgCube.prototype.svgTransform = function (element, op, inputs, xi, yi) {
|
||||
if (isNaN(xi)) {
|
||||
xi = 0.5;
|
||||
}
|
||||
if (isNaN(yi)) {
|
||||
yi = 0.5;
|
||||
}
|
||||
var svgBox = this.svg.getClientRects()[0]
|
||||
// this.paper.getBBox()
|
||||
var cbox = element.getBoundingClientRect();
|
||||
var x = cbox.left + xi * cbox.width -svgBox.left;
|
||||
var y = cbox.top + yi * cbox.height -svgBox.top;
|
||||
//
|
||||
var matrix = this.svg.createSVGMatrix()
|
||||
matrix = matrix.translate(x, y)
|
||||
matrix = matrix[op].apply(matrix, inputs);
|
||||
matrix = matrix.translate(-x, -y);
|
||||
|
||||
var transform = this.svg.createSVGTransform();
|
||||
transform.setMatrix(matrix);
|
||||
//element.transform.baseVal.appendItem(transform); // for reverse order
|
||||
element.transform.baseVal.insertItemBefore(transform, 0) // normal order
|
||||
}
|
||||
|
||||
/*
|
||||
* transform an element to be the left of an isometric cube
|
||||
* Inputs: dom element, angle in degrees, and xi,yi which
|
||||
* are the transform origin as a fraction of element size
|
||||
*/
|
||||
SvgCube.prototype.toLeft = function (element, angle, xi, yi) {
|
||||
// half it's width
|
||||
xi = 0
|
||||
yi = 1
|
||||
if (this.f>0){
|
||||
this.svgTransform(element, 'scaleNonUniform', [1,this.f],0.5,0.5)
|
||||
}
|
||||
this.svgTransform(element, 'translate', [-1, -1]) // pixel adjustment HACK
|
||||
this.svgTransform(element, 'scaleNonUniform', [1 / 2, 1 / 2], xi, yi)
|
||||
// skew it, in degrees
|
||||
this.svgTransform(element, 'skewY', [angle], xi, yi)
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* transform an element to be the right of an isometric cube
|
||||
* Inputs: dom element, angle in degrees, and xi,yi which
|
||||
* are the transform origin as a fraction of element size
|
||||
*/
|
||||
SvgCube.prototype.toRight = function (element, angle, xi, yi) {
|
||||
xi = 1
|
||||
yi = 1
|
||||
if (this.f>0){
|
||||
this.svgTransform(element, 'scaleNonUniform', [1,this.f],0.5,0.5)
|
||||
}
|
||||
this.svgTransform(element, 'translate', [-1, -2]) // pixel adjustment HACK
|
||||
// half it's width to fiit in canvas
|
||||
this.svgTransform(element, 'scaleNonUniform', [1 / 2, 1 / 2], xi, yi)
|
||||
// skew it
|
||||
this.svgTransform(element, 'skewY', [-angle], xi, yi)
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* transform an element to be the top of an isometric cube
|
||||
* Inputs: dom element, angle in degrees, and xi,yi which
|
||||
* are the transform origin as a fraction of element size
|
||||
*/
|
||||
SvgCube.prototype.toTop = function (element, angle, xi, yi) {
|
||||
var rot = angle * Math.PI / 180;
|
||||
this.svgTransform(element, 'translate', [-2, -1]) // pixel adjustment HACK
|
||||
|
||||
// rotate so it's a diamond
|
||||
this.svgTransform(element, 'rotate', [45], xi, yi)
|
||||
// squish - along x axis to fit in canvas, along y axis for perspective change
|
||||
this.svgTransform(element, 'scaleNonUniform', [Math.sin(45 * Math.PI / 180), Math.tan(rot) * Math.sin(45 * Math.PI / 180)], xi, yi)
|
||||
}
|
||||
|
||||
SvgCube.prototype.moveTop = function (element) {
|
||||
// align top of cube with top of canvas
|
||||
var cbox = element.getBoundingClientRect();
|
||||
this.svgTransform(element, 'translate', [-cbox.left + this.pPx, -cbox.top + this.pPx])
|
||||
}
|
||||
|
||||
/*
|
||||
* align left of cube with top,
|
||||
* fit upper-left of left panel with middle-left of top panel
|
||||
*/
|
||||
SvgCube.prototype.moveLeft = function (elem, elemT) {
|
||||
var cboxL = elem.getBoundingClientRect();
|
||||
var cboxT = elemT.getBoundingClientRect();
|
||||
// align left
|
||||
var x = cboxT.left - cboxL.left
|
||||
// align top of left with half height of
|
||||
var y = cboxT.top - cboxL.top + cboxT.height / 2
|
||||
this.svgTransform(elem, 'translate', [x, y])
|
||||
}
|
||||
|
||||
/*
|
||||
* align right of cube with top,
|
||||
* fit upper-right of right panel with middle-right of top panel
|
||||
*/
|
||||
SvgCube.prototype.moveRight = function (elem, elemT) {
|
||||
// line up left with top, move to half tops height, and to align left
|
||||
var cboxL = elem.getBoundingClientRect();
|
||||
var cboxT = elemT.getBoundingClientRect();
|
||||
|
||||
// align right with right
|
||||
var x = cboxT.right - cboxL.right
|
||||
|
||||
// align top of left with half height of
|
||||
var y = cboxT.top - cboxL.top + cboxT.height / 2
|
||||
this.svgTransform(elem, 'translate', [x, y])
|
||||
}
|
||||
|
||||
/* draw outline get line color from option.strokeColor, and width from options.stroke-width */
|
||||
SvgCube.prototype.drawOutline = function(lw){
|
||||
lw=lw||this.options.stroke["stroke-width"];
|
||||
var ms = this.measurements(lw/2)
|
||||
|
||||
|
||||
var tb = this.imageT.getBBox()
|
||||
var lb = this.imageL.getBBox()
|
||||
var rb = this.imageR.getBBox()
|
||||
|
||||
// Draw outline of top
|
||||
var strTop=
|
||||
'M'+ms.mw +' '+ms.th +' '+ // Move to bottom
|
||||
'L'+ms.bw +' '+ms.mh+' '+ // left
|
||||
'L'+ms.mw +' '+ms.bh+ ' '+ // top
|
||||
'L'+ms.tw +' '+ms.mh+' '+ // right
|
||||
'Z' // close
|
||||
var pathTop = this.paper.path(strTop);
|
||||
|
||||
// // outline of left
|
||||
var strLeft=
|
||||
'M'+ms.mw +' '+ms.th+' '+ // middle
|
||||
'L'+ms.bw +' '+ms.uq+' '+ // left top
|
||||
'L'+ms.bw +' '+ms.lq+' '+ // left bottom
|
||||
'L'+ms.mw +' '+ms.sh+' '+ // middle bottom
|
||||
'Z'
|
||||
var pathLeft = this.paper.path(strLeft);
|
||||
//
|
||||
// right
|
||||
var strRight=
|
||||
'M'+ms.mw +' '+ms.th+' '+ // middle
|
||||
'L'+ms.mw +' '+ms.sh +' '+ // middle bottom
|
||||
'L'+ms.tw +' '+ms.lq+' '+ // right bottom
|
||||
'L'+ms.tw +' '+ms.uq+' '+ // right top
|
||||
'Z' // close
|
||||
var pathRight = this.paper.path(strRight);
|
||||
|
||||
// join into set
|
||||
var pathGroup = this.paper.group();
|
||||
pathGroup.append(pathTop);
|
||||
pathGroup.append(pathLeft);
|
||||
pathGroup.append(pathRight);
|
||||
|
||||
// set attrs from options
|
||||
// ref http://raphaeljs.com/reference.html#Element.attr
|
||||
var blackList = ['url','target','src','title']
|
||||
for (var a in this.options.stroke){
|
||||
if (this.options.stroke.hasOwnProperty(a) && blackList.indexOf(a)<0){
|
||||
pathGroup.attr(a,this.options.stroke[a]);
|
||||
}
|
||||
}
|
||||
this.outline=pathGroup;
|
||||
}
|
||||
|
||||
|
||||
/* draw outline get line color from option.strokeColor, and width from options.stroke-width */
|
||||
SvgCube.prototype.drawShading = function(lw){
|
||||
lw=lw||this.options.stroke["stroke-width"];
|
||||
var ms = this.measurements(0);
|
||||
var pathGroup = this.paper.g();
|
||||
|
||||
var strTop=
|
||||
'M'+ms.mw +' '+ms.th +' '+ // Move to bottom
|
||||
'L'+ms.bw +' '+ms.mh+' '+ // left
|
||||
'L'+ms.mw +' '+ms.bh+ ' '+ // top
|
||||
'L'+ms.tw +' '+ms.mh+' '+ // right
|
||||
'Z' // close
|
||||
var pathTop = this.paper.path(strTop);
|
||||
pathGroup.append(pathTop);
|
||||
|
||||
// outline of left
|
||||
var strLeft=
|
||||
'M'+ms.mw +' '+ms.th+' '+ // middle
|
||||
'L'+ms.bw +' '+ms.uq+' '+ // left top
|
||||
'L'+ms.bw +' '+ms.lq+' '+ // left bottom
|
||||
'L'+ms.mw +' '+ms.sh+' '+ // middle bottom
|
||||
'Z'
|
||||
var pathLeft = this.paper.path(strLeft);
|
||||
pathGroup.append(pathLeft);
|
||||
|
||||
// last line from middle down
|
||||
var strRight=
|
||||
'M'+ms.mw +' '+ms.th+' '+ // middle
|
||||
'L'+ms.mw +' '+ms.sh +' '+ // middle bottom
|
||||
'L'+ms.tw +' '+ms.lq+' '+ // right bottom
|
||||
'L'+ms.tw +' '+ms.uq+' '+ // right top
|
||||
'Z' // close
|
||||
var pathRight = this.paper.path(strRight);
|
||||
pathGroup.append(pathRight);
|
||||
|
||||
|
||||
// style the set
|
||||
pathGroup.attr({
|
||||
'stroke': 'none',
|
||||
'fill': 'black',
|
||||
'stroke-width': 0,
|
||||
'stroke-opacity': 0,
|
||||
'stroke-linecap': 'round',
|
||||
'stroke-linejoin': 'round'
|
||||
});
|
||||
// shade each side, 0 is no shading, 1 is black
|
||||
pathTop.attr({'fill-opacity': this.options.topShad});
|
||||
pathLeft.attr({'fill-opacity': this.options.leftShad});
|
||||
pathRight.attr({'fill-opacity': this.options.rightShad});
|
||||
this.shading=pathGroup;
|
||||
|
||||
}
|
||||
|
||||
/*clip the cube using an elipse to give rounded corners */
|
||||
SvgCube.prototype.clipCircle = function(amount){
|
||||
var cp = document.createElementNS("http://www.w3.org/2000/svg","clipPath")
|
||||
cp.id="cp";
|
||||
var rxc=51+4*(1-this.f)*(1-this.f);
|
||||
var ryc=50-2/Math.sqrt(1-this.f);
|
||||
cp.innerHTML = '<ellipse xmlns="http://www.w3.org/2000/svg" cx="50%" cy="50%" rx="'+rxc+'%" ry="'+ryc+'%" fill="white"/>'
|
||||
this.paper.node.getElementsByTagName("defs")[0].appendChild(cp);
|
||||
this.paper.node.setAttribute("clip-path","url(#cp)");
|
||||
}
|
||||
|
||||
|
||||
/* returns svg string */
|
||||
SvgCube.prototype.toSVG = function(){
|
||||
var svg3 = this.paper.toString();
|
||||
//var svg = this.paper.node.outerHTML;
|
||||
//var svg2 = xmlserializer.serializeToString(this.paper.node);
|
||||
if (this.paper.node.attributes.getNamedItem("clip-path")){
|
||||
// patch svg export to add clip
|
||||
// HACK I have to add these manually to the export sadly as raphael.export doesn't handle them and also misses some recent change to canvas
|
||||
svg3=svg3.replace("<svg",'<svg clip-path="url(#cp)"')
|
||||
svg3=svg3.replace("<image",this.paper.node.getElementsByTagName("defs")[0].outerHTML+"<image")
|
||||
svg3=svg3.replace("clippath","clipPath")
|
||||
svg3=svg3.replace("clippath","clipPath")
|
||||
|
||||
}
|
||||
return svg3
|
||||
}
|
||||
|
||||
/* draw cube from urls in options and outline according to options */
|
||||
SvgCube.prototype.drawCube = function (){
|
||||
|
||||
var imgS = this.options.size / Math.sqrt(2);
|
||||
this.cube = this.paper.g();
|
||||
this.cube.attr({
|
||||
class: 'cube cube2',
|
||||
id: "c2notnested",
|
||||
});
|
||||
this.leftImg = this.cube.image(this.options.leftUrl,0,0,imgS,imgS);
|
||||
this.leftImg.attr({
|
||||
class: 'face left',
|
||||
})
|
||||
this.rightImg = this.cube.image(this.options.rightUrl,0,0,imgS,imgS);
|
||||
this.rightImg.attr({
|
||||
class: 'face right',
|
||||
})
|
||||
this.topImg = this.cube.image(this.options.topUrl,0,0,imgS,imgS);
|
||||
this.topImg.attr({
|
||||
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)};
|
||||
}
|
||||
|
||||
// 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){};
|
||||
@@ -0,0 +1,458 @@
|
||||
'use strict';
|
||||
|
||||
try{
|
||||
var Snap = require('snapsvg');
|
||||
} catch(e) {};
|
||||
var SvgCube = function (options) {
|
||||
|
||||
// Inputs and options
|
||||
var defaultOptions = {
|
||||
angle: 30,
|
||||
size: 64,
|
||||
verbose: false,
|
||||
// outline
|
||||
drawOutline: true,
|
||||
drawShading: true,
|
||||
clipCircle: false,
|
||||
stroke: {
|
||||
"arrow-end": 'none',
|
||||
"stroke": 'black', // stroke color for outline
|
||||
"stroke-width": Math.sqrt(options.size)/2, // outline width
|
||||
"stroke-linecap": "round",
|
||||
"stroke-linejoin": "round",
|
||||
"fill": "none",
|
||||
},
|
||||
// cube
|
||||
flatten: 0, // fraction to vertically flatten the cube
|
||||
topUrl: '', // url for image in top of cuve
|
||||
topRot: 0, // rotation of top image in degrees
|
||||
topShad: 0, // shading for top
|
||||
leftUrl: '',
|
||||
leftRot: 0,
|
||||
leftShad: 0.1,
|
||||
rightUrl: '',
|
||||
rightRot: 0,
|
||||
rightShad: 0.3,
|
||||
svgNS: "http://www.w3.org/2000/svg",
|
||||
padding: 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];
|
||||
}
|
||||
}
|
||||
}
|
||||
this.options = options
|
||||
|
||||
this.angle = options.angle
|
||||
|
||||
this.w = options.size; // input image width
|
||||
this.h = options.size;
|
||||
this.f = options.flatten
|
||||
|
||||
this.rot = this.angle * Math.PI / 180
|
||||
this.padding = options.padding; // pading fraction
|
||||
|
||||
|
||||
this.cw = this.w; // we will keep same width but change height
|
||||
this.ch = (1 + this.padding) * (this.h / 2 + this.h * Math.tan(this.rot)) -this.h/2*(1-this.f); //canvas height full
|
||||
|
||||
// create SVG element
|
||||
this.paper = Snap(this.cw, this.ch);
|
||||
this.svg=this.paper.node
|
||||
var o = this.options;
|
||||
|
||||
var style = document.createElement('style');
|
||||
this.paper.defs.appendChild(style)
|
||||
var styleStr = ` <style>
|
||||
.cube, .cube .face, .cube .face * {
|
||||
height: ${o.size}px;
|
||||
width: ${o.size}px;
|
||||
}
|
||||
.cube {
|
||||
position: absolute;
|
||||
background-color: #f66;
|
||||
-webkit-transform: translate(${o.size/2}px,${0}px);
|
||||
-webkit-transform-style: preserve-3d;
|
||||
-webkit-transition: .25s;
|
||||
transform: rotateX(${o.angle}deg) scaleY(${o.flatten});
|
||||
}
|
||||
|
||||
.cube * {
|
||||
transform-origin: 0% 100%;
|
||||
}
|
||||
|
||||
.cube2 .top {
|
||||
position: relative;
|
||||
-webkit-transform: rotateX(45deg) rotateZ(-45deg) rotateX(0deg);
|
||||
-webkit-transform-style: preserve-3d;
|
||||
-webkit-transition: .25s;
|
||||
|
||||
}
|
||||
.cube2 .left {
|
||||
-webkit-transform: rotateX(45deg) rotateZ(-45deg) rotateX(90deg);
|
||||
-webkit-transform-style: preserve-3d;
|
||||
-webkit-transition: .25s;
|
||||
position: absolute;
|
||||
|
||||
}
|
||||
.cube2 .right {
|
||||
-webkit-transform: rotateX(45deg) rotateZ(-45deg) rotateY(90deg);
|
||||
-webkit-transform-style: preserve-3d;
|
||||
-webkit-transition: .25s;
|
||||
position: absolute;
|
||||
}
|
||||
</style>`
|
||||
console.log(styleStr);
|
||||
style.innerHTML= styleStr
|
||||
|
||||
}
|
||||
|
||||
/* drawing measurements as a function of padding */
|
||||
SvgCube.prototype.measurements= function(p){
|
||||
if (p===undefined){
|
||||
p=0;
|
||||
}
|
||||
|
||||
var f = this.options.flatten
|
||||
|
||||
var tBox = this.imageT.getBBox()
|
||||
var lBox = this.imageL.getBBox()
|
||||
var rBox = this.imageR.getBBox()
|
||||
|
||||
return {
|
||||
// measurements
|
||||
uf : 1-f,
|
||||
p : 0, // lw/2, // padding
|
||||
|
||||
tw: this.cw-p/2, // right side. adjust by half line thickness to keep line in canvas
|
||||
th: tBox.height-p/2, // height of square, and dist to middle
|
||||
|
||||
mw: this.cw/2, // middle x
|
||||
mh: tBox.height/2, // middle of top square
|
||||
|
||||
bh: 0+p/2, // top of picture, bottom y
|
||||
bw: 0+p/2, // left of picture, bottom of x
|
||||
|
||||
sw: this.cw-p/2,// bottom of cube
|
||||
sh: this.ch-p/2, // right of cube
|
||||
|
||||
lq: -tBox.height/2+this.ch-p/2, // lower quarter of height
|
||||
uq: tBox.height/2+p/2 // upper quarter
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Adds a svg transform to an element, the transform has the origin of
|
||||
* xi,yi fraction of the element, so 0.5,0.5 is the middle,
|
||||
* unlike normalsvg it adds transforms in order of application not reverse order
|
||||
* Usage: svgTransform(elementImage,'rotate',[45],0.5,0.5)
|
||||
* This would rotate 45 degrees around center of image
|
||||
*/
|
||||
SvgCube.prototype.svgTransform = function (element, op, inputs, xi, yi) {
|
||||
if (isNaN(xi)) {
|
||||
xi = 0.5;
|
||||
}
|
||||
if (isNaN(yi)) {
|
||||
yi = 0.5;
|
||||
}
|
||||
var svgBox = this.svg.getClientRects()[0]
|
||||
// this.paper.getBBox()
|
||||
var cbox = element.getBoundingClientRect();
|
||||
var x = cbox.left + xi * cbox.width -svgBox.left;
|
||||
var y = cbox.top + yi * cbox.height -svgBox.top;
|
||||
//
|
||||
var matrix = this.svg.createSVGMatrix()
|
||||
matrix = matrix.translate(x, y)
|
||||
matrix = matrix[op].apply(matrix, inputs);
|
||||
matrix = matrix.translate(-x, -y);
|
||||
|
||||
var transform = this.svg.createSVGTransform();
|
||||
transform.setMatrix(matrix);
|
||||
//element.transform.baseVal.appendItem(transform); // for reverse order
|
||||
element.transform.baseVal.insertItemBefore(transform, 0) // normal order
|
||||
}
|
||||
|
||||
/*
|
||||
* transform an element to be the left of an isometric cube
|
||||
* Inputs: dom element, angle in degrees, and xi,yi which
|
||||
* are the transform origin as a fraction of element size
|
||||
*/
|
||||
SvgCube.prototype.toLeft = function (element, angle, xi, yi) {
|
||||
// half it's width
|
||||
xi = 0
|
||||
yi = 1
|
||||
if (this.f>0){
|
||||
this.svgTransform(element, 'scaleNonUniform', [1,this.f],0.5,0.5)
|
||||
}
|
||||
this.svgTransform(element, 'translate', [-1, -1]) // pixel adjustment HACK
|
||||
this.svgTransform(element, 'scaleNonUniform', [1 / 2, 1 / 2], xi, yi)
|
||||
// skew it, in degrees
|
||||
this.svgTransform(element, 'skewY', [angle], xi, yi)
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* transform an element to be the right of an isometric cube
|
||||
* Inputs: dom element, angle in degrees, and xi,yi which
|
||||
* are the transform origin as a fraction of element size
|
||||
*/
|
||||
SvgCube.prototype.toRight = function (element, angle, xi, yi) {
|
||||
xi = 1
|
||||
yi = 1
|
||||
if (this.f>0){
|
||||
this.svgTransform(element, 'scaleNonUniform', [1,this.f],0.5,0.5)
|
||||
}
|
||||
this.svgTransform(element, 'translate', [-1, -2]) // pixel adjustment HACK
|
||||
// half it's width to fiit in canvas
|
||||
this.svgTransform(element, 'scaleNonUniform', [1 / 2, 1 / 2], xi, yi)
|
||||
// skew it
|
||||
this.svgTransform(element, 'skewY', [-angle], xi, yi)
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* transform an element to be the top of an isometric cube
|
||||
* Inputs: dom element, angle in degrees, and xi,yi which
|
||||
* are the transform origin as a fraction of element size
|
||||
*/
|
||||
SvgCube.prototype.toTop = function (element, angle, xi, yi) {
|
||||
var rot = angle * Math.PI / 180;
|
||||
this.svgTransform(element, 'translate', [-2, -1]) // pixel adjustment HACK
|
||||
|
||||
// rotate so it's a diamond
|
||||
this.svgTransform(element, 'rotate', [45], xi, yi)
|
||||
// squish - along x axis to fit in canvas, along y axis for perspective change
|
||||
this.svgTransform(element, 'scaleNonUniform', [Math.sin(45 * Math.PI / 180), Math.tan(rot) * Math.sin(45 * Math.PI / 180)], xi, yi)
|
||||
}
|
||||
|
||||
SvgCube.prototype.moveTop = function (element) {
|
||||
// align top of cube with top of canvas
|
||||
var cbox = element.getBoundingClientRect();
|
||||
this.svgTransform(element, 'translate', [-cbox.left + this.pPx, -cbox.top + this.pPx])
|
||||
}
|
||||
|
||||
/*
|
||||
* align left of cube with top,
|
||||
* fit upper-left of left panel with middle-left of top panel
|
||||
*/
|
||||
SvgCube.prototype.moveLeft = function (elem, elemT) {
|
||||
var cboxL = elem.getBoundingClientRect();
|
||||
var cboxT = elemT.getBoundingClientRect();
|
||||
// align left
|
||||
var x = cboxT.left - cboxL.left
|
||||
// align top of left with half height of
|
||||
var y = cboxT.top - cboxL.top + cboxT.height / 2
|
||||
this.svgTransform(elem, 'translate', [x, y])
|
||||
}
|
||||
|
||||
/*
|
||||
* align right of cube with top,
|
||||
* fit upper-right of right panel with middle-right of top panel
|
||||
*/
|
||||
SvgCube.prototype.moveRight = function (elem, elemT) {
|
||||
// line up left with top, move to half tops height, and to align left
|
||||
var cboxL = elem.getBoundingClientRect();
|
||||
var cboxT = elemT.getBoundingClientRect();
|
||||
|
||||
// align right with right
|
||||
var x = cboxT.right - cboxL.right
|
||||
|
||||
// align top of left with half height of
|
||||
var y = cboxT.top - cboxL.top + cboxT.height / 2
|
||||
this.svgTransform(elem, 'translate', [x, y])
|
||||
}
|
||||
|
||||
/* draw outline get line color from option.strokeColor, and width from options.stroke-width */
|
||||
SvgCube.prototype.drawOutline = function(lw){
|
||||
lw=lw||this.options.stroke["stroke-width"];
|
||||
var ms = this.measurements(lw/2)
|
||||
|
||||
|
||||
var tb = this.imageT.getBBox()
|
||||
var lb = this.imageL.getBBox()
|
||||
var rb = this.imageR.getBBox()
|
||||
|
||||
// Draw outline of top
|
||||
var strTop=
|
||||
'M'+ms.mw +' '+ms.th +' '+ // Move to bottom
|
||||
'L'+ms.bw +' '+ms.mh+' '+ // left
|
||||
'L'+ms.mw +' '+ms.bh+ ' '+ // top
|
||||
'L'+ms.tw +' '+ms.mh+' '+ // right
|
||||
'Z' // close
|
||||
var pathTop = this.paper.path(strTop);
|
||||
|
||||
// // outline of left
|
||||
var strLeft=
|
||||
'M'+ms.mw +' '+ms.th+' '+ // middle
|
||||
'L'+ms.bw +' '+ms.uq+' '+ // left top
|
||||
'L'+ms.bw +' '+ms.lq+' '+ // left bottom
|
||||
'L'+ms.mw +' '+ms.sh+' '+ // middle bottom
|
||||
'Z'
|
||||
var pathLeft = this.paper.path(strLeft);
|
||||
//
|
||||
// right
|
||||
var strRight=
|
||||
'M'+ms.mw +' '+ms.th+' '+ // middle
|
||||
'L'+ms.mw +' '+ms.sh +' '+ // middle bottom
|
||||
'L'+ms.tw +' '+ms.lq+' '+ // right bottom
|
||||
'L'+ms.tw +' '+ms.uq+' '+ // right top
|
||||
'Z' // close
|
||||
var pathRight = this.paper.path(strRight);
|
||||
|
||||
// join into set
|
||||
var pathGroup = this.paper.group();
|
||||
pathGroup.append(pathTop);
|
||||
pathGroup.append(pathLeft);
|
||||
pathGroup.append(pathRight);
|
||||
|
||||
// set attrs from options
|
||||
// ref http://raphaeljs.com/reference.html#Element.attr
|
||||
var blackList = ['url','target','src','title']
|
||||
for (var a in this.options.stroke){
|
||||
if (this.options.stroke.hasOwnProperty(a) && blackList.indexOf(a)<0){
|
||||
pathGroup.attr(a,this.options.stroke[a]);
|
||||
}
|
||||
}
|
||||
this.outline=pathGroup;
|
||||
}
|
||||
|
||||
|
||||
/* draw outline get line color from option.strokeColor, and width from options.stroke-width */
|
||||
SvgCube.prototype.drawShading = function(lw){
|
||||
lw=lw||this.options.stroke["stroke-width"];
|
||||
var ms = this.measurements(0);
|
||||
var pathGroup = this.paper.g();
|
||||
|
||||
var strTop=
|
||||
'M'+ms.mw +' '+ms.th +' '+ // Move to bottom
|
||||
'L'+ms.bw +' '+ms.mh+' '+ // left
|
||||
'L'+ms.mw +' '+ms.bh+ ' '+ // top
|
||||
'L'+ms.tw +' '+ms.mh+' '+ // right
|
||||
'Z' // close
|
||||
var pathTop = this.paper.path(strTop);
|
||||
pathGroup.append(pathTop);
|
||||
|
||||
// outline of left
|
||||
var strLeft=
|
||||
'M'+ms.mw +' '+ms.th+' '+ // middle
|
||||
'L'+ms.bw +' '+ms.uq+' '+ // left top
|
||||
'L'+ms.bw +' '+ms.lq+' '+ // left bottom
|
||||
'L'+ms.mw +' '+ms.sh+' '+ // middle bottom
|
||||
'Z'
|
||||
var pathLeft = this.paper.path(strLeft);
|
||||
pathGroup.append(pathLeft);
|
||||
|
||||
// last line from middle down
|
||||
var strRight=
|
||||
'M'+ms.mw +' '+ms.th+' '+ // middle
|
||||
'L'+ms.mw +' '+ms.sh +' '+ // middle bottom
|
||||
'L'+ms.tw +' '+ms.lq+' '+ // right bottom
|
||||
'L'+ms.tw +' '+ms.uq+' '+ // right top
|
||||
'Z' // close
|
||||
var pathRight = this.paper.path(strRight);
|
||||
pathGroup.append(pathRight);
|
||||
|
||||
|
||||
// style the set
|
||||
pathGroup.attr({
|
||||
'stroke': 'none',
|
||||
'fill': 'black',
|
||||
'stroke-width': 0,
|
||||
'stroke-opacity': 0,
|
||||
'stroke-linecap': 'round',
|
||||
'stroke-linejoin': 'round'
|
||||
});
|
||||
// shade each side, 0 is no shading, 1 is black
|
||||
pathTop.attr({'fill-opacity': this.options.topShad});
|
||||
pathLeft.attr({'fill-opacity': this.options.leftShad});
|
||||
pathRight.attr({'fill-opacity': this.options.rightShad});
|
||||
this.shading=pathGroup;
|
||||
|
||||
}
|
||||
|
||||
/*clip the cube using an elipse to give rounded corners */
|
||||
SvgCube.prototype.clipCircle = function(amount){
|
||||
var cp = document.createElementNS("http://www.w3.org/2000/svg","clipPath")
|
||||
cp.id="cp";
|
||||
var rxc=51+4*(1-this.f)*(1-this.f);
|
||||
var ryc=50-2/Math.sqrt(1-this.f);
|
||||
cp.innerHTML = '<ellipse xmlns="http://www.w3.org/2000/svg" cx="50%" cy="50%" rx="'+rxc+'%" ry="'+ryc+'%" fill="white"/>'
|
||||
this.paper.node.getElementsByTagName("defs")[0].appendChild(cp);
|
||||
this.paper.node.setAttribute("clip-path","url(#cp)");
|
||||
}
|
||||
|
||||
|
||||
/* returns svg string */
|
||||
SvgCube.prototype.toSVG = function(){
|
||||
var svg3 = this.paper.toString();
|
||||
//var svg = this.paper.node.outerHTML;
|
||||
//var svg2 = xmlserializer.serializeToString(this.paper.node);
|
||||
if (this.paper.node.attributes.getNamedItem("clip-path")){
|
||||
// patch svg export to add clip
|
||||
// HACK I have to add these manually to the export sadly as raphael.export doesn't handle them and also misses some recent change to canvas
|
||||
svg3=svg3.replace("<svg",'<svg clip-path="url(#cp)"')
|
||||
svg3=svg3.replace("<image",this.paper.node.getElementsByTagName("defs")[0].outerHTML+"<image")
|
||||
svg3=svg3.replace("clippath","clipPath")
|
||||
svg3=svg3.replace("clippath","clipPath")
|
||||
|
||||
}
|
||||
return svg3
|
||||
}
|
||||
|
||||
/* draw cube from urls in options and outline according to options */
|
||||
SvgCube.prototype.drawCube = function (){
|
||||
|
||||
var imgS = this.options.size / Math.sqrt(2);
|
||||
this.cube = this.paper.g();
|
||||
this.cube.attr({
|
||||
class: 'cube cube2',
|
||||
id: "c2notnested",
|
||||
});
|
||||
this.leftImg = this.cube.image(this.options.leftUrl,0,0,imgS,imgS);
|
||||
this.leftImg.attr({
|
||||
class: 'face left',
|
||||
})
|
||||
this.rightImg = this.cube.image(this.options.rightUrl,0,0,imgS,imgS);
|
||||
this.rightImg.attr({
|
||||
class: 'face right',
|
||||
})
|
||||
this.topImg = this.cube.image(this.options.topUrl,0,0,imgS,imgS);
|
||||
this.topImg.attr({
|
||||
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)};
|
||||
}
|
||||
|
||||
// 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"
|
||||
}
|
||||
|
||||
|
||||
try{
|
||||
module.exports=SvgCube
|
||||
} catch(e){};
|
||||
@@ -0,0 +1,477 @@
|
||||
'use strict';
|
||||
// http://cssdeck.com/labs/pure-css-animated-isometric-boxes
|
||||
try{
|
||||
var Snap = require('snapsvg');
|
||||
} catch(e) {};
|
||||
|
||||
var SvgCube = function (options) {
|
||||
|
||||
// Inputs and options
|
||||
var defaultOptions = {
|
||||
angle: 30,
|
||||
size: 64,
|
||||
verbose: false,
|
||||
// outline
|
||||
drawOutline: true,
|
||||
drawShading: true,
|
||||
clipCircle: false,
|
||||
stroke: {
|
||||
"arrow-end": 'none',
|
||||
"stroke": 'black', // stroke color for outline
|
||||
"stroke-width": Math.sqrt(options.size)/2, // outline width
|
||||
"stroke-linecap": "round",
|
||||
"stroke-linejoin": "round",
|
||||
"fill": "none",
|
||||
},
|
||||
// cube
|
||||
flatten: 0, // fraction to vertically flatten the cube
|
||||
topUrl: '', // url for image in top of cuve
|
||||
topRot: 0, // rotation of top image in degrees
|
||||
topShad: 0, // shading for top
|
||||
leftUrl: '',
|
||||
leftRot: 0,
|
||||
leftShad: 0.1,
|
||||
rightUrl: '',
|
||||
rightRot: 0,
|
||||
rightShad: 0.3,
|
||||
svgNS: "http://www.w3.org/2000/svg",
|
||||
padding: 0,
|
||||
rotateX: 0,
|
||||
rotateY: 0,
|
||||
rotateZ: 0,
|
||||
perspective: 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];
|
||||
}
|
||||
}
|
||||
}
|
||||
this.options = options
|
||||
|
||||
this.init();
|
||||
|
||||
}
|
||||
|
||||
SvgCube.prototype.init = function(){
|
||||
|
||||
this.angle = this.options.angle
|
||||
|
||||
this.w = this.options.size; // input image width
|
||||
this.h = this.options.size;
|
||||
this.f = this.options.flatten
|
||||
|
||||
this.rot = this.angle * Math.PI / 180
|
||||
this.padding = this.options.padding; // pading fraction
|
||||
|
||||
|
||||
this.cw = this.w; // we will keep same width but change height
|
||||
this.ch = (1 + this.padding) * (this.h / 2 + this.h * Math.tan(this.rot)) -this.h/2*(1-this.f); //canvas height full
|
||||
|
||||
// create SVG element
|
||||
this.paper = Snap(this.cw, this.ch);
|
||||
this.svg=this.paper.node
|
||||
var o = this.options;
|
||||
|
||||
var style = document.createElement('style');
|
||||
this.paper.defs.appendChild(style)
|
||||
var styleStr = ` <style>
|
||||
.cube, .cube .face, .cube .face * {
|
||||
height: ${o.size}px;
|
||||
width: ${o.size}px;
|
||||
}
|
||||
.cube {
|
||||
position: absolute;
|
||||
background-color: #f66;
|
||||
|
||||
-webkit-transform: translate(${this.cw/2}px,${0*this.ch/2}px) perspective(${o.perspective}px) rotateX(${o.rotateX}deg) rotateY(${o.rotateY}deg) rotateZ(${o.rotateZ}deg);
|
||||
-webkit-transform-style: preserve-3d;
|
||||
-webkit-transition: .25s;
|
||||
}
|
||||
|
||||
|
||||
.cube * {
|
||||
transform-origin: 0% 100%;
|
||||
}
|
||||
|
||||
.cube2 .top {
|
||||
position: relative;
|
||||
-webkit-transform: rotateX(45deg) rotateZ(-45deg) rotateX(0deg);
|
||||
-webkit-transform-style: preserve-3d;
|
||||
-webkit-transition: .25s;
|
||||
|
||||
}
|
||||
.cube2 .left {
|
||||
-webkit-transform: rotateX(45deg) rotateZ(-45deg) rotateX(90deg);
|
||||
-webkit-transform-style: preserve-3d;
|
||||
-webkit-transition: .25s;
|
||||
position: absolute;
|
||||
|
||||
}
|
||||
.cube2 .right {
|
||||
-webkit-transform: rotateX(45deg) rotateZ(-45deg) rotateY(90deg);
|
||||
-webkit-transform-style: preserve-3d;
|
||||
-webkit-transition: .25s;
|
||||
position: absolute;
|
||||
}
|
||||
</style>`
|
||||
console.log(styleStr);
|
||||
style.innerHTML= styleStr
|
||||
|
||||
}
|
||||
|
||||
/* drawing measurements as a function of padding */
|
||||
SvgCube.prototype.measurements= function(p){
|
||||
if (p===undefined){
|
||||
p=0;
|
||||
}
|
||||
|
||||
var f = this.options.flatten
|
||||
|
||||
var tBox = this.imageT.getBBox()
|
||||
var lBox = this.imageL.getBBox()
|
||||
var rBox = this.imageR.getBBox()
|
||||
|
||||
return {
|
||||
// measurements
|
||||
uf : 1-f,
|
||||
p : 0, // lw/2, // padding
|
||||
|
||||
tw: this.cw-p/2, // right side. adjust by half line thickness to keep line in canvas
|
||||
th: tBox.height-p/2, // height of square, and dist to middle
|
||||
|
||||
mw: this.cw/2, // middle x
|
||||
mh: tBox.height/2, // middle of top square
|
||||
|
||||
bh: 0+p/2, // top of picture, bottom y
|
||||
bw: 0+p/2, // left of picture, bottom of x
|
||||
|
||||
sw: this.cw-p/2,// bottom of cube
|
||||
sh: this.ch-p/2, // right of cube
|
||||
|
||||
lq: -tBox.height/2+this.ch-p/2, // lower quarter of height
|
||||
uq: tBox.height/2+p/2 // upper quarter
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Adds a svg transform to an element, the transform has the origin of
|
||||
* xi,yi fraction of the element, so 0.5,0.5 is the middle,
|
||||
* unlike normalsvg it adds transforms in order of application not reverse order
|
||||
* Usage: svgTransform(elementImage,'rotate',[45],0.5,0.5)
|
||||
* This would rotate 45 degrees around center of image
|
||||
*/
|
||||
SvgCube.prototype.svgTransform = function (element, op, inputs, xi, yi) {
|
||||
if (isNaN(xi)) {
|
||||
xi = 0.5;
|
||||
}
|
||||
if (isNaN(yi)) {
|
||||
yi = 0.5;
|
||||
}
|
||||
var svgBox = this.svg.getClientRects()[0]
|
||||
// this.paper.getBBox()
|
||||
var cbox = element.getBoundingClientRect();
|
||||
var x = cbox.left + xi * cbox.width -svgBox.left;
|
||||
var y = cbox.top + yi * cbox.height -svgBox.top;
|
||||
//
|
||||
var matrix = this.svg.createSVGMatrix()
|
||||
matrix = matrix.translate(x, y)
|
||||
matrix = matrix[op].apply(matrix, inputs);
|
||||
matrix = matrix.translate(-x, -y);
|
||||
|
||||
var transform = this.svg.createSVGTransform();
|
||||
transform.setMatrix(matrix);
|
||||
//element.transform.baseVal.appendItem(transform); // for reverse order
|
||||
element.transform.baseVal.insertItemBefore(transform, 0) // normal order
|
||||
}
|
||||
|
||||
/*
|
||||
* transform an element to be the left of an isometric cube
|
||||
* Inputs: dom element, angle in degrees, and xi,yi which
|
||||
* are the transform origin as a fraction of element size
|
||||
*/
|
||||
SvgCube.prototype.toLeft = function (element, angle, xi, yi) {
|
||||
// half it's width
|
||||
xi = 0
|
||||
yi = 1
|
||||
if (this.f>0){
|
||||
this.svgTransform(element, 'scaleNonUniform', [1,this.f],0.5,0.5)
|
||||
}
|
||||
this.svgTransform(element, 'translate', [-1, -1]) // pixel adjustment HACK
|
||||
this.svgTransform(element, 'scaleNonUniform', [1 / 2, 1 / 2], xi, yi)
|
||||
// skew it, in degrees
|
||||
this.svgTransform(element, 'skewY', [angle], xi, yi)
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* transform an element to be the right of an isometric cube
|
||||
* Inputs: dom element, angle in degrees, and xi,yi which
|
||||
* are the transform origin as a fraction of element size
|
||||
*/
|
||||
SvgCube.prototype.toRight = function (element, angle, xi, yi) {
|
||||
xi = 1
|
||||
yi = 1
|
||||
if (this.f>0){
|
||||
this.svgTransform(element, 'scaleNonUniform', [1,this.f],0.5,0.5)
|
||||
}
|
||||
this.svgTransform(element, 'translate', [-1, -2]) // pixel adjustment HACK
|
||||
// half it's width to fiit in canvas
|
||||
this.svgTransform(element, 'scaleNonUniform', [1 / 2, 1 / 2], xi, yi)
|
||||
// skew it
|
||||
this.svgTransform(element, 'skewY', [-angle], xi, yi)
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* transform an element to be the top of an isometric cube
|
||||
* Inputs: dom element, angle in degrees, and xi,yi which
|
||||
* are the transform origin as a fraction of element size
|
||||
*/
|
||||
SvgCube.prototype.toTop = function (element, angle, xi, yi) {
|
||||
var rot = angle * Math.PI / 180;
|
||||
this.svgTransform(element, 'translate', [-2, -1]) // pixel adjustment HACK
|
||||
|
||||
// rotate so it's a diamond
|
||||
this.svgTransform(element, 'rotate', [45], xi, yi)
|
||||
// squish - along x axis to fit in canvas, along y axis for perspective change
|
||||
this.svgTransform(element, 'scaleNonUniform', [Math.sin(45 * Math.PI / 180), Math.tan(rot) * Math.sin(45 * Math.PI / 180)], xi, yi)
|
||||
}
|
||||
|
||||
SvgCube.prototype.moveTop = function (element) {
|
||||
// align top of cube with top of canvas
|
||||
var cbox = element.getBoundingClientRect();
|
||||
this.svgTransform(element, 'translate', [-cbox.left + this.pPx, -cbox.top + this.pPx])
|
||||
}
|
||||
|
||||
/*
|
||||
* align left of cube with top,
|
||||
* fit upper-left of left panel with middle-left of top panel
|
||||
*/
|
||||
SvgCube.prototype.moveLeft = function (elem, elemT) {
|
||||
var cboxL = elem.getBoundingClientRect();
|
||||
var cboxT = elemT.getBoundingClientRect();
|
||||
// align left
|
||||
var x = cboxT.left - cboxL.left
|
||||
// align top of left with half height of
|
||||
var y = cboxT.top - cboxL.top + cboxT.height / 2
|
||||
this.svgTransform(elem, 'translate', [x, y])
|
||||
}
|
||||
|
||||
/*
|
||||
* align right of cube with top,
|
||||
* fit upper-right of right panel with middle-right of top panel
|
||||
*/
|
||||
SvgCube.prototype.moveRight = function (elem, elemT) {
|
||||
// line up left with top, move to half tops height, and to align left
|
||||
var cboxL = elem.getBoundingClientRect();
|
||||
var cboxT = elemT.getBoundingClientRect();
|
||||
|
||||
// align right with right
|
||||
var x = cboxT.right - cboxL.right
|
||||
|
||||
// align top of left with half height of
|
||||
var y = cboxT.top - cboxL.top + cboxT.height / 2
|
||||
this.svgTransform(elem, 'translate', [x, y])
|
||||
}
|
||||
|
||||
/* draw outline get line color from option.strokeColor, and width from options.stroke-width */
|
||||
SvgCube.prototype.drawOutline = function(lw){
|
||||
lw=lw||this.options.stroke["stroke-width"];
|
||||
var ms = this.measurements(lw/2)
|
||||
|
||||
|
||||
var tb = this.imageT.getBBox()
|
||||
var lb = this.imageL.getBBox()
|
||||
var rb = this.imageR.getBBox()
|
||||
|
||||
// Draw outline of top
|
||||
var strTop=
|
||||
'M'+ms.mw +' '+ms.th +' '+ // Move to bottom
|
||||
'L'+ms.bw +' '+ms.mh+' '+ // left
|
||||
'L'+ms.mw +' '+ms.bh+ ' '+ // top
|
||||
'L'+ms.tw +' '+ms.mh+' '+ // right
|
||||
'Z' // close
|
||||
var pathTop = this.paper.path(strTop);
|
||||
|
||||
// // outline of left
|
||||
var strLeft=
|
||||
'M'+ms.mw +' '+ms.th+' '+ // middle
|
||||
'L'+ms.bw +' '+ms.uq+' '+ // left top
|
||||
'L'+ms.bw +' '+ms.lq+' '+ // left bottom
|
||||
'L'+ms.mw +' '+ms.sh+' '+ // middle bottom
|
||||
'Z'
|
||||
var pathLeft = this.paper.path(strLeft);
|
||||
//
|
||||
// right
|
||||
var strRight=
|
||||
'M'+ms.mw +' '+ms.th+' '+ // middle
|
||||
'L'+ms.mw +' '+ms.sh +' '+ // middle bottom
|
||||
'L'+ms.tw +' '+ms.lq+' '+ // right bottom
|
||||
'L'+ms.tw +' '+ms.uq+' '+ // right top
|
||||
'Z' // close
|
||||
var pathRight = this.paper.path(strRight);
|
||||
|
||||
// join into set
|
||||
var pathGroup = this.paper.group();
|
||||
pathGroup.append(pathTop);
|
||||
pathGroup.append(pathLeft);
|
||||
pathGroup.append(pathRight);
|
||||
|
||||
// set attrs from options
|
||||
// ref http://raphaeljs.com/reference.html#Element.attr
|
||||
var blackList = ['url','target','src','title']
|
||||
for (var a in this.options.stroke){
|
||||
if (this.options.stroke.hasOwnProperty(a) && blackList.indexOf(a)<0){
|
||||
pathGroup.attr(a,this.options.stroke[a]);
|
||||
}
|
||||
}
|
||||
this.outline=pathGroup;
|
||||
}
|
||||
|
||||
|
||||
/* draw outline get line color from option.strokeColor, and width from options.stroke-width */
|
||||
SvgCube.prototype.drawShading = function(lw){
|
||||
lw=lw||this.options.stroke["stroke-width"];
|
||||
var ms = this.measurements(0);
|
||||
var pathGroup = this.paper.g();
|
||||
|
||||
var strTop=
|
||||
'M'+ms.mw +' '+ms.th +' '+ // Move to bottom
|
||||
'L'+ms.bw +' '+ms.mh+' '+ // left
|
||||
'L'+ms.mw +' '+ms.bh+ ' '+ // top
|
||||
'L'+ms.tw +' '+ms.mh+' '+ // right
|
||||
'Z' // close
|
||||
var pathTop = this.paper.path(strTop);
|
||||
pathGroup.append(pathTop);
|
||||
|
||||
// outline of left
|
||||
var strLeft=
|
||||
'M'+ms.mw +' '+ms.th+' '+ // middle
|
||||
'L'+ms.bw +' '+ms.uq+' '+ // left top
|
||||
'L'+ms.bw +' '+ms.lq+' '+ // left bottom
|
||||
'L'+ms.mw +' '+ms.sh+' '+ // middle bottom
|
||||
'Z'
|
||||
var pathLeft = this.paper.path(strLeft);
|
||||
pathGroup.append(pathLeft);
|
||||
|
||||
// last line from middle down
|
||||
var strRight=
|
||||
'M'+ms.mw +' '+ms.th+' '+ // middle
|
||||
'L'+ms.mw +' '+ms.sh +' '+ // middle bottom
|
||||
'L'+ms.tw +' '+ms.lq+' '+ // right bottom
|
||||
'L'+ms.tw +' '+ms.uq+' '+ // right top
|
||||
'Z' // close
|
||||
var pathRight = this.paper.path(strRight);
|
||||
pathGroup.append(pathRight);
|
||||
|
||||
|
||||
// style the set
|
||||
pathGroup.attr({
|
||||
'stroke': 'none',
|
||||
'fill': 'black',
|
||||
'stroke-width': 0,
|
||||
'stroke-opacity': 0,
|
||||
'stroke-linecap': 'round',
|
||||
'stroke-linejoin': 'round'
|
||||
});
|
||||
// shade each side, 0 is no shading, 1 is black
|
||||
pathTop.attr({'fill-opacity': this.options.topShad});
|
||||
pathLeft.attr({'fill-opacity': this.options.leftShad});
|
||||
pathRight.attr({'fill-opacity': this.options.rightShad});
|
||||
this.shading=pathGroup;
|
||||
|
||||
}
|
||||
|
||||
/*clip the cube using an elipse to give rounded corners */
|
||||
SvgCube.prototype.clipCircle = function(amount){
|
||||
var cp = document.createElementNS("http://www.w3.org/2000/svg","clipPath")
|
||||
cp.id="cp";
|
||||
var rxc=51+4*(1-this.f)*(1-this.f);
|
||||
var ryc=50-2/Math.sqrt(1-this.f);
|
||||
cp.innerHTML = '<ellipse xmlns="http://www.w3.org/2000/svg" cx="50%" cy="50%" rx="'+rxc+'%" ry="'+ryc+'%" fill="white"/>'
|
||||
this.paper.node.getElementsByTagName("defs")[0].appendChild(cp);
|
||||
this.paper.node.setAttribute("clip-path","url(#cp)");
|
||||
}
|
||||
|
||||
|
||||
/* returns svg string */
|
||||
SvgCube.prototype.toSVG = function(){
|
||||
var svg3 = this.paper.toString();
|
||||
//var svg = this.paper.node.outerHTML;
|
||||
//var svg2 = xmlserializer.serializeToString(this.paper.node);
|
||||
if (this.paper.node.attributes.getNamedItem("clip-path")){
|
||||
// patch svg export to add clip
|
||||
// HACK I have to add these manually to the export sadly as raphael.export doesn't handle them and also misses some recent change to canvas
|
||||
svg3=svg3.replace("<svg",'<svg clip-path="url(#cp)"')
|
||||
svg3=svg3.replace("<image",this.paper.node.getElementsByTagName("defs")[0].outerHTML+"<image")
|
||||
svg3=svg3.replace("clippath","clipPath")
|
||||
svg3=svg3.replace("clippath","clipPath")
|
||||
|
||||
}
|
||||
return svg3
|
||||
}
|
||||
|
||||
/* draw cube from urls in options and outline according to options */
|
||||
SvgCube.prototype.drawCube = function (){
|
||||
|
||||
var imgS = this.options.size / Math.sqrt(2);
|
||||
this.cube = this.paper.g();
|
||||
this.cube.attr({
|
||||
class: 'cube cube2',
|
||||
id: "c2notnested",
|
||||
});
|
||||
this.leftImg = this.cube.image(this.options.leftUrl,0,0,imgS,imgS);
|
||||
this.leftImg.attr({
|
||||
class: 'face left',
|
||||
})
|
||||
this.rightImg = this.cube.image(this.options.rightUrl,0,0,imgS,imgS);
|
||||
this.rightImg.attr({
|
||||
class: 'face right',
|
||||
})
|
||||
this.topImg = this.cube.image(this.options.topUrl,0,0,imgS,imgS);
|
||||
this.topImg.attr({
|
||||
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)};
|
||||
}
|
||||
|
||||
// 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){};
|
||||
@@ -0,0 +1,48 @@
|
||||
var page = require('webpage').create(),
|
||||
system = require('system'),
|
||||
address, output, size;
|
||||
|
||||
if (system.args.length < 3 || system.args.length > 5) {
|
||||
console.log('Usage: rasterize.js URL filename [paperwidth*paperheight|paperformat] [zoom]');
|
||||
console.log(' paper (pdf output) examples: "5in*7.5in", "10cm*20cm", "A4", "Letter"');
|
||||
console.log(' image (png/jpg output) examples: "1920px" entire page, window width 1920px');
|
||||
console.log(' "800px*600px" window, clipped to 800x600');
|
||||
phantom.exit(1);
|
||||
} else {
|
||||
address = system.args[1];
|
||||
output = system.args[2];
|
||||
page.viewportSize = { width: 600, height: 600 };
|
||||
if (system.args.length > 3 && system.args[2].substr(-4) === ".pdf") {
|
||||
size = system.args[3].split('*');
|
||||
page.paperSize = size.length === 2 ? { width: size[0], height: size[1], margin: '0px' }
|
||||
: { format: system.args[3], orientation: 'portrait', margin: '1cm' };
|
||||
} else if (system.args.length > 3 && system.args[3].substr(-2) === "px") {
|
||||
size = system.args[3].split('*');
|
||||
if (size.length === 2) {
|
||||
pageWidth = parseInt(size[0], 10);
|
||||
pageHeight = parseInt(size[1], 10);
|
||||
page.viewportSize = { width: pageWidth, height: pageHeight };
|
||||
page.clipRect = { top: 0, left: 0, width: pageWidth, height: pageHeight };
|
||||
} else {
|
||||
console.log("size:", system.args[3]);
|
||||
pageWidth = parseInt(system.args[3], 10);
|
||||
pageHeight = parseInt(pageWidth * 3/4, 10); // it's as good an assumption as any
|
||||
console.log ("pageHeight:",pageHeight);
|
||||
page.viewportSize = { width: pageWidth, height: pageHeight };
|
||||
}
|
||||
}
|
||||
if (system.args.length > 4) {
|
||||
page.zoomFactor = system.args[4];
|
||||
}
|
||||
page.open(address, function (status) {
|
||||
if (status !== 'success') {
|
||||
console.log('Unable to load the address!');
|
||||
phantom.exit(1);
|
||||
} else {
|
||||
window.setTimeout(function () {
|
||||
page.render(output);
|
||||
phantom.exit();
|
||||
}, 200);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
After Width: | Height: | Size: 75 KiB |
@@ -0,0 +1,43 @@
|
||||
.cube, .cube .face, .cube .face * {
|
||||
height: 170px;
|
||||
width: 170px;
|
||||
}
|
||||
.cube {
|
||||
position: relative;
|
||||
-webkit-transform: translate(11em,11em)
|
||||
transform: translate(11em,11em)
|
||||
}
|
||||
|
||||
.cube * {
|
||||
transform-origin: 0% 100%;
|
||||
}
|
||||
|
||||
.cube2 .top {
|
||||
position: relative;
|
||||
-webkit-transform: rotateX(45deg) rotateZ(-45deg) rotateX(0deg);
|
||||
-webkit-transform-style: preserve-3d;
|
||||
-webkit-transition: .25s;
|
||||
transform: rotateX(45deg) rotateZ(-45deg) rotateX(0deg);
|
||||
transform-style: preserve-3d;
|
||||
transition: .25s;
|
||||
|
||||
}
|
||||
.cube2 .left {
|
||||
-webkit-transform: rotateX(45deg) rotateZ(-45deg) rotateX(90deg);
|
||||
-webkit-transform-style: preserve-3d;
|
||||
-webkit-transition: .25s;
|
||||
transform: rotateX(45deg) rotateZ(-45deg) rotateX(90deg);
|
||||
transform-style: preserve-3d;
|
||||
transition: .25s;
|
||||
position: absolute;
|
||||
|
||||
}
|
||||
.cube2 .right {
|
||||
-webkit-transform: rotateX(45deg) rotateZ(-45deg) rotateY(90deg);
|
||||
-webkit-transform-style: preserve-3d;
|
||||
-webkit-transition: .25s;
|
||||
transform: rotateX(45deg) rotateZ(-45deg) rotateY(90deg);
|
||||
transform-style: preserve-3d;
|
||||
transition: .25s;
|
||||
position: absolute;
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
<svg height="1128" version="1.1" width="1128" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg" >
|
||||
<desc>https://en.wikipedia.org/wiki/Isometric_projection </desc>
|
||||
<foreignObject>
|
||||
<style>
|
||||
.cube, .cube .face, .cube .face * {
|
||||
height: 170px;
|
||||
width: 170px;
|
||||
}
|
||||
.cube {
|
||||
position: relative;
|
||||
-webkit-transform: translate(11em,11em)
|
||||
}
|
||||
|
||||
.cube * {
|
||||
transform-origin: 0% 100%;
|
||||
}
|
||||
|
||||
.cube2 .top {
|
||||
position: relative;
|
||||
-webkit-transform: rotateX(45deg) rotateZ(-45deg) rotateX(0deg);
|
||||
-webkit-transform-style: preserve-3d;
|
||||
-webkit-transition: .25s;
|
||||
|
||||
}
|
||||
.cube2 .left {
|
||||
-webkit-transform: rotateX(45deg) rotateZ(-45deg) rotateX(90deg);
|
||||
-webkit-transform-style: preserve-3d;
|
||||
-webkit-transition: .25s;
|
||||
position: absolute;
|
||||
|
||||
}
|
||||
.cube2 .right {
|
||||
-webkit-transform: rotateX(45deg) rotateZ(-45deg) rotateY(90deg);
|
||||
-webkit-transform-style: preserve-3d;
|
||||
-webkit-transition: .25s;
|
||||
position: absolute;
|
||||
}
|
||||
</style>
|
||||
</foreignObject>
|
||||
|
||||
<g class="cube cube2" id="c2notnested" >
|
||||
<image
|
||||
class="face top"
|
||||
xlink:href="grass.svg"
|
||||
/>
|
||||
<image
|
||||
class="face left"
|
||||
xlink:href="grass.svg"
|
||||
/>
|
||||
<image
|
||||
class="face right"
|
||||
xlink:href="grass.svg"
|
||||
/>
|
||||
</g>
|
||||
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.7 KiB |
@@ -0,0 +1,97 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Snap.js isometric SVG</title>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div>
|
||||
|
||||
<button><a id="download" href="">Download</a></button
|
||||
</div>
|
||||
|
||||
</body>
|
||||
|
||||
<script type="text/javascript" src="../../node_modules/snapsvg/dist/snap.svg.js" ></script>
|
||||
<script type="text/javascript" src="http://cdnjs.cloudflare.com/ajax/libs/dat-gui/0.5/dat.gui.min.js" ></script>
|
||||
|
||||
<!-- <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/snap.svg/0.4.1/snap.svg-min.js"></script> -->
|
||||
<script src="projectSVG.js"></script>
|
||||
<script>
|
||||
|
||||
|
||||
var cube1
|
||||
var a = document.querySelector("#download")
|
||||
|
||||
a.onclick=function(){
|
||||
if (cube1){
|
||||
var angle = parseInt(angleInput.valueAsNumber/100)
|
||||
var f = parseInt(fInput.valueAsNumber/100)
|
||||
a.type = 'image/svg+xml';
|
||||
var svgString = cube1.toSVG();
|
||||
var blob = new Blob([svgString], {"type": "image/svg+xml"});
|
||||
a.download=cube1.options.topUrl+'_a'+angle+'_f'+f+'_cube.svg'
|
||||
a.href = (window.URL || webkitURL).createObjectURL(blob);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// redraw cube oninput
|
||||
var update = function () {
|
||||
if (cube1) {
|
||||
cube1.update()
|
||||
}
|
||||
}
|
||||
|
||||
window.onload = function () {
|
||||
|
||||
cube1 = new SvgCube({
|
||||
angle: 45,
|
||||
flatten: 0,
|
||||
topUrl: 'top.svg',
|
||||
leftUrl: 'front.svg',
|
||||
rightUrl: 'right.svg',
|
||||
clipCircle: false,
|
||||
stroke: {
|
||||
"arrow-end": 'none',
|
||||
"stroke": 'black', // stroke color for outline
|
||||
"stroke-width": 2, // outline width
|
||||
"stroke-linecap": "round",
|
||||
"stroke-linejoin": "round",
|
||||
"stroke-opacity": 0.5,
|
||||
},
|
||||
size: 256,
|
||||
});
|
||||
cube1.drawCube()
|
||||
|
||||
var gui = new dat.GUI();
|
||||
gui.remember(cube1.options);
|
||||
gui.add(cube1.options,'angle').min(0.00).max(90).step(1).onChange(update);
|
||||
gui.add(cube1.options,'flatten').min(0.00).max(90).step(1).onChange(update);
|
||||
gui.add(cube1.options,'size').min(1).max(512).step(1).onChange(update);
|
||||
|
||||
gui.add(cube1.options,'rotateX').min(0).max(360).step(1).onChange(update);
|
||||
gui.add(cube1.options,'rotateY').min(0).max(360).step(1).onChange(update);
|
||||
gui.add(cube1.options,'rotateZ').min(0).max(360).step(1).onChange(update);
|
||||
gui.add(cube1.options,'perspective').min(0).max(500).step(1).onChange(update);
|
||||
|
||||
gui.add(cube1.options,'topUrl').onChange(update);
|
||||
gui.add(cube1.options,'leftUrl').onChange(update);
|
||||
gui.add(cube1.options,'rightUrl').onChange(update);
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
var module
|
||||
if (module){
|
||||
module.exports=SvgCube
|
||||
}
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
</html>
|
||||
|
After Width: | Height: | Size: 73 KiB |
@@ -0,0 +1,52 @@
|
||||
var webdriverio = require('webdriverio');
|
||||
|
||||
var path = require('path');
|
||||
var fs = require('fs');
|
||||
var system = require('system')
|
||||
var globby = require('globby');
|
||||
|
||||
var options = {
|
||||
desiredCapabilities: {
|
||||
browserName: 'chrome'
|
||||
}
|
||||
};
|
||||
|
||||
var config = {
|
||||
debug: true
|
||||
}
|
||||
|
||||
var input = process.argv[2];
|
||||
console.log('input:',input);
|
||||
|
||||
|
||||
globby(input).then(inputs => {
|
||||
console.log('glob(',input,') =>', inputs);
|
||||
for (var i=0; i<inputs.length;i++){
|
||||
var file = inputs[i];
|
||||
|
||||
var address = path.join(process.cwd(),file);
|
||||
var url = 'file://'+path.join(process.cwd(),file);
|
||||
var outfile = address.replace('.svg','.png');
|
||||
|
||||
console.log(file, url,'=>',outfile);
|
||||
webdriverio
|
||||
.remote(options)
|
||||
.init()
|
||||
.url(url)
|
||||
.getTitle().then(function(title) {
|
||||
console.log('Title is: ' + title);
|
||||
})
|
||||
.saveScreenshot(
|
||||
[outfile],
|
||||
function(err, screenshot, response) {
|
||||
if (config.debug){
|
||||
console.log({file,err,screenshot,response});
|
||||
} else if (err){
|
||||
'saveScreenshot',console.log(err);
|
||||
}
|
||||
}
|
||||
)
|
||||
.end();
|
||||
}
|
||||
}, this)
|
||||
|
||||