vendor: 4,133 bytes, lines 1-140
1/** 2 * Copyright (C) 2010-2013 Graham Breach 3 * 4 * This program is free software: you can redistribute it and/or modify 5 * it under the terms of the GNU Lesser General Public License as published by 6 * the Free Software Foundation, either version 3 of the License, or 7 * (at your option) any later version. 8 * 9 * This program is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU Lesser General Public License for more details. 13 * 14 * You should have received a copy of the GNU Lesser General Public License 15 * along with this program. If not, see <http://www.gnu.org/licenses/>. 16 */ 17/** 18 * jQuery.tagcanvas 2.2 19 * For more information, please contact <[email protected]> 20 */ 21(function($){ 22"use strict"; 23var i, j, abs = Math.abs, sin = Math.sin, cos = Math.cos, max = Math.max, 24 min = Math.min, ceil = Math.ceil, sqrt = Math.sqrt, pow = Math.pow, 25 hexlookup3 = {}, hexlookup2 = {}, hexlookup1 = { 26 0:"0,", 1:"17,", 2:"34,", 3:"51,", 4:"68,", 5:"85,", 27 6:"102,", 7:"119,", 8:"136,", 9:"153,", a:"170,", A:"170,", 28 b:"187,", B:"187,", c:"204,", C:"204,", d:"221,", D:"221,", 29 e:"238,", E:"238,", f:"255,", F:"255," 30 }, Oproto, Tproto, TCproto, Mproto, Vproto, TSproto, doc = document, ocanvas, 31 handlers = {}; 32for(i = 0; i < 256; ++i) { 33 j = i.toString(16); 34 if(i < 16) 35 j = '0' + j; 36 hexlookup2[j] = hexlookup2[j.toUpperCase()] = i.toString() + ','; 37} 38function Defined(d) { 39 return typeof d != 'undefined'; 40} 41function IsObject(o) { 42 return typeof o == 'object' && o != null; 43} 44function Clamp(v, mn, mx) { 45 return isNaN(v) ? mx : min(mx, max(mn, v)); 46} 47function Nop() { 48 return false; 49} 50function TimeNow() { 51 return new Date().valueOf(); 52} 53function SortList(l, f) { 54 var nl = [], tl = l.length, i; 55 for(i = 0; i < tl; ++i) 56 nl.push(l[i]); 57 nl.sort(f); 58 return nl; 59} 60function Shuffle(a) { 61 var i = a.length-1, t, p; 62 while(i) { 63 p = ~~(Math.random()*i); 64 t = a[i]; 65 a[i] = a[p]; 66 a[p] = t; 67 --i; 68 } 69} 70function Vector(x, y, z) { 71 this.x = x; 72 this.y = y; 73 this.z = z; 74} 75Vproto = Vector.prototype; 76Vproto.length = function() { 77 return sqrt(this.x * this.x + this.y * this.y + this.z * this.z); 78}; 79Vproto.dot = function(v) { 80 return this.x * v.x + this.y * v.y + this.z * v.z; 81}; 82Vproto.cross = function(v) { 83 var x = this.y * v.z - this.z * v.y, 84 y = this.z * v.x - this.x * v.z, 85 z = this.x * v.y - this.y * v.x; 86 return new Vector(x, y, z); 87}; 88Vproto.angle = function(v) { 89 var dot = this.dot(v), ac; 90 if(dot == 0) 91 return Math.PI / 2.0; 92 ac = dot / (this.length() * v.length()); 93 if(ac >= 1) 94 return 0; 95 if(ac <= -1) 96 return Math.PI; 97 return Math.acos(ac); 98}; 99Vproto.unit = function() { 100 var l = this.length(); 101 return new Vector(this.x / l, this.y / l, this.z / l); 102}; 103function MakeVector(lg, lt) { 104 lt = lt * Math.PI / 180; 105 lg = lg * Math.PI / 180; 106 var x = sin(lg) * cos(lt), y = -sin(lt), z = -cos(lg) * cos(lt); 107 return new Vector(x, y, z); 108} 109function Matrix(a) { 110 this[1] = {1: a[0], 2: a[1], 3: a[2]}; 111 this[2] = {1: a[3], 2: a[4], 3: a[5]}; 112 this[3] = {1: a[6], 2: a[7], 3: a[8]}; 113} 114Mproto = Matrix.prototype; 115Matrix.Identity = function() { 116 return new Matrix([1,0,0, 0,1,0, 0,0,1]); 117}; 118Matrix.Rotation = function(angle, u) { 119 var sina = sin(angle), cosa = cos(angle), mcos = 1 - cosa; 120 return new Matrix([ 121 cosa + pow(u.x, 2) * mcos, u.x * u.y * mcos - u.z * sina, u.x * u.z * mcos + u.y * sina, 122 u.y * u.x * mcos + u.z * sina, cosa + pow(u.y, 2) * mcos, u.y * u.z * mcos - u.x * sina, 123 u.z * u.x * mcos - u.y * sina, u.z * u.y * mcos + u.x * sina, cosa + pow(u.z, 2) * mcos 124 ]); 125} 126Mproto.mul = function(m) { 127 var a = [], i, j, mmatrix = (m.xform ? 1 : 0); 128 for(i = 1; i <= 3; ++i) 129 for(j = 1; j <= 3; ++j) { 130 if(mmatrix) 131 a.push(this[i][1] * m[1][j] + 132 this[i][2] * m[2][j] + 133 this[i][3] * m[3][j]); 134 else 135 a.push(this[i][j] * m); 136 } 137 return new Matrix(a); 138}; 139Mproto.xform = function(p) { 140 var a = {}, x = p.x, y = p.y, z = p.z;
141 a.x = x * this[1][1] + y * this[2][1] + z * this[3][1]; 142 a.y = x * this[1][2] + y * this[2][2] + z * this[3][2]; 143 a.z = x * this[1][3] + y * this[2][3] + z * this[3][3]; 144 return a; 145}; 146function PointsOnSphere(n,xr,yr,zr) { 147 var i, y, r, phi, pts = [], inc = Math.PI * (3-sqrt(5)), off = 2/n; 148 for(i = 0; i < n; ++i) { 149 y = i * off - 1 + (off / 2); 150 r = sqrt(1 - y*y); 151 phi = i * inc; 152 pts.push([cos(phi) * r * xr, y * yr, sin(phi) * r * zr]); 153 } 154 return pts; 155} 156function Cylinder(n,o,xr,yr,zr) { 157 var phi, pts = [], inc = Math.PI * (3-sqrt(5)), off = 2/n, i, j, k, l; 158 for(i = 0; i < n; ++i) { 159 j = i * off - 1 + (off / 2); 160 phi = i * inc; 161 k = cos(phi); 162 l = sin(phi); 163 pts.push(o ? [j * xr, k * yr, l * zr] : [k * xr, j * yr, l * zr]); 164 } 165 return pts; 166} 167function Ring(o, n, xr, yr, zr, j) { 168 var phi, pts = [], inc = Math.PI * 2 / n, i, k, l; 169 for(i = 0; i < n; ++i) { 170 phi = i * inc; 171 k = cos(phi); 172 l = sin(phi); 173 pts.push(o ? [j * xr, k * yr, l * zr] : [k * xr, j * yr, l * zr]); 174 } 175 return pts; 176} 177function PointsOnCylinderV(n,xr,yr,zr) { return Cylinder(n, 0, xr, yr, zr) } 178function PointsOnCylinderH(n,xr,yr,zr) { return Cylinder(n, 1, xr, yr, zr) } 179function PointsOnRingV(n, xr, yr, zr, offset) { 180 offset = isNaN(offset) ? 0 : offset * 1; 181 return Ring(0, n, xr, yr, zr, offset); 182} 183function PointsOnRingH(n, xr, yr, zr, offset) { 184 offset = isNaN(offset) ? 0 : offset * 1; 185 return Ring(1, n, xr, yr, zr, offset); 186} 187function SetAlpha(c,a) { 188 var d = c, p1, p2, ae = (a*1).toPrecision(3) + ')'; 189 if(c[0] === '#') { 190 if(!hexlookup3[c]) 191 if(c.length === 4) 192 hexlookup3[c] = 'rgba(' + hexlookup1[c[1]] + hexlookup1[c[2]] + hexlookup1[c[3]]; 193 else 194 hexlookup3[c] = 'rgba(' + hexlookup2[c.substr(1,2)] + hexlookup2[c.substr(3,2)] + hexlookup2[c.substr(5,2)]; 195 d = hexlookup3[c] + ae; 196 } else if(c.substr(0,4) === 'rgb(' || c.substr(0,4) === 'hsl(') { 197 d = (c.replace('(','a(').replace(')', ',' + ae)); 198 } else if(c.substr(0,5) === 'rgba(' || c.substr(0,5) === 'hsla(') { 199 p1 = c.lastIndexOf(',') + 1, p2 = c.indexOf(')'); 200 a *= parseFloat(c.substring(p1,p2)); 201 d = c.substr(0,p1) + a.toPrecision(3) + ')'; 202 } 203 return d; 204} 205function NewCanvas(w,h) { 206 // if using excanvas, give up now 207 if(window.G_vmlCanvasManager) 208 return null; 209 var c = doc.createElement('canvas'); 210 c.width = w; 211 c.height = h; 212 return c; 213} 214// I think all browsers pass this test now... 215function ShadowAlphaBroken() { 216 var cv = NewCanvas(3,3), c, i; 217 if(!cv) 218 return false; 219 c = cv.getContext('2d'); 220 c.strokeStyle = '#000'; 221 c.shadowColor = '#fff'; 222 c.shadowBlur = 3; 223 c.globalAlpha = 0; 224 c.strokeRect(2,2,2,2); 225 c.globalAlpha = 1; 226 i = c.getImageData(2,2,1,1); 227 cv = null; 228 return (i.data[0] > 0); 229} 230function FindGradientColour(t,p) { 231 var l = 1024, g = t.weightGradient, cv, c, i, gd, d; 232 if(t.gCanvas) { 233 c = t.gCanvas.getContext('2d'); 234 } else { 235 t.gCanvas = cv = NewCanvas(l,1); 236 if(!cv) 237 return null; 238 c = cv.getContext('2d'); 239 gd = c.createLinearGradient(0,0,l,0); 240 for(i in g) 241 gd.addColorStop(1-i, g[i]); 242 c.fillStyle = gd; 243 c.fillRect(0,0,l,1); 244 } 245 d = c.getImageData(~~((l-1)*p),0,1,1).data; 246 return 'rgba(' + d[0] + ',' + d[1] + ',' + d[2] + ',' + (d[3]/255) + ')'; 247} 248function TextSet(c,f,l,s,sc,sb,so,wm,wl) { 249 var xo = (sb || 0) + (so && so[0] < 0 ? abs(so[0]) : 0), 250 yo = (sb || 0) + (so && so[1] < 0 ? abs(so[1]) : 0), i, xc; 251 c.font = f; 252 c.textBaseline = 'top'; 253 c.fillStyle = l; 254 sc && (c.shadowColor = sc); 255 sb && (c.shadowBlur = sb); 256 so && (c.shadowOffsetX = so[0], c.shadowOffsetY = so[1]); 257 for(i = 0; i < s.length; ++i) { 258 xc = wl ? (wm - wl[i]) / 2 : 0; 259 c.fillText(s[i], xo + xc, yo); 260 yo += parseInt(f); 261 } 262} 263function TextToCanvas(s,f,ht,w,h,l,sc,sb,so,padx,pady,wmax,wlist) { 264 var cw = w + abs(so[0]) + sb + sb, ch = h + abs(so[1]) + sb + sb, cv, c; 265 cv = NewCanvas(cw+padx,ch+pady); 266 if(!cv) 267 return null; 268 c = cv.getContext('2d'); 269 TextSet(c,f,l,s,sc,sb,so,wmax,wlist); 270 return cv; 271} 272function AddShadowToImage(i,sc,sb,so) { 273 var sw = abs(so[0]), sh = abs(so[1]), 274 cw = i.width + (sw > sb ? sw + sb : sb * 2), 275 ch = i.height + (sh > sb ? sh + sb : sb * 2),
276 xo = (sb || 0) + (so[0] < 0 ? sw : 0), 277 yo = (sb || 0) + (so[1] < 0 ? sh : 0), cv, c; 278 cv = NewCanvas(cw, ch); 279 if(!cv) 280 return null; 281 c = cv.getContext('2d'); 282 sc && (c.shadowColor = sc); 283 sb && (c.shadowBlur = sb); 284 so && (c.shadowOffsetX = so[0], c.shadowOffsetY = so[1]); 285 c.drawImage(i, xo, yo, i.width, i.height); 286 return cv; 287} 288function FindTextBoundingBox(s,f,ht) { 289 var w = parseInt(s.toString().length * ht), h = parseInt(ht * 2 * s.length), 290 cv = NewCanvas(w,h), c, idata, w1, h1, x, y, i, ex; 291 if(!cv) 292 return null; 293 c = cv.getContext('2d'); 294 c.fillStyle = '#000'; 295 c.fillRect(0,0,w,h); 296 TextSet(c,ht + 'px ' + f,'#fff',s,0,0,[]) 297 298 idata = c.getImageData(0,0,w,h); 299 w1 = idata.width; h1 = idata.height; 300 ex = { 301 min: { x: w1, y: h1 }, 302 max: { x: -1, y: -1 } 303 }; 304 for(y = 0; y < h1; ++y) { 305 for(x = 0; x < w1; ++x) { 306 i = (y * w1 + x) * 4; 307 if(idata.data[i+1] > 0) { 308 if(x < ex.min.x) ex.min.x = x; 309 if(x > ex.max.x) ex.max.x = x; 310 if(y < ex.min.y) ex.min.y = y; 311 if(y > ex.max.y) ex.max.y = y; 312 } 313 } 314 } 315 // device pixels might not be css pixels 316 if(w1 != w) { 317 ex.min.x *= (w / w1); 318 ex.max.x *= (w / w1); 319 } 320 if(h1 != h) { 321 ex.min.y *= (w / h1); 322 ex.max.y *= (w / h1); 323 } 324 325 cv = null; 326 return ex; 327} 328function FixFont(f) { 329 return "'" + f.replace(/(\'|\")/g,'').replace(/\s*,\s*/g, "', '") + "'"; 330} 331function AddHandler(h,f,e) { 332 e = e || doc; 333 if(e.addEventListener) 334 e.addEventListener(h,f,false); 335 else 336 e.attachEvent('on' + h, f); 337} 338function AddImage(i, o, t, tc) { 339 var s = tc.imageScale, ic; 340 // image not loaded, wait for image onload 341 if(!o.complete) 342 return AddHandler('load',function() { AddImage(i,o,t,tc); }, o); 343 if(!i.complete) 344 return AddHandler('load',function() { AddImage(i,o,t,tc); }, i); 345 346 // Yes, this does look like nonsense, but it makes sure that both the 347 // width and height are actually set and not just calculated. This is 348 // required to keep proportional sizes when the images are hidden, so 349 // the images can be used again for another cloud. 350 o.width = o.width; 351 o.height = o.height; 352 353 if(s) { 354 i.width = o.width * s; 355 i.height = o.height * s; 356 } 357 t.w = i.width; 358 t.h = i.height; 359 if(tc.txtOpt && tc.shadow) { 360 ic = AddShadowToImage(i, tc.shadow, tc.shadowBlur, tc.shadowOffset); 361 if(ic) { 362 t.image = ic; 363 t.w = ic.width; 364 t.h = ic.height; 365 } 366 } 367} 368function GetProperty(e,p) { 369 var dv = doc.defaultView, pc = p.replace(/\-([a-z])/g,function(a){return a.charAt(1).toUpperCase()}); 370 return (dv && dv.getComputedStyle && dv.getComputedStyle(e,null).getPropertyValue(p)) || 371 (e.currentStyle && e.currentStyle[pc]); 372} 373function FindWeight(t,a) { 374 var w = 1, p; 375 if(t.weightFrom) { 376 w = 1 * (a.getAttribute(t.weightFrom) || t.textHeight); 377 } else if(p = GetProperty(a,'font-size')) { 378 w = (p.indexOf('px') > -1 && p.replace('px','') * 1) || 379 (p.indexOf('pt') > -1 && p.replace('pt','') * 1.25) || 380 p * 3.3; 381 } else { 382 t.weight = false; 383 } 384 return w; 385} 386function EventToCanvasId(e) { 387 return e.target && Defined(e.target.id) ? e.target.id : 388 e.srcElement.parentNode.id; 389} 390function EventXY(e, c) { 391 var xy, p, xmul = parseInt(GetProperty(c, 'width')) / c.width, 392 ymul = parseInt(GetProperty(c, 'height')) / c.height; 393 if(Defined(e.offsetX)) { 394 xy = {x: e.offsetX, y: e.offsetY}; 395 } else { 396 p = AbsPos(c.id); 397 if(Defined(e.changedTouches)) 398 e = e.changedTouches[0]; 399 if(e.pageX) 400 xy = {x: e.pageX - p.x, y: e.pageY - p.y}; 401 } 402 if(xy && xmul && ymul) { 403 xy.x /= xmul; 404 xy.y /= ymul; 405 } 406 return xy; 407} 408function MouseOut(e) { 409 var cv = e.target || e.fromElement.parentNode, tc = TagCanvas.tc[cv.id]; 410 if(tc) { 411 tc.mx = tc.my = -1; 412 tc.UnFreeze(); 413 tc.EndDrag(); 414 } 415} 416function MouseMove(e) { 417 var i, t = TagCanvas, tc, p, tg = EventToCanvasId(e); 418 for(i in t.tc) { 419 tc = t.tc[i]; 420 if(tc.tttimer) { 421 clearTimeout(tc.tttimer); 422 tc.tttimer = null; 423 } 424 } 425 if(tg && t.tc[tg]) { 426 tc = t.tc[tg]; 427 if(p = EventXY(e, tc.canvas)) { 428 tc.mx = p.x; 429 tc.my = p.y; 430 tc.Drag(e, p); 431 } 432 tc.drawn = 0; 433 } 434} 435function MouseDown(e) { 436 var t = TagCanvas, cb = doc.addEventListener ? 0 : 1, 437 tg = EventToCanvasId(e); 438 if(tg && e.button == cb && t.tc[tg]) { 439 t.tc[tg].BeginDrag(e); 440 } 441} 442function MouseUp(e) { 443 var t = TagCanvas, cb = doc.addEventListener ? 0 : 1, 444 tg = EventToCanvasId(e), tc; 445 if(tg && e.button == cb && t.tc[tg]) { 446 tc = t.tc[tg]; 447 MouseMove(e); 448 if(!tc.EndDrag() && !tc.touched) 449 tc.Clicked(e); 450 } 451} 452function TouchDown(e) { 453 var t = TagCanvas, tg = EventToCanvasId(e); 454 if(tg && e.changedTouches && t.tc[tg]) { 455 t.tc[tg].touched = 1; 456 t.tc[tg].BeginDrag(e); 457 } 458} 459function TouchUp(e) { 460 var t = TagCanvas, tg = EventToCanvasId(e); 461 if(tg && e.changedTouches && t.tc[tg]) { 462 TouchMove(e); 463 if(!t.tc[tg].EndDrag()){ 464 t.tc[tg].Draw(); 465 t.tc[tg].Clicked(e); 466 } 467 } 468} 469function TouchMove(e) { 470 var i, t = TagCanvas, tc, p, tg = EventToCanvasId(e); 471 for(i in t.tc) { 472 tc = t.tc[i]; 473 if(tc.tttimer) { 474 clearTimeout(tc.tttimer); 475 tc.tttimer = null; 476 } 477 } 478 if(tg && t.tc[tg] && e.changedTouches) { 479 tc = t.tc[tg]; 480 if(p = EventXY(e, tc.canvas)) { 481 tc.mx = p.x; 482 tc.my = p.y; 483 tc.Drag(e, p); 484 } 485 tc.drawn = 0; 486 } 487} 488function MouseWheel(e) { 489 var t = TagCanvas, tg = EventToCanvasId(e); 490 if(tg && t.tc[tg]) { 491 e.cancelBubble = true; 492 e.returnValue = false;
vendor: 4,359 bytes, lines 493-651
493 e.preventDefault && e.preventDefault(); 494 t.tc[tg].Wheel((e.wheelDelta || e.detail) > 0); 495 } 496} 497function DrawCanvas(t) { 498 var tc = TagCanvas.tc, i, interval; 499 t = t || TimeNow(); 500 for(i in tc) { 501 interval = tc[i].interval; 502 tc[i].Draw(t); 503 } 504 TagCanvas.NextFrame(interval); 505} 506function AbsPos(id) { 507 var e = doc.getElementById(id), r = e.getBoundingClientRect(), 508 dd = doc.documentElement, b = doc.body, w = window, 509 xs = w.pageXOffset || dd.scrollLeft, 510 ys = w.pageYOffset || dd.scrollTop, 511 xo = dd.clientLeft || b.clientLeft, 512 yo = dd.clientTop || b.clientTop; 513 return { x: r.left + xs - xo, y: r.top + ys - yo }; 514} 515function Project(tc,p1,sx,sy) { 516 var m = tc.radius * tc.z1 / (tc.z1 + tc.z2 + p1.z); 517 return { 518 x: p1.x * m * sx, 519 y: p1.y * m * sy, 520 z: p1.z, 521 w: (tc.z1 - p1.z) / tc.z2 522 }; 523} 524/** 525 * @constructor 526 * for recursively splitting tag contents on <br> tags 527 */ 528function TextSplitter(e) { 529 this.e = e; 530 this.br = 0; 531 this.line = []; 532 this.text = []; 533 this.original = e.innerText || e.textContent; 534} 535TSproto = TextSplitter.prototype; 536TSproto.Lines = function(e) { 537 var r = e ? 1 : 0, cn, cl, i; 538 e = e || this.e; 539 cn = e.childNodes; 540 cl = cn.length; 541 542 for(i = 0; i < cl; ++i) { 543 if(cn[i].nodeName == 'BR') { 544 this.text.push(this.line.join(' ')); 545 this.br = 1; 546 } else if(cn[i].nodeType == 3) { 547 if(this.br) { 548 this.line = [cn[i].nodeValue]; 549 this.br = 0; 550 } else { 551 this.line.push(cn[i].nodeValue); 552 } 553 } else { 554 this.Lines(cn[i]); 555 } 556 } 557 r || this.br || this.text.push(this.line.join(' ')); 558 return this.text; 559} 560TSproto.SplitWidth = function(w, c, f, h) { 561 var i, j, words, text = []; 562 c.font = h + 'px ' + f; 563 for(i = 0; i < this.text.length; ++i) { 564 words = this.text[i].split(/\s+/); 565 this.line = [words[0]]; 566 for(j = 1; j < words.length; ++j) { 567 if(c.measureText(this.line.join(' ') + ' ' + words[j]).width > w) { 568 text.push(this.line.join(' ')); 569 this.line = [words[j]]; 570 } else { 571 this.line.push(words[j]); 572 } 573 } 574 text.push(this.line.join(' ')); 575 } 576 return this.text = text; 577} 578/** 579 * @constructor 580 */ 581function Outline(tc) { 582 this.ts = TimeNow(); 583 this.tc = tc; 584 this.x = this.y = this.w = this.h = this.sc = 1; 585 this.z = 0; 586 this.Draw = tc.pulsateTo < 1 && tc.outlineMethod != 'colour' ? this.DrawPulsate : this.DrawSimple; 587 this.SetMethod(tc.outlineMethod); 588} 589Oproto = Outline.prototype; 590Oproto.SetMethod = function(om) { 591 var methods = { 592 block: ['PreDraw','DrawBlock'], 593 colour: ['PreDraw','DrawColour'], 594 outline: ['PostDraw','DrawOutline'], 595 classic: ['LastDraw','DrawOutline'], 596 none: ['LastDraw'] 597 }, funcs = methods[om] || methods.outline; 598 if(om == 'none') { 599 this.Draw = function() { return 1; } 600 } else { 601 this.drawFunc = this[funcs[1]]; 602 } 603 this[funcs[0]] = this.Draw; 604}; 605Oproto.Update = function(x,y,w,h,sc,z,xo,yo) { 606 var o = this.tc.outlineOffset, o2 = 2 * o; 607 this.x = sc * x + xo - o; 608 this.y = sc * y + yo - o; 609 this.w = sc * w + o2; 610 this.h = sc * h + o2; 611 this.sc = sc; // used to determine frontmost 612 this.z = z; 613}; 614Oproto.DrawOutline = function(c,x,y,w,h,colour) { 615 c.strokeStyle = colour; 616 c.strokeRect(x,y,w,h); 617}; 618Oproto.DrawColour = function(c,x,y,w,h,colour,tag,x1,y1) { 619 return this[tag.image ? 'DrawColourImage' : 'DrawColourText'](c,x,y,w,h,colour,tag,x1,y1); 620}; 621Oproto.DrawColourText = function(c,x,y,w,h,colour,tag,x1,y1) { 622 var normal = tag.colour; 623 tag.colour = colour; 624 tag.alpha = 1; 625 tag.Draw(c,x1,y1); 626 tag.colour = normal; 627 return 1; 628}; 629Oproto.DrawColourImage = function(c,x,y,w,h,colour,tag,x1,y1) { 630 var ccanvas = c.canvas, fx = ~~max(x,0), fy = ~~max(y,0), 631 fw = min(ccanvas.width - fx, w) + .5|0, fh = min(ccanvas.height - fy,h) + .5|0, cc; 632 if(ocanvas) 633 ocanvas.width = fw, ocanvas.height = fh; 634 else 635 ocanvas = NewCanvas(fw, fh); 636 if(!ocanvas) 637 return this.SetMethod('outline'); // if using IE and images, give up! 638 cc = ocanvas.getContext('2d'); 639 640 cc.drawImage(ccanvas,fx,fy,fw,fh,0,0,fw,fh); 641 c.clearRect(fx,fy,fw,fh); 642 tag.alpha = 1; 643 tag.Draw(c,x1,y1); 644 c.setTransform(1,0,0,1,0,0); 645 c.save(); 646 c.beginPath(); 647 c.rect(fx,fy,fw,fh); 648 c.clip(); 649 c.globalCompositeOperation = 'source-in'; 650 c.fillStyle = colour; 651 c.fillRect(fx,fy,fw,fh);
652 c.restore(); 653 c.globalCompositeOperation = 'destination-over'; 654 c.drawImage(ocanvas,0,0,fw,fh,fx,fy,fw,fh); 655 c.globalCompositeOperation = 'source-over'; 656 return 1; 657}; 658Oproto.DrawBlock = function(c,x,y,w,h,colour) { 659 c.fillStyle = colour; 660 c.fillRect(x,y,w,h); 661}; 662Oproto.DrawSimple = function(c, tag, x1, y1) { 663 var t = this.tc; 664 c.setTransform(1,0,0,1,0,0); 665 c.strokeStyle = t.outlineColour; 666 c.lineWidth = t.outlineThickness; 667 c.shadowBlur = c.shadowOffsetX = c.shadowOffsetY = 0; 668 c.globalAlpha = 1; 669 return this.drawFunc(c,this.x,this.y,this.w,this.h,t.outlineColour,tag,x1,y1); 670}; 671Oproto.DrawPulsate = function(c, tag, x1, y1) { 672 var diff = TimeNow() - this.ts, t = this.tc; 673 c.setTransform(1,0,0,1,0,0); 674 c.strokeStyle = t.outlineColour; 675 c.lineWidth = t.outlineThickness; 676 c.shadowBlur = c.shadowOffsetX = c.shadowOffsetY = 0; 677 c.globalAlpha = t.pulsateTo + ((1 - t.pulsateTo) * 678 (0.5 + (cos(2 * Math.PI * diff / (1000 * t.pulsateTime)) / 2))); 679 return this.drawFunc(c,this.x,this.y,this.w,this.h,t.outlineColour,tag,x1,y1); 680}; 681Oproto.Active = function(c,x,y) { 682 return (x >= this.x && y >= this.y && 683 x <= this.x + this.w && y <= this.y + this.h); 684}; 685Oproto.PreDraw = Oproto.PostDraw = Oproto.LastDraw = Nop; 686/** 687 * @constructor 688 */ 689function Tag(tc,text,a,v,w,h,col,font,original) { 690 var c = tc.ctxt; 691 this.tc = tc; 692 this.image = text.src ? text : null; 693 this.text = text.src ? [] : text; 694 this.text_original = original; 695 this.line_widths = []; 696 this.title = a.title || null; 697 this.a = a; 698 this.position = new Vector(v[0], v[1], v[2]); 699 this.x = this.y = this.z = 0; 700 this.w = w; 701 this.h = h; 702 this.colour = col || tc.textColour; 703 this.textFont = font || tc.textFont; 704 this.weight = this.sc = this.alpha = 1; 705 this.weighted = !tc.weight; 706 this.outline = new Outline(tc); 707 if(!this.image) { 708 this.textHeight = tc.textHeight; 709 this.extents = FindTextBoundingBox(this.text, this.textFont, this.textHeight); 710 this.Measure(c,tc); 711 } 712 this.SetShadowColour = tc.shadowAlpha ? this.SetShadowColourAlpha : this.SetShadowColourFixed; 713 this.SetDraw(tc); 714} 715Tproto = Tag.prototype; 716Tproto.EqualTo = function(e) { 717 var i = e.getElementsByTagName('img'); 718 if(this.a.href != e.href) 719 return 0; 720 if(i.length) 721 return this.image.src == i[0].src; 722 return (e.innerText || e.textContent) == this.text_original; 723}; 724Tproto.SetDraw = function(t) { 725 this.Draw = this.image ? (t.ie > 7 ? this.DrawImageIE : this.DrawImage) : this.DrawText; 726 t.noSelect && (this.CheckActive = Nop); 727}; 728Tproto.MeasureText = function(c) { 729 var i, l = this.text.length, w = 0, wl; 730 for(i = 0; i < l; ++i) { 731 this.line_widths[i] = wl = c.measureText(this.text[i]).width; 732 w = max(w, wl); 733 } 734 return w; 735}; 736Tproto.Measure = function(c,t) { 737 this.h = this.extents ? this.extents.max.y + this.extents.min.y : this.textHeight; 738 c.font = this.font = this.textHeight + 'px ' + this.textFont; 739 this.w = this.MeasureText(c); 740 if(t.txtOpt) { 741 var s = t.txtScale, th = s * this.textHeight, f = th + 'px ' + this.textFont, 742 soff = [s*t.shadowOffset[0],s*t.shadowOffset[1]], cw; 743 c.font = f; 744 cw = this.MeasureText(c); 745 this.image = TextToCanvas(this.text, f, th, cw, s * this.h, this.colour, 746 t.shadow, s * t.shadowBlur, soff, s, s, cw, this.line_widths); 747 if(this.image) { 748 this.w = this.image.width / s; 749 this.h = this.image.height / s; 750 } 751 this.SetDraw(t); 752 t.txtOpt = !!this.image; 753 } 754}; 755Tproto.SetFont = function(f, c) { 756 this.textFont = f; 757 this.colour = c; 758 this.extents = FindTextBoundingBox(this.text, this.textFont, this.textHeight); 759 this.Measure(this.tc.ctxt, this.tc); 760}; 761Tproto.SetWeight = function(w) { 762 if(!this.text.length) 763 return; 764 this.weight = w; 765 this.Weight(this.tc.ctxt, this.tc); 766 this.Measure(this.tc.ctxt, this.tc); 767}; 768Tproto.Weight = function(c,t) { 769 var w = this.weight, m = t.weightMode; 770 this.weighted = true; 771 if(m == 'colour' || m == 'both') 772 this.colour = FindGradientColour(t, (w - t.min_weight) / (t.max_weight-t.min_weight)); 773 if(m == 'size' || m == 'both') { 774 if(t.weightSizeMin > 0 && t.weightSizeMax > t.weightSizeMin) { 775 this.textHeight = t.weightSize * 776 (t.weightSizeMin + (t.weightSizeMax - t.weightSizeMin) *
vendor: 4,202 bytes, lines 777-909
777 (w - t.min_weight) / (t.max_weight - t.min_weight)); 778 } else { 779 this.textHeight = w * t.weightSize; 780 } 781 } 782 this.extents = FindTextBoundingBox(this.text, this.textFont, this.textHeight); 783}; 784Tproto.SetShadowColourFixed = function(c,s,a) { 785 c.shadowColor = s; 786}; 787Tproto.SetShadowColourAlpha = function(c,s,a) { 788 c.shadowColor = SetAlpha(s, a); 789}; 790Tproto.DrawText = function(c,xoff,yoff) { 791 var t = this.tc, x = this.x, y = this.y, s = this.sc, i, xl; 792 c.globalAlpha = this.alpha; 793 c.fillStyle = this.colour; 794 t.shadow && this.SetShadowColour(c,t.shadow,this.alpha); 795 c.font = this.font; 796 x += xoff / s; 797 y += (yoff / s) - (this.h / 2); 798 for(i = 0; i < this.text.length; ++i) { 799 xl = x - (this.line_widths[i] / 2); 800 c.setTransform(s, 0, 0, s, s * xl, s * y); 801 c.fillText(this.text[i], 0, 0); 802 y += this.textHeight; 803 } 804}; 805Tproto.DrawImage = function(c,xoff,yoff) { 806 var x = this.x, y = this.y, s = this.sc, 807 i = this.image, w = this.w, h = this.h, a = this.alpha, 808 shadow = this.shadow; 809 c.globalAlpha = a; 810 shadow && this.SetShadowColour(c,shadow,a); 811 x += (xoff / s) - (w / 2); 812 y += (yoff / s) - (h / 2); 813 c.setTransform(s, 0, 0, s, s * x, s * y); 814 c.drawImage(i, 0, 0, w, h); 815}; 816Tproto.DrawImageIE = function(c,xoff,yoff) { 817 var i = this.image, s = this.sc, 818 w = i.width = this.w*s, h = i.height = this.h * s, 819 x = (this.x*s) + xoff - (w/2), y = (this.y*s) + yoff - (h/2); 820 c.setTransform(1,0,0,1,0,0); 821 c.globalAlpha = this.alpha; 822 c.drawImage(i, x, y); 823}; 824Tproto.Calc = function(m,a) { 825 var pp, t = this.tc, mnb = t.minBrightness, 826 mxb = t.maxBrightness, r = t.max_radius; 827 pp = m.xform(this.position); 828 this.xformed = pp; 829 pp = Project(t, pp, t.stretchX, t.stretchY); 830 this.x = pp.x; 831 this.y = pp.y; 832 this.z = pp.z; 833 this.sc = pp.w; 834 this.alpha = a * Clamp(mnb + (mxb - mnb) * (r - this.z) / (2 * r), 0, 1); 835}; 836Tproto.CheckActive = function(c,xoff,yoff) { 837 var t = this.tc, o = this.outline, 838 w = this.w, h = this.h, 839 x = this.x - w/2, y = this.y - h/2; 840 o.Update(x, y, w, h, this.sc, this.z, xoff, yoff); 841 return o.Active(c, t.mx, t.my) ? o : null; 842}; 843Tproto.Clicked = function(e) { 844 var a = this.a, t = a.target, h = a.href, evt; 845 if(t != '' && t != '_self') { 846 if(self.frames[t]) { 847 self.frames[t].document.location = h; 848 } else{ 849 try { 850 if(top.frames[t]) { 851 top.frames[t].document.location = h; 852 return; 853 } 854 } catch(err) { 855 // different domain/port/protocol? 856 } 857 window.open(h, t); 858 } 859 return; 860 } 861 if(doc.createEvent) { 862 evt = doc.createEvent('MouseEvents'); 863 evt.initMouseEvent('click', 1, 1, window, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, null); 864 if(!a.dispatchEvent(evt)) 865 return; 866 } else if(a.fireEvent) { 867 if(!a.fireEvent('onclick')) 868 return; 869 } 870 doc.location = h; 871}; 872/** 873 * @constructor 874 */ 875function TagCanvas(cid,lctr,opt) { 876 var i, p, c = doc.getElementById(cid), cp = ['id','class','innerHTML']; 877 878 if(!c) throw 0; 879 if(Defined(window.G_vmlCanvasManager)) { 880 c = window.G_vmlCanvasManager.initElement(c); 881 this.ie = parseFloat(navigator.appVersion.split('MSIE')[1]); 882 } 883 if(c && (!c.getContext || !c.getContext('2d').fillText)) { 884 p = doc.createElement('DIV'); 885 for(i = 0; i < cp.length; ++i) 886 p[cp[i]] = c[cp[i]]; 887 c.parentNode.insertBefore(p,c); 888 c.parentNode.removeChild(c); 889 throw 0; 890 } 891 for(i in TagCanvas.options) 892 this[i] = opt && Defined(opt[i]) ? opt[i] : 893 (Defined(TagCanvas[i]) ? TagCanvas[i] : TagCanvas.options[i]); 894 895 this.canvas = c; 896 this.ctxt = c.getContext('2d'); 897 this.z1 = 250 / this.depth; 898 this.z2 = this.z1 / this.zoom; 899 this.radius = min(c.height, c.width) * 0.0075; // fits radius of 100 in canvas 900 this.max_weight = 0; 901 this.min_weight = 200; 902 this.textFont = this.textFont && FixFont(this.textFont); 903 this.textHeight *= 1; 904 this.pulsateTo = Clamp(this.pulsateTo, 0, 1); 905 this.minBrightness = Clamp(this.minBrightness, 0, 1); 906 this.maxBrightness = Clamp(this.maxBrightness, this.minBrightness, 1); 907 this.ctxt.textBaseline = 'top'; 908 this.lx = (this.lock + '').indexOf('x') + 1; 909 this.ly = (this.lock + '').indexOf('y') + 1;
910 this.frozen = this.dx = this.dy = this.fixedAnim = this.touched = 0; 911 this.fixedAlpha = 1; 912 this.source = lctr || cid; 913 this.transform = Matrix.Identity(); 914 this.startTime = this.time = TimeNow(); 915 this.Animate = this.dragControl ? this.AnimateDrag : this.AnimatePosition; 916 this.animTiming = (typeof TagCanvas[this.animTiming] == 'function' ? 917 TagCanvas[this.animTiming] : TagCanvas.Smooth); 918 if(this.shadowBlur || this.shadowOffset[0] || this.shadowOffset[1]) { 919 // let the browser translate "red" into "#ff0000" 920 this.ctxt.shadowColor = this.shadow; 921 this.shadow = this.ctxt.shadowColor; 922 this.shadowAlpha = ShadowAlphaBroken(); 923 } else { 924 delete this.shadow; 925 } 926 this.Load(); 927 if(lctr && this.hideTags) { 928 (function(t) { 929 if(TagCanvas.loaded) 930 t.HideTags(); 931 else 932 AddHandler('load', function() { t.HideTags(); }, window); 933 })(this); 934 } 935 936 this.yaw = this.initial ? this.initial[0] * this.maxSpeed : 0; 937 this.pitch = this.initial ? this.initial[1] * this.maxSpeed : 0; 938 if(this.tooltip) { 939 if(this.tooltip == 'native') { 940 this.Tooltip = this.TooltipNative; 941 } else { 942 this.Tooltip = this.TooltipDiv; 943 if(!this.ttdiv) { 944 this.ttdiv = doc.createElement('div'); 945 this.ttdiv.className = this.tooltipClass; 946 this.ttdiv.style.position = 'absolute'; 947 this.ttdiv.style.zIndex = c.style.zIndex + 1; 948 AddHandler('mouseover',function(e){e.target.style.display='none';},this.ttdiv); 949 doc.body.appendChild(this.ttdiv); 950 } 951 } 952 } else { 953 this.Tooltip = this.TooltipNone; 954 } 955 if(!this.noMouse && !handlers[cid]) { 956 AddHandler('mousemove', MouseMove, c); 957 AddHandler('mouseout', MouseOut, c); 958 AddHandler('mouseup', MouseUp, c); 959 AddHandler('touchstart', TouchDown, c); 960 AddHandler('touchend', TouchUp, c); 961 AddHandler('touchcancel', TouchUp, c); 962 AddHandler('touchmove', TouchMove, c); 963 if(this.dragControl) { 964 AddHandler('mousedown', MouseDown, c); 965 AddHandler('selectstart', Nop, c); 966 } 967 if(this.wheelZoom) { 968 AddHandler('mousewheel', MouseWheel, c); 969 AddHandler('DOMMouseScroll', MouseWheel, c); 970 } 971 handlers[cid] = 1; 972 } 973 TagCanvas.started || (TagCanvas.started = setTimeout(DrawCanvas, this.interval)); 974} 975TCproto = TagCanvas.prototype; 976TCproto.SourceElements = function() { 977 if(doc.querySelectorAll) 978 return doc.querySelectorAll('#' + this.source); 979 return [doc.getElementById(this.source)]; 980}; 981TCproto.HideTags = function() { 982 var el = this.SourceElements(), i; 983 for(i = 0; i < el.length; ++i) 984 el[i].style.display = 'none'; 985}; 986TCproto.GetTags = function() { 987 var el = this.SourceElements(), etl, tl = [], i, j; 988 for(i = 0; i < el.length; ++i) { 989 etl = el[i].getElementsByTagName('a'); 990 for(j = 0; j < etl.length; ++j) { 991 tl.push(etl[j]); 992 } 993 } 994 return tl; 995}; 996TCproto.CreateTag = function(e, p) { 997 var im = e.getElementsByTagName('img'), i, t, ts, font; 998 p = p || [0, 0, 0]; 999 if(im.length) { 1000 i = new Image; 1001 i.src = im[0].src; 1002 t = new Tag(this, i, e, p, 0, 0); 1003 AddImage(i, im[0], t, this); 1004 return t; 1005 } 1006 ts = new TextSplitter(e); 1007 t = ts.Lines(); 1008 font = this.textFont || FixFont(GetProperty(e,'font-family')); 1009 if(this.splitWidth) 1010 t = ts.SplitWidth(this.splitWidth, this.ctxt, font, this.textHeight); 1011 1012 return new Tag(this, t, e, p, 2, this.textHeight + 2, 1013 this.textColour || GetProperty(e,'color'), font, ts.original); 1014}; 1015TCproto.UpdateTag = function(t, a) { 1016 var colour = this.textColour || GetProperty(a, 'color'), 1017 font = this.textFont || FixFont(GetProperty(a, 'font-family')); 1018 t.title = a.title; 1019 if(t.colour != colour || t.textFont != font) 1020 t.SetFont(font, colour); 1021}; 1022TCproto.Weight = function(tl) { 1023 var l = tl.length, w, i, weights = []; 1024 for(i = 0; i < l; ++i) { 1025 w = FindWeight(this, tl[i].a); 1026 if(w > this.max_weight) this.max_weight = w; 1027 if(w < this.min_weight) this.min_weight = w; 1028 weights.push(w); 1029 } 1030 if(this.max_weight > this.min_weight) { 1031 for(i = 0; i < l; ++i) { 1032 tl[i].SetWeight(weights[i]); 1033 } 1034 } 1035}; 1036TCproto.Load = function() { 1037 var tl = this.GetTags(), taglist = [], shape, 1038 shapeArgs, rx, ry, rz, vl, i, tagmap = [], pfuncs = { 1039 sphere: PointsOnSphere, 1040 vcylinder: PointsOnCylinderV, 1041 hcylinder: PointsOnCylinderH, 1042 vring: PointsOnRingV, 1043 hring: PointsOnRingH 1044 }; 1045 1046 if(tl.length) { 1047 tagmap.length = tl.length; 1048 for(i = 0; i < tl.length; ++i) 1049 tagmap[i] = i; 1050 this.shuffleTags && Shuffle(tagmap); 1051 rx = 100 * this.radiusX; 1052 ry = 100 * this.radiusY; 1053 rz = 100 * this.radiusZ; 1054 this.max_radius = max(rx, max(ry, rz)); 1055 1056 if(this.shapeArgs) { 1057 this.shapeArgs[0] = tl.length; 1058 } else { 1059 shapeArgs = this.shape.toString().split(/[(),]/); 1060 shape = shapeArgs.shift(); 1061 this.shape = pfuncs[shape] || pfuncs.sphere; 1062 this.shapeArgs = [tl.length, rx, ry, rz].concat(shapeArgs); 1063 } 1064 vl = this.shape.apply(this, this.shapeArgs); 1065 this.listLength = tl.length; 1066 for(i = 0; i < tl.length; ++i) { 1067 taglist.push(this.CreateTag(tl[tagmap[i]], vl[i])); 1068 } 1069 this.weight && this.Weight(taglist, true); 1070 } 1071 this.taglist = taglist; 1072}; 1073TCproto.Update = function() { 1074 var tl = this.GetTags(), newlist = [], 1075 taglist = this.taglist, found, 1076 added = [], removed = [], vl, ol, nl, i, j; 1077 1078 if(!this.shapeArgs) 1079 return this.Load(); 1080 1081 if(tl.length) { 1082 nl = this.listLength = tl.length; 1083 ol = taglist.length; 1084 1085 // copy existing list, populate "removed" 1086 for(i = 0; i < ol; ++i) { 1087 newlist.push(taglist[i]); 1088 removed.push(i); 1089 } 1090 1091 // find added and removed tags 1092 for(i = 0; i < nl; ++i) { 1093 for(j = 0, found = 0; j < ol; ++j) { 1094 if(taglist[j].EqualTo(tl[i])) { 1095 this.UpdateTag(newlist[j], tl[i]); 1096 found = removed[j] = -1; 1097 } 1098 } 1099 if(!found) 1100 added.push(i); 1101 } 1102 1103 // clean out found tags from removed list 1104 for(i = 0, j = 0; i < ol; ++i) { 1105 if(removed[j] == -1) 1106 removed.splice(j,1); 1107 else 1108 ++j; 1109 } 1110 1111 // insert new tags in gaps where old tags removed 1112 if(removed.length) { 1113 Shuffle(removed); 1114 while(removed.length && added.length) { 1115 i = removed.shift(); 1116 j = added.shift(); 1117 newlist[i] = this.CreateTag(tl[j]); 1118 } 1119 1120 // remove any more (in reverse order) 1121 removed.sort(function(a,b) {return a-b}); 1122 while(removed.length) { 1123 newlist.splice(removed.pop(), 1); 1124 } 1125 } 1126 1127 // add any extra tags 1128 j = newlist.length / (added.length + 1); 1129 i = 0; 1130 while(added.length) { 1131 newlist.splice(ceil(++i * j), 0, this.CreateTag(tl[added.shift()])); 1132 } 1133 1134 // assign correct positions to tags 1135 this.shapeArgs[0] = nl = newlist.length; 1136 vl = this.shape.apply(this, this.shapeArgs); 1137 for(i = 0; i < nl; ++i) 1138 newlist[i].position = new Vector(vl[i][0], vl[i][1], vl[i][2]); 1139 1140 // reweight tags 1141 this.weight && this.Weight(newlist); 1142 } 1143 this.taglist = newlist; 1144}; 1145TCproto.SetShadow = function(c) { 1146 c.shadowBlur = this.shadowBlur; 1147 c.shadowOffsetX = this.shadowOffset[0]; 1148 c.shadowOffsetY = this.shadowOffset[1]; 1149}; 1150TCproto.Draw = function(t) { 1151 if(this.paused) 1152 return; 1153 var cv = this.canvas, cw = cv.width, ch = cv.height, max_sc = 0, 1154 tdelta = (t - this.time) * this.interval / 1000, 1155 x = cw / 2 + this.offsetX, y = ch / 2 + this.offsetY, c = this.ctxt, 1156 active, a, i, aindex = -1, tl = this.taglist, l = tl.length, 1157 frontsel = this.frontSelect, centreDrawn = (this.centreFunc == Nop), fixed; 1158 this.time = t; 1159 if(this.frozen && this.drawn) 1160 return this.Animate(cw,ch,tdelta); 1161 fixed = this.AnimateFixed(); 1162 c.setTransform(1,0,0,1,0,0); 1163 this.active = null; 1164 for(i = 0; i < l; ++i) 1165 tl[i].Calc(this.transform, this.fixedAlpha); 1166 tl = SortList(tl, function(a,b) {return b.z-a.z}); 1167 1168 for(i = 0; i < l; ++i) { 1169 a = this.mx >= 0 && this.my >= 0 && this.taglist[i].CheckActive(c, x, y); 1170 if(a && a.sc > max_sc && (!frontsel || a.z <= 0)) { 1171 active = a; 1172 aindex = i; 1173 active.tag = this.taglist[i]; 1174 max_sc = a.sc; 1175 } 1176 } 1177 this.active = active; 1178 1179 this.txtOpt || (this.shadow && this.SetShadow(c)); 1180 c.clearRect(0,0,cw,ch); 1181 for(i = 0; i < l; ++i) { 1182 if(!centreDrawn && tl[i].z <= 0) { 1183 // run the centreFunc if the next tag is at the front
vendor: 10,109 bytes, lines 1184-1546
1184 try { this.centreFunc(c, cw, ch, x, y); } 1185 catch(e) { 1186 alert(e); 1187 // don't run it again 1188 this.centreFunc = Nop; 1189 } 1190 centreDrawn = true; 1191 } 1192 1193 if(!(active && active.tag == tl[i] && active.PreDraw(c, tl[i], x, y))) 1194 tl[i].Draw(c, x, y); 1195 active && active.tag == tl[i] && active.PostDraw(c); 1196 } 1197 if(this.freezeActive && active) { 1198 this.Freeze(); 1199 } else { 1200 this.UnFreeze(); 1201 this.drawn = (l == this.listLength); 1202 } 1203 if(this.fixedCallback) { 1204 this.fixedCallback(this,this.fixedCallbackTag); 1205 this.fixedCallback = null; 1206 } 1207 fixed || this.Animate(cw, ch, tdelta); 1208 active && active.LastDraw(c); 1209 cv.style.cursor = active ? this.activeCursor : ''; 1210 this.Tooltip(active,this.taglist[aindex]); 1211}; 1212TCproto.TooltipNone = function() { }; 1213TCproto.TooltipNative = function(active,tag) { 1214 this.canvas.title = active && tag.title ? tag.title : ''; 1215}; 1216TCproto.TooltipDiv = function(active,tag) { 1217 var tc = this, s = tc.ttdiv.style, cid = tc.canvas.id, none = 'none'; 1218 if(active && tag.title) { 1219 if(tag.title != tc.ttdiv.innerHTML) 1220 s.display = none; 1221 tc.ttdiv.innerHTML = tag.title; 1222 tag.title = tc.ttdiv.innerHTML; 1223 if(s.display == none && ! tc.tttimer) { 1224 tc.tttimer = setTimeout(function() { 1225 var p = AbsPos(cid); 1226 s.display = 'block'; 1227 s.left = p.x + tc.mx + 'px'; 1228 s.top = p.y + tc.my + 24 + 'px'; 1229 tc.tttimer = null; 1230 }, tc.tooltipDelay); 1231 } 1232 } else { 1233 s.display = none; 1234 } 1235}; 1236TCproto.Transform = function(tc, p, y) { 1237 if(p || y) { 1238 var sp = sin(p), cp = cos(p), sy = sin(y), cy = cos(y), 1239 ym = new Matrix([cy,0,sy, 0,1,0, -sy,0,cy]), 1240 pm = new Matrix([1,0,0, 0,cp,-sp, 0,sp,cp]); 1241 tc.transform = tc.transform.mul(ym.mul(pm)); 1242 } 1243}; 1244TCproto.AnimateFixed = function() { 1245 var fa, t1, angle, m, d; 1246 if(this.fadeIn) { 1247 t1 = TimeNow() - this.startTime; 1248 if(t1 >= this.fadeIn) { 1249 this.fadeIn = 0; 1250 this.fixedAlpha = 1; 1251 } else { 1252 this.fixedAlpha = t1 / this.fadeIn; 1253 } 1254 } 1255 if(this.fixedAnim) { 1256 if(!this.fixedAnim.transform) 1257 this.fixedAnim.transform = this.transform; 1258 fa = this.fixedAnim, t1 = TimeNow() - fa.t0, angle = fa.angle, 1259 m, d = this.animTiming(fa.t, t1); 1260 this.transform = fa.transform; 1261 if(t1 >= fa.t) { 1262 this.fixedCallbackTag = fa.tag; 1263 this.fixedCallback = fa.cb; 1264 this.fixedAnim = this.yaw = this.pitch = 0; 1265 } else { 1266 angle *= d; 1267 } 1268 m = Matrix.Rotation(angle, fa.axis); 1269 this.transform = this.transform.mul(m); 1270 return (this.fixedAnim != 0); 1271 } 1272 return false; 1273}; 1274TCproto.AnimatePosition = function(w, h, t) { 1275 var tc = this, x = tc.mx, y = tc.my, s, r; 1276 if(!tc.frozen && x >= 0 && y >= 0 && x < w && y < h) { 1277 s = tc.maxSpeed, r = tc.reverse ? -1 : 1; 1278 tc.lx || (tc.yaw = r * t * ((s * 2 * x / w) - s)); 1279 tc.ly || (tc.pitch = r * t * -((s * 2 * y / h) - s)); 1280 tc.initial = null; 1281 } else if(!tc.initial) { 1282 if(tc.frozen && !tc.freezeDecel) 1283 tc.yaw = tc.pitch = 0; 1284 else 1285 tc.Decel(tc); 1286 } 1287 this.Transform(tc, tc.pitch, tc.yaw); 1288}; 1289TCproto.AnimateDrag = function(w, h, t) { 1290 var tc = this, rs = 100 * t * tc.maxSpeed / tc.max_radius / tc.zoom; 1291 if(tc.dx || tc.dy) { 1292 tc.lx || (tc.yaw = tc.dx * rs / tc.stretchX); 1293 tc.ly || (tc.pitch = tc.dy * -rs / tc.stretchY); 1294 tc.dx = tc.dy = 0; 1295 tc.initial = null; 1296 } else if(!tc.initial) { 1297 tc.Decel(tc); 1298 } 1299 this.Transform(tc, tc.pitch, tc.yaw); 1300}; 1301TCproto.Freeze = function() { 1302 if(!this.frozen) { 1303 this.preFreeze = [this.yaw, this.pitch]; 1304 this.frozen = 1; 1305 this.drawn = 0; 1306 } 1307}; 1308TCproto.UnFreeze = function() { 1309 if(this.frozen) { 1310 this.yaw = this.preFreeze[0]; 1311 this.pitch = this.preFreeze[1]; 1312 this.frozen = 0; 1313 } 1314}; 1315TCproto.Decel = function(tc) { 1316 var s = tc.minSpeed, ay = abs(tc.yaw), ap = abs(tc.pitch); 1317 if(!tc.lx && ay > s) 1318 tc.yaw = ay > tc.z0 ? tc.yaw * tc.decel : 0; 1319 if(!tc.ly && ap > s) 1320 tc.pitch = ap > tc.z0 ? tc.pitch * tc.decel : 0; 1321}; 1322TCproto.Zoom = function(r) { 1323 this.z2 = this.z1 * (1/r); 1324 this.drawn = 0; 1325}; 1326TCproto.Clicked = function(e) { 1327 var a = this.active; 1328 try { 1329 if(a && a.tag) 1330 if(this.clickToFront === false || this.clickToFront === null) 1331 a.tag.Clicked(e); 1332 else 1333 this.TagToFront(a.tag, this.clickToFront, function() { a.tag.Clicked(e); }); 1334 } catch(ex) { 1335 } 1336}; 1337TCproto.Wheel = function(i) { 1338 var z = this.zoom + this.zoomStep * (i ? 1 : -1); 1339 this.zoom = min(this.zoomMax,max(this.zoomMin,z)); 1340 this.Zoom(this.zoom); 1341}; 1342TCproto.BeginDrag = function(e) { 1343 this.down = EventXY(e, this.canvas); 1344 e.cancelBubble = true; 1345 e.returnValue = false; 1346 e.preventDefault && e.preventDefault(); 1347}; 1348TCproto.Drag = function(e, p) { 1349 if(this.dragControl && this.down) { 1350 var t2 = this.dragThreshold * this.dragThreshold, 1351 dx = p.x - this.down.x, dy = p.y - this.down.y; 1352 if(this.dragging || dx * dx + dy * dy > t2) { 1353 this.dx = dx; 1354 this.dy = dy; 1355 this.dragging = 1; 1356 this.down = p; 1357 } 1358 } 1359}; 1360TCproto.EndDrag = function() { 1361 var res = this.dragging; 1362 this.dragging = this.down = null; 1363 return res; 1364}; 1365TCproto.Pause = function() { this.paused = true; }; 1366TCproto.Resume = function() { this.paused = false; }; 1367TCproto.FindTag = function(t) { 1368 if(!Defined(t)) 1369 return null; 1370 Defined(t.index) && (t = t.index); 1371 if(!IsObject(t)) 1372 return this.taglist[t]; 1373 var srch, tgt, i; 1374 if(Defined(t.id)) 1375 srch = 'id', tgt = t.id; 1376 else if(Defined(t.text)) 1377 srch = 'innerText', tgt = t.text; 1378 1379 for(i = 0; i < this.taglist.length; ++i) 1380 if(this.taglist[i].a[srch] == tgt) 1381 return this.taglist[i]; 1382}; 1383TCproto.RotateTag = function(tag, lt, lg, time, callback) { 1384 var t = tag.xformed, v1 = new Vector(t.x, t.y, t.z), 1385 v2 = MakeVector(lg, lt), angle = v1.angle(v2), u = v1.cross(v2).unit(); 1386 if(angle == 0) { 1387 this.fixedCallbackTag = tag; 1388 this.fixedCallback = callback; 1389 } else { 1390 this.fixedAnim = {angle: -angle, axis: u, t: time, t0: TimeNow(), cb: callback, tag: tag}; 1391 } 1392}; 1393TCproto.TagToFront = function(tag, time, callback) { 1394 this.RotateTag(tag, 0, 0, time, callback); 1395}; 1396TagCanvas.Start = function(id,l,o) { 1397 TagCanvas.tc[id] = new TagCanvas(id,l,o); 1398}; 1399function tccall(f,id) { 1400 TagCanvas.tc[id] && TagCanvas.tc[id][f](); 1401} 1402TagCanvas.Linear = function(t, t0) { return t0 / t; } 1403TagCanvas.Smooth = function(t, t0) { return 0.5 - cos(t0 * Math.PI / t) / 2; } 1404TagCanvas.Pause = function(id) { tccall('Pause',id); }; 1405TagCanvas.Resume = function(id) { tccall('Resume',id); }; 1406TagCanvas.Reload = function(id) { tccall('Load',id); }; 1407TagCanvas.Update = function(id) { tccall('Update',id); }; 1408TagCanvas.TagToFront = function(id, options) { 1409 if(!IsObject(options)) 1410 return false; 1411 options.lat = options.lng = 0; 1412 return TagCanvas.RotateTag(id, options); 1413}; 1414TagCanvas.RotateTag = function(id, options) { 1415 if(!IsObject(options)) 1416 return false; 1417 if(TagCanvas.tc[id]) { 1418 if(isNaN(options['time'])) 1419 options.time = 500; 1420 var tt = TagCanvas.tc[id].FindTag(options); 1421 if(tt) { 1422 TagCanvas.tc[id].RotateTag(tt, options['lat'], options['lng'], 1423 options['time'], options['callback']); 1424 return true; 1425 } 1426 } 1427 return false; 1428}; 1429TagCanvas.NextFrame = function(iv) { 1430 var raf = window.requestAnimationFrame = window.requestAnimationFrame || 1431 window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame || 1432 window.msRequestAnimationFrame; 1433 TagCanvas.NextFrame = raf ? TagCanvas.NextFrameRAF : TagCanvas.NextFrameTimeout; 1434 TagCanvas.NextFrame(iv); 1435}; 1436TagCanvas.NextFrameRAF = function() { 1437 requestAnimationFrame(DrawCanvas); 1438}; 1439TagCanvas.NextFrameTimeout = function(iv) { 1440 setTimeout(DrawCanvas, iv); 1441}; 1442TagCanvas.tc = {}; 1443TagCanvas.options = { 1444z1: 20000, 1445z2: 20000, 1446z0: 0.0002, 1447freezeActive: false, 1448freezeDecel: false, 1449activeCursor: 'pointer', 1450pulsateTo: 1, 1451pulsateTime: 3, 1452reverse: false, 1453depth: 0.5, 1454maxSpeed: 0.05, 1455minSpeed: 0, 1456decel: 0.95, 1457interval: 20, 1458minBrightness: 0.1, 1459maxBrightness: 1, 1460outlineColour: '#ffff99', 1461outlineThickness: 2, 1462outlineOffset: 5, 1463outlineMethod: 'outline', 1464textColour: '#ff99ff', 1465textHeight: 15, 1466textFont: 'Helvetica, Arial, sans-serif', 1467shadow: '#000', 1468shadowBlur: 0, 1469shadowOffset: [0,0], 1470initial: null, 1471hideTags: true, 1472zoom: 1, 1473weight: false, 1474weightMode: 'size', 1475weightFrom: null, 1476weightSize: 1, 1477weightSizeMin: null, 1478weightSizeMax: null, 1479weightGradient: {0:'#f00', 0.33:'#ff0', 0.66:'#0f0', 1:'#00f'}, 1480txtOpt: true, 1481txtScale: 2, 1482frontSelect: false, 1483wheelZoom: true, 1484zoomMin: 0.3, 1485zoomMax: 3, 1486zoomStep: 0.05, 1487shape: 'sphere', 1488lock: null, 1489tooltip: null, 1490tooltipDelay: 300, 1491tooltipClass: 'tctooltip', 1492radiusX: 1, 1493radiusY: 1, 1494radiusZ: 1, 1495stretchX: 1, 1496stretchY: 1, 1497offsetX: 0, 1498offsetY: 0, 1499shuffleTags: false, 1500noSelect: false, 1501noMouse: false, 1502imageScale: 1, 1503paused: false, 1504dragControl: false, 1505dragThreshold: 4, 1506centreFunc: Nop, 1507splitWidth: 0, 1508animTiming: 'Smooth', 1509clickToFront: false, 1510fadeIn: 0 1511}; 1512for(i in TagCanvas.options) TagCanvas[i] = TagCanvas.options[i]; 1513window.TagCanvas = TagCanvas; 1514jQuery.fn.tagcanvas = function(options, lctr) { 1515 var fn = { 1516 pause: function() { 1517 $(this).each(function() { tccall('Pause',$(this)[0].id); }); 1518 }, 1519 resume: function() { 1520 $(this).each(function() { tccall('Resume',$(this)[0].id); }); 1521 }, 1522 reload: function() { 1523 $(this).each(function() { tccall('Load',$(this)[0].id); }); 1524 }, 1525 update: function() { 1526 $(this).each(function() { tccall('Update',$(this)[0].id); }); 1527 }, 1528 tagtofront: function() { 1529 $(this).each(function() { TagCanvas.TagToFront($(this)[0].id, lctr); }); 1530 }, 1531 rotatetag: function() { 1532 $(this).each(function() { TagCanvas.RotateTag($(this)[0].id, lctr); }); 1533 } 1534 }; 1535 if(typeof options == 'string' && fn[options]) { 1536 fn[options].apply(this); 1537 } else { 1538 TagCanvas.jquery = 1; 1539 $(this).each(function() { TagCanvas.Start($(this)[0].id, lctr, options); }); 1540 return TagCanvas.started; 1541 } 1542}; 1543 1544// set a flag for when the window has loaded 1545AddHandler('load',function(){TagCanvas.loaded=1},window); 1546})(jQuery);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.