Cropping works!

This commit is contained in:
2016-01-17 17:21:55 +08:00
parent 1f91c71657
commit ebb0d790ae
7 changed files with 377 additions and 224 deletions
+207 -166
View File
@@ -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 = ` <style id="projection">
.cube {
height: ${this.ch}px;
width: ${this.cw}px;
}
.face {
height: ${o.size}px;
width: ${o.size}px;
}
.cube {
position: absolute;
-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) scaleX(${o.scaleX}) scaleY(${o.scaleY}) scaleZ(${o.scaleZ});
-webkit-transform-style: preserve-3d;
-webkit-transition: 0.25s;
}
.back {
transform: translateZ(-${o.size/2}px) rotateY(180deg);
}
.right {
transform: rotateY(-270deg) translateX(${o.size/2}px);
transform-origin: center right;
}
.left {
transform: rotateY(270deg) translateX(-${o.size/2}px);
transform-origin: center left;
}
.top {
transform: rotateX(-90deg) translateY(-${o.size/2}px);
transform-origin: top center;
}
.bottom {
transform: rotateX(90deg) translateY(${o.size/2}px);
transform-origin: bottom center;
}
.front {
transform: translateZ(${o.size/2}px);
}
/* custom orientation/rotation settings for each image */
.back>embed{
transform: rotate(${o.backRot}deg);
}
.front>embed{
transform: rotate(${o.frontRot}deg);
}
.right>embed{
transform: rotate(${o.rightRot}deg);
}
.left>embed{
transform: rotate(${o.leftRot}deg);
}
.top>embed{
transform: rotate(${180+o.topRot}deg);
}
.bottom>embed{
transform: rotate(${o.bottomRot}deg);
}
b{
position:absolute;
transition: all 1s linear;
}
/* outline */
.face {
box-sizing: border-box;
border: ${o.stroke['stroke-width']}px solid ${o.stroke.stroke};
}
/* shade in sides */
.wrap {
overflow: hidden;
width: ${o.size}px;
margin: 0 auto;
}
.tint {
position: absolute;
}
.tint:before {
content: "";
display: block;
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
}
.tint:hover:before { background: none; }
.tint.top:before { background: rgba(0,0,0, ${o.topShad});}
.tint.left:before { background: rgba(0,0,0, ${o.leftShad});}
.tint.right:before { background: rgba(0,0,0, ${o.rightShad});}
.tint.back:before { background: rgba(0,0,0, ${o.backShad}); }
.tint.front:before { background: rgba(0,0,0, ${o.frontShad}); }
.tint.bottom:before { background: rgba(0,0,0, ${o.bottomShad}); }
/* curved cube. Need something block seeing through, and also extra faces, 1 px in, so inside looks uniform color. Only work for one main color */
/*.face {
border-radius: ${o.borderRadius}px;
}
.mid {
background-color: #e3e2db; /* make stroke color TODO */
border-radius: 0px;
}*/
</style>`
// Now we generate some css to put everything in good positions
var transitions = 0;
var styleStr = '' +
'<style id="projection"> ' +
' .cube { ' +
' height: ' + this.ch + 'px; ' +
' width: ' + this.cw + 'px; ' +
' } ' +
' .face { ' +
' height: ' + o.size + 'px; ' +
' width: ' + o.size + 'px; ' +
' } ' +
' .cube { ' +
' position: absolute; ' +
' -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) scaleX(' + o.scaleX + ') scaleY(' + o.scaleY + ') scaleZ(' + o.scaleZ + '); ' +
' -webkit-transform-style: preserve-3d; ' +
' -webkit-transition: '+transitions+'s; ' +
' } ' +
' .back { ' +
' transform: translateZ(-' + o.size / 2 + 'px) rotateY(180deg); ' +
' } ' +
' .right { ' +
' transform: rotateY(-270deg) translateX(' + o.size / 2 + 'px); ' +
' transform-origin: center right; ' +
' } ' +
' .left { ' +
' transform: rotateY(270deg) translateX(-' + o.size / 2 + 'px); ' +
' transform-origin: center left; ' +
' } ' +
' .top { ' +
' transform: rotateX(-90deg) translateY(-' + o.size / 2 + 'px); ' +
' transform-origin: top center; ' +
' } ' +
' .bottom { ' +
' transform: rotateX(90deg) translateY(' + o.size / 2 + 'px); ' +
' transform-origin: bottom center; ' +
' } ' +
' .front { ' +
' transform: translateZ(' + o.size / 2 + 'px); ' +
' } ' +
' /* custom orientation/rotation settings for each image */ ' +
' .back>embed{ ' +
' transform: rotate(' + o.backRot + 'deg); ' +
' } ' +
' .front>embed{ ' +
' transform: rotate(' + o.frontRot + 'deg); ' +
' } ' +
' .right>embed{ ' +
' transform: rotate(' + o.rightRot + 'deg); ' +
' } ' +
' .left>embed{ ' +
' transform: rotate(' + o.leftRot + 'deg); ' +
' } ' +
' .top>embed{ ' +
' transform: rotate(' + 90 + o.topRot + 'deg); ' +
' } ' +
' .bottom>embed{ ' +
' transform: rotate(' + o.bottomRot + 'deg); ' +
' } ' +
' b{ ' +
' position:absolute; ' +
' transition: all '+transitions+'s linear; ' +
' } ' +
' /* outline */ ' +
' .face { ' +
' box-sizing: border-box; ' +
' border: ' + o.stroke['stroke-width'] + 'px solid ' + o.stroke.stroke + '; ' +
' } ' +
' /* shade in sides */ ' +
' .wrap { ' +
' overflow: hidden; ' +
' width: ' + o.size + 'px; ' +
' margin: 0 auto; ' +
' } ' +
' .tint { ' +
' position: absolute; ' +
' } ' +
' .tint:before { ' +
' content: ""; ' +
' display: block; ' +
' position: absolute; ' +
' top: 0; ' +
' bottom: 0; ' +
' left: 0; ' +
' right: 0; ' +
' } ' +
' .tint:hover:before { background: none; } ' +
' .tint.top:before { background: rgba(0,0,0, ' + o.topShad + ');} ' +
' .tint.left:before { background: rgba(0,0,0, ' + o.leftShad + ');} ' +
' .tint.right:before { background: rgba(0,0,0, ' + o.rightShad + ');} ' +
' .tint.back:before { background: rgba(0,0,0, ' + o.backShad + '); } ' +
' .tint.front:before { background: rgba(0,0,0, ' + o.frontShad + '); } ' +
' .tint.bottom:before { background: rgba(0,0,0, ' + o.bottomShad + '); } ' +
' /* curved cube. Need something block seeing through, and also extra faces, 1 px in, so inside looks uniform color. Only work for one main color */ ' +
' /*.face { ' +
' border-radius: ' + o.borderRadius + 'px; ' +
' } ' +
' .mid { ' +
' background-color: #e3e2db; /* make stroke color TODO */ ' +
' border-radius: 0px; ' +
' }*/ ' +
' </style>';
if ($('body>.cube').length === 0) {
var cube = $('<div class="cube cube2"></div>')
var cube = $('<div class="cube cube2"></div>');
var imageFront = $(`<b width="256" height="256" class="front tint"><embed type="image/svg+xml" src="${o.frontUrl}" class="face"></embed></b>`)
var imageFront = $('<b width="256" height="256" class="front tint"><embed type="image/svg+xml" src="' + o.frontUrl + '" class="face"></embed></b>');
cube.append(imageFront);
var imageL = $(`<b width="256" height="256" class="left tint"><embed type="image/svg+xml" src="${o.leftUrl}" class="face"></embed></b>`)
var imageL = $('<b width="256" height="256" class="left tint"><embed type="image/svg+xml" src="' + o.leftUrl + '" class="face"></embed></b>');
cube.append(imageL);
var imageRight = $(`<b width="256" height="256" class="right tint"><embed type="image/svg+xml" src="${o.rightUrl}" class="face"></embed></b>`)
var imageRight = $('<b width="256" height="256" class="right tint"><embed type="image/svg+xml" src="' + o.rightUrl + '" class="face"></embed></b>');
cube.append(imageRight);
var imageTop = $(`<b width="256" height="256" class="top tint"><embed type="image/svg+xml" src="${o.topUrl}" class="face"></embed></b>`)
var imageTop = $('<b width="256" height="256" class="top tint"><embed type="image/svg+xml" src="' + o.topUrl + '" class="face"></embed></b>');
cube.append(imageTop);
var imageBack = $(`<b width="256" height="256" class="back tint"><embed type="image/svg+xml" src="${o.backUrl}" class="face"></embed></b>`)
var imageBack = $('<b width="256" height="256" class="back tint"><embed type="image/svg+xml" src="' + o.backUrl + '" class="face"></embed></b>');
cube.append(imageBack);
var imageBottom = $(`<b width="256" height="256" class="bottom tint"><embed type="image/svg+xml" src="${o.bottomUrl}" class="face"></embed></b>`)
var imageBottom = $('<b width="256" height="256" class="bottom tint"><embed type="image/svg+xml" src="' + o.bottomUrl + '" class="face"></embed></b>');
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());
};