emsApplication/applications/WebConfigure/web/js/bench.js

2639 lines
76 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

var Bench ={
create:function(id, options) {
var bn = {};
//public vars
bn.dirty = false; //is config need be saved
bn.shapes = []; //all shape instances in svg
bn.symbols = []; //all shape's template(symbol)
bn.paper = null; //raphael core container object
bn.temp = {}; //all vars in temp object
bn.enablePan = true; //
//bn.realScale = 20; //unit : meter for rule calculation
bn.options = {};
///////// function init code here /////////
bn.init = function (domId) {
//fields
bn.id = domId;
bn.domId = "#" + domId; //div id
//bn.offset = offset; //size of screen not belong to svg element
//states
bn.mouseState = "default"; //mouse state: default/drawFloor....
//members
bn.getSize = function () {
//var w = $(bn.domId).width();
var w = $(document).width() - 491;
var h = $(window).height() - $(bn.domId).position().top ;
//var h = $(window).height() - $(bn.domId).offset().top + 117;
//h = $(bn.domId).prop('scrollHeight');
return { width: w, height: h };
};
//inner functions
function createPaper() {
var size =bn.getSize();
bn.paper =new Raphael(document.getElementById(bn.id),
size.width, size.height);
bn.paper.canvas.setAttribute('preserveAspectRatio', 'xMidYMid meet');
bn.paper.setViewBox(0, 0, size.width, size.height);
bn.resetSelection();
}
function enablePaperResize() {
$(window).resize(function () {
if (bn.temp.resizeTO) clearTimeout(bn.temp.resizeTO);
bn.temp.resizeTO = setTimeout(function () {
$(this).trigger('resizeEnd');
}, 300);
});
$(window).unbind('resizeEnd').bind('resizeEnd', function () {
//resize canvas
bn.paper.setSize(bn.getSize().width,
bn.getSize().height);
});
}
function defineMouseBehavior() {
bn.viewBoxWidth = bn.paper.width;
bn.viewBoxHeight = bn.paper.height;
var canvasID = bn.domId;
var startX, startY;
var mousedown = false;
var dX, dY;
var oX = 0, oY = 0, oWidth = bn.viewBoxWidth, oHeight = bn.viewBoxHeight;
bn.viewBox = bn.paper.setViewBox(oX, oY, bn.viewBoxWidth, bn.viewBoxHeight);
bn.viewBox.X = oX;
bn.viewBox.Y = oY;
function handleZoom(delta) {
if (delta < 0) {
bn.setZoom(0.95);
}
else {
bn.setZoom(1.05);
}
}
//Event handler for mouse wheel event.
function wheel(e) {
var event = e.originalEvent;
var delta = 0;
if (!event) /* For IE. */
event = window.event;
if (event.wheelDelta) { /* IE/Opera. */
delta = event.wheelDelta / 120;
} else if (event.detail) {
/** Mozilla case. */
delta = -event.detail / 3;
}
/** If delta is nonzero, handle it.
* Basically, delta is now positive if wheel was scrolled up,
* and negative, if wheel was scrolled down.
*/
if (delta) {
handleZoom(delta);
}
//Prevent default actions caused by mouse wheel
if (event.preventDefault)
event.preventDefault();
event.returnValue = false;
}
$(canvasID).unbind('mousewheel DOMMouseScroll').bind(
{'mousewheel DOMMouseScroll': wheel});
function updateWallPath(mx, my) {
var cp = bn.canvasPoint(mx, my);
if (bn.temp.wallCache) {
var twidth = Math.abs(cp.x - bn.temp.wallCache.lastX);
var theight = Math.abs(cp.y - bn.temp.wallCache.lastY);
if (twidth > theight) {
bn.temp.wallCache.lastX = cp.x;
bn.temp.wallCache.path += " H " + cp.x + " ";
}
else {
bn.temp.wallCache.lastY = cp.y;
bn.temp.wallCache.path += " V " + cp.y + " ";
}
}
else {
bn.temp.wallCache = {};
bn.temp.wallCache.ps = [];
bn.temp.wallCache.path = "M " + cp.x + " " + cp.y + " ";
bn.temp.wallCache.lastX = cp.x;
bn.temp.wallCache.lastY = cp.y;
}
var p = bn.addShape("pointIndicator",
{x: bn.temp.wallCache.lastX, y: bn.temp.wallCache.lastY});
bn.temp.wallCache.ps.push(p);
}
function panWindow(px, py) {
if (bn.mouseState === "pan")
$(canvasID).css('cursor', "url('/img/3d/hand-pull-lightblue.cur'), default");
dX = startX - px;
dY = startY - py;
var x = bn.viewBoxWidth / bn.paper.width;
var y = bn.viewBoxHeight / bn.paper.height;
dX *= x;
dY *= y;
bn.paper.setViewBox(bn.viewBox.X + dX, bn.viewBox.Y + dY, bn.viewBoxWidth, bn.viewBoxHeight, true);
}
function getDoorPosition(x, y) {
//find one wall
var els = [];
var elements = bn.paper.getElementsByPoint(x,y);
elements.forEach(function(el){
if (el.sym != undefined) els.push(el);
});
var pointRanges = [];
var range = 5;
while( range > 0)
{
pointRanges.push({ x1: x + range, y1: y});
pointRanges.push({ x1: x, y1: y + range});
pointRanges.push({ x1: x - range, y1: y});
pointRanges.push({ x1: x, y1: y - range});
range--;
}
var pts = [];
pointRanges.forEach(function(point){
var elements = bn.paper.getElementsByPoint(point.x1, point.y1);
pts = _.filter(elements, function (el) {
return el.sym !== undefined;
});
pts.forEach(function(ptsItem){
if (_.contains(els, ptsItem) !== true){
els.push(ptsItem);
}
});
});
var wps = _.filter(els, function (el) {
return el.sym.name === "floorPath" || el.sym.name === "wallPath";
});
//find multi-points
if (_.isUndefined(wps)) return;
if (wps.length == 0 ) return;
var positions = [];
wps.forEach(function(pt){
//get path points collection
var lastX, lastY;
var ptPoints = _.reduce(pt.realPath, function (ps, segment) {
var point = {};
if (segment[0] == "M") {
point.x = segment[1];
point.y = segment[2];
lastX = point.x;
lastY = point.y;
point.type = "M";
}
if (segment[0] == "H") {
point.x = segment[1];
point.y = lastY;
lastX = point.x;
point.type = "H";
}
if (segment[0] == "V") {
point.y = segment[1];
point.x = lastX;
lastY = point.y;
point.type = "V";
}
ps.push(point);
return ps;
}, []);
var position = _.reduce(ptPoints, function (pos, poi) {
if (pos.min > Math.abs(poi.x - x)) {
pos.min = Math.abs(poi.x - x);
pos.type = "X";
pos.x = poi.x;
pos.y = poi.y;
}
if (pos.min > Math.abs(poi.y - y)) {
pos.min = Math.abs(poi.y - y);
pos.type = "Y";
pos.x = poi.x;
pos.y = poi.y;
}
return pos;
}, {min: 99999999});
positions.push(position);
});
//find right points
var minPosition = _.min(positions, function(o){
return o.min;
});
return minPosition;
}
function updateWallShape() {
$(bn.domId).css('cursor', 'crosshair');
if (bn.temp.wallCache.line) {
bn.temp.wallCache.line.attr("path", bn.temp.wallCache.path);
}
else {
bn.temp.wallCache.line = bn.paper.path(bn.temp.wallCache.path);
bn.temp.wallCache.line.attr({
"type": "path",
"stroke": "#28a4c9",
"stroke-width": 40,
"stroke-linejoin": "round",
"stroke-linecap": "round",
"pointer-events": "all"
});
}
if (bn.temp.wallCache.ps.length == 3){
if (bn.currentSymbol.name == "floorPath"){
bn.selectDefaultSymbol();
}
}
}
function finishRuler(mx, my) {
var cp = bn.canvasPoint(mx, my);
if (!bn.temp.rule) {
bn.temp.rule = {};
bn.temp.rule.start = cp;
bn.temp.rule.startIndicator = bn.addShape("pointIndicator", cp);
} else {
var shp = bn.addShape("ruler", {start: bn.temp.rule.start, end: cp});
bn.temp.rule.startIndicator.delete();
bn.temp.rule = undefined;
mousedown = false;
bn.selectDefaultSymbol();
}
}
function prepareSelection(e){
var el = bn.paper.getElementByPoint(e.pageX, e.pageY);
if (bn.isSelectable(el)){
var shp = bn.getShapeByElement(el);
if (shp)
{
if (!shp.selected)
{
bn.resetSelection();
bn.setSelection(el);
}
bn.selection.one = true;
}
}
else {
//selection default 0;
bn.selection.one = false;
var p1 = bn.canvasPoint(e.pageX, e.pageY);
setMarquee(p1.x, p1.y, 0, 0);
bn.marquee.toFront();
}
}
$(canvasID).mousedown(function (e) {
//if (bn.paper.getElementByPoint(e.pageX, e.pageY) != null) {
// bn.resetSelection();
// bn.selectByClick(e);
// if (bn.mouseState !== "drawWall" &&
// bn.mouseState !== "drawWallPart" &&
// bn.mouseState !== "drawRuler" &&
// bn.mouseState !== "drawShape") return;
//}
if (bn.mouseState === "default") prepareSelection(e);
//common
mousedown = true;
startX = e.pageX;
startY = e.pageY;
//all situation can pan window
panWindow(e.pageX, e.pageY);
if (bn.mouseState === "drawWall") {
updateWallPath(e.pageX, e.pageY);
}
if (bn.mouseState == "drawRuler") {
finishRuler(e.pageX, e.pageY);
}
if (bn.mouseState == "drawShape"){
var sp = bn.addShape(bn.currentSymbol.name, bn.canvasPoint(e.pageX,e.pageY));
bn.shapes.forEach(function(shp){
if (shp.selected) {
shp.updateLook();
}
});
bn.resetSelection();
bn.setSelection(sp.element);
}
if (bn.mouseState === "drawWallPart") {
var cp = bn.canvasPoint(e.pageX, e.pageY);
var pos = getDoorPosition(cp.x, cp.y);
//var pos = getDoorPosition(e.clientX, e.clientY);
if (_.isUndefined(pos)) return;
var symbolName = bn.currentSymbol.name;
if (pos.min < 100) {
if (pos.type == "Y") {
bn.addShape(symbolName, {x: cp.x, y: pos.y - 15, type: pos.type});
}
else {
bn.addShape(symbolName, {x: pos.x - 15, y: cp.y, type: "X"});
}
}
}
});
function setMarquee(x, y, width, height) {
bn.marquee.attr({"x": x});
bn.marquee.attr({"y": y});
bn.marquee.attr({"width": width});
bn.marquee.attr({"height": height});
}
function updateSelection(e){
if (bn.selection.one) return;
if (bn.selectRect) return;
var p1 = bn.canvasPoint(startX, startY);
var p2 = bn.canvasPoint(e.pageX, e.pageY);
function Interval(lo, hi) {
this.lo = Math.min(lo, hi);
this.hi = Math.max(lo, hi);
}
Interval.prototype.contains = function(value) {
return this.lo <= value && value <= this.hi;
};
Interval.prototype.isOverlapping = function(that) {
return (
this.contains(that.lo) ||
this.contains(that.hi) ||
that.contains(this.lo) ||
that.contains(this.hi)
);
};
function inSelection(shape) {
var mBBox = bn.marquee.getBBox();
var sBBox = shape.element.getBBox();
var marqueeX = new Interval(mBBox.x, mBBox.x + mBBox.width);
var marqueeY = new Interval(mBBox.y, mBBox.y + mBBox.height);
var shapeX = new Interval(sBBox.x, sBBox.x + sBBox.width);
var shapeY = new Interval(sBBox.y, sBBox.y + sBBox.height);
return marqueeX.contains(shapeX.lo) &&
marqueeX.contains(shapeX.hi) &&
marqueeY.contains(shapeY.lo) &&
marqueeY.contains(shapeY.hi);
}
function selectShapes() {
bn.shapes.forEach(function(shape){
if (!bn.isSelectable(shape.element)) return;
if ( inSelection(shape) ) {
bn.setSelection(shape.element);
} else {
bn.removeSelection(shape);
}
});
}
bn.marquee.show();
setMarquee(
Math.min(p1.x, p2.x), Math.min(p1.y, p2.y),
Math.abs(p1.x - p2.x), Math.abs(p1.y - p2.y)
);
selectShapes();
}
$(canvasID).mousemove(function (e) {
if (mousedown == false) {
return;
}
if (bn.mouseState === "default") updateSelection(e);
if (bn.mouseState === "pan") panWindow(e.pageX, e.pageY);
});
function finishSelection()
{
setMarquee(0,0,0,0);
if (!bn.selection.one)
{
if (bn.selectRect)
{
bn.shapes.forEach(function(shp){
if (shp.selected) {
shp.updateLook();
}
});
bn.resetSelection();
}
else
{
if (bn.selection.length == 0) return;
var box = bn.selection.getBBox();
//console.log(box.x,box.y,box.width);
bn.selectRect = bn.paper.rect(box.x,box.y,box.width,box.height);
bn.selectRect.attr({fill: "green"});
bn.selectRect.attr({"fill-opacity": "0.2"});
bn.selectRect.attr({"stroke-opacity": "0.3"});
bn.selectRect.attr({"stroke-dasharray":"-"});
bn.selectRect.attr({stroke: "green"});
bn.selectRect.attr({"stroke-width": 10});
bn.selectRect.toFront();
bn.selectRect.draggable();
}
}
bn.selection.getBBox();
}
$(canvasID).mouseup(function (e) {
//common
if (mousedown == false) return;
bn.viewBox.X += dX;
bn.viewBox.Y += dY;
mousedown = false;
if (bn.mouseState === "default")
finishSelection();
var cp = bn.canvasPoint(e.pageX, e.pageY);
if (bn.mouseState === "drawWall") {
updateWallShape();
} else if (bn.mouseState === "drawRuler") {
if (bn.temp.rule) $(canvasID).css('cursor', 'crosshair');
} else if (bn.mouseState === "drawWallPart") {
$(canvasID).css('cursor', 'crosshair');
} else if (bn.mouseState === "drawShape"){
}
else {
$(canvasID).css('cursor', 'default');
}
});
}
function defineKeyBehavior() {
$(document).keyup(function (e) {
if (e.keyCode == 27) { // escape key maps to keycode `27`
if (bn.currentSymbol.handleKey)
bn.currentSymbol.handleKey("ESC");
}
if (e.keyCode == 46) {
bn.delete();
}
if (e.keyCode == 37) {
bn.move('left');
}
if (e.keyCode == 39){
bn.move('right');
}
if (e.keyCode == 38){
bn.move('up');
}
if (e.keyCode == 40){
bn.move('down');
}
});
$(document).keydown(function (e) {
if (e.keyCode == 37) {
bn.move('left');
}
if (e.keyCode == 39){
bn.move('right');
}
if (e.keyCode == 38){
bn.move('up');
}
if (e.keyCode == 40){
bn.move('down');
}
});
}
//actions
createPaper();
defineMouseBehavior();
defineKeyBehavior();
bn.selectDefaultSymbol();
enablePaperResize();
};
bn.clear = function () {
bn.temp = {}; //clear all temporary vars
bn.dirty = false; //set to default
bn.shapes = []; //clear shape instances
bn.paper.clear();
bn.resetSelection();
};
bn.load = function (config) {
bn.clear();
if (config) {
bn.loadConfig = config;
}
else {
bn.loadConfig = bn.demoConfig;
}
bn.setZoom(bn.loadConfig.editorZoom);
var loadShape = function(sp) {
var shp = bn.addShape(sp.param2D.symbol, sp.param2D);
if (shp) {
shp.config = sp;
shp.updateLook();
}
};
bn.loadConfig.shapes.forEach(function (shp) {
loadShape(shp);
});
bn.shapes.forEach(function (shp) {
if (shp.element.sym.name === "floorPath") return;
if (shp.element.sym.name === "floorImage") return;
shp.element.toFront();
});
bn.dirty = false;
};
bn.addShape = function (symbolName, param) {
var sym = _.find(bn.symbols, function (item) {
return item.name === symbolName;
});
if (_.isUndefined(sym)) return;
/*unique elements create by each symbols*/
var el = sym.create(param);
$(el).keyup(function(event) {
if (e.keyCode == 46) {
bn.delete();
}
});
el.sym = sym;
var shp = _.extend({}, bn.shapeClass);
shp.element = el;
bn.shapes.push(shp);
if (!shp.config) shp.newConfig();
shp.updateLook();
bn.dirty = true;
return shp;
};
bn.shapeMakeup = function (el, sym) {
//el.hover(function () {
// this.glowEffect = this.glow({color: "blue", width: 15});
//}, function () {
// this.glowEffect.remove();
//});
if (sym.class)
{
$(el.node).attr("class", sym.class);
}
if (sym.style)
{
for(var a in sym.style)
{
el.attr(a, sym.style[a]);
}
}
if (sym.class !== "floorPath")
el.draggable();
return el;
};
bn.selectSymbol = function (sym) {
if (bn.currentSymbol) {
if (bn.currentSymbol.endState)
bn.currentSymbol.endState();
}
bn.mouseState = sym.mouseState;
bn.currentSymbol = sym;
if (sym.initState) sym.initState();
//update cursor & mouseState for common purpose
$(bn.domId).css('cursor', 'auto');
if (sym.cursor) $(bn.domId).css('cursor', sym.cursor);
bn.update();
};
bn.selectDefaultSymbol = function () {
bn.selectSymbol(bn.symbols[0]);
};
bn.findShapeBySymbolName = function (name) {
var sps = _.filter(bn.shapes, function (shp) {
return shp.element.sym !== undefined;
});
return _.find(sps, function (shp) {
return shp.element.sym.name === name;
});
};
bn.setZoom = function (zoom){
var vBHo = bn.viewBoxHeight;
var vBWo = bn.viewBoxWidth;
var vX = bn.viewBox.X;
var vY = bn.viewBox.Y;
bn.viewBoxWidth *= zoom;
bn.viewBoxHeight *= zoom;
bn.viewBox.X -= (bn.viewBoxWidth - vBWo) / 2;
bn.viewBox.Y -= (bn.viewBoxHeight - vBHo) / 2;
//bn.viewBox.X = zoom * vX;
//bn.viewBox.Y = zoom * vY;
bn.paper.setViewBox(bn.viewBox.X, bn.viewBox.Y, bn.viewBoxWidth, bn.viewBoxHeight, true);
};
bn.setSelection = function (el) {
el.attr({"stroke": "#8ADBB2"});
el.attr({"fill": "#74ED34"});
el.attr({"fill-opacity": "0.7"});
el.attr({"stroke-opacity": "0.7"});
var exist = false;
if (bn.selection) {
bn.selection.forEach(function (e) {
if (e === el) exist = true;
});
if (!exist)
{
if (el.sym) bn.selection.push(el);
}
bn.getShapeByElement(el).selected = true;
//bn.selection.draggable();
//console.log(bn.selection);
var selectedShapes = [];
bn.selection.forEach(function (e) {
selectedShapes.push(bn.getShapeByElement(e));
});
bn.ev("shapeSelected", selectedShapes);
}
};
bn.isSelectable = function(el){
if (el == null) return false;
if (el === bn.selectRect) return true;
if (_.isUndefined(el.sym)) return false;
if (el.sym.name === "floorPath") return false;
if (el.sym.name === "floorImage") return false;
return true;
};
bn.resetSelection = function (){
var selectedShapes = [];
if (bn.shapes) {
bn.shapes.forEach(function (shp) {
if (shp.selected) selectedShapes.push(shp);
});
bn.ev("resetShape", selectedShapes);
}
if (_.isUndefined(bn.marquee))
bn.marquee = bn.paper.rect(0, 0, 0, 0);
{
bn.marquee = bn.paper.rect(0, 0, 0, 0);
bn.marquee.attr({fill: "none"});
bn.marquee.attr({"stroke-dasharray":"-"});
bn.marquee.attr({stroke: "green"});
bn.marquee.attr({"stroke-width": 10});
bn.marquee.toFront();
}
bn.selection = bn.paper.set();
if (bn.selectRect) {
bn.selectRect.remove();
bn.selectRect = undefined ;
}
bn.shapes.forEach(function(shp){
shp.resetStyle();
shp.selected = false;
});
};
bn.getShapeByElement = function(el){
var res = null;
bn.shapes.forEach(function(shp){
if (shp.element === el) res = shp;
});
return res;
};
bn.removeSelection = function (shape){
shape.resetStyle();
shape.selected = false;
bn.selection.exclude(shape.element);
};
bn.save = function (){
//get floor calc center2D for 3d config position update
var floor = _.find(bn.shapes, function(shp){
return shp.element.sym.name == "floorPath";
});
if (floor) floor.element.sym.calcCenter(floor.element);
bn.loadConfig.shapes.length = 0;
bn.shapes.forEach(function(shp){
shp.updateConfig();
bn.loadConfig.shapes.push(shp.config);
});
bn.uploadConfig(bn.loadConfig);
//bn.demoConfig = bn.loadConfig;
//bn.info(angular.toJson(bn.loadConfig));
bn.dirty = false;
};
bn.newConfig = function(){
var languageJson = angular.fromJson(sessionStorage.getItem('languageJson'));
var prompt = languageJson.Room3D.Edit.Prompt;
var nc = {
"name": "new floor",
"title": prompt.Room,
"description": prompt.Note,
"version": "0.0.1",
"editorZoom": 1,
"shapes":[]
};/*"新机房" "备注请放在这里"*/
bn.load(nc);
};
bn.canvasPoint = function (pageX, pageY) {
var rX = pageX - $(bn.domId).position().left;
var rY = pageY - $(bn.domId).position().top;
var x = bn.viewBoxWidth / bn.paper.width;
var y = bn.viewBoxHeight / bn.paper.height;
var tX = bn.viewBox.X + rX * x;
var tY = bn.viewBox.Y + rY * y;
return {x: tX, y: tY};
};
bn.delete = function(){
if (bn.selection.length == 0) return;
var needremoves = [];
bn.shapes.forEach(function(shape){
if (shape.selected) needremoves.push(shape);
});
needremoves.forEach(function(shp){
shp.delete();
});
};
bn.align = function(type){
if (bn.selection.length < 2) return;
if (type == "left"){
var leftElement = _.min(bn.selection, function(el){
var box = el.getBBox();
return box.x;
});
var leftPosition = leftElement.getBBox().x;
bn.selection.forEach(function(el){
var offset = leftPosition - el.getBBox().x;
var shp = bn.getShapeByElement(el);
//el.nt_translate(offset,0);
shp.translate(offset,0);
});
}
if (type == "hcenter"){
var ec = bn.selection.length;
var sy = 0;
bn.selection.forEach(function(el){
sy = sy + el.getBBox().y;
});
var mid = sy/ec;
bn.selection.forEach(function(el){
var shp = bn.getShapeByElement(el);
var offset = mid - el.getBBox().y;
//el.nt_translate(0, offset);
shp.translate(0,offset);
});
}
if (type == "right"){
var rightElement = _.max(bn.selection, function(el){
var box = el.getBBox();
return box.x;
});
var rightPosition = rightElement.getBBox().x + rightElement.getBBox().width;
bn.selection.forEach(function(el){
var shp = bn.getShapeByElement(el);
var offset = rightPosition - el.getBBox().x - el.getBBox().width;
shp.translate(offset, 0);
//el.nt_translate(offset, 0);
});
}
if (type == "top"){
var topElement = _.min(bn.selection, function(el){
return el.getBBox().y;
});
var topPosition = topElement.getBBox().y;
bn.selection.forEach(function(el){
var shp = bn.getShapeByElement(el);
var offset = topPosition - el.getBBox().y;
//el.nt_translate(0,offset);
shp.translate(0,offset);
});
}
if (type == "vcenter"){
var ec = bn.selection.length;
var sx = 0;
bn.selection.forEach(function(el){
sx = sx + el.getBBox().x;
});
var mid = sx/ec;
bn.selection.forEach(function(el){
var shp = bn.getShapeByElement(el);
var offset = mid - el.getBBox().x;
//el.nt_translate(offset,0);
shp.translate(offset, 0);
});
}
if (type == "bottom"){
var bottomElement = _.max(bn.selection, function(el){
var box = el.getBBox();
return box.y;
});
var bottomPosition = bottomElement.getBBox().y + bottomElement.getBBox().height;
bn.selection.forEach(function(el){
var shp = bn.getShapeByElement(el);
var offset = bottomPosition - el.getBBox().y - el.getBBox().height;
//el.nt_translate(0,offset);
shp.translate(0,offset);
});
}
bn.dirty = true;
};
bn.spacing = function(type){
if (bn.selection.length < 2) return;
if (type == "h"){
var leftElement = _.min(bn.selection, function(el){
var box = el.getBBox();
return box.x;
});
var leftPosition = leftElement.getBBox().x;
var ar = _.sortBy(bn.selection, function(el){
return -(leftPosition - el.getBBox().x); });
var languageJson = angular.fromJson(sessionStorage.getItem('languageJson'));
var prompt = languageJson.Room3D.Edit.Prompt;
/*"请输入物体间隔距离(cm)"*/
bn.input(prompt.Distance,0,languageJson.InputBox).then(function(data){
if (data.result){
var interval = parseFloat(data.val);
var leftSpace = 0;
ar.forEach(function(el){
el.nt_translate(leftPosition - el.getBBox().x,0);
el.nt_translate(leftSpace,0);
leftSpace = leftSpace + el.getBBox().width + interval;
});
}
});
}
if (type == "v"){
var topElement = _.min(bn.selection, function(el){
var box = el.getBBox();
return box.y;
});
var topPosition = topElement.getBBox().y;
var ar = _.sortBy(bn.selection, function(el){
return -(topPosition - el.getBBox().y); });
var languageJson = angular.fromJson(sessionStorage.getItem('languageJson'));
var prompt = languageJson.Room3D.Edit.Prompt;
/*"请输入物体间隔距离(cm)"*/
bn.input(prompt.Distance,0,languageJson.InputBox).then(function(data){
if (data.result){
var interval = parseFloat(data.val);
var topSpace = 0;
ar.forEach(function(el){
el.nt_translate(0, topPosition - el.getBBox().y);
el.nt_translate(0, topSpace);
topSpace = topSpace + el.getBBox().height + interval;
});
}
});
}
bn.dirty = true;
};
bn.copy = function(){
if (bn.selection.length == 0) return;
var copyitems = [];
bn.selection.forEach(function(el){
var shp = bn.getShapeByElement(el);
if (shp) copyitems.push(shp.clone());
});
bn.resetSelection();
copyitems.forEach(function(shp){
bn.shapes.push(shp);
bn.setSelection(shp.element);
});
var box = bn.selection.getBBox();
bn.selectRect = bn.paper.rect(box.x,box.y,box.width,box.height);
bn.selectRect.attr({fill: "green"});
bn.selectRect.attr({"fill-opacity": "0.2"});
bn.selectRect.attr({"stroke-opacity": "0.3"});
bn.selectRect.attr({"stroke-dasharray":"-"});
bn.selectRect.attr({stroke: "green"});
bn.selectRect.attr({"stroke-width": 10});
bn.selectRect.toFront();
bn.selectRect.draggable();
bn.dirty = true;
};
bn.move = function(type){
if (bn.selection.length < 1) return;
if (type == "left"){
bn.selection.forEach(function(el){
bn.getShapeByElement(el).translate(-1,0);
//el.nt_translate(-1,0);
});
}
if (type == "right"){
bn.selection.forEach(function(el){
bn.getShapeByElement(el).translate(1,0);
//el.nt_translate(1,0);
});
}
if (type == "up"){
bn.selection.forEach(function(el){
bn.getShapeByElement(el).translate(0,-1);
//el.nt_translate(0,-1);
});
}
if (type == "down"){
bn.selection.forEach(function(el){
bn.getShapeByElement(el).translate(0,1);
//el.nt_translate(0,1);
});
}
bn.dirty = true;
};
bn.toBack = function(){
//if (bn.selection.length < 1) return;
bn.selection.forEach(function(el){
el.toBack();
});
//floor and image can not select, so it's must be at bottom.
var floor = _.find(bn.shapes, function(shp){
return shp.element.sym.name == "floorPath";
});
if (floor) floor.element.toBack();
var floorImage = _.find(bn.shapes, function(shp){
return shp.element.sym.name == "floorImage";
});
if (floorImage) floorImage.element.toBack();
};
bn.toFront = function(){
if (bn.selection.length < 1) return;
bn.selection.forEach(function(el){
el.toFront();
});
};
var languageJson = angular.fromJson(sessionStorage.getItem('languageJson'));
var edit = languageJson.Room3D.Edit;
bn.symbols = [
{
name: "cursor",
title: edit.Cursor,/*"选择"*/
tip: edit.CursorPrompt,/*"选中物体,可操作各种物体"*/
icon: "/img/3d/cursor.png",
mouseState: "default",
cursor: "default",
visible: true,
initState: function(){
}
},
{
name: "pan",
title: edit.Pan,/*"移动"*/
tip: edit.PanPrompt,/*"拖动移动画布"*/
icon: "/img/3d/move.png",
mouseState: "pan",
cursor: "default",
visible: true,
handleKey : function (key){
if (key === "ESC"){
bn.selectDefaultSymbol();
}
},
initState: function(){
}
},
{
name: "pointIndicator",
title: edit.Point,/*"点"*/
tip: edit.PointPrompt,/*"鼠标点击提示"*/
visible: false,
class: "pointIndicator",
props: {
radius: 60
},
create: function (param) {
return bn.shapeMakeup(bn.paper.circle(param.x, param.y, this.props.radius), this);
}
},
{
name: "floorImage",
title: edit.FloorImage,/*"地板底图"*/
tip: edit.ImagePrompt,/*"用来做地板衬底方便绘制"*/
type: "part",
elementType: "path",
scale: 1,
tempParam: null,
create: function (param) {
var cp = bn.getSize();
var fx = (cp.width - param.width) / 2;
var fy = (cp.height - param.height) / 2;
var el = bn.paper.image(param.src, fx, fy, param.width, param.height);
// if (param.scale)
// {
// el.scale(param.scale,param.scale);
// this.scale = param.scale;
// }
return el;
},
updateScale: function(element, realSize, rulerLength){
var x = bn.viewBoxWidth / bn.paper.width;
this.scale = (100 * realSize) / (rulerLength);
//var y = bn.viewBoxHeight / bn.paper.height;
element.scale(this.scale,this.scale);
this.tempParam = {
width : element.getBBox().width,
height : element.getBBox().height
};
},
update3DConfig: function(element, config){
delete config['param3D'];
},
update2DConfig: function(element, config){
_.extend(config.param2D , this.tempParam);
//config.param2D = this.tempParam;
config.param2D.scale = this.scale;
},
},
{
name: "ruler",
title: edit.Ruler,/*"标尺"*/
tip: edit.RulerPrompt,/*"标尺状态: 标记地板底图尺寸用于缩放底图到适当大小"*/
icon: "/img/3d/ruler.png",
mouseState: "drawRuler",
cursor: "crosshair",
visible: true,
class: "rulerPath",
props:{
},
handleKey : function (key){
if (key === "ESC"){
bn.selectDefaultSymbol();
}
},
create: function (param) {
var line = bn.paper.path(["M", param.start.x, param.start.y,
"L", param.end.x, param.end.y]);
return bn.shapeMakeup(line, this);
},
initState: function () {
var ruler = bn.findShapeBySymbolName("ruler");
if (ruler) {
/*"此操作将删除已经存在的标尺比例,重新计算底图缩放比例,是否继续?"*/
bn.confirm(edit.Prompt.RulerConfirm,languageJson.ConfirmBox).then(function (data) {
if (data === true) {
ruler.delete();
var imgElement =bn.findShapeBySymbolName("floorImage").element;
imgElement.transform("");
}
if (data === false) bn.selectDefaultSymbol();
});
}
},
endState: function () {
var ruler = bn.findShapeBySymbolName("ruler");
if (ruler) {
/*"请输入该线段对应实际长度,单位:米"*/
bn.input(edit.Prompt.RulerInput,"0",languageJson.InputBox).then(function (data) {
if (data.result){
var v = parseFloat(data.val);
if (v <= 0 || v > 9999)
{
/*"输入的尺寸不正确, 请重新绘制"*/
bn.info(edit.Prompt.RulerInfo,languageJson.MessageBox);
ruler.delete();
return;
}
var imgElement =bn.findShapeBySymbolName("floorImage").element;
imgElement.sym.updateScale(imgElement, v,
ruler.element.getTotalLength());
}
ruler.delete();
});
}
},
update3DConfig: function(element, config){
delete config['param3D'];
},
update2DConfig: function(element, config){
config.param2D.start = {};
config.param2D.start.x = element.getBBox().x;
config.param2D.start.y = element.getBBox().y;
config.param2D.end = {};
config.param2D.end.x = element.getBBox().x + element.getBBox().width;
config.param2D.end.y = element.getBBox().y + element.getBBox().height;
}
},
{
name: "floorPath",
title: edit.FloorPath,/*"地板"*/
tip: edit.PathPrompt,/*"画地板状态: 画矩形封闭区域,点三点形成矩形"*/
icon: "/img/3d/Floor2.png",
mouseState: "drawWall",
cursor: "crosshair",
unit: "floor",
moldId:"wallpath-default",
visible: true,
style:{
"stroke":"#28a4c9",
"stroke-width":"40",
"stroke-linejoin":"round",
"stroke-linecap": "round",
"pointer-events": "all",
"fill-opacity":"0.5",
"fill":"#b9def0"
},
create: function (param) {
return bn.shapeMakeup(bn.paper.path(param.path), this);
},
update: function(cfg, element){
var mold = _.find(molds, function(m){
return m.id == cfg.param3D.moldId; });
if (cfg.param2D.angle) element.animate({
transform:"r" + cfg.param2D.angle }, 500);
element.animate({"stroke-width": mold.size.width }, 500);
},
handleKey : function (key){
if (key === "ESC"){
bn.selectDefaultSymbol();
}
},
endState: function (){
if (_.isUndefined(bn.temp.wallCache)) return;
if (_.isUndefined(bn.temp.wallCache.ps)) return;
bn.temp.wallCache.ps.forEach(function(shp){
shp.delete();
});
//因为只能绘制矩形地板的原因需对结果Path进行计算
//只能点3个点用直角折线形成精确的第三点并封闭来构成真正的矩形
var startPoint = {};
var endSegment = "";
var index = 0;
var floorLine = _.reduce(bn.temp.wallCache.line.attrs.path, function (ps, segment) {
if (index == 3) return ps;
index ++;
if (segment[0] == "M") {
ps = "M " + segment[1] + " " + segment[2];
startPoint.x = segment[1];
startPoint.y = segment[2];
}
if (segment[0] == "H") {
ps = ps + " H " + segment[1];
if (index == 3) endSegment = " V " + startPoint.y + " Z ";
}
if (segment[0] == "V") {
ps = ps + " V " + segment[1];
if (index == 3) endSegment = " H " + startPoint.x + " Z ";
}
return ps;
}, "");
if (index == 3) floorLine = floorLine + endSegment;
//console.log(floorLine);
var shp = bn.addShape("floorPath", {path: floorLine});
bn.toBack();
bn.temp.wallCache.line.remove();
bn.temp.wallCache = undefined;
//this.update2DConfig(shp.element, shp.config);
//this.update3DConfig(shp.element. shp.config);
},
calcCenter: function(element){
var fp = element;
if (fp) {
var ps = fp.attr("path");
var w, h;
var sx,sy,mx,my;
var sx = parseFloat(ps[0][1]);
var sy = parseFloat(ps[0][2]);
if (ps[1][0] === "H")
mx = parseFloat(ps[1][1]);
else
mx = parseFloat(ps[2][1]);
if (ps[1][0] === "V")
my = parseFloat(ps[1][1]);
else
my = parseFloat(ps[2][1]);
}
w = Math.abs(mx - sx);
h = Math.abs(my - sy);
bn.center2D = {};
bn.center2D.x = sx + w / 2;
bn.center2D.y = sy + h / 2;
},
initState: function(){
bn.enablePan = false;
var fp = bn.findShapeBySymbolName("floorPath");
if (fp) {
/*"地板只允许有一个,确定重新绘制?"*/
bn.confirm(edit.Prompt.FloorConfirm,languageJson.ConfirmBox).then(function (data) {
if (data === true) {
fp.delete();
}
else
bn.selectDefaultSymbol();
});
}
else{
/*"点击三个点形成直角折线来自动形成矩形地板"*/
bn.info(edit.Prompt.FloorInfo,languageJson.MessageBox);
}
},
update2DConfig: function(element, config){
//todo: when moved all path string changed to 'c'
config.param2D.path = element.attr("path").toString();
},
update3DConfig: function(element, config) {
config.param3D.floorTexture = "/img/3d/floor05.png";
var fp = element;
if (fp) {
var ps = fp.attr("path");
var w, h;
var sx,sy,mx,my;
var sx = parseFloat(ps[0][1]);
var sy = parseFloat(ps[0][2]);
if (ps[1][0] === "H")
mx = parseFloat(ps[1][1]);
else
mx = parseFloat(ps[2][1]);
if (ps[1][0] === "V")
my = parseFloat(ps[1][1]);
else
my = parseFloat(ps[2][1]);
}
w = Math.abs(mx - sx);
h = Math.abs(my - sy);
config.param3D.floorWidth = w;
config.param3D.floorHeight = h;
bn.center2D = {};
bn.center2D.x = sx + w / 2;
bn.center2D.y = sy + h / 2;
}
},
{
name: "wallPath",
title: edit.WallPath,/*"墙壁"*/
tip: edit.WallPrompt,/*"画墙状态:鼠标点击画墙等折线路径物体"*/
icon: "/img/3d/wall.png",
mouseState: "drawWall",
unit: "wallPath",
moldId:"wallpath-default",
cursor: "crosshair",
visible: true,
style:{
"stroke":"#28a4c9",
"stroke-width":"40",
"stroke-linejoin":"round",
"stroke-linecap": "round",
"pointer-events": "all",
"fill-opacity":"0.5",
"fill":"#b9def0"
},
update: function(cfg, element){
var mold = _.find(molds, function(m){
return m.id == cfg.param3D.moldId; });
if (cfg.param2D.angle) element.animate({
transform:"r" + cfg.param2D.angle }, 500);
element.animate({"stroke-width": mold.size.width }, 500);
},
create: function (param) {
//this.linePath = param.path;
return bn.shapeMakeup(bn.paper.path(param.path), this);
},
handleKey : function (key){
if (key === "ESC"){
bn.selectDefaultSymbol();
}
},
endState: function (){
if (_.isUndefined(bn.temp.wallCache)) return;
if (_.isUndefined(bn.temp.wallCache.ps)) return;
bn.temp.wallCache.ps.forEach(function(shp){
shp.delete();
});
bn.addShape("wallPath", bn.temp.wallCache);
bn.temp.wallCache.line.remove();
bn.temp.wallCache = undefined;
},
update2DConfig: function(element, config){
if (config.param2D.pathArray)
{
var oldPath = bn.paper.path(config.param2D.pathArray.toString());
// var pathOffset = {
// x: element.getBBox().x - oldPath.getBBox().x,
// y: element.getBBox().y - oldPath.getBBox().y
// };
// var newX = parseFloat(element.realPath[0][1]) + pathOffset.x;
// var newY = parseFloat(element.realPath[0][2]) + pathOffset.y;
var pathNew = oldPath.attrs.path.slice(0);
pathNew[0][1] = element.getBBox().x;
pathNew[0][2] = element.getBBox().y;
config.param2D.path = pathNew.toString();
config.param2D.pathArray = pathNew;
oldPath.remove();
}
else if (element.attrs.path){
config.param2D.path = element.attrs.path.toString();
config.param2D.pathArray = element.attrs.path;
}
},
update3DConfig: function(element, config){
var ps = config.param2D.pathArray;
var lines = bn.util.get3DLinesBySegments(ps, 10);
config.param3D.lines = lines;
}
},
{
name: "door",
title: edit.Door,/*"门窗"*/
tip: edit.DoorPrompt,/*"画门窗状态:在墙上鼠标点击的位置放置门窗"*/
icon: "/img/3d/door.png",
mouseState: "drawWallPart",
unit: "door",
moldId:"door-default",
visible: true,
cursor:"crosshair",
style:{
"fill": "#FF8080"
},
props: {
width: 190,
height: 30
},
create: function (param) {
var rect;
if (param.type === "Y") {
rect = bn.paper.rect(param.x, param.y, this.props.width, this.props.height);
}
else {
rect = bn.paper.rect(param.x, param.y, this.props.height, this.props.width);
}
return bn.shapeMakeup(rect, this);
},
handleKey : function (key){
if (key === "ESC"){
bn.selectDefaultSymbol();
}
},
update: function(cfg, element){
var mold = _.find(molds, function(m){
return m.id == cfg.param3D.moldId; });
if (cfg.param2D.angle) element.animate({
transform:"r" + cfg.param2D.angle }, 500);
if (element.attrs.width > element.attrs.height)
{
element.animate({
width:mold.size.width,
height:mold.size.depth
}, 500);
}
else
{
element.animate({
width:mold.size.depth,
height:mold.size.width
}, 500);
}
},
update2DConfig: function(element, config){
config.param2D.x = element.getBBox().x;
config.param2D.y = element.getBBox().y;
if (element.attrs.width > element.attrs.height)
config.param2D.type = "Y";
else
config.param2D.type = "X";
},
update3DConfig: function(element, config){
var c = bn.util.boxCenter(element);
config.param3D.position = bn.util.Point3D(c);
config.param3D.position.y = parseFloat(config.param3D.aboveGround);
if (element.attrs.width > element.attrs.height)
config.param3D.direct = "X";
else
config.param3D.direct = "Z";
}
},
{
name: "rack",
title: edit.Rack,/*"机架"*/
tip: edit.RackPrompt,/*"放置机架等盒状物体"*/
icon: "/img/3d/rack.jpg",
cursor:"url('/img/3d/object.cur'), default",
mouseState: "drawShape",
visible: true,
unit: "rack",
moldId:"rack-default",
style:{
"fill": "blue",
"fill-opacity":"0.5",
"stroke": "#437ded",
"stroke-width":10,
"pointer-events":"all"
},
props: {
width: 70,
depth: 100,
height: 220
},
handleKey : function (key){
if (key === "ESC"){
bn.selectDefaultSymbol();
}
},
create: function (param) {
var rect = bn.paper.rect(param.x, param.y,
this.props.width, this.props.depth);
return bn.shapeMakeup(rect, this);
},
update: function(cfg, element){
var mold = _.find(molds, function(m){
return m.id == cfg.param3D.moldId; });
if (cfg.param2D.angle) element.animate({
transform:"R" + cfg.param2D.angle }, 600);
element.animate({
width:mold.size.width,
height:mold.size.depth
}, 500);
},
update2DConfig: function(element, config){
//element.animate({transform:""}, 10);
config.param2D.x = element.attrs.x;
config.param2D.y = element.attrs.y;
},
update3DConfig: function(element, config){
var c = bn.util.boxCenter(element);
config.param3D.position = bn.util.Point3D(c);
}
},
//{
// name: "camera",
// title: "摄像头",
// tip: "放置摄像头在鼠标点击位置",
// icon: "/img/3d/camera.jpg",
// cursor:"url('/img/3d/object.cur'), default",
// mouseState: "drawShape",
// visible: true,
// style:{
// "stroke": "#ed4f44",
// "stroke-width":"10",
// "fill-opacity":"0.5",
// "fill":"red"
// },
// props: {
// radius: 30
// },
// handleKey : function (key){
// if (key === "ESC"){
// bn.selectDefaultSymbol();
// }
// },
// create: function (param) {
// return bn.shapeMakeup(bn.paper.circle(param.x, param.y, this.props.radius), this);
// },
// update2DConfig: function(element, config){
// config.param2D.x = element.getBBox().x;
// config.param2D.y = element.getBBox().y;
// },
// update3DConfig: function(element, config){
// config.param3D = {
// "unit": "camera",
// "angle": 0,
// "high": 300,
// "position":{x:0,y:0,z:0}
// };
// var c = bn.util.boxCenter(element);
// config.param3D.position = bn.util.Point3D(c);
// config.param3D.position.y = config.param3D.high;
// }
//},
{
name: "flat",
title: edit.Flat,/*"装饰"*/
tip: edit.FlatPrompt,/*"放置平面图形到3D画布"*/
icon: "/img/3d/plant.png",
cursor:"url('/img/3d/object.cur'), default",
mouseState: "drawShape",
unit:"flat",
moldId: "flat-default",
visible: true,
style:{
"stroke": "#ed4fee",
"stroke-width":"10",
"fill-opacity":"0.5",
"fill":"yellow"
},
props:{
"width":"100",
"depth":"100"
},
handleKey : function (key){
if (key === "ESC"){
bn.selectDefaultSymbol();
}
},
create: function (param) {
var rect = bn.paper.rect(param.x, param.y,
this.props.width, this.props.width);
return bn.shapeMakeup(rect, this);
},
update2DConfig: function(element, config){
config.param2D.x = element.getBBox().x;
config.param2D.y = element.getBBox().y;
config.param2D.width = element.getBBox().width;
},
update: function(cfg, element){
var mold = _.find(molds, function(m){
return m.id == cfg.param3D.moldId; });
element.animate({
width:mold.size.width,
height:mold.size.width
}, 500);
},
update3DConfig: function(element, config){
var c = bn.util.boxCenter(element);
config.param3D.position = bn.util.Point3D(c);
config.param3D.position.y = config.param3D.high;
}
}
];
bn.shapeClass = {
newConfig:function(){
var that = this;
if (!this.config)
{
this.config = {};
this.config.name = this.element.sym.name;
this.config.title = this.element.sym.title;
this.config.param2D = {};
this.config.param2D.symbol = this.element.sym.name;
this.config.param2D.angle = 0;
this.config.param3D = {};
this.config.param3D.unit = this.element.sym.unit;
this.config.param3D.moldId = this.element.sym.moldId;
this.config.param3D.angle = 0;
this.config.param3D.aboveGround = 0;
this.config.param3D.bindings = [];
}
this.config.id = this.element.id;
},
getBindingTitle:function(){
if (!this.config.param3D.bindings) return "无";
var str = "<ul>";
this.config.param3D.bindings.forEach(function(item){
str = str + "<li>" + item.title + "</li>";
});
var str = str + "</ul>";
},
translate:function(dx,dy){
if (this.element.matrix.split().rotate)
{
this.element.transform('');
}
this.element.nt_translate(dx,dy);
this.updateLook();
},
updateLook:function(){
if (this.element.sym)
{
if (this.element.sym.update){
this.element.sym.update(this.config, this.element);
}
}
},
updateConfig:function(){
var that = this;
if (that.element.sym)
{
if (that.element.sym.update2DConfig)
that.element.sym.update2DConfig(that.element,that.config);
if (that.element.sym.update3DConfig)
that.element.sym.update3DConfig(that.element,that.config);
}
},
delete:function(){
bn.shapes = _.without(bn.shapes, this);
if (this.element.glowEffect)
this.element.glowEffect.remove();
this.element.remove();
bn.proofer.resetUI();
bn.resetSelection();
bn.dirty = true;
},
resetStyle:function(){
var that = this;
if (that.element.sym.style)
{
for(var a in that.element.sym.style)
{
if (a == "stroke-width" && that.element.sym.name == "wallPath") continue;
that.element.attr(a, that.element.sym.style[a]);
}
}
},
clone:function(){
var that = this;
var ns = _.extend({}, that);
ns.config = angular.fromJson(angular.toJson(that.config));
ns.element = that.element.clone();
ns.config.id = that.element.id;
ns.element.sym = _.extend({}, that.element.sym);
ns.selected = that.selected;
if (that.element.sym.class !== "floorPath")
ns.element.draggable();
return ns;
}
};
bn.util = {};
bn.util.Point3D = function(point2D){
var p ={};
if (bn.center2D)
{
p.x = point2D.x - bn.center2D.x;
p.z = point2D.y - bn.center2D.y;
}
else{
p.x = point2D.x;
p.z = point2D.y;
}
return p;
};
bn.util.boxCenter = function(el){
var box = el.getBBox();
var p = {x: box.x + box.width / 2 , y:box.y + box.height / 2};
return p;
};
bn.util.get3DLinesBySegments = function (segs, y) {
var lastX, lastY;
var lines = [];
var parr = _.reduce(segs, function (ps, segment) {
var point = {};
if (segment[0] == "M") {
point.x = parseFloat(segment[1]);
point.y = parseFloat(segment[2]);
lastX = point.x;
lastY = point.y;
}
if (segment[0] == "H") {
point.x = parseFloat(segment[1]);
point.y = lastY;
lastX = point.x;
}
if (segment[0] == "V") {
point.y = parseFloat(segment[1]);
point.x = lastX;
lastY = point.y;
}
var p3 = bn.util.Point3D(point);
p3.y = parseFloat(y);
var startPoint = ps[ps.length - 1];
if (startPoint)
{
var line = {
start: startPoint,
end: p3
};
lines.push(line);
}
ps.push(p3);
return ps;
}, []);
return lines;
};
bn.proofer = {
showSettings: function(shapes, setting){
//single:
if (_.isUndefined(shapes)) return;
bn.proofer.shapes = shapes;
bn.proofer.setting = setting;
if (shapes.length == 1){
var shp = shapes[0];
if (!shp.config) shp.newConfig();
setting.title = shp.config.title;
setting.angle = shp.config.param2D.angle;
setting.aboveGround = shp.config.param3D.aboveGround;
setting.molds = this.getMolds(shp.element.sym.name);
setting.mold = _.find(setting.molds,
function(m){ return m.id == shp.config.param3D.moldId; });
setting.bindings = shp.config.param3D.bindings;
}
if (shapes.length > 1){
var allSame = true; var ns = [];
ns.push(shapes[0].element.sym.name);
shapes.forEach(function(shp){
if (!_.contains(ns, shp.element.sym.name))
allSame = false;
});
if (allSame){
setting.molds = this.getMolds(shapes[0].element.sym.name);
}
else
setting.molds = undefined;
setting.title = undefined;
setting.angle = undefined;
setting.aboveGround = undefined;
setting.mold = undefined;
setting.bindings = [];
}
},
resetUI: function(){
if (bn.proofer.setting){
bn.proofer.setting.molds = undefined;
bn.proofer.setting.title = undefined;
bn.proofer.setting.angle = undefined;
bn.proofer.setting.aboveGround = undefined;
bn.proofer.setting.mold = undefined;
bn.proofer.setting.bindings = [];
}
},
getMolds: function(symbolName){
var ms = [];
molds.forEach(function(m){
if (m.name === symbolName) ms.push(m);
});
return ms;
},
saveShapes: function(shapes, setting){
if (shapes.length == 1){
var shp = shapes[0];
if (shp.config)
{
shp.config.title = setting.title;
shp.config.param2D.angle = parseFloat(setting.angle);
shp.config.param3D.angle = parseFloat(setting.angle);
shp.config.param3D.moldId = setting.mold.id;
shp.config.param3D.aboveGround = parseFloat(setting.aboveGround);
shp.config.param3D.bindings = setting.bindings;
shp.updateLook();
}
}
if (shapes.length > 1){
var allSame = true; var ns = [];
ns.push(shapes[0].element.sym.name);
shapes.forEach(function(shp){
if (!_.contains(ns, shp.element.sym.name))
allSame = false;
});
shapes.forEach(function(shp){
if (setting.title)
shp.config.title = setting.title;
if (setting.angle)
{
shp.config.param2D.angle = parseFloat(setting.angle);
shp.config.param3D.angle = parseFloat(setting.angle);
}
if (allSame){
if (setting.mold){
shp.config.param3D.moldId = setting.mold.id;
}
}
if (setting.aboveGround)
shp.config.param3D.aboveGround = parseFloat(setting.aboveGround);
shp.updateLook();
});
}
},
//rend: function(shapes, setting){
//
// //when focus lose or save, save config to shape
// this.updateShapes(shapes,setting);
//
// //3 load proof by shape's mold define
// //4 user can use set in template or modify it
// //multiple:
// //1 if shape's symbol is same, they can change style (not binding)
// //2 when focus lose or save, save copied config to each shape
//},
proofs:[
{
type:"rack",
load: function(shape, setting){
},
save: function(shape, setting){
}
}
]
};
(function(R) {
R.el.draggable = function(move, start, up) {
this._ui = this._ui || {};
var that = this;
this._ui.onMove = R.is(move, 'function') ?
move : function(distanceX, distanceY, x, y, deltaX, deltaY) {
if (that.sym){
if (that.sym.name == "floorPath") return;
if (that.sym.name == "wallPath") return;
}
bn.dirty = true;
bn.update();
if (that === bn.selectRect)
{
that.translate(deltaX, deltaY);
bn.shapes.forEach(function(shp){
if (shp.selected)
{
if (shp.element.matrix.split().rotate)
{
that._ui.rotatestr = "r"+shp.element.matrix.split().rotate;
shp.element.transform('');
}
shp.element.nt_translate(deltaX,deltaY);
}
});
}
else{
if (that.sym){
if (that.matrix.split().rotate)
{
that._ui.rotatestr = "r"+ that.matrix.split().rotate;
that.transform('');
}
that.nt_translate(deltaX,deltaY);
}
}
};
this._ui.onStart = R.is(start, 'function') ? start : function(x, y) {
if (bn.mouseState !== "default") return;
//if (that.glowEffect) that.glowEffect.remove();
$(bn.domId).css( 'cursor', "url('/img/3d/hand-pull-darkblue.cur'), default");
};
function onMove(distanceX, distanceY, x, y) {
if (bn.mouseState !== "default") return;
var cp = bn.canvasPoint(x, y);
var deltaX = cp.x - that._ui.lastX;
var deltaY = cp.y - that._ui.lastY;
that._ui.lastX = cp.x;
that._ui.lastY = cp.y;
//if (that.glowEffect) that.glowEffect.remove();
that._ui.onMove(distanceX, distanceY, x, y, deltaX, deltaY);
that.paper.safari();
}
function onStart(x, y) {
if (bn.mouseState !== "default") return;
if (that.sym)
if (that.sym.name == "floorPath") return;
var cp = bn.canvasPoint(x, y);
that._ui.lastX = cp.x;
that._ui.lastY = cp.y;
//if (that.glowEffect) that.glowEffect.remove();
that._ui.onStart(x, y);
}
function onUp(e){
if (that.sym){
bn.getShapeByElement(that).updateLook();
}
$(bn.domId).css( 'cursor', "auto" );
}
return this.drag(onMove, onStart, onUp);
};
})(Raphael);
(function() {
/** define 2 custom attributes translateNT and scaleNT (relative attributes) */
var initCA = function(shape) {
if(!shape.paper.customAttributes["translateNT"]) {
shape.paper.customAttributes["translateNT"] = function(dx, dy) {
if (this.type == "circle" || this.type == "ellipse") {
return {
"cx" : this.attr("cx") + dx,
"cy" : this.attr("cy") + dy
};
} else if (this.type == "rect" || this.type == "text"
|| this.type == "image") {
return {
"x" : this.attr("x") + dx,
"y" : this.attr("y") + dy
};
} else if (this.type == "path") {
var matrix = Raphael.matrix(1, 0, 0, 1, 0, 0);
matrix.translate(dx, dy);
var newPath = Raphael.mapPath(this.attr("path"), matrix);
this.attr({
"path" : newPath
});
}
};
shape.paper.customAttributes["scaleNT"] = function(dx, dy) {
if (this.type == "circle") {
return {
"r" : this.attr("r") * Math.max(dx, dy)
};
} else if (this.type == "ellipse") {
return {
"rx" : this.attr("rx") * dx,
"ry" : this.attr("ry") * dy
};
} else if (this.type == "rect" || this.type == "image") {
return {
"width" : this.attr("width") * dx,
"height" : this.attr("height") * dy
};
} else if (this.type == "text") {
var fs = parseInt(this.attr("font-size") + "");
return {
"font-size" : fs * Math.max(dx, dy)
};
} else if (this.type == "path") {
var bb = this.getBBox(), cx = bb.x + bb.width / 2, cy = bb.y
+ bb.height / 2;
var matrix = Raphael.matrix(1, 0, 0, 1, 0, 0);
matrix.scale(dx, dy, cx, cy);
var newPath = Raphael.mapPath(this.attr("path"), matrix);
return {
"path" : newPath
};
}
}
}
};
Raphael.el.nt_translate = function(dx, dy) {
initCA(this);
if (this.type == "circle" || this.type == "ellipse") {
this.attr({
"cx" : this.attr("cx") + dx,
"cy" : this.attr("cy") + dy
});
} else if (this.type == "rect" || this.type == "text"
|| this.type == "image") {
this.attr({
"x" : this.attr("x") + dx,
"y" : this.attr("y") + dy
});
} else if (this.type == "path") {
var matrix = Raphael.matrix(1, 0, 0, 1, 0, 0);
matrix.translate(dx, dy);
var newPath = Raphael.mapPath(this.attr("path"), matrix);
this.attr({
"path" : newPath
});
}
return this;
};
Raphael.el.nt_scale = function(dx, dy) {
initCA(this);
if (this.type == "circle") {
this.attr({
"r" : this.attr("r") * Math.max(dx, dy)
});
} else if (this.type == "ellipse") {
this.attr({
"rx" : this.attr("rx") * dx,
"ry" : this.attr("ry") * dy
});
} else if (this.type == "rect" || this.type == "image") {
this.attr({
"width" : this.attr("width") * dx,
"height" : this.attr("height") * dy
});
} else if (this.type == "text") {
var fs = parseInt(this.attr("font-size") + "");
this.attr({
"font-size" : fs * Math.max(dx, dy)
});
} else if (this.type == "path") {
var bb = this.getBBox(), cx = bb.x + bb.width / 2, cy = bb.y
+ bb.height / 2;
var matrix = Raphael.matrix(1, 0, 0, 1, 0, 0);
matrix.scale(dx, dy, cx, cy);
var newPath = Raphael.mapPath(this.attr("path"), matrix);
this.attr({
"path" : newPath
});
}
return this;
}
Raphael.st.nt_translate = function(dx, dy) {
initCA(this);
this.forEach(function(shape, idx) {
shape.nt_translate(dx, dy);
return true;
});
return this;
};
Raphael.st.nt_scale = function(dx, dy) {
initCA(this);
this.forEach(function(shape, idx) {
shape.nt_scale(dx, dy);
return true;
});
return this;
};
})();
//add reference service from outside
bn.inject = function(){
bn.$scope = bn.options.shell.$scope;
bn.$modal = bn.options.shell.$modal;
bn.$q = bn.options.shell.$q;
bn.$srv = bn.options.shell.$srv;
bn.$upload = bn.options.shell.$upload;
bn.$scope.setting = {};
bn.$scope.$on('shapeSelected', function(e, shapes) {
bn.proofer.showSettings(shapes, bn.$scope.setting);
if(!bn.$scope.$$phase) {
bn.$scope.$apply();
}
});
bn.$scope.$on('resetShape', function(e, shapes) {
bn.proofer.saveShapes(shapes, bn.$scope.setting);
if(!bn.$scope.$$phase) {
bn.$scope.$apply();
}
});
bn.$scope.change = function(){
bn.dirty = true;
bn.proofer.saveShapes(bn.proofer.shapes, bn.$scope.setting);
if(!bn.$scope.$$phase) {
bn.$scope.$apply();
}
};
};
bn.update = function(){
if(!bn.$scope.$$phase) {
bn.$scope.$apply();
}
};
bn.input = function(msg, inputValue, inputBox){
var deferred = bn.$q.defer();
var $modalScope = bn.$scope.$new(true);
$modalScope.message = msg;
$modalScope.inputValue = inputValue;
$modalScope.ok = function (){
deferred.resolve({val:this.inputValue, result:true});
this.$hide();
};
$modalScope.cancel = function (){
deferred.resolve({val:undefined, result:false});
this.$hide();
};
if($modalScope.languageJson == undefined)
$modalScope.languageJson = {};
$modalScope.languageJson.InputBox = inputBox;
bn.$modal({scope: $modalScope,
templateUrl: '/partials/inputBox.html',
show: true});
return deferred.promise;
};
bn.option = function(){
var imgShape, floorShape;
var $modalScope = bn.$scope.$new(false);
$modalScope.m = {};
var getMolds= function(symbolName){
var ms = [];
molds.forEach(function(m){
if (m.name === symbolName) ms.push(m);
});
return ms;
};
var load= function(){
imgShape = _.find(bn.shapes, function(shp){
return shp.config.name == "floorImage";
});
if (imgShape)
{
$modalScope.m.img = imgShape.config.param2D.src;
}
floorShape = _.find(bn.shapes, function(shp){
return shp.config.name == "floorPath";
});
if (floorShape){
$modalScope.floorDisable = false;
$modalScope.m.mold= _.find(molds,
function(m){ return m.id == floorShape.config.param3D.moldId; });
}
else
$modalScope.floorDisable = true;
};
$modalScope.walltype = false;
$modalScope.molds = getMolds("wallPath");
load();
$modalScope.change = function(){
if ($modalScope.m.mold){
floorShape.config.param3D.moldId = $modalScope.m.mold.id;
floorShape.updateLook();
}
bn.dirty = true;
};
$modalScope.$on("fileSelected",
function(event, msg) {
$modalScope.file = msg;
});
$modalScope.$on("fileSelected2",
function(event, msg) {
$modalScope.file2 = msg;
});
$modalScope.upload = function() {
var file = $modalScope.file;
if (file === undefined) return;
bn.$upload.uploadFile($modalScope.file).then(function(data) {
if ($modalScope.m.img) bn.$upload.deleteUploadFile($modalScope.m.img);
$modalScope.m.img = data;
bn.setBackground(data);
});
};
$modalScope.ok = function (){
this.$hide();
};
bn.$modal({scope: $modalScope,
templateUrl: '/partials/pageOption.html',
show: true});
};
bn.setBackground = function(imgurl) {
var languageJson = angular.fromJson(sessionStorage.getItem('languageJson'));
var edit = languageJson.Room3D.Edit;
var img = new Image();
img.src = imgurl;
img.onload = function() {
var cfg = {
"id": "0",
"name": "floorImage",
"title": edit.FloorImage,
"param2D": {
"symbol": "floorImage",
"src": imgurl,
"height": this.height,
"width": this.width,
"transparent": "0.4"
}
};/*"地板底图"*/
var old = bn.findShapeBySymbolName("floorImage");
if (old) old.delete();
var shp = bn.addShape("floorImage", cfg.param2D);
if (shp) {
shp.config = cfg;
shp.updateLook();
}
}
};
bn.setBinding = function(bs){
if (!bs) return;
var $modalScope = bn.$scope.$new(true);
var echo= function(){
bs.forEach(function(item){
var dev = _.find($modalScope.data.devices,
function(d){ return d.id === item.id; });
if (dev) $modalScope.data.selecteds.push(dev);
})
};
$modalScope.data = {};
$modalScope.data.selecteds = [];
bn.$srv.getBinding().then(function(data){
$modalScope.data.devices = data;
echo();
});
$modalScope.ok = function (){
bs.length = 0;
$modalScope.data.selecteds.forEach(function(item){
bs.push(item);
});
bn.dirty = true;
this.$hide();
};
$modalScope.deleteBind = function (){
bs.length = 0;
bn.dirty = true;
this.$hide();
};
var languageJson = angular.fromJson(sessionStorage.getItem('languageJson'));
if($modalScope.languageJson == undefined)
$modalScope.languageJson = {Configuration:{TextControl:{}}};
$modalScope.languageJson.Configuration.TextControl.BindingSettings = languageJson.Configuration.TextControl.BindingSettings;
bn.$modal({scope: $modalScope,
templateUrl: '/partials/bindingDlg.html',
show: true});
};
bn.confirm = function(msg,confirmBox){
var deferred = bn.$q.defer();
var $modalScope = bn.$scope.$new(true);
$modalScope.message = msg;
$modalScope.ok = function (){
deferred.resolve(true);
this.$hide();
};
$modalScope.cancel = function (){
deferred.resolve(false);
this.$hide();
};
if($modalScope.languageJson == undefined) $modalScope.languageJson = {};
$modalScope.languageJson.ConfirmBox = confirmBox;
bn.$modal({scope: $modalScope,
templateUrl: '/partials/confirmBox.html',
show: true});
return deferred.promise;
};
bn.info = function(msg,messageBox){
var $modalScope = bn.$scope.$new(true);
$modalScope.message = msg;
if($modalScope.languageJson == undefined) $modalScope.languageJson = {};
$modalScope.languageJson.MessageBox = messageBox;
bn.$modal({scope: $modalScope,
templateUrl: '/partials/messageBox.html',
show: true});
};
bn.uploadConfig = function(cfg){
bn.$srv.saveConfig("demo", angular.toJson(cfg));
};
bn.ev = function(event, obj){
bn.$scope.$emit(event, obj);
};
bn.local = function(key){
var languageJson = angular.fromJson(sessionStorage.getItem('languageJson'));
var zh ={
new: "新建",
save: "保存",
clone: "复制并粘贴",
delete: "删除",
page_option: "画面设置",
align_top: "上对齐",
align_bottom: "下对齐",
align_vcenter: "水平居中",
align_left: "左对齐",
align_hcenter: "垂直居中",
align_right: "右对齐",
align_vscale: "垂直等间距",
align_hscale: "水平等间距",
to_back: "移动到最下层",
to_front: "移动到最上层",
move_up: "向上移动物体",
move_down: "向下移动物体",
move_left: "向左移动物体",
move_right: "向右移动物体"
};
var lan = undefined;
if(languageJson.Room3D.Head)
lan = languageJson.Room3D.Head;
else
lan = zh;
for(var a in lan)
{
if (a == key) return lan[a];
}
return null;
};
bn.dispose = function(){
var disposeObject = function(obj){
for(var b in obj){
if(typeof(obj[b]) === "function" && obj[b].name === "event"){
obj[b] = undefined;
}
else if(typeof(obj[b]) === "function" && obj[b].length > 0){
disposeObject(obj[b]);
}
else if(typeof(obj[b]) === "object" && b === "dispatch"){
disposeObject(obj[b]);
}
}
};
$(window).off();
$(window).unbind();
$(document).off();
$(document).unbind();
$(bn.domId).off();
$(bn.domId).unbind();
bn.clear();
bn.paper.clear();
var clearPaper = function (paper){
var paperDom = paper.canvas;
paperDom.parentNode.removeChild(paperDom);
};
clearPaper(bn.paper);
disposeObject(bn.paper);
bn.paper = undefined;
delete bn.options;
bn.$scope.change = undefined;
bn.$scope = undefined;
bn.$modal = undefined;
bn.$q = undefined;
bn.$srv = undefined;
bn.$upload = undefined;
disposeObject(bn);
bn = undefined;
};
///////// create main code here /////////
bn.options = _.extend(bn.options, options);
bn.inject();
bn.init(id);
bn.newConfig();
return bn;
}
};