123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291 |
- /*
- Copyright (c) 2004-2012, The Dojo Foundation All Rights Reserved.
- Available via Academic Free License >= 2.1 OR the modified BSD license.
- see: http://dojotoolkit.org/license for details
- */
- if(!dojo._hasResource["dojox.drawing.util.common"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
- dojo._hasResource["dojox.drawing.util.common"] = true;
- 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;
- }
- }
- };
-
- })();
- }
|