1
1
/********************************************************************************
3
Mouse coordinate and canvas globals
5
Handles both Touch and Mouse/Keyboard input at the same time
7
*********************************************************************************/
9
// Mouse coordinate globals
16
/********************************************************************************
18
Canvas Setup and Click Handling Code
20
Handles both Touch and Mouse/Keyboard input at the same time and executes
22
Also declares canvas globals
24
*********************************************************************************/
26
function setupcanvas()
28
acanvas=document.getElementById('a');
29
context=acanvas.getContext("2d");
31
setTimeout("foo();",50);
36
function setupClickHandling()
38
// Mouse and Keyboard Events
39
acanvas.addEventListener('mousemove', ev_mousemove, false);
40
acanvas.addEventListener('mouseup', ev_mouseup, false);
41
acanvas.addEventListener('mousedown', ev_mousedown, false);
44
acanvas.addEventListener('touchstart', ev_touchstart, false);
45
acanvas.addEventListener('touchend', ev_touchend, false);
46
acanvas.addEventListener('touchmove', ev_touchmove, false);
49
// Keyboard/Mouse Mouse Up Handler
50
function ev_mouseup(ev)
55
// Keyboard/Mouse Mouse Down Handler
56
function ev_mousedown(ev)
61
// Keyboard/Mouse Mouse Move Handler
62
function ev_mousemove (ev)
65
if (ev.layerX||ev.layerX==0) { // Firefox
66
cx=ev.layerX-acanvas.offsetLeft;
67
cy=ev.layerY-acanvas.offsetTop;
68
} else if (ev.offsetX || ev.offsetX == 0) { // Opera
69
cx=ev.offsetX-acanvas.offsetLeft;
70
cy=ev.offsetY-acanvas.offsetTop;
73
coord=findPos(acanvas);
77
handler_mousemove(cx,cy);
81
function ev_touchstart(event){
82
event.preventDefault();
83
var numtouch = event.touches.length;
85
targetEvent = event.touches.item(0);
87
var cx = targetEvent.pageX;
88
var cy = targetEvent.pageY;
98
function ev_touchend(event){
99
event.preventDefault();
100
var numtouch = event.touches.length;
106
function ev_touchmove(event){
107
event.preventDefault();
108
var numtouch = event.touches.length;
110
targetEvent = event.touches.item(0);
112
var cx = targetEvent.pageX;
113
var cy = targetEvent.pageY;
115
handler_mousemove(cx,cy);
118
// Fix scrolling on touch devices
119
var ScrollFix = function(elem) {
120
// Variables to track inputs
121
var startY, startTopScroll;
123
elem = elem || document.querySelector(elem);
125
// If there is no element, then do nothing
129
// Handle the start of interactions
130
elem.addEventListener('touchstart', function(event){
131
startY = event.touches[0].pageY;
132
startTopScroll = elem.scrollTop;
134
if(startTopScroll <= 0)
137
if(startTopScroll + elem.offsetHeight >= elem.scrollHeight)
138
elem.scrollTop = elem.scrollHeight - elem.offsetHeight - 1;
142
/********************************************************************************
144
Canvas Diagram Drawing Code
146
*********************************************************************************/
148
// Draws a stroked rectangle of certain thicknes and color
150
function drawrect(x1,y1,x2,y2,color)
152
context.lineWidth = 1.5;
153
context.strokeStyle = color;
154
context.strokeRect(x1,y1,x2-x1,y2-y1);
159
// Draws a perfect round circle
161
function drawcircle(radius,color)
163
context.lineWidth = 1.5;
164
context.strokeStyle = color;
165
context.arc(0, 0, radius, 0 , 2 * Math.PI, false);
168
// Draws 90 degree arc
170
function drawellipse(x1,y1,x2,y2)
178
context.moveTo(x1,y1+ry);
179
context.quadraticCurveTo(x1,y1,x1+rx,y1);
180
context.quadraticCurveTo(x2,y1,x2,y1+ry);
181
context.quadraticCurveTo(x2,y2,x2-rx,y2);
182
context.quadraticCurveTo(x1,y2,x1,y1+ry);
189
function point(x,y,col)
191
context.strokeStyle="#000";
192
context.lineWidth = 1;
194
context.fillStyle=col;
195
context.fillRect(x-4,y-4,8,8);
196
context.strokeRect(x-4,y-4,8,8);
199
// Draw a box around a point to indicate highlight
201
function highlight(px,py)
203
context.strokeStyle="#aaa";
204
context.lineWidth = 1;
206
context.strokeRect(px-8,py-8,16,16);
210
// Draw a line using current context
212
function drawline(x1,y1,x2,y2,strokestyle,linewidth)
214
context.strokeStyle = strokestyle;
215
context.lineWidth = linewidth;
217
context.moveTo(x1,y1);
218
context.lineTo(x2,y2);
222
function fourpoints(x1,y1,x2,y2,x3,y3,x4,y4,col)
230
function drawdiamond(x1,y1,x2,y2)
236
context.moveTo(x1,y1+ry);
237
context.lineTo(x1+rx,y2);
238
context.lineTo(x2,y1+ry);
239
context.lineTo(x1+rx,y1);
240
context.lineTo(x1,y1+ry);
244
// Dashed Line in Segments of given size
246
function dashedline(sx,sy,ex,ey,dashlen,linewidth,col)
252
len=Math.sqrt((dx*dx)+(dy*dy));
253
notimes=Math.round(len/dashlen);
258
context.lineWidth = linewidth;
259
context.strokeStyle=col;
268
for(var i=0;i<notimes;i++){
270
context.moveTo(xk,yk);
271
context.lineTo(xk+xh,yk+yh);
281
// Arcto only works if both x1 and y2 are on circle border
283
function arcto(x0,y0,x1,y1,x2,y2)
286
var r = Math.sqrt((x1-x0)*(x1-x0) + (y1-y0)*(y1-y0));
289
var startAngle = (180/Math.PI*Math.atan2(y1-y0, x1-x0));
290
var endAngle = (180/Math.PI*Math.atan2(y2-y0, x2-x0));
292
context.arc(x0, y0, r, 0, Math.PI*2.0, 1.0);
296
// Draws 90 degree arc
298
function arcdeg(x1,y1,x2,y2,x3,y3)
302
// First quadrant positive positive
303
dashedline(x1,y1,x2,y2,8,1.0,"#999");
304
dashedline(x3,y3,x2,y2,8,1.0,"#999");
319
context.strokeStyle = '#49f';
320
context.lineWidth = 1.0;
322
context.moveTo(x1,y1);
326
context.lineTo(x1+(Math.sin(((Math.PI/96.0)*-i)+(Math.PI*1.0))*rx),y3+(Math.cos(((Math.PI/96.0)*-i)+(Math.PI*1.0))*ry));
328
context.lineTo(x3+(Math.sin(((Math.PI/96.0)*i)+(Math.PI*1.5))*rx),y1+(Math.cos(((Math.PI/96.0)*i)+(Math.PI*1.5))*ry));
332
context.lineTo(x1+(Math.sin(((Math.PI/96.0)*-i)+(Math.PI*1.0))*rx),y3+(Math.cos(((Math.PI/96.0)*-i)+(Math.PI*1.0))*ry));
334
context.lineTo(x3+(Math.sin(((Math.PI/96.0)*i)+(Math.PI*1.5))*rx),y1+(Math.cos(((Math.PI/96.0)*i)+(Math.PI*1.5))*ry));
342
// function that draws one part of the sun
344
function sundial(radius,angle,scale)
347
cosv=Math.cos(angle);
348
sinv=Math.sin(angle);
359
context.bezierCurveTo((-1.5*xaddx)+(yaddx*1.5)+xk,(-1.5*xaddy)+(yaddy*1.5)+yk,xaddx+(yaddx*2.0)+xk,xaddy+(yaddy*2.0)+yk,xaddx+(yaddx*3.0)+xk,xaddy+(yaddy*3.0)+yk);
360
context.bezierCurveTo(xaddx+yaddx+xk,xaddy+yaddy+yk,(1.5*xaddx)+yaddx+xk,(1.5*xaddy)+yaddy+yk,(3.0*xaddx)+xk,(3.0*xaddy)+yk);
363
// function that daws the sun
367
context.fillStyle = "#fe9";
368
context.strokeStyle = "#d82";
369
context.lineWidth = 1.5;
372
context.moveTo(30,0);
373
for(i=0.0;i<360.0;i+=22.5){
374
angle=(i/360.0)*2*Math.PI;
381
// Draws the ball (used in various examples)
383
function drawball(cx,cy,radie,innerradie,ballradie,col1,inangle,inangleadd)
386
angleadd=(inangleadd/360.0)*2*Math.PI;
388
context.fillStyle = col1;
390
for(i=0;i<360;i+=inangle){
392
angle=(i/360.0)*2*Math.PI;
393
angle2=angle+angleadd;
394
angle3=angle+(angleadd*2.0);
395
angle4=angle-angleadd;
397
cosv=Math.cos(angle);
398
sinv=Math.sin(angle);
400
cosv2=Math.cos(angle2);
401
sinv2=Math.sin(angle2);
403
cosv4=Math.cos(angle4);
404
sinv4=Math.sin(angle4);
408
context.moveTo(cx,cy);
409
context.quadraticCurveTo(cx+(cosv*innerradie),cy+(sinv*innerradie),cx+(cosv2*radie),cy+(sinv2*radie));
410
context.arc(cx,cy,radie,angle2,angle,1.0);
411
context.quadraticCurveTo(cx+(cosv4*innerradie),cy+(sinv4*innerradie),cx,cy);
418
context.arc(cx,cy,radie,0,Math.PI*2.0,1.0);
423
// Draws underlined/dashed underlined text clipped inside a rectangle, a quadratic curve ellipsis or a diamond
425
function cliptext(x1,y1,x2,y2,tex,font,align,edgeoffs,baseline,color,clipkind,underlinekind)
438
// Make Rectangle / Ellipse / Diamond Clipping Paths
440
context.moveTo(x1,y1);
441
context.lineTo(x1,y2);
442
context.lineTo(x2-edgeoffs,y2);
443
context.lineTo(x2-edgeoffs,y1);
444
context.lineTo(x1,y1);
445
}else if(clipkind==2){
446
context.moveTo(x1,y1+ry);
447
context.quadraticCurveTo(x1+edgeoffs,y1+edgeoffs,x1+edgeoffs+rx,y1+edgeoffs);
448
context.quadraticCurveTo(x2-edgeoffs,y1+edgeoffs,x2-edgeoffs,y1+ry+edgeoffs);
449
context.quadraticCurveTo(x2-edgeoffs,y2-edgeoffs,x2-rx-edgeoffs,y2-edgeoffs);
450
context.quadraticCurveTo(x1+edgeoffs,y2-edgeoffs,x1+edgeoffs,y1+ry+edgeoffs);
451
}else if(clipkind==3){
452
context.moveTo(x1,y1+ry);
453
context.lineTo(x1+rx,y2);
454
context.lineTo(x2,y1+ry);
455
context.lineTo(x1+rx,y1);
456
context.lineTo(x1,y1+ry);
464
context.textAlign = "left";
465
context.fillStyle = color;
467
var metrics = context.measureText(tex);
468
var hwidth = metrics.width*0.5;
470
// Compute left-justified centered coordinate
471
if((rx-hwidth-edgeoffs)<0){
477
context.fillText(tex, tx, y2-ry+baseline);
479
// Draw underlining - can handle dashed underline!
480
if(underlinekind==1){
481
drawline(tx,y2-ry+baseline+5.0,tx+(hwidth*2),y2-ry+baseline+5.0,"#000",2.0);
484
if(clipkind!=0) context.restore();
488
// Draws cardinality at a certain offset from a coordinate
489
function drawcardinality(x,y,side,tex,xoffs,yoffs,font,baseline,sign,color)
491
// Xoffs is along line
493
// Yoffs is distance from line
496
var metrics = context.measureText(tex);
497
var twidth = metrics.width;
503
context.textAlign = "left";
504
context.fillStyle = color;
506
if(side==1&&sign==1){
507
context.fillText(tex, x-twidth-xoffs, y-yoffs);
508
drawrect(x-twidth-xoffs, y-yoffs,x-xoffs, y-yoffs-theight);
509
}else if(side==2&&sign==1){
510
context.fillText(tex, x+yoffs, y+xoffs+theight);
511
drawrect(x+yoffs, y+xoffs+theight,x+yoffs+twidth, y+xoffs);
512
}else if(side==3&&sign==1){
513
context.fillText(tex, x+xoffs, y-yoffs);
514
}else if(side==4&&sign==1){
515
context.fillText(tex, x+yoffs, y-xoffs);
516
}else if(side==1&&sign==2){
517
context.fillText(tex, x-twidth-xoffs, y+theight+yoffs);
518
drawrect(x-twidth-xoffs, y+yoffs,x-xoffs, y+theight+yoffs);
519
}else if(side==2&&sign==2){
520
context.fillText(tex, x-yoffs-twidth, y+xoffs+theight);
521
drawrect(x-yoffs-twidth, y+xoffs,x-yoffs, y+xoffs+theight);
522
}else if(side==3&&sign==2){
523
context.fillText(tex, x+xoffs, y+theight+yoffs);
524
}else if(side==4&&sign==2){
525
context.fillText(tex, x-yoffs-twidth, y-xoffs);
531
/********************************************************************************
533
Canvas and Diagram Measuring Functions
535
These functions allow us to measure pixels in diagram and other apps
537
*********************************************************************************/
540
// Recursive Pos of div in document - should work in most browsers
542
function findPos(obj) {
543
var curleft = curtop = 0;
544
if (obj.offsetParent) {
545
curleft = obj.offsetLeft
546
curtop = obj.offsetTop
547
while (obj = obj.offsetParent) {
548
curleft += obj.offsetLeft
549
curtop += obj.offsetTop
558
// Make side coordinates for drawing Model
560
function makeside(side,x1,y1,x2,y2,perc){
567
yk=y1+((y2-y1)*perc);
569
xk=x1+((x2-x1)*perc);
573
yk=y1+((y2-y1)*perc);
586
// Computes side identifier for a mouse coordinate and object coordinates
588
function computeside(x,y,x1,y1,x2,y2,sidetol){
590
var obj_sidentifier="None";
592
var obj_centerdist=0;
595
if(x>x1-sidetol&&x<x1+sidetol&&y>y1-sidetol&&y<y2+sidetol){
597
obj_sideperc=makesideperc(y,y1,y2);
598
obj_centerdist=centerdist(y,y1,y2);
601
// Bottom Not Including Left Side or Right Side
602
if(x>x1+sidetol&&x<x2-sidetol&&y>y2-sidetol&&y<y2+sidetol){
604
obj_sideperc=makesideperc(x,x1,x2);
605
obj_centerdist=centerdist(x,x1,x2);
609
if(x>x2-sidetol&&x<x2+sidetol&&y>y1-sidetol&&y<y2+sidetol){
611
obj_sideperc=makesideperc(y,y1,y2);
612
obj_centerdist=centerdist(y,y1,y2);
615
// Top Not Including Left Side or Right Side
616
if(x>x1+sidetol&&x<x2-sidetol&&y>y1-sidetol&&y<y1+sidetol){
618
obj_sideperc=makesideperc(x,x1,x2);
619
obj_centerdist=centerdist(x,x1,x2);
623
side:obj_sidentifier,
630
// Make side perc for ER model
632
function makesideperc(x,x1,x2){
636
if(perc>1.0) perc=1.0;
637
if(perc<0.0) perc=0.0;
642
function centerdist(x,x1,x2){
648
// Euclidian distance - Yo!
650
function distance(x1,y1,x2,y2){
652
var dist=Math.sqrt(((y2-y1)*(y2-y1))+((x2-x1)*(x2-x1)));
657
// Are we over a line or not.
659
function overline(x,y,x1,y1,x2,y2,tolerance)
667
straighttolerance=2.0;
669
var box1,boy1,box2,boy2;
687
// drawrect(box1-tolerance,boy1-tolerance,box2+tolerance,boy2+tolerance,"#aaa");
689
if((x>(box1-tolerance))&&(x<(box2+tolerance))&&(y>(boy1-tolerance))&&(y<(boy2+tolerance))){
690
// Straight X, Straight Y or Positive or Negative Incline
691
if(Math.abs(dx)<straighttolerance){
693
if(y>y1-tolerance&&y<y2+tolerance){
694
distance=Math.abs(x1-x);
697
if(y>y2-tolerance&&y<y1+tolerance){
698
distance=Math.abs(x1-x);
701
}else if(Math.abs(dy)<straighttolerance){
703
if(x>x1-tolerance&&x<x2+tolerance){
704
distance=Math.abs(y1-y);
707
if(x>x2-tolerance&&x<x1+tolerance){
708
distance=Math.abs(y1-y);
711
}else if(Math.abs(dx)>=Math.abs(dy)){
714
distance=Math.abs(yk-y);
718
distance=Math.abs(xk-x);
b'\\ No newline at end of file'
2
Mouse coordinate and canvas globals
3
Handles both Touch and Mouse/Keyboard input at the same time
4
*********************************************************************************/
6
// Mouse coordinate globals
12
/********************************************************************************
13
Canvas Setup and Click Handling Code
15
Handles both Touch and Mouse/Keyboard input at the same time and executes
17
Also declares canvas globals
18
*********************************************************************************/
20
function setupcanvas() {
21
acanvas = document.getElementById('a');
22
context = acanvas.getContext("2d");
23
setTimeout("foo();",50);
27
function setupClickHandling() {
28
// Mouse and Keyboard Events
29
acanvas.addEventListener('mousemove', ev_mousemove, false);
30
acanvas.addEventListener('mouseup', ev_mouseup, false);
31
acanvas.addEventListener('mousedown', ev_mousedown, false);
34
acanvas.addEventListener('touchstart', ev_touchstart, false);
35
acanvas.addEventListener('touchend', ev_touchend, false);
36
acanvas.addEventListener('touchmove', ev_touchmove, false);
39
// Keyboard/Mouse Mouse Up Handler
40
function ev_mouseup(ev) {
44
// Keyboard/Mouse Mouse Down Handler
45
function ev_mousedown(ev) {
49
// Keyboard/Mouse Mouse Move Handler
50
function ev_mousemove (ev) {
52
if (ev.layerX || ev.layerX == 0) { // Firefox
53
cx = ev.layerX - acanvas.offsetLeft;
54
cy = ev.layerY - acanvas.offsetTop;
55
} else if (ev.offsetX || ev.offsetX == 0) { // Opera
56
cx = ev.offsetX - acanvas.offsetLeft;
57
cy = ev.offsetY - acanvas.offsetTop;
59
coord = findPos(acanvas);
62
handler_mousemove(cx, cy);
66
function ev_touchstart(event) {
67
event.preventDefault();
68
var numtouch = event.touches.length;
69
targetEvent = event.touches.item(0);
70
var cx = targetEvent.pageX;
71
var cy = targetEvent.pageY;
78
function ev_touchend(event) {
79
event.preventDefault();
80
var numtouch = event.touches.length;
85
function ev_touchmove(event) {
86
event.preventDefault();
87
var numtouch = event.touches.length;
88
targetEvent = event.touches.item(0);
89
var cx = targetEvent.pageX;
90
var cy = targetEvent.pageY;
91
handler_mousemove(cx, cy);
94
// Fix scrolling on touch devices
95
var ScrollFix = function(elem) {
96
// Variables to track inputs
97
var startY, startTopScroll;
98
elem = elem || document.querySelector(elem);
100
// If there is no element, then do nothing
105
// Handle the start of interactions
106
elem.addEventListener('touchstart', function(event) {
107
startY = event.touches[0].pageY;
108
startTopScroll = elem.scrollTop;
110
if(startTopScroll <= 0) {
114
if(startTopScroll + elem.offsetHeight >= elem.scrollHeight) {
115
elem.scrollTop = elem.scrollHeight - elem.offsetHeight - 1;
120
/********************************************************************************
121
Canvas Diagram Drawing Code
122
*********************************************************************************/
124
// Draws a stroked rectangle of certain thicknes and color
125
function drawrect(x1, y1, x2, y2, color) {
126
context.lineWidth = 1.5;
127
context.strokeStyle = color;
128
context.strokeRect(x1, y1, x2 - x1, y2 - y1);
131
// Draws a perfect round circle
132
function drawcircle(radius, color) {
133
context.lineWidth = 1.5;
134
context.strokeStyle = color;
135
context.arc(0, 0, radius, 0 , 2 * Math.PI, false);
138
// Draws 90 degree arc
139
function drawellipse(x1, y1, x2, y2) {
140
var rx = (x2 - x1) * 0.5;
141
var ry = (y2 - y1) * 0.5;
143
context.moveTo(x1, y1 + ry);
144
context.quadraticCurveTo(x1, y1, x1 + rx, y1);
145
context.quadraticCurveTo(x2, y1, x2, y1 + ry);
146
context.quadraticCurveTo(x2, y2, x2 - rx, y2);
147
context.quadraticCurveTo(x1, y2, x1, y1 + ry);
152
function point(x, y, col) {
153
context.strokeStyle = "#000";
154
context.lineWidth = 1;
155
context.fillStyle = col;
156
context.fillRect(x - 4, y - 4, 8, 8);
157
context.strokeRect(x - 4, y - 4, 8, 8);
160
// Draw a box around a point to indicate highlight
161
function highlight(px, py) {
162
context.strokeStyle = "#aaa";
163
context.lineWidth = 1;
164
context.strokeRect(px - 8, py - 8, 16, 16);
167
// Draw a line using current context
168
function drawline(x1, y1, x2, y2, strokestyle, linewidth) {
169
context.strokeStyle = strokestyle;
170
context.lineWidth = linewidth;
172
context.moveTo(x1, y1);
173
context.lineTo(x2, y2);
177
function fourpoints(x1, y1, x2, y2, x3, y3, x4, y4, col) {
184
function drawdiamond(x1, y1, x2, y2) {
185
var rx = (x2 - x1) * 0.5;
186
var ry = (y2 - y1) * 0.5;
188
context.moveTo(x1, y1 + ry);
189
context.lineTo(x1 + rx, y2);
190
context.lineTo(x2, y1 + ry);
191
context.lineTo(x1 + rx, y1);
192
context.lineTo(x1, y1 + ry);
196
// Dashed Line in Segments of given size
197
function dashedline(sx, sy, ex, ey, dashlen, linewidth, col) {
200
len = Math.sqrt((dx * dx) + (dy * dy));
201
notimes = Math.round(len / dashlen);
204
context.lineWidth = linewidth;
205
context.strokeStyle = col;
212
for(var i = 0; i < notimes; i++) {
213
context.moveTo(xk, yk);
214
context.lineTo(xk + xh, yk + yh);
221
// Arcto only works if both x1 and y2 are on circle border
222
function arcto(x0, y0, x1, y1, x2, y2) {
223
var r = Math.sqrt((x1 - x0) * (x1 - x0) + (y1 - y0) * (y1 - y0));
226
var startAngle = (180 / Math.PI * Math.atan2(y1 - y0, x1 - x0));
227
var endAngle = (180 / Math.PI * Math.atan2(y2 - y0, x2 - x0));
228
context.arc(x0, y0, r, 0, Math.PI * 2.0, 1.0);
231
// Draws 90 degree arc
232
function arcdeg(x1, y1, x2, y2, x3, y3) {
233
// First quadrant positive positive
234
dashedline(x1, y1, x2, y2, 8, 1.0, "#999");
235
dashedline(x3, y3, x2, y2, 8, 1.0, "#999");
236
point(x1, y1, "#ff5");
237
point(x2, y2, "#f55");
238
point(x3, y3, "#f55");
240
k = (y3 - y1) / (x3 - x1);
241
yk = y1 + ((x2 - x1) * k);
244
point(x2, yk, "#f5f");
246
context.strokeStyle = '#49f';
247
context.lineWidth = 1.0;
249
context.moveTo(x1, y1);
250
for(i = 0; i < 48; i++) {
253
context.lineTo(x1 + (Math.sin(((Math.PI / 96.0) * -i) + (Math.PI * 1.0)) * rx), y3 + (Math.cos(((Math.PI / 96.0) * -i) + (Math.PI * 1.0)) * ry));
255
context.lineTo(x3 + (Math.sin(((Math.PI / 96.0) * i) + (Math.PI * 1.5)) * rx), y1 + (Math.cos(((Math.PI / 96.0) * i) + (Math.PI * 1.5)) * ry));
259
context.lineTo(x1 + (Math.sin(((Math.PI / 96.0) * -i) + (Math.PI * 1.0)) * rx), y3 + (Math.cos(((Math.PI / 96.0) * -i) + (Math.PI * 1.0)) * ry));
261
context.lineTo(x3 + (Math.sin(((Math.PI / 96.0) * i) + (Math.PI * 1.5)) * rx), y1 + (Math.cos(((Math.PI / 96.0) * i) + (Math.PI * 1.5)) * ry));
268
// function that draws one part of the sun
269
function sundial(radius, angle, scale) {
270
cosv = Math.cos(angle);
271
sinv = Math.sin(angle);
272
yaddx = scale * cosv;
273
yaddy = scale * sinv;
274
xaddx = -scale * sinv;
275
xaddy = scale * cosv;
279
context.bezierCurveTo((-1.5 * xaddx) + (yaddx * 1.5) + xk, (-1.5 * xaddy) + (yaddy * 1.5) + yk, xaddx + (yaddx * 2.0) + xk, xaddy + (yaddy * 2.0) + yk, xaddx + (yaddx * 3.0) + xk, xaddy + (yaddy * 3.0) + yk);
280
context.bezierCurveTo(xaddx + yaddx + xk, xaddy + yaddy + yk, (1.5 * xaddx) + yaddx + xk, (1.5 * xaddy) + yaddy + yk, (3.0 * xaddx) + xk, (3.0 * xaddy) + yk);
283
// function that daws the sun
285
context.fillStyle = "#fe9";
286
context.strokeStyle = "#d82";
287
context.lineWidth = 1.5;
289
context.moveTo(30, 0);
290
for(i = 0.0; i < 360.0; i += 22.5) {
291
angle = (i / 360.0) * 2 * Math.PI;
292
sundial(30, angle, 3);
298
// Draws the ball (used in various examples)
299
function drawball(cx, cy, radie, innerradie, ballradie, col1, inangle, inangleadd) {
301
angleadd = (inangleadd / 360.0) * 2 * Math.PI;
302
context.fillStyle = col1;
303
for(i = 0; i < 360; i += inangle) {
304
angle = (i / 360.0) * 2 * Math.PI;
305
angle2 = angle + angleadd;
306
angle3 = angle + (angleadd * 2.0);
307
angle4 = angle - angleadd;
309
cosv = Math.cos(angle);
310
sinv = Math.sin(angle);
312
cosv2 = Math.cos(angle2);
313
sinv2 = Math.sin(angle2);
315
cosv4 = Math.cos(angle4);
316
sinv4 = Math.sin(angle4);
320
context.moveTo(cx, cy);
321
context.quadraticCurveTo(cx + (cosv * innerradie), cy + (sinv * innerradie), cx + (cosv2 * radie), cy + (sinv2 * radie));
322
context.arc(cx, cy, radie, angle2, angle, 1.0);
323
context.quadraticCurveTo(cx + (cosv4 * innerradie), cy + (sinv4 * innerradie), cx, cy);
328
context.arc(cx, cy, radie, 0, Math.PI * 2.0, 1.0);
332
// Draws underlined/dashed underlined text clipped inside a rectangle, a quadratic curve ellipsis or a diamond
333
function cliptext(x1, y1, x2, y2, tex, font, align, edgeoffs, baseline, color, clipkind, underlinekind) {
334
var rx = (x2 - x1) * 0.5;
335
var ry = (y2 - y1) * 0.5;
343
// Make Rectangle / Ellipse / Diamond Clipping Paths
345
context.moveTo(x1, y1);
346
context.lineTo(x1, y2);
347
context.lineTo(x2 - edgeoffs, y2);
348
context.lineTo(x2 - edgeoffs, y1);
349
context.lineTo(x1, y1);
350
} else if(clipkind == 2) {
351
context.moveTo(x1, y1 + ry);
352
context.quadraticCurveTo(x1 + edgeoffs, y1 + edgeoffs, x1 + edgeoffs + rx, y1 + edgeoffs);
353
context.quadraticCurveTo(x2 - edgeoffs, y1 + edgeoffs, x2 - edgeoffs , y1 + ry + edgeoffs);
354
context.quadraticCurveTo(x2 - edgeoffs, y2 - edgeoffs, x2 - rx - edgeoffs, y2 - edgeoffs);
355
context.quadraticCurveTo(x1 + edgeoffs, y2 - edgeoffs, x1 + edgeoffs, y1 + ry + edgeoffs);
356
} else if(clipkind == 3) {
357
context.moveTo(x1, y1 + ry);
358
context.lineTo(x1 + rx, y2);
359
context.lineTo(x2, y1 + ry);
360
context.lineTo(x1 + rx, y1);
361
context.lineTo(x1, y1 + ry);
369
context.textAlign = "left";
370
context.fillStyle = color;
372
var metrics = context.measureText(tex);
373
var hwidth = metrics.width * 0.5;
375
// Compute left-justified centered coordinate
376
if((rx - hwidth - edgeoffs) < 0) {
379
tx = x1 + rx - hwidth;
382
context.fillText(tex, tx, y2 - ry + baseline);
384
// Draw underlining - can handle dashed underline!
385
if(underlinekind == 1) {
386
drawline(tx, y2 - ry + baseline + 5.0, tx + (hwidth*2), y2 - ry + baseline + 5.0, "#000", 2.0);
389
if(clipkind != 0) context.restore();
393
// Draws cardinality at a certain offset from a coordinate
394
function drawcardinality(x, y, side, tex, xoffs, yoffs, font, baseline, sign, color)
396
// Xoffs is along line
398
// Yoffs is distance from line
401
var metrics = context.measureText(tex);
402
var twidth = metrics.width;
408
context.textAlign = "left";
409
context.fillStyle = color;
411
if(side == 1 && sign == 1){
412
context.fillText(tex, x - twidth - xoffs, y - yoffs);
413
drawrect(x - twidth - xoffs, y - yoffs,x - xoffs, y - yoffs - theight);
414
}else if(side == 2 && sign == 1){
415
context.fillText(tex, x + yoffs, y + xoffs + theight);
416
drawrect(x + yoffs, y + xoffs + theight,x + yoffs + twidth, y + xoffs);
417
}else if(side == 3 && sign == 1){
418
context.fillText(tex, x + xoffs, y - yoffs);
419
}else if(side == 4 && sign == 1){
420
context.fillText(tex, x + yoffs, y - xoffs);
421
}else if(side == 1 && sign == 2){
422
context.fillText(tex, x - twidth - xoffs, y + theight + yoffs);
423
drawrect(x - twidth - xoffs, y + yoffs,x - xoffs, y + theight + yoffs);
424
}else if(side == 2 && sign == 2){
425
context.fillText(tex, x - yoffs - twidth, y + xoffs + theight);
426
drawrect(x - yoffs - twidth, y + xoffs,x - yoffs, y + xoffs + theight);
427
}else if(side == 3 && sign == 2){
428
context.fillText(tex, x + xoffs, y + theight + yoffs);
429
}else if(side == 4 && sign == 2){
430
context.fillText(tex, x - yoffs - twidth, y - xoffs);
434
/********************************************************************************
435
Canvas and Diagram Measuring Functions
437
These functions allow us to measure pixels in diagram and other apps
438
*********************************************************************************/
440
// Recursive Pos of div in document - should work in most browsers
441
function findPos(obj) {
442
var curleft = curtop = 0;
443
if(obj.offsetParent) {
444
curleft = obj.offsetLeft;
445
curtop = obj.offsetTop;
446
while (obj = obj.offsetParent) {
447
curleft += obj.offsetLeft;
448
curtop += obj.offsetTop;
457
// Make side coordinates for drawing Model
458
function makeside(side, x1, y1, x2, y2, perc) {
464
yk = y1 + ((y2 - y1) * perc);
465
} else if(side == 2) {
466
xk = x1 + ((x2 - x1) * perc);
468
} else if(side == 3){
470
yk = y1 + ((y2 - y1) * perc);
471
} else if(side == 4){
472
xk = x1 + ((x2 - x1) * perc)
482
// Computes side identifier for a mouse coordinate and object coordinates
483
function computeside(x, y, x1, y1, x2, y2, sidetol) {
484
var obj_sidentifier = "None";
485
var obj_sideperc = 0;
486
var obj_centerdist = 0;
489
if(x > x1 - sidetol && x < x1 + sidetol && y > y1 - sidetol && y < y2 + sidetol) {
491
obj_sideperc = makesideperc(y, y1, y2);
492
obj_centerdist = centerdist(y, y1, y2);
495
// Bottom Not Including Left Side or Right Side
496
if(x > x1 + sidetol && x < x2 - sidetol && y > y2 - sidetol && y < y2 + sidetol) {
498
obj_sideperc = makesideperc(x, x1, x2);
499
obj_centerdist = centerdist(x, x1, x2);
503
if(x > x2 - sidetol && x < x2 + sidetol && y > y1 - sidetol && y < y2 + sidetol) {
505
obj_sideperc = makesideperc(y, y1, y2);
506
obj_centerdist=centerdist(y, y1, y2);
509
// Top Not Including Left Side or Right Side
510
if(x > x1 + sidetol && x < x2 - sidetol && y > y1 - sidetol && y < y1 + sidetol) {
512
obj_sideperc = makesideperc(x, x1, x2);
513
obj_centerdist=centerdist(x, x1, x2);
517
side:obj_sidentifier,
523
// Make side perc for ER model
524
function makesideperc(x, x1, x2) {
528
if(perc > 1.0) perc = 1.0;
529
if(perc < 0.0) perc = 0.0;
534
function centerdist(x, x1, x2){
535
r = x1 + ((x2 - x1) * 0.5);
540
// Euclidian distance - Yo!
541
function distance(x1, y1, x2, y2) {
542
var dist = Math.sqrt(((y2 - y1) * (y2 - y1)) + ((x2 - x1) * (x2 - x1)));
547
// Are we over a line or not.
548
function overline(x, y, x1, y1, x2, y2, tolerance) {
549
var distance = 10000;
553
straighttolerance = 2.0;
555
var box1, boy1, box2, boy2;
573
//drawrect(box1-tolerance,boy1-tolerance,box2+tolerance,boy2+tolerance,"#aaa");
574
if((x > (box1 - tolerance)) && (x < (box2 + tolerance)) && (y > (boy1 - tolerance)) && (y < (boy2 + tolerance))) {
575
// Straight X, Straight Y or Positive or Negative Incline
576
if(Math.abs(dx) < straighttolerance) {
578
if(y > y1 - tolerance && y < y2 + tolerance) {
579
distance = Math.abs(x1 - x);
582
if(y > y2 - tolerance && y < y1 + tolerance) {
583
distance = Math.abs(x1 - x);
586
} else if(Math.abs(dy) < straighttolerance) {
588
if(x > x1 - tolerance && x < x2 + tolerance) {
589
distance = Math.abs(y1 - y);
592
if(x > x2 - tolerance && x < x1 + tolerance) {
593
distance = Math.abs(y1 - y);
596
} else if(Math.abs(dx) >= Math.abs(dy)) {
598
yk = y1 + ((x - x1) * k);
599
distance = Math.abs(yk - y);
602
xk = x1 + ((y - y1) * k);
603
distance = Math.abs(xk - x);