285 lines
7.8 KiB
JavaScript
285 lines
7.8 KiB
JavaScript
//>>built
|
|
// wrapped by build app
|
|
define("dojox/drawing/util/common", ["dijit","dojo","dojox","dojo/require!dojox/math/round"], function(dijit,dojo,dojox){
|
|
dojo.provide("dojox.drawing.util.common");
|
|
dojo.require("dojox.math.round");
|
|
|
|
(function(){
|
|
|
|
var uidMap = {};
|
|
var start = 0;
|
|
dojox.drawing.util.common = {
|
|
// summary:
|
|
// A collection of common methods used for DojoX Drawing.
|
|
// This singleton is accessible in most Drawing classes
|
|
// as this.util
|
|
//
|
|
// NOTE:
|
|
// A lot of functions use a EventObject
|
|
// as an argument. An attempt was made to accept
|
|
// either that object or a list of numbers. That wasn't
|
|
// finished (it didn't work well in all cases) but is
|
|
// likely to happen in the future.
|
|
// In cases where you are not sending a Mouse object,
|
|
// form your argument like so:
|
|
// var obj = {
|
|
// start:{
|
|
// x:Number, // start x
|
|
// y:Number // start y
|
|
// },
|
|
// x: Number, // end x
|
|
// y:Number // end y
|
|
// }
|
|
//
|
|
//
|
|
radToDeg: function(/*Numer*/n){
|
|
// summary:
|
|
// Convert the passed number to degrees.
|
|
return (n*180)/Math.PI; // Number
|
|
},
|
|
|
|
degToRad: function(/*Numer*/n){
|
|
// summary:
|
|
// Convert the passed number to radians.
|
|
return (n*Math.PI)/180; // Number
|
|
},
|
|
|
|
angle: function(/*EventObject*/obj, /* ? Float */snap){
|
|
// summary:
|
|
// Return angle based on mouse object
|
|
// arguments:
|
|
// obj: EventObject
|
|
// Manager.Mouse event.
|
|
// snap: Float
|
|
// Returns nearest angle within snap limits
|
|
//
|
|
//obj = this.argsToObj.apply(this, arguments);
|
|
if(snap){
|
|
snap = snap/180;
|
|
var radians = this.radians(obj),
|
|
seg = Math.PI * snap,
|
|
rnd = dojox.math.round(radians/seg),
|
|
new_radian = rnd*seg;
|
|
return dojox.math.round(this.radToDeg(new_radian)); // Whole Number
|
|
|
|
}else{
|
|
return this.radToDeg(this.radians(obj)); // Float
|
|
}
|
|
},
|
|
|
|
oppAngle: function(/*Angle*/ang){
|
|
(ang+=180) > 360 ? ang = ang - 360 : ang;
|
|
return ang;
|
|
},
|
|
|
|
radians: function(/*EventObject*/o){
|
|
// summary:
|
|
// Return the radians derived from the coordinates
|
|
// in the Mouse object.
|
|
//
|
|
//var o = this.argsToObj.apply(this, arguments);
|
|
return Math.atan2(o.start.y-o.y,o.x-o.start.x);
|
|
},
|
|
|
|
length: function(/*EventObject*/o){
|
|
// summary:
|
|
// Return the length derived from the coordinates
|
|
// in the Mouse object.
|
|
//
|
|
return Math.sqrt(Math.pow(o.start.x-o.x, 2)+Math.pow(o.start.y-o.y, 2));
|
|
},
|
|
|
|
lineSub: function(/*Number*/x1, /*Number*/y1, /*Number*/x2, /*Number*/y2, /*Number*/amt){
|
|
// summary:
|
|
// Subtract an amount from a line
|
|
// description:
|
|
// x1,y1,x2,y2 represents the Line. 'amt' represents the amount
|
|
// to subtract from it.
|
|
//
|
|
var len = this.distance(this.argsToObj.apply(this, arguments));
|
|
len = len < amt ? amt : len;
|
|
var pc = (len-amt)/len;
|
|
var x = x1 - (x1-x2) * pc;
|
|
var y = y1 - (y1-y2) * pc;
|
|
return {x:x, y:y}; // Object
|
|
},
|
|
|
|
argsToObj: function(){
|
|
// summary:
|
|
// Attempts to determine in a Mouse Object
|
|
// was passed or indiviual numbers. Returns
|
|
// an object.
|
|
//
|
|
var a = arguments;
|
|
if(a.length < 4){ return a[0]; }
|
|
return {
|
|
start:{
|
|
x:a[0],
|
|
y:a[1]
|
|
},
|
|
x:a[2],
|
|
y:a[3]//,
|
|
//snap:a[4]
|
|
}; // Object
|
|
},
|
|
|
|
distance: function(/*EventObject or x1,y1,x2,y2*/){
|
|
// summary:
|
|
// Return the length derived from the coordinates
|
|
// in the Mouse object. Different from util.length
|
|
// in that this always returns an absolute value.
|
|
//
|
|
var o = this.argsToObj.apply(this, arguments);
|
|
return Math.abs(Math.sqrt(Math.pow(o.start.x-o.x, 2)+Math.pow(o.start.y-o.y, 2))); // Number
|
|
},
|
|
|
|
slope:function(/*Object*/p1, /*Object*/p2){
|
|
// summary:
|
|
// Given two poits of a line, returns the slope.
|
|
if(!(p1.x-p2.x)){ return 0; }
|
|
return ((p1.y-p2.y)/(p1.x-p2.x)); // Number
|
|
},
|
|
|
|
pointOnCircle: function(/*Number*/cx, /*Number*/cy, /*Number*/radius, /*Number*/angle){
|
|
// summary:
|
|
// A *very* helpful method. If you know the center
|
|
// (or starting) point, length and angle, find the
|
|
// x,y point at the end of that line.
|
|
//
|
|
var radians = angle * Math.PI / 180.0;
|
|
var x = radius * Math.cos(radians);
|
|
var y = radius * Math.sin(radians);
|
|
return {
|
|
x:cx+x,
|
|
y:cy-y
|
|
}; // Object
|
|
},
|
|
|
|
constrainAngle: function(/*EventObject*/obj, /*Number*/min, /*Number*/max){
|
|
// summary:
|
|
// Ensures the angle in the Mouse Object is within the
|
|
// min and max limits. If not one of those limits is used.
|
|
// Returns an x,y point for the angle used.
|
|
//
|
|
var angle = this.angle(obj);
|
|
if(angle >= min && angle <= max){
|
|
return obj; // Object
|
|
}
|
|
var radius = this.length(obj);
|
|
var new_angle = angle > max ? max : min - angle < 100 ? min : max;
|
|
return this.pointOnCircle(obj.start.x,obj.start.y,radius, new_angle); // Object
|
|
},
|
|
|
|
snapAngle: function(/*EventObject*/obj, /*Float*/ca){
|
|
// summary:
|
|
// Snaps a line to the nearest angle
|
|
// obj: Mouse object (see dojox.drawing.Mouse)
|
|
// ca: Fractional amount to snap to
|
|
// A decimal number fraction of a half circle
|
|
// .5 would snap to 90 degrees
|
|
// .25 would snap to 45 degrees
|
|
// .125 would snap to 22.5 degrees, etc.
|
|
//
|
|
var radians = this.radians(obj),
|
|
radius = this.length(obj),
|
|
seg = Math.PI * ca,
|
|
rnd = Math.round(radians/seg),
|
|
new_radian = rnd*seg,
|
|
new_angle = this.radToDeg(new_radian),
|
|
pt = this.pointOnCircle(obj.start.x,obj.start.y,radius,new_angle);
|
|
return pt; // Object
|
|
},
|
|
|
|
// helpers
|
|
idSetStart: function(num){
|
|
start=num;
|
|
},
|
|
|
|
uid: function(/* ? String */str){
|
|
// summary:
|
|
// Creates a unique ID.
|
|
// arguments:
|
|
// str: String
|
|
// If provided, kept in a map, incremented
|
|
// and used in the id. Otherwise 'shape' is used.
|
|
//
|
|
str = str || "shape";
|
|
uidMap[str] = uidMap[str]===undefined ? start : uidMap[str] + 1;
|
|
return str + uidMap[str]; // String
|
|
},
|
|
|
|
abbr: function(type){
|
|
// summary:
|
|
// Converts a namespace (typically a tool or a stencil) into
|
|
// an abbreviation
|
|
return type.substring(type.lastIndexOf(".")+1).charAt(0).toLowerCase()
|
|
+ type.substring(type.lastIndexOf(".")+2);
|
|
},
|
|
mixin: function(o1, o2){
|
|
// TODO: make faster
|
|
//return dojo.mixin(dojo.clone(o1), dojo.clone(o2));
|
|
},
|
|
|
|
objects:{}, //private?
|
|
register: function(/*Object*/obj){
|
|
// summary:
|
|
// Since util is the only Singleton in Drawing (besides
|
|
// keys) it is used to help connect the Drawing object
|
|
// the Toolbar. Since multiple drawings can be on one
|
|
// page, this function serves a little more use than
|
|
// on first apearance.
|
|
this.objects[obj.id] = obj;
|
|
},
|
|
byId: function(/*String*/id){
|
|
// summary:
|
|
// Get an object that was registered with util.register
|
|
//
|
|
return this.objects[id];
|
|
},
|
|
attr: function(/* Object */ elem, /* property */ prop, /* ? value */ value, squelchErrors){
|
|
// summary:
|
|
// Helper function to attach attributes to SVG and VML raw nodes.
|
|
//
|
|
|
|
if(!elem){ return false; }
|
|
try{
|
|
|
|
// util is a crappy check, but we need to tell the diff
|
|
// between a Drawing shape and a GFX shape
|
|
if(elem.shape && elem.util){
|
|
elem = elem.shape;
|
|
}
|
|
|
|
if(!value && prop=="id" && elem.target){
|
|
|
|
var n = elem.target;
|
|
while(!dojo.attr(n, "id")){
|
|
n = n.parentNode;
|
|
}
|
|
return dojo.attr(n, "id");
|
|
}
|
|
|
|
if(elem.rawNode || elem.target){
|
|
var args = Array.prototype.slice.call(arguments);
|
|
args[0] = elem.rawNode || elem.target;
|
|
return dojo.attr.apply(dojo, args);
|
|
}
|
|
return dojo.attr(elem, "id");
|
|
|
|
|
|
|
|
}catch(e){
|
|
if(!squelchErrors){
|
|
// For debugging only. These errors actually cause errors in IE's console
|
|
//console.error("BAD ATTR: prop:", prop, "el:", elem)
|
|
//console.error(e)
|
|
//console.trace();
|
|
}
|
|
return false;
|
|
}
|
|
}
|
|
};
|
|
|
|
})();
|
|
});
|