1
/********************************************************************************
3
Mouse coordinate and canvas globals
5
Handles both Touch and Mouse/Keyboard input at the same time
7
*********************************************************************************/
9
// Mouse coordinate globals
15
/********************************************************************************
17
Canvas Setup and Click Handling Code
19
Handles both Touch and Mouse/Keyboard input at the same time and executes
21
Also declares canvas globals
23
*********************************************************************************/
24
function setupCanvas() {
25
acanvas = document.getElementById( 'a' );
26
context = acanvas.getContext( "2d" );
27
setTimeout( "foo();", 50 );
31
function setupClickHandling() {
32
// Mouse and Keyboard Events
33
acanvas.addEventListener( 'mousemove', ev_mousemove, false );
34
acanvas.addEventListener( 'mouseup', ev_mouseup, false );
35
acanvas.addEventListener( 'mousedown', ev_mousedown, false );
37
acanvas.addEventListener( 'touchstart', ev_touchstart, false);
38
acanvas.addEventListener( 'touchend', ev_touchend, false);
39
acanvas.addEventListener( 'touchmove', ev_touchmove, false);
42
// Keyboard/Mouse Mouse Up Handler
43
function evMouseup(ev) {
47
// Keyboard/Mouse Mouse Down Handler
48
function evMousedown(ev) {
52
// Keyboard/Mouse Mouse Move Handler
53
function evMouseMove(ev) {
56
if( ev.layerX || ev.layerX == 0 ) {
57
cx = ev.layerX - acanvas.offsetLeft;
58
cy = ev.layerY - acanvas.offsetTop;
60
} else if( ev.offsetX || ev.offsetX == 0 ) {
61
cx = ev.offsetX - acanvas.offsetLeft;
62
cy = ev.offsetY - acanvas.offsetTop;
64
coord = findPos(acanvas);
67
handler_mousemove( cx, cy );
71
function evTouchStart( event ) {
72
event.preventDefault();
73
var numtouch = event.touches.length;
74
targetEvent = event.touches.item( 0 );
75
var cx = targetEvent.pageX;
76
var cy = targetEvent.pageY;
83
function evTouchEnd( event ) {
84
event.preventDefault();
85
var numtouch = event.touches.length;
90
function evTouchMove( event ) {
91
event.preventDefault();
92
var numtouch = event.touches.length;
93
targetEvent = event.touches.item( 0 );
94
var cx = targetEvent.pageX;
95
var cy = targetEvent.pageY;
96
handlerMouseMove( cx, cy );
99
// Fix scrolling on touch devices
100
var scrollFix = function(elem) {
101
// Variables to track inputs
102
var startY, startTopScroll;
103
elem = elem || document.querySelector( elem );
104
// If there is no element, then do nothing
108
// Handle the start of interactions
109
elem.addEventListener( 'touchstart', function( event ) {
110
startY = event.touches[ 0 ].pageY;
111
startTopScroll = elem.scrollTop;
112
if( startTopScroll <= 0 ) {
115
if( startTopScroll + elem.offsetHeight >= elem.scrollHeight ) {
116
elem.scrollTop = elem.scrollHeight - elem.offsetHeight - 1;
121
/********************************************************************************
123
Canvas Diagram Drawing Code
125
*********************************************************************************/
127
// Draws a stroked rectangle of certain thicknes and color
128
function drawrect( x1, y1, x2, y2, color ) {
129
context.lineWidth = 1.5;
130
context.strokeStyle = color;
131
context.strokeRect( x1, y1, x2 - x1, y2 - y1 );
134
// Draws a perfect round circle
135
function drawcircle( radius, color ) {
136
context.lineWidth = 1.5;
137
context.strokeStyle = color;
138
context.arc( 0, 0, radius, 0 , 2 * Math.PI, false );
141
// Draws 90 degree arc
142
function drawellipse( x1, y1, x2, y2 ) {
143
var rx = ( x2 - x1 ) * 0.5;
144
var ry = ( y2 - y1 ) * 0.5;
146
context.moveTo( x1, y1 + ry );
147
context.quadraticCurveTo( x1, y1, x1 + rx, y1);
148
context.quadraticCurveTo( x2, y1, x2, y1 + ry);
149
context.quadraticCurveTo( x2, y2, x2 - rx, y2);
150
context.quadraticCurveTo( x1, y2, x1, y1 + ry);
155
function point( x, y, col ) {
156
context.strokeStyle = "#000";
157
context.lineWidth = 1;
158
context.fillStyle = col;
159
context.fillRect( x - 4, y - 4, 8, 8 );
160
context.strokeRect( x - 4, y - 4, 8, 8 );
163
// Draw a box around a point to indicate highlight
164
function highlight( px, py ) {
165
context.strokeStyle = "#aaa";
166
context.lineWidth = 1;
167
context.strokeRect( px - 8, py - 8, 16, 16 );
170
// Draw a line using current context
171
function drawline( x1, y1, x2, y2, strokestyle, linewidth ) {
172
context.strokeStyle = strokestyle;
173
context.lineWidth = linewidth;
175
context.moveTo( x1, y1 );
176
context.lineTo( x2, y2 );
180
function fourpoints( x1, y1, x2, y2, x3, y3, x4, y4, col ) {
181
point( x1, y1, col );
182
point( x2, y2, col );
183
point( x3, y3, col );
184
point( x4, y4, col );
187
function drawdiamond( x1, y1, x2, y2 ) {
188
var rx = ( x2 - x1 ) * 0.5;
189
var ry = ( y2 - y1 ) * 0.5;
191
context.moveTo( x1, y1 + ry);
192
context.lineTo( x1 + rx, y2);
193
context.lineTo( x2, y1 + ry);
194
context.lineTo( x1 + rx, y1);
195
context.lineTo( x1, y1 + ry);
199
// Dashed Line in Segments of given size
200
function dashedline( sx, sy, ex, ey, dashlen, linewidth, col ) {
203
len = Math.sqrt(( dx * dx ) + ( dy * dy ));
204
notimes = Math.round( len / dashlen );
207
context.lineWidth = linewidth;
208
context.strokeStyle = col;
215
for( var i = 0; i < notimes; i++ ) {
216
context.moveTo( xk, yk );
217
context.lineTo( xk + xh, yk + yh );
224
// Arcto only works if both x1 and y2 are on circle border
225
function arcTo( x0, y0, x1, y1, x2, y2 ) {
226
var r = Math.sqrt(( x1 - x0 ) * ( x1 - x0 ) + ( y1 - y0 ) * ( y1 - y0 ));
229
var startAngle = ( 180 / Math.PI * Math.atan2( y1 - y0, x1 - x0 ));
230
var endAngle = ( 180 / Math.PI * Math.atan2( y2 - y0, x2 - x0 ));
231
context.arc( x0, y0, r, 0, Math.PI * 2.0, 1.0);
234
// Draws 90 degree arc
235
function arcDeg( x1, y1, x2, y2, x3, y3) {
236
// First quadrant positive positive
237
dashedline( x1, y1, x2, y2, 8, 1.0, "#999" );
238
dashedline( x3, y3, x2, y2, 8, 1.0, "#999" );
239
point( x1, y1, "#ff5");
240
point( x2, y2, "#f55");
241
point( x3, y3, "#f55");
242
k = ( y3 - y1 ) / ( x3 - x1);
243
yk = y1 + (( x2 - x1 ) * k );
246
point( x2, yk, "#f5f" );
247
context.strokeStyle = '#49f';
248
context.lineWidth = 1.0;
250
context.moveTo( x1, y1 );
251
for( i = 0; i < 48; i++ ) {
254
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 ));
256
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));
260
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 ));
262
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 ));
269
// function that draws one part of the sun
270
function sunDial( radius, angle, scale ) {
271
cosv = Math.cos(angle);
272
sinv = Math.sin(angle);
273
yaddx = scale * cosv;
274
yaddy = scale * sinv;
275
xaddx = -scale * sinv;
276
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 draws 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 ) {
300
angleadd = ( inangleadd / 360.0 ) * 2 * Math.PI;
301
context.fillStyle = col1;
302
for( i = 0; i < 360; i += inangle ) {
303
angle = ( i / 360.0 ) * 2 * Math.PI;
304
angle2 = angle + angleadd;
305
angle3 = angle + ( angleadd * 2.0 );
306
angle4 = angle - angleadd;
307
cosv = Math.cos( angle );
308
sinv = Math.sin( angle );
309
cosv2 = Math.cos( angle2 );
310
sinv2 = Math.sin( angle2 );
311
cosv4 = Math.cos( angle4 );
312
sinv4 = Math.sin( angle4 );
314
context.moveTo( cx, cy );
315
context.quadraticCurveTo( cx + ( cosv * innerradie ), cy + ( sinv * innerradie ), cx + ( cosv2 * radie ), cy + ( sinv2 * radie ));
316
context.arc( cx, cy, radie, angle2, angle, 1.0 );
317
context.quadraticCurveTo( cx + ( cosv4 * innerradie ), cy + ( sinv4 * innerradie ), cx, cy );
321
context.arc( cx, cy, radie, 0, Math.PI * 2.0, 1.0 );
325
// Draws underlined/dashed underlined text clipped inside a rectangle, a quadratic curve ellipsis or a diamond
326
function cliptext(x1,y1,x2,y2,tex,font,align,edgeoffs,baseline,color,clipkind,underlinekind) {
327
var rx = ( x2 - x1 ) * 0.5;
328
var ry = ( y2 - y1 ) * 0.5;
330
if( clipkind != 0 ) {
334
// Make Rectangle / Ellipse / Diamond Clipping Paths
335
if( clipkind == 1 ) {
336
context.moveTo( x1, y1 );
337
context.lineTo( x1, y2 );
338
context.lineTo( x2 - edgeoffs, y2 );
339
context.lineTo( x2 - edgeoffs, y1 );
340
context.lineTo( x1, y1 );
341
} else if( clipkind == 2 ) {
342
context.moveTo( x1, y1 + ry );
343
context.quadraticCurveTo( x1 + edgeoffs, y1 + edgeoffs, x1 + edgeoffs + rx, y1 + edgeoffs);
344
context.quadraticCurveTo( x2 - edgeoffs, y1 + edgeoffs, x2 - edgeoffs, y1 + ry + edgeoffs);
345
context.quadraticCurveTo( x2 - edgeoffs, y2 - edgeoffs, x2 - rx - edgeoffs, y2 - edgeoffs);
346
context.quadraticCurveTo( x1 + edgeoffs, y2 - edgeoffs, x1 + edgeoffs, y1 + ry + edgeoffs);
347
} else if( clipkind == 3 ) {
348
context.moveTo( x1, y1 + ry );
349
context.lineTo( x1 + rx, y2 );
350
context.lineTo( x2, y1 + ry );
351
context.lineTo( x1 + rx, y1 );
352
context.lineTo( x1, y1 + ry );
354
if( clipkind != 0 ) {
358
context.textAlign = "left";
359
context.fillStyle = color;
360
var metrics = context.measureText( tex );
361
var hwidth = metrics.width * 0.5;
362
// Compute left-justified centered coordinate
363
if(( rx - hwidth - edgeoffs ) < 0 ) {
366
tx = x1 + rx - hwidth;
368
context.fillText( tex, tx, y2 - ry + baseline );
369
// Draw underlining - can handle dashed underline!
370
if( underlinekind == 1 ) {
371
drawline( tx, y2 - ry + baseline + 5.0, tx + ( hwidth * 2 ), y2 - ry + baseline + 5.0, "#000", 2.0 );
378
// Draws cardinality at a certain offset from a coordinate
379
function drawcardinality( x, y, side, tex, xoffs, yoffs, font, baseline, sign, color ) {
380
// Xoffs is along line
382
// Yoffs is distance from line
384
var metrics = context.measureText( tex );
385
var twidth = metrics.width;
387
point( x, y, "#f8f" );
389
context.textAlign = "left";
390
context.fillStyle = color;
391
if( side == 1 && sign == 1 ) {
392
context.fillText( tex, x - twidth - xoffs, y - yoffs );
393
drawrect( x - twidth - xoffs, y - yoffs, x - xoffs, y - yoffs - theight);
394
} else if( side == 2 && sign == 1 ) {
395
context.fillText( tex, x + yoffs, y + xoffs + theight );
396
drawrect( x + yoffs, y + xoffs + theight, x + yoffs + twidth, y + xoffs);
397
} else if( side == 3 && sign == 1 ) {
398
context.fillText( tex, x + xoffs, y - yoffs );
399
} else if( side == 4 && sign == 1 ) {
400
context.fillText( tex, x + yoffs, y - xoffs );
401
} else if( side == 1 && sign == 2 ) {
402
context.fillText( tex, x - twidth - xoffs, y + theight + yoffs );
403
drawrect( x - twidth - xoffs, y + yoffs, x - xoffs, y + theight + yoffs);
404
} else if( side == 2 && sign == 2 ) {
405
context.fillText( tex, x - yoffs - twidth, y + xoffs + theight );
406
drawrect( x - yoffs - twidth, y + xoffs, x - yoffs, y + xoffs + theight );
407
} else if( side == 3 && sign == 2 ) {
408
context.fillText( tex, x + xoffs, y + theight + yoffs);
409
} else if( side == 4 && sign == 2 ) {
410
context.fillText( tex, x - yoffs - twidth, y - xoffs);
415
/********************************************************************************
417
Canvas and Diagram Measuring Functions
419
These functions allow us to measure pixels in diagram and other apps
421
*********************************************************************************/
424
// Recursive Pos of div in document - should work in most browsers
425
function findPos( obj ){
426
var curleft = curtop = 0;
427
if( obj.offsetParent ) {
428
curleft = obj.offsetLeft;
429
curtop = obj.offsetTop;
430
while( obj = obj.offsetParent ) {
431
curleft += obj.offsetLeft;
432
curtop += obj.offsetTop;
440
// Make side coordinates for drawing Model
441
function makeside(side,x1,y1,x2,y2,perc){
446
yk = y1 + (( y2-y1 ) * perc );
447
}else if( side == 2 ) {
448
xk = x1 + (( x2 - x1 ) * perc );
450
}else if( side == 3 ) {
452
yk = y1 + (( y2 - y1 ) * perc );
453
}else if( side == 4 ) {
454
xk = x1 + (( x2 - x1 ) * perc );
462
// Computes side identifier for a mouse coordinate and object coordinates
463
function computeside( x, y, x1, y1, x2, y2, sidetol ) {
464
var obj_sidentifier = "None";
465
var obj_sideperc = 0;
466
var obj_centerdist = 0;
468
if( x > x1 - sidetol && x < x1 + sidetol && y > y1 - sidetol && y < y2 + sidetol ) {
470
obj_sideperc = makesideperc( y, y1, y2 );
471
obj_centerdist = centerdist( y, y1, y2 );
473
// Bottom Not Including Left Side or Right Side
474
if( x > x1 + sidetol && x < x2 - sidetol && y > y2 - sidetol && y < y2 + sidetol ) {
476
obj_sideperc = makesideperc( x, x1, x2 );
477
obj_centerdist = centerdist( x, x1, x2 );
480
if( x > x2 - sidetol && x < x2 + sidetol && y > y1 - sidetol && y < y2 + sidetol ) {
482
obj_sideperc = makesideperc( y, y1, y2 );
483
obj_centerdist = centerdist( y, y1, y2 );
485
// Top Not Including Left Side or Right Side
486
if( x > x1 + sidetol && x < x2 - sidetol && y > y1 - sidetol && y < y1 + sidetol ) {
488
obj_sideperc = makesideperc( x, x1, x2 );
489
obj_centerdist = centerdist( x, x1, x2 );
492
side:obj_sidentifier, perc:obj_sideperc, dist:obj_centerdist;
496
// Make side perc for ER model
497
function makeSidePerc( x, x1, x2 ) {
499
perc = ( x - x1 ) / r;
509
function centerDist( x, x1, x2 ) {
510
r = x1 + (( x2 - x1 ) * 0.5 );
514
// Euclidian distance - Yo!
515
function distance( x1, y1, x2, y2 ) {
516
var dist = Math.sqrt((( y2 - y1 ) * ( y2 - y1 )) + (( x2 - x1 ) * ( x2 - x1 )));
520
// Are we over a line or not.
521
function overline( x, y, x1, y1, x2, y2, tolerance ) {
522
var distance = 10000;
525
straighttolerance = 2.0;
526
var box1, boy1, box2, boy2;
541
//drawrect(box1-tolerance,boy1-tolerance,box2+tolerance,boy2+tolerance,"#aaa");
542
if(( x > ( box1 - tolerance )) && ( x < ( box2 + tolerance )) && ( y > ( boy1 - tolerance )) && ( y < ( boy2 + tolerance ))) {
543
// Straight X, Straight Y or Positive or Negative Incline
544
if( Math.abs( dx ) < straighttolerance ) {
546
if( y > y1 - tolerance && y < y2 + tolerance ) {
547
distance = Math.abs( x1 - x );
550
if( y > y2 - tolerance && y < y1 + tolerance ) {
551
distance = Math.abs( x1 - x );
554
} else if( Math.abs( dy ) < straighttolerance ) {
556
if( x > x1 - tolerance && x < x2 + tolerance ) {
557
distance = Math.abs( y1 - y );
560
if( x > x2 - tolerance && x < x1 + tolerance ) {
561
distance = Math.abs( y1 - y );
564
} else if( Math.abs( dx ) >= Math.abs( dy )) {
566
yk = y1 + (( x - x1 ) * k );
567
distance = Math.abs( yk - y );
570
xk = x1 + (( y - y1 ) * k );
571
distance = Math.abs( xk - x );
b'\\ No newline at end of file'