1/* 2 * jQuery scrollintoview() plugin and :scrollable selector filter 3 * 4 * Version 1.8 (14 Jul 2011) 5 * Requires jQuery 1.4 or newer 6 * 7 * Copyright (c) 2011 Robert Koritnik 8 * Licensed under the terms of the MIT license 9 * http://www.opensource.org/licenses/mit-license.php 10 */ 11(function(f){var c={vertical:{x:false,y:true},horizontal:{x:true,y:false},both:{x:true,y:true},x:{x:true,y:false},y:{x:false,y:true}};var b={duration:"fast",direction:"both"};var e=/^(?:html)$/i;var g=function(k,j){j=j||(document.defaultView&&document.defaultView.getComputedStyle?document.defaultView.getComputedStyle(k,null):k.currentStyle);var i=document.defaultView&&document.defaultView.getComputedStyle?true:false;var h={top:(parseFloat(i?j.borderTopWidth:f.css(k,"borderTopWidth"))||0),left:(parseFloat(i?j.borderLeftWidth:f.css(k,"borderLeftWidth"))||0),bottom:(parseFloat(i?j.borderBottomWidth:f.css(k,"borderBottomWidth"))||0),right:(parseFloat(i?j.borderRightWidth:f.css(k,"borderRightWidth"))||0)};return{top:h.top,left:h.left,bottom:h.bottom,right:h.right,vertical:h.top+h.bottom,horizontal:h.left+h.right}};var d=function(h){var j=f(window);var i=e.test(h[0].nodeName);return{border:i?{top:0,left:0,bottom:0,right:0}:g(h[0]),scroll:{top:(i?j:h).scrollTop(),left:(i?j:h).scrollLeft()},scrollbar:{right:i?0:h.innerWidth()-h[0].clientWidth,bottom:i?0:h.innerHeight()-h[0].clientHeight},rect:(function(){var k=h[0].getBoundingClientRect();return{top:i?0:k.top,left:i?0:k.left,bottom:i?h[0].clientHeight:k.bottom,right:i?h[0].clientWidth:k.right}})()}};f.fn.extend({scrollintoview:function(j){j=f.extend({},b,j);j.direction=c[typeof(j.direction)==="string"&&j.direction.toLowerCase()]||c.both;var n="";if(j.direction.x===true){n="horizontal"}if(j.direction.y===true){n=n?"both":"vertical"}var l=this.eq(0);var i=l.closest(":scrollable("+n+")");if(i.length>0){i=i.eq(0);var m={e:d(l),s:d(i)};var h={top:m.e.rect.top-(m.s.rect.top+m.s.border.top),bottom:m.s.rect.bottom-m.s.border.bottom-m.s.scrollbar.bottom-m.e.rect.bottom,left:m.e.rect.left-(m.s.rect.left+m.s.border.left),right:m.s.rect.right-m.s.border.right-m.s.scrollbar.right-m.e.rect.right};var k={};if(j.direction.y===true){if(h.top<0){k.scrollTop=m.s.scroll.top+h.top}else{if(h.top>0&&h.bottom<0){k.scrollTop=m.s.scroll.top+Math.min(h.top,-h.bottom)}}}if(j.direction.x===true){if(h.left<0){k.scrollLeft=m.s.scroll.left+h.left}else{if(h.left>0&&h.right<0){k.scrollLeft=m.s.scroll.left+Math.min(h.left,-h.right)}}}if(!f.isEmptyObject(k)){if(e.test(i[0].nodeName)){i=f("html,body")}i.animate(k,j.duration).eq(0).queue(function(o){f.isFunction(j.complete)&&j.complete.call(i[0]);o()})}else{f.isFunction(j.complete)&&j.complete.call(i[0])}}return this}});var a={auto:true,scroll:true,visible:false,hidden:false};f.extend(f.expr[":"],{scrollable:function(k,i,n,h){var m=c[typeof(n[3])==="string"&&n[3].toLowerCase()]||c.both;var l=(document.defaultView&&document.defaultView.getComputedStyle?document.defaultView.getComputedStyle(k,null):k.currentStyle);var o={x:a[l.overflowX.toLowerCase()]||false,y:a[l.overflowY.toLowerCase()]||false,isRoot:e.test(k.nodeName)};if(!o.x&&!o.y&&!o.isRoot){return false}var j={height:{scroll:k.scrollHeight,client:k.clientHeight},width:{scroll:k.scrollWidth,client:k.clientWidth},scrollableX:function(){return(o.x||o.isRoot)&&this.width.scroll>this.width.client},scrollableY:function(){return(o.y||o.isRoot)&&this.height.scroll>this.height.client}};return m.y&&j.scrollableY()||m.x&&j.scrollableX()}})})(jQuery); 12 13 14if (!Function.prototype.bind) { 15 Function.prototype.bind = function(oThis) { 16 if (typeof this !== 'function') 17 throw new TypeError('Function.prototype.bind - what is trying to be bound is not callable'); 18 var aArgs = Array.prototype.slice.call(arguments, 1), 19 fToBind = this, 20 fNOP = function() {}, 21 fBound = function() { 22 return fToBind.apply(this instanceof fNOP && oThis ? this : oThis, 23 aArgs.concat(Array.prototype.slice.call(arguments))); 24 }; 25 fNOP.prototype = this.prototype; 26 fBound.prototype = new fNOP(); 27 return fBound; 28 }; 29} 30 31(function () { 32 if (!self.CB5) self.CB5 = {}; 33 var util = {}; 34 CB5.config = {}; 35 CB5.util = util; 36 CB5.plugin = {}; 37 CB5.emailReg = /^[a-z0-9!#$%&'*+\/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+\/=?^_`{|}~-]+)*@(?:[a-zöäëÃ0-9](?:[a-zöäëÃ0-9-]*[a-zöäëÃ0-9])?\.)+(?:[a-z]{2}|aero|asia|biz|cat|com|coop|edu|gov|info|int|jobs|mil|mobi|museum|name|net|org|pro|tel|travel|xxx)$/i; 38 39 CB5.isTouch = /iPad|iPhone|iPod|Android/.test(navigator.userAgent); 40 CB5.isIOS = /iPad|iPhone|iPod/.test(navigator.userAgent); 41 42 CB5.vendorCss = function(o, prop, value) { 43 o[prop] = value; 44 prop = prop.charAt(0).toUpperCase() + prop.substr(1); 45 o['Webkit' + prop] = o['Moz' + prop] = o['ms' + prop] = o['O' + prop] = value; 46 return o; 47 }; 48 CB5.scrollTop = function () {return Math.max($('body').scrollTop(), $('html').scrollTop());}; 49 50 51 CB5.getRealPath = function (path) 52 { 53 var map = { 54 user:'files', 55 shared:'shared/html5', 56 resource:CB5.config.rootUrl + 'action/resource', 57 thumb:CB5.config.rootUrl + 'action/thumb', 58 search: CB5.config.rootUrl + 'action/search', 59 topbanner: CB5.config.rootUrl + 'action/topbanner', 60 library: 'lib/browse' 61 }; 62 var a = path.split('://'); 63 return (a[0] in map) ? map[a[0]] + '/' + a[1] : path; 64 }; 65 66 67 var Class = function () {}; 68 Class.extend = function (config) { 69 var proto = new this(); 70 for (var name in config) 71 proto[name] = config[name]; 72 var Cls = config.init; 73 Cls.prototype = proto; 74 Cls.extend = this.extend; 75 76 proto.constructor = Cls; 77 proto.super = this.prototype; 78 return Cls; 79 }; 80 util.Class = Class; 81 82 83 var loadScriptMap = {}; 84 util.loadScript = function(url, callback) { 85 86 if (url instanceof Array) { 87 var cnt = url.length; 88 url.forEach(function (u) { 89 util.loadScript(u, function () { 90 cnt --; 91 if (cnt == 0) callback(); 92 }); 93 }); 94 return; 95 } 96 97 if (loadScriptMap[url]) { 98 if (loadScriptMap[url] == 'loaded') callback(); 99 else loadScriptMap[url].push(callback); 100 return; 101 } 102 103 var script = document.createElement('script'); 104 loadScriptMap[url] = [callback]; 105 script.type = 'text/javascript'; 106 if (callback) script.addEventListener('load', function () { 107 loadScriptMap[url].forEach(function (cb) { 108 cb(); 109 }); 110 loadScriptMap[url] = 'loaded'; 111 }); 112 script.src = url; 113 document.body.appendChild(script); 114 }; 115 CB5.loadScript = util.loadScript; 116 117 118 119 util.noiseFill = function (color, color2, intensity, opacity) { 120 121 var n = parseInt('0x' + color); 122 var argb = {a: (0xFF000000 & n) >>> 24, r: (0xFF0000 & n) >>> 16,g: (0xFF00 & n) >>> 8,b: 0xFF & n}; 123 124 var size = 50; 125 var canvas = document.createElement('canvas'); 126 canvas.width = canvas.height = size; 127 128 var ctx = canvas.getContext('2d'); 129 ctx.fillStyle = util.Color.toRgba(color, true); 130 ctx.fillRect(0, 0, size, size); 131 var imgData = ctx.getImageData(0, 0, size, size), 132 numPixels = Math.round( intensity * Math.pow(size, 2) ); 133 134 n = parseInt('0x' + color2); 135 var noiseArgb = {a: (0xFF000000 & n) >>> 24, r: (0xFF0000 & n) >>> 16,g: (0xFF00 & n) >>> 8,b: 0xFF & n}; 136 137 // Add color to random pixels in the canvas 138 while (numPixels--) { // Read about the double bitwise NOT trick here: goo.gl/6DPpt 139 var x = ~~(Math.random()*canvas.width), 140 y = ~~(Math.random()*canvas.height), 141 index = (x + y * imgData.width) * 4; 142 143 var op = Math.random() * opacity * noiseArgb.a/255; 144 imgData.data[index] = ~~(argb.r*(1-op) + noiseArgb.r*op);//R 145 imgData.data[index+1] = ~~(argb.g*(1-op) + noiseArgb.g*op);//G 146 imgData.data[index+2] = ~~(argb.b*(1-op) + noiseArgb.b*op);//B 147 } 148 149 ctx.putImageData(imgData, 0, 0); 150 return canvas.toDataURL('image/png'); 151 }; 152 153 154 util.round4 = function (n) { 155 return Math.round(n * 10000) / 10000; 156 }; 157 158 // ----------------------------------------------------------------------- 159 // Drawing on canvas 160 // ----------------------------------------------------------------------- 161 util.Drawing = { 162 163 drawStar: function(g, x, y, points, 164 innerRadiusX, 165 innerRadiusY, 166 outerRadiusX, 167 outerRadiusY, 168 angle) 169 { 170 var count = Math.abs(points); 171 172 if (count > 2) 173 { 174 var step = (Math.PI * 2) / points; 175 var halfStep = step / 2; 176 177 var startAngle = (angle / 180) * Math.PI; 178 g.moveTo(x + (Math.cos(startAngle) * outerRadiusX), y - (Math.sin(startAngle) * outerRadiusY)); 179 180 var dx; 181 var dy; 182 183 // draw lines 184 for (var n = 1; n <= count; n++) 185 {
186 dx = x + Math.cos(startAngle + (step * n) - halfStep) * innerRadiusX; 187 dy = y - Math.sin(startAngle + (step * n) - halfStep) * innerRadiusY; 188 g.lineTo(dx, dy); 189 dx = x + Math.cos(startAngle + (step * n)) * outerRadiusX; 190 dy = y - Math.sin(startAngle + (step * n)) * outerRadiusY; 191 g.lineTo(dx, dy); 192 } 193 } 194 }, //end drawStar 195 196 drawBurst : function(g, x, y, sides, innerRadiusX, innerRadiusY, outerRadiusX, outerRadiusY, angle) 197 { 198 if (sides < 3) return; 199 200 var step = (Math.PI * 2) / sides; 201 var halfStep = step / 2; 202 var qtrStep = step / 4; 203 var start = (angle / 180) * Math.PI; 204 g.moveTo(x + (Math.cos(start) * outerRadiusX), y - (Math.sin(start) * outerRadiusY)); 205 206 var cx; 207 var cy; 208 var dx; 209 var dy; 210 211 for (var n = 1; n <= sides; n++) 212 { 213 cx = x + Math.cos(start + (step * n) - (qtrStep * 3)) * (innerRadiusX / Math.cos(qtrStep)); 214 cy = y - Math.sin(start + (step * n) - (qtrStep * 3)) * (innerRadiusY / Math.cos(qtrStep)); 215 dx = x + Math.cos(start + (step * n) - halfStep) * innerRadiusX; 216 dy = y - Math.sin(start + (step * n) - halfStep) * innerRadiusY; 217 g.curveTo(cx, cy, dx, dy);
218 cx = x + Math.cos(start + (step * n) - qtrStep) * (innerRadiusX / Math.cos(qtrStep)); 219 cy = y - Math.sin(start + (step * n) - qtrStep) * (innerRadiusY / Math.cos(qtrStep)); 220 dx = x + Math.cos(start + (step * n)) * outerRadiusX; 221 dy = y - Math.sin(start + (step * n)) * outerRadiusY; 222 g.curveTo(cx, cy, dx, dy); 223 } 224 }, //end draw burst 225 226 drawArc : function(g, x, y, radiusX, radiusY, arc, startAngle) 227 { 228 g.moveTo(x, y); 229 if (Math.abs(arc)>360) 230 arc = 360; 231 var segs = Math.ceil(Math.abs(arc) / 45); 232 233 var segAngle = arc / segs; 234 235 var theta = -(segAngle / 180) * Math.PI; 236 var angle = -(startAngle / 180) * Math.PI; 237 var ax = x - Math.cos(angle) * radiusX; 238 var ay = y - Math.sin(angle) * radiusY; 239 if (segs > 0) 240 { 241 var angleMid; 242 var bx; 243 var by; 244 var cx; 245 var cy; 246 for (var i = 0; i < segs; i++) 247 { 248 angle += theta; 249 angleMid = angle - (theta / 2); 250 bx = ax + Math.cos(angle) * radiusX; 251 by = ay + Math.sin(angle) * radiusY; 252 cx = ax + Math.cos(angleMid) * (radiusX / Math.cos(theta / 2)); 253 cy = ay + Math.sin(angleMid) * (radiusY / Math.cos(theta / 2)); 254 g.curveTo(cx, cy, bx, by); 255 } 256 } 257 //return new Point(bx, by); 258 }, //end drawArc 259 260 drawWedge : function (g, x, y, startAngle, arc, radiusX, radiusY) 261 { 262 g.moveTo(x, y); 263 if (arguments.length == 6) radiusY = radiusX; 264 var segAngle, theta, angle, angleMid, segs, ax, ay, bx, by, cx, cy; 265 if (Math.abs(arc) > 360) arc = 360; 266 segs = Math.ceil(Math.abs(arc) / 45); 267 segAngle = arc / segs; 268 theta = -(segAngle / 180) * Math.PI; 269 angle = -(startAngle / 180) * Math.PI; 270 if (segs > 0) 271 {
272 ax = x + Math.cos(startAngle / 180 * Math.PI) * radiusX; 273 ay = y + Math.sin(-startAngle / 180 * Math.PI) * radiusY; 274 g.lineTo(ax, ay); 275 for (var i = 0; i < segs; i++) 276 { 277 angle += theta; 278 angleMid = angle - (theta / 2); 279 bx = x + Math.cos(angle) * radiusX; 280 by = y + Math.sin(angle) * radiusY; 281 cx = x + Math.cos(angleMid) * (radiusX / Math.cos(theta / 2)); 282 cy = y + Math.sin(angleMid) * (radiusY / Math.cos(theta / 2)); 283 g.curveTo(cx, cy, bx, by); 284 } 285 // close the wedge by drawing a line to the center 286 g.lineTo(x, y); 287 } 288 }, //end drawWedge 289 290 drawPoly: function(g, x, y, sides, radiusX, radiusY, angle) 291 { 292 var count = Math.abs(sides); 293 if (count > 2) 294 { 295 var step, startAngle, dx, dy; 296 step = (Math.PI * 2) / sides; 297 startAngle = (angle / 180) * Math.PI; 298 g.moveTo(x + (Math.cos(startAngle) * radiusX), y - (Math.sin(startAngle) * radiusY)); 299 for (var n = 1; n <= count; n++) 300 { 301 dx = x + Math.cos(startAngle + (step * n)) * radiusX; 302 dy = y - Math.sin(startAngle + (step * n)) * radiusY; 303 g.lineTo(dx, dy); 304 } 305 } 306 }, //end drawPoly 307 308 drawGear : function (g, x, y, sides, 309 innerRadiusX, 310 innerRadiusY, 311 outerRadiusX, 312 outerRadiusY, 313 angle, 314 holeSides, 315 holeRadiusX, 316 holeRadiusY) 317 { 318 sides = Math.round(sides); 319 holeSides = Math.round(holeSides); 320 if (sides > 2) 321 { 322 // init vars 323 var step; 324 var qtrStep; 325 var startAngle; 326 var dx; 327 var dy; 328 329 step = (Math.PI * 2) / sides; 330 qtrStep = step / 4; 331 332 startAngle = (angle / 180) * Math.PI; 333 g.moveTo(x + (Math.cos(startAngle) * outerRadiusX), y - (Math.sin(startAngle) * outerRadiusY)); 334 335 // draw lines 336 for (var n = 1; n <= sides; n++) 337 {
338 dx = x + Math.cos(startAngle + (step * n) - (qtrStep * 3)) * innerRadiusX; 339 dy = y - Math.sin(startAngle + (step * n) - (qtrStep * 3)) * innerRadiusY; 340 g.lineTo(dx, dy); 341 dx = x + Math.cos(startAngle + (step * n) - (qtrStep * 2)) * innerRadiusX; 342 dy = y - Math.sin(startAngle + (step * n) - (qtrStep * 2)) * innerRadiusY; 343 g.lineTo(dx, dy); 344 dx = x + Math.cos(startAngle + (step * n) - qtrStep) * outerRadiusX; 345 dy = y - Math.sin(startAngle + (step * n) - qtrStep) * outerRadiusY; 346 g.lineTo(dx, dy); 347 dx = x + Math.cos(startAngle + (step * n)) * outerRadiusX; 348 dy = y - Math.sin(startAngle + (step * n)) * outerRadiusY; 349 g.lineTo(dx, dy); 350 } 351 352 if (holeSides > 2) 353 { 354 if(!holeRadiusX) 355 holeRadiusX = innerRadiusX / 3; 356 357 if(!holeRadiusY) 358 holeRadiusY = innerRadiusY / 3; 359 360 step = (Math.PI * 2) / holeSides; 361 g.moveTo(x + (Math.cos(startAngle) * holeRadiusX), y - (Math.sin(startAngle) * holeRadiusY)); 362 for (var m = holeSides; m >= 1; m--) 363 {
364 dx = x + Math.cos(startAngle + (step * m)) * holeRadiusX; 365 dy = y - Math.sin(startAngle + (step * m)) * holeRadiusY; 366 g.lineTo(dx, dy); 367 } 368 } 369 } 370 },//end drawGear 371 372 drawDonut: function(g, x, y, 373 innerRadiusX, 374 innerRadiusY, 375 outerRadiusX, 376 outerRadiusY) { 377 g.ctx.arc(x, y, outerRadiusX, 0, 2 * Math.PI); 378 g.ctx.arc(x, y, innerRadiusX, 0, 2 * Math.PI, 1); 379 380 }, //end drawDonut 381 drawMask: function(g, type, ox, oy, osx, osy, ix, iy, isx, isy) { 382 shapes = type.split('-'); 383 g.drawShape(shapes[0], ox, oy, osx, osy, false); 384 g.drawShape(shapes[1], ix, iy, isx, isy, true); 385 } //end drawFrame 386 387 }; 388 389 // ----------------------------------------------------------------------- 390 // Color functions 391 // ----------------------------------------------------------------------- 392 (function() { 393 394 var Color = CB5.Color = util.Color = {}; 395 396 /*private*/ 397 function any2rgb(c) { 398 if (/^rgba/.test(c)) { 399 var a = c.substr(5).substr(0, c.length-6).split(','); 400 return [Number(a[0]), Number(a[1]), Number(a[2]), Number(a[3])]; 401 } 402 if (/^rgb\(/.test(c)) { 403 var a = c.slice(4, -1).split(','); 404 return [Number(a[0]), Number(a[1]), Number(a[2]), 1]; 405 } 406 return any2rgb(Color.toRgba(c)); 407 } 408 Color.toArray = function (c) { 409 return any2rgb(c); 410 }; 411 Color.toRgba = function (ahex, pad0es) { 412 if (!ahex) return('rgba(0,0,0,0)'); 413 if (typeof ahex == 'number') 414 ahex = ('00000000' + ahex.toString(16)).slice(-8); 415 if (ahex.slice(0,3) == 'rgb') return Color.toRgba(Color.toAHEX(ahex)); 416 if(ahex.charAt(0)=='#') ahex = ahex.substr(1); 417 if (pad0es && ahex.length < 8) ahex = ('00000000'+ahex).substr(-8); 418 if (ahex.length == 6) ahex = 'ff' + ahex; 419 if (ahex.length != 8) return('rgba(0,0,0,0)'); 420 return 'rgba('+ 421 parseInt('0x' + ahex.substr(2, 2)) + ',' + 422 parseInt('0x' + ahex.substr(4, 2)) + ',' + 423 parseInt('0x' + ahex.substr(6, 2)) + ',' + 424 Math.round(parseInt('0x' + ahex.substr(0, 2))/2.55)/100 + ')'; 425 }; 426 Color.toAHEX = function (any) { 427 var a = any2rgb(any); 428 return hex2(a[3]*255) + hex2(a[0]) + hex2(a[1]) + hex2(a[2]); 429 }; 430 Color.mixColors = mixColors; 431 function mixColors(c1, c2, p, outFormat) { 432 var v1 = any2rgb(c1); 433 var v2 = any2rgb(c2); 434 var v3 = [v1[0]*p+v2[0]*(1-p), v1[1]*p+v2[1]*(1-p), v1[2]*p+v2[2]*(1-p), v1[3]*p+v2[3]*(1-p)]; 435 if (outFormat == 'uhex') 436 return hex2(v3[3]*255) + hex2(v3[0]) + hex2(v3[1]) + hex2(v3[2]); 437 return 'rgba('+Math.round(v3[0])+','+Math.round(v3[1])+','+Math.round(v3[2])+','+v3[3]+')'; 438 } 439 440 function hex2(v) { 441 return ('00' + Math.round(v).toString(16)).substr(-2); 442 } 443 444 Color.pad0 = function (color) { 445 return ('00000000' + color).substr(-8); 446 }; 447 Color.getAlpha = function (rgba) { 448 return parseFloat(rgba.substr(rgba.lastIndexOf(',')+1)); 449 }; 450 })(); 451 452 453 454})(); 455 456 457 458 459 460(function () { 461// ----------------------------------------------------------------------- 462// PACKAGE GEOM 463// ----------------------------------------------------------------------- 464 var debug = self.console ? console[console.debug ? 'debug' : 'log'].bind(console) : $.noop; 465 466 var geom = {}; 467 var Class = CB5.util.Class; 468 CB5.util.geom = geom; 469 470 /** @class */ 471 geom.Point = Class.extend({ 472 x: 0, y: 0, 473 /** @constructs */ 474 init: function (x, y) { 475 if (arguments.length == 0) return; 476 this.x = Number(x); 477 this.y = Number(y); 478 }, 479 /** 480 * @returns {geom.Point} 481 */ 482 clone: function () { 483 return new geom.Point(this.x, this.y); 484 }, 485 put: function (x, y) { 486 this.x = x; 487 this.y = y; 488 }, 489 /** 490 * @param {geom.Point} p 491 * @returns {geom.Point} new Point 492 */ 493 subtract: function (p) { 494 this.x -= p.x; 495 this.y -= p.y; 496 return this; 497 }, 498 add: function (p) { 499 this.x += p.x; 500 this.y += p.y; 501 return this; 502 }, 503 scale: function (c) { 504 this.x *= c; 505 this.y *= c; 506 return this; 507 }, 508 size: function () { 509 return Math.sqrt(this.x*this.x + this.y*this.y); 510 }, 511 limit: function (minX, minY, maxX, maxY) { 512 this.x = Math.max(minX, Math.min(maxX, this.x)); 513 this.y = Math.max(minY, Math.min(maxY, this.y)); 514 return this; 515 }, 516 toString: function () { 517 return '(' + this.x + ',' + this.y + ')'; 518 } 519 }); 520 521 /** @class */ 522 geom.Matrix = Class.extend({ 523 a: 1, b: 0, c: 0, d: 1, tx: 0, ty: 0, 524 /** @constructs 525 * @param {String=} data 526 */ 527 init: function (data) { 528 if (arguments.length == 0) return; 529 if (arguments.length > 3) { 530 this.a = Number(arguments[0]); 531 this.b = Number(arguments[1]); 532 this.c = Number(arguments[2]); 533 this.d = Number(arguments[3]); 534 if (arguments[4]) this.tx = Number(arguments[4]); 535 if (arguments[5]) this.ty = Number(arguments[5]); 536 return; 537 } 538 var a = data.split(','); 539 this.a = Number(a[0]); 540 this.b = Number(a[1]); 541 this.c = Number(a[2]); 542 this.d = Number(a[3]); 543 this.tx = Number(a[4]); 544 this.ty = Number(a[5]); 545 }, 546 547 /** @returns geom.Matrix */ 548 invert: function () { 549 var det = this.a * this.d - this.b * this.c; 550 var tx = this.tx, a = this.a; 551 this.tx = (this.c * this.ty - this.d * tx) / det; 552 this.ty = (this.b * tx - this.a * this.ty) / det; 553 554 this.a = this.d / det; 555 this.b = -this.b / det; 556 this.c = -this.c / det; 557 this.d = a / det; 558 return this; 559 }, 560 561 /** @param {geom.Point} p 562 * @returns geom.Point */ 563 transformPoint: function (p) { 564 var x = p.x, y = p.y; 565 p.x = this.a * x + this.c * y + this.tx; 566 p.y = this.b * x + this.d * y + this.ty; 567 return p; 568 }, 569 570 /** 571 * @return {geom.Matrix} 572 */ 573 normalize: function () { 574 var len = Math.sqrt(this.a * this.a + this.b * this.b); 575 this.a /= len; 576 this.b /= len; 577 len = Math.sqrt(this.c * this.c + this.d * this.d); 578 this.c /= len; 579 this.d /= len; 580 return this; 581 }, 582 583 isUnit: function () { 584 return this.a == 1 && this.b == 0 && this.c == 0 && this.d == 1; 585 }, 586 587 round4: function () { 588 this.a = Math.round(this.a * 10000) / 10000; 589 this.b = Math.round(this.b * 10000) / 10000; 590 this.c = Math.round(this.c * 10000) / 10000; 591 this.d = Math.round(this.d * 10000) / 10000; 592 this.tx = Math.round(this.tx * 10000) / 10000; 593 this.ty = Math.round(this.ty * 10000) / 10000; 594 return this; 595 }, 596 597 /** 598 * @param {geom.Matrix} m 599 * @return {geom.Matrix} 600 */ 601 concat: function (m) { 602 var a = this.a, 603 b = this.b, 604 c = this.c, 605 d = this.d, 606 tx = this.tx; 607 this.a = m.a * a + m.c * b; 608 this.b = m.b * a + m.d * b; 609 this.c = m.a * c + m.c * d; 610 this.d = m.b * c + m.d * d; 611 this.tx = m.tx + m.c * this.ty + m.a * tx; 612 this.ty = m.ty + m.d * this.ty + m.b * tx; 613 return this; 614 }, 615 616 /** 617 * Applies delta matrix in place 618 * @param {geom.Matrix} delta 619 * @param {geom.Matrix} space 620 * @returns {geom.Matrix} 621 */ 622 applyDelta: function (delta, space) { 623 return this.concat(space.clone().invert()).concat(delta).concat(space); 624 }, 625 626 scale: function (sx, sy, noTranslate) { 627 if (arguments.length == 0) { 628 return new geom.Point( 629 Math.sqrt(this.a * this.a + this.b * this.b), 630 Math.sqrt(this.c * this.c + this.d * this.d)); 631 }
632 if (arguments.length == 1) sy = sx; 633 this.a *= sx; 634 this.b *= sy; 635 this.c *= sx; 636 this.d *= sy; 637 if (!noTranslate) { 638 this.tx *= sx; 639 this.ty *= sy; 640 } 641 return this; 642 }, 643 644 rotate: function (rad) { 645 var m = new geom.Matrix(); 646 m.a = Math.cos(rad); 647 m.c = -Math.sin(rad); 648 m.b = Math.sin(rad); 649 m.d = Math.cos(rad); 650 this.concat(m); 651 return this; 652 }, 653 654 /** @returns geom.Matrix */ 655 translate: function (tx, ty) { 656 this.tx += Number(tx); 657 this.ty += Number(ty); 658 return this; 659 }, 660 661 put: function (tx, ty) { 662 this.tx = tx; 663 this.ty = ty; 664 return this; 665 }, 666 667 pos: function () { 668 return new geom.Point(this.tx, this.ty); 669 }, 670 671 /** @param {Number=} d */ 672 getWidth: function (d) { 673 if (d == null) d = 100; 674 return Math.sqrt(this.a * this.a + this.b * this.b) * d; 675 }, 676 677 /** @param {Number=} d */ 678 getHeight: function (d) { 679 if (d == null) d = 100; 680 return Math.sqrt(this.c * this.c + this.d * this.d) * d; 681 }, 682 683 setHeight: function (h) { 684 var delta = new geom.Matrix(); 685 delta.d = h / this.getHeight(); 686 return this.copy(delta.concat(this)); 687 }, 688 689 setWidth: function (w) { 690 var delta = new geom.Matrix(); 691 delta.a = w / this.getWidth(); 692 return this.copy(delta.concat(this)); 693 }, 694 695 /** 696 * @return {geom.Matrix} 697 */ 698 clone: function () { 699 return new geom.Matrix(this.serialize()); 700 }, 701 702 copy: function (m) { 703 this.a = m.a; 704 this.b = m.b; 705 this.c = m.c; 706 this.d = m.d; 707 this.tx = m.tx; 708 this.ty = m.ty; 709 return this; 710 }, 711 712 serialize: function () { 713 this.a = Math.round(this.a*1e10)/1e10; 714 this.b = Math.round(this.b*1e10)/1e10; 715 this.c = Math.round(this.c*1e10)/1e10; 716 this.d = Math.round(this.d*1e10)/1e10; 717 this.tx = Math.round(this.tx*1e10)/1e10; 718 this.ty = Math.round(this.ty*1e10)/1e10; 719 return [this.a, this.b, this.c, this.d, this.tx, this.ty].join(','); 720 }, 721 722 toString: function () { 723 return '[' + this.serialize() + ']'; 724 }, 725 726 equals: function (m) { 727 return Math.abs(m.a - this.a) < 1e-4 && 728 Math.abs(m.b - this.b) < 1e-4 && 729 Math.abs(m.c - this.c) < 1e-4 && 730 Math.abs(m.d - this.d) < 1e-4 && 731 Math.abs(m.tx - this.tx) < 1e-4 && 732 Math.abs(m.ty - this.ty) < 1e-4; 733 } 734 735 736 }); 737 738 geom.Rectangle = Class.extend({ 739 left: 0, 740 top: 0, 741 right: 0, 742 bottom: 0, 743 /** @constructs */ 744 init: function (left, top, right, bottom) { 745 if (arguments.length == 0) return; 746 if (arguments.length == 1) { 747 var rect = left; 748 this.left = rect.left; 749 this.top = rect.top; 750 this.right = rect.right; 751 this.bottom = rect.bottom; 752 return; 753 } 754 this.left = Math.min(left, right); 755 this.top = Math.min(top, bottom); 756 this.right = Math.max(left, right); 757 this.bottom = Math.max(top, bottom); 758 }, 759 clone: function () { 760 return new geom.Rectangle(this.left, this.top, this.right, this.bottom); 761 }, 762 scale: function (p) { 763 this.left *= p.x; 764 this.top *= p.y; 765 this.right *= p.x; 766 this.bottom *= p.y; 767 return this; 768 }, 769 width: function () { 770 return this.right - this.left; 771 }, 772 height: function () { 773 return this.bottom - this.top; 774 }, 775 /** contains rectangle or point */ 776 contains: function (r) { 777 if ('bottom' in r) 778 return this.left < r.left && this.top < r.top && this.right > r.right && this.bottom > r.bottom; 779 return r.x > this.left && r.y > this.top && r.x < this.right && r.y < this.bottom; 780 }, 781 restrict: function (r) { 782 if (this.left < r.left) this.left = r.left; 783 if (this.top < r.top) this.top = r.top; 784 if (this.left > r.right - 1) this.left = r.right - 1; 785 if (this.top > r.bottom - 1) this.top = r.bottom - 1; 786 if (this.bottom > r.bottom) this.bottom = r.bottom; 787 if (this.right > r.right) this.right = r.right; 788 if (this.bottom < r.top + 1) this.bottom = r.top + 1; 789 if (this.right < r.left + 1) this.right = r.left + 1; 790 }, 791 extend: function (rect) { 792 this.left > rect.left && (this.left = rect.left); 793 this.top > rect.top && (this.top = rect.top); 794 this.right < rect.right && (this.right = rect.right); 795 this.bottom < rect.bottom && (this.bottom = rect.bottom); 796 }, 797 extendP: function (p) { 798 this.left > p.x && (this.left = p.x); 799 this.top > p.y && (this.top = p.y); 800 this.right < p.x && (this.right = p.x); 801 this.bottom < p.y && (this.bottom = p.y); 802 }, 803 translate: function (dx, dy) { 804 this.left += dx; 805 this.top += dy; 806 this.right += dx; 807 this.bottom += dy; 808 }, 809 css: function () { 810 return {left: this.left, top: this.top, width: this.right - this.left, height: this.bottom - this.top}; 811 }, 812 toString: function () { 813 return '[geom.Rectangle ' + [this.left, this.top, this.right, this.bottom] + ']'; 814 } 815 }); 816
817 var util = CB5.util; 818 $.fn.matrix = function (m) { 819 if (arguments.length == 0) { 820 var sm = this.css('transform'); 821 if (sm && sm.indexOf('matrix') == 0) { 822 sm = sm.substring(sm.indexOf('(') + 1, sm.indexOf(')')); 823 m = new geom.Matrix(sm); 824 } else 825 m = new geom.Matrix(); 826 var top = parseFloat(this.css('top')); 827 if (!isNaN(top)) { 828 m.ty += top; 829 m.tx += parseFloat(this.css('left')); 830 } 831 return m; 832 } 833 834 m = m.clone().round4(); 835 836 this.css('transform-origin', '0px 0px'); 837 if (m.isUnit()) { 838 this.css({top: m.ty, left: m.tx}); 839 this.css('transform', ''); 840 } else { 841 var str = 'matrix(' + m.a + ',' + m.b + ',' + m.c + ',' + m.d + ',' + m.tx + ',' + m.ty + ')'; 842 this.css({top: '', left: ''}); 843 this.css({transform: str}); 844 } 845 }; 846 847 /** @returns {geom.Point} */ 848 util.getEventPosition = function(evt) { 849 if (evt.originalEvent) evt = evt.originalEvent; 850 var t = evt.changedTouches || evt.touches; 851 t = t ? t[0] : evt; 852 var zoom = document.body.style.zoom ? parseFloat(document.body.style.zoom) : 1; 853 return new geom.Point(t.pageX/zoom, t.pageY/zoom); 854 }; 855 856 /** 857 * $.parseParams - parse query string paramaters into an object. 858 */ 859 (function() { 860 var re = /([^&=]+)=?([^&]*)/g; 861 var decodeRE = /\+/g; // Regex for replacing addition symbol with a space 862 var decode = function (str) {return decodeURIComponent( str.replace(decodeRE, " ") );}; 863 util.parseParams = function(query) { 864 var params = {}, e; 865 while ( e = re.exec(query) ) { 866 var k = decode( e[1] ), v = decode( e[2] ); 867 if (k.substring(k.length - 2) === '[]') { 868 k = k.substring(0, k.length - 2); 869 (params[k] || (params[k] = [])).push(v); 870 } 871 else params[k] = v; 872 } 873 return params; 874 }; 875 })(); 876 877 878 $.fn.cbDraggable = function (opts) { 879 var $me = this, y0, y; 880 opts = $.extend({ 881 dir: 'y',//or x 882 max: 10000, 883 min: -10000, 884 drag: $.noop, 885 stop: $.noop, 886 cancel: null, 887 linkMul: 1, 888 id:'', 889 preventDefault: true 890 }, opts); 891 892 var css = opts.dir == 'y' ? 'top' : 'left'; 893 var moved = false; 894 895 var p0; 896 var lastY = 0; 897 898 $me.on('mousedown touchstart', function (e) { 899 opts.preventDefault && e.preventDefault(); 900 if (opts.cancel && $(e.target).is(opts.cancel)) return; 901 p0 = util.getEventPosition(e); 902 y0 = parseInt($me.css(css)) - p0[opts.dir]; 903 $(self).on('mousemove.cb-drag touchmove.cb-drag', move).on('mouseup.cb-drag touchend.cb-drag', up); 904 $me.addClass('dragging'); 905 moved = false; 906 }); 907 908 var dy = 0;//parseInt(self.getComputedStyle($me[0]).marginTop); 909 910 function move(e) { 911 opts.preventDefault && e.preventDefault(); 912 var p = util.getEventPosition(e); 913 y = Math.max(Math.min(y0 + p[opts.dir], opts.max-dy), opts.min-dy); 914 $me.attr('data-drag-dir', y > lastY ? '1' : '0'); 915 lastY = y; 916 $me.css(css, y + 'px'); 917 $me.find('> .drag-value').text(y*opts.linkMul); 918 //return false in drag to cancel drag 919 var ret = opts.drag(y+dy, p.subtract(p0)); 920 moved = true; 921 if (ret === false) up(); 922 } 923 function up(e) { 924 $(self).off('.cb-drag'); 925 $me.removeClass('dragging'); 926 if (e && !moved && opts.click) opts.click(); 927 if (!e || !moved) return; 928 opts.stop(y+dy, opts.id); 929 } 930 }; 931 932 933 function noiseFill(color, color2, intensity, opacity) { 934 935 var n = parseInt('0x' + color); 936 var argb = {a: (0xFF000000 & n) >>> 24, r: (0xFF0000 & n) >>> 16,g: (0xFF00 & n) >>> 8,b: 0xFF & n}; 937 938 var size = 50; 939 var canvas = document.createElement('canvas'); 940 canvas.width = canvas.height = size; 941 942 var ctx = canvas.getContext('2d'); 943 ctx.fillStyle = util.Color.toRgba(color, true); 944 ctx.fillRect(0, 0, size, size); 945 var imgData = ctx.getImageData(0, 0, size, size), 946 numPixels = Math.round( intensity * Math.pow(size, 2) )//, maxAlpha = 255 * opacity; 947 948 var n = parseInt('0x' + color2); 949 var noiseArgb = {a: (0xFF000000 & n) >>> 24, r: (0xFF0000 & n) >>> 16,g: (0xFF00 & n) >>> 8,b: 0xFF & n}; 950 951 // Add color to random pixels in the canvas 952 while (numPixels--) { // Read about the double bitwise NOT trick here: goo.gl/6DPpt 953 var x = ~~(Math.random()*canvas.width), 954 y = ~~(Math.random()*canvas.height), 955 index = (x + y * imgData.width) * 4; 956 957 var op = Math.random() * opacity * noiseArgb.a/255; 958 imgData.data[index] = ~~(argb.r*(1-op) + noiseArgb.r*op);//R 959 imgData.data[index+1] = ~~(argb.g*(1-op) + noiseArgb.g*op);//G 960 imgData.data[index+2] = ~~(argb.b*(1-op) + noiseArgb.b*op);//B 961 } 962 963 ctx.putImageData(imgData, 0, 0); 964 return canvas.toDataURL('image/png'); 965 } 966 967 968 util.fillStyleCss = function (style) { 969 var css = []; 970 function gradStops() { 971 var aStops = []; 972 var colors = []; 973 var ratios = style.ratios; 974 var aColors = style.colors; 975 for (var i=0; i<aColors.length; i++) { 976 var color = util.Color.toRgba(aColors[i], true); 977 colors.push(color); 978 var pos = Math.round(ratios[i]/255*100*10000)/10000; 979 aStops.push(color + ' ' + pos + '%'); 980 } 981 return aStops.join(','); 982 } 983 984 if (style.type == 'solid') 985 css.push({background: util.Color.toRgba(style.color, true)}); 986 else if (style.type == 'linear') { 987 var rot = Number(style.rotation); 988 var angle = -Math.round(rot / Math.PI * 180); 989 var stdAngle = 90 - angle; 990 css.push({background: 'linear-gradient('+stdAngle+'deg, '+gradStops()+')'}); 991 } else if (style.type == 'bitmap') { 992 var repeat = style.repeat == 'fill' ? 'no-repeat' : style.repeat; 993 var align = style.align ? style.align : 'center top'; 994 var color = style.solid ? util.Color.toRgba(style.solid, true) : '';
995 css.push({background: color + ' url(' + CB5.getRealPath(style.src) + ') ' + align + ' ' + repeat}); 996 css.push({'background-size': style.repeat == 'fill' ? 'cover' : 'auto'}); 997 } else if (style.type == 'radial') { 998 var pos = (Number(style.translatex)+.5)*100 + '% ' + (Number(style.translatey)+.5)*100 + '%'; 999 var stops = gradStops(); 1000 css.push({background: 'radial-gradient(ellipse farthest-side at '+pos+','+stops+')'}); 1001 css.push({background: '-moz-radial-gradient('+pos+',ellipse farthest-side,'+stops+')'}); 1002 css.push({background: '-webkit-radial-gradient('+pos+',ellipse farthest-side,'+stops+')'}); 1003 } else if (style.type == 'none') { 1004 css.push({background: 'none'}); 1005 } else if (style.type == 'noise') { 1006 css.push({background: 'url('+noiseFill(style.color, style.color2, style.intensity, style.opacity)+')'}); 1007 } else 1008 debug('unimplemented fill:', style); 1009 return css; 1010 }; 1011 1012 1013 $.fn.fillStyle = function (style) { 1014 util.fillStyleCss(style).forEach(this.css, this); 1015 return this; 1016 }; 1017 1018 util.lineStyleCss = function (data) { 1019 if (!data) return []; 1020 var a = (typeof data == 'string') ? data.split(',') : data; 1021 var lineWidth = a[1]; 1022 var lineColor = a[0]; 1023 return [{border: 'solid ' + util.Color.toRgba(lineColor, true) + ' ' + Math.round(lineWidth) + 'px'}]; 1024 }; 1025 1026 util.cssFromList = function (list) { 1027 return list.map(function (css) { 1028 return Object.keys(css).map(function (name) { 1029 return '\t'+name.replace(/([a-z])([A-Z])/g, '$1-$2').toLowerCase() + ': ' + css[name] + ';'; 1030 }).join('\n'); 1031 }).join('\n'); 1032 }; 1033 1034 $.fn.lineStyle = function (data) { 1035 util.lineStyleCss(data).forEach(this.css, this); 1036 return this; 1037 }; 1038 1039 util.filterCss = function (filter, isText) { 1040 if (!filter) return []; 1041 return filter.map(function (param) { 1042 1043 if (param.type == 'dropShadow') { 1044 //debug(print_r($data,1)); 1045 var ds = param.distance; 1046 var dx = Math.round(ds * Math.cos(param.angle / 180 * Math.PI)); 1047 var dy = Math.round(ds * Math.sin(param.angle / 180 * Math.PI)); 1048 var blur = param.blur; 1049 1050 var hex = Number(param.color).toString(16); 1051 if (param.strength) { 1052 if (isText) param.strength *= 0.6; 1053 hex = ('000000' + hex).slice(-6); 1054 hex = Math.round(param.strength * 255).toString(16) + hex; 1055 } 1056 var colorCss = util.Color.toRgba(hex); 1057 1058 var shadow = dx+'px '+dy+'px '+blur+'px '+colorCss; 1059 if (isText) return {textShadow: shadow}; 1060 return {'-moz-box-shadow':shadow, '-webkit-box-shadow':shadow, boxShadow:shadow}; 1061 } 1062 1063 if (param.type == 'glow') { 1064 var blur = param.x; 1065 var spread = param.x; 1066 var strength = param.strength/2; 1067 var color = util.Color.toRgba(Number(param.color).toString(16)); 1068 var a = color.slice(5, -1).split(','); 1069 a[3] = strength; 1070 color = 'rgba(' + a.join(',') + ')'; 1071 1072 var shadow = '0px 0px '+blur+'px '+spread+'px ' + color; 1073 return {'-moz-box-shadow':shadow, '-webkit-box-shadow':shadow, boxShadow:shadow}; 1074 } 1075 debug('unknown filter: '+param.type); 1076 return {}; 1077 }); 1078 }; 1079 1080 util.drawMenuButton = function ($cnv) { 1081 var sz = $cnv.width(); 1082 var m = sz/4; 1083 var l = (sz - 2*m) / 5; 1084 var ctx = $cnv[0].getContext('2d'); 1085 ctx.fillStyle = '#ffffff'; 1086 ctx.rect(m, m, sz-2*m, l); 1087 ctx.rect(m, m+2*l, sz-2*m, l); 1088 ctx.rect(m, m+4*l, sz-2*m, l); 1089 ctx.fill(); 1090 }; 1091 1092 /* HTML building */ 1093 var html = { 1094 img: function (src) { return $('<img/>').attr('src', src); }, 1095 div: function (clazz) { return clazz ? $('<div/>').addClass(clazz) : $('<div/>'); }, 1096 span: function (clazz) { return clazz ? $('<span/>').addClass(clazz) : $('<span/>'); }, 1097 table: function () { return $('<table/>'); }, 1098 tr: function () {return $('<tr/>'); }, 1099 th: function () {return $('<th/>'); }, 1100 td: function () {return $('<td/>'); }, 1101 a: function () {return $('<a/>'); }, 1102 input: function (type) {return $('<input/>').attr('type', type?type:'text'); }, 1103 mark: function() {return html.div().css({background:'red', width:10, height:10, position: 'absolute'});}, 1104 vcenter: function ($content) { 1105 return html.table().height('100%').width('100%') 1106 .append(html.td().css('vertical-align','middle').append($content)); 1107 }, 1108 colorIcon: function () {return $('<div class="color-icon"><div></div></div>')}, 1109 option: function (text, value) { 1110 var ret = $('<option/>').text(text); 1111 if (arguments.length == 2) ret.val(value); 1112 return ret; 1113 }, 1114 loading: function () {return html.div('loading').css('display','inline-block')}, 1115 iframe: function (src) { return $('<iframe/>').attr('src', src); } 1116 }; 1117 util.html = html; 1118
1119 util.buildMobileNavBar = function (mobiNav, mobiFooter, navHeight, template, colors, titleCss, navCss) { 1120 var $titleBar = mobiNav.find('> .titleBar'); 1121 $titleBar.attr('class').split(/\s+/).forEach(function (cls) { 1122 if (cls.substr(0, 8) == 'template') $titleBar.removeClass(cls); 1123 }); 1124 $titleBar.css({ 1125 height: navHeight 1126 }).find('.titleH').css(titleCss); 1127 $titleBar.addClass(template); 1128 var $paneTogg = mobiNav.find('> canvas').attr({width:navHeight, height:navHeight}).addClass('naviPaneTogg'); 1129 1130 mobiNav.css({ 1131 'background-color': util.Color.toRgba(colors.navigationBackground) 1132 //color: util.Color.toRgba(colors.navigationText) 1133 }).find('.item,a').css(navCss); 1134 1135 mobiFooter.css({ 1136 padding: 10, 1137 'text-align': 'center', 1138 'background-color': util.Color.toRgba(colors.navigationBackground) 1139 }); 1140 1141 mobiFooter.find('a').css({ 1142 //color: util.Color.toRgba(colors.navigationText), 1143 'text-decoration': 'none' 1144 }).css(navCss); 1145 1146 1147 util.drawMenuButton($paneTogg); 1148 }; 1149 1150 util.wrapElement = function ($el) { 1151 if (!$el.parent().is('.cb-effects')) { 1152 $el.wrap($('<div class="cb-effects"/>')); 1153 $el.parent().css('visibility', $el.css('visibility')); 1154 $el.css('visibility', ''); 1155 } 1156 }; 1157 1158 util.pickFile = function (hnd, multiple, images) { 1159 var $file = $('<input type="file">'); 1160 if (images) $file.attr('accept', 'image/png, image/x-png, image/gif, image/jpeg'); 1161 if (multiple) $file.attr('multiple', true); 1162 $file.on('change', function () { 1163 if (this.files.length == 0) return; 1164 hnd(multiple ? this.files : this.files[0]); 1165 }); 1166 $file.trigger('click'); 1167 } 1168})(); 1169 1170//LINK ACTIONS 1171(function () { 1172 1173 //hide elements that will be shown by links 1174 $(function () { 1175 var prefix = 'javascript:CB5.action_showhide('; 1176 $('a[href]').each(function () { 1177 var href = $(this).attr('href'); 1178 if (href.slice(0, prefix.length) === prefix) { 1179 var ids = JSON.parse(href.slice(prefix.length, -1)).show; 1180 ids.forEach(function (id) { 1181 getEl(id).css({visibility:'hidden'}); 1182 }); 1183 } 1184 }); 1185 }); 1186 1187 //Element Show/Hide 1188 CB5.action_showhide = function (o) { 1189 o.hide.forEach(function (id) { 1190 getEl(id).animate({opacity: 0}); 1191 }); 1192 o.show.forEach(function (id) { 1193 getEl(id).css({visibility:'visible', opacity:0}).animate({opacity:1}); 1194 }); 1195 } 1196 1197 function getEl(id, b) { 1198 var $el = $('#'+id); 1199 if ($el.parent().is('.cb-effects')) 1200 $el = $el.parent(); 1201 return $el; 1202 } 1203 1204 1205 //Show mobile 1206 CB5.action_mobile = function () { 1207 top.location = '?full=0&mobile=1'; 1208 }; 1209 //submit form 1210 CB5.action_submit = function () { 1211 $('.cb-form').last().submit(); 1212 }; 1213 1214 CB5.action_scroll = function (id) { 1215 $('#'+id+',#m_'+id).scrollintoview(); 1216 history.pushState(null, '', '#'+id); 1217 } 1218 1219})(); 1220 1221//Image effects: reflection, ... 1222(function () { 1223 var util = CB5.util; 1224 1225 //Effects, now with Pixastic 1226 util.Filter = { 1227 'do': function (canvas, action, options) { 1228 if (action == 'blur' && typeof blurCanvas != 'undefined') { 1229 blurCanvas(canvas, options.amount); 1230 return; 1231 } 1232 1233 options.resultCanvas = canvas; 1234 options.leaveDOM = true; 1235 if (typeof Pixastic != 'undefined') 1236 Pixastic.process(canvas, action, options); 1237 } 1238 }; 1239 1240 CB5.ImageEffects = { 1241 //TODO separate reflection from filters 1242 render: function ($img, matrix, filterData, reflectionData) { 1243 var $cnv; 1244 var filters = []; 1245 if (filterData) { 1246 filterData.split(',').forEach(function (str) { 1247 var p = util.parseParams(str); 1248 if (p.type == 'dropShadow' || p.type == 'glow') return; 1249 filters.push(p); 1250 }, this); 1251 } 1252 1253 if (!filters.length && !reflectionData) return; 1254 $img.wrap('<div class="cb-effects"/>'); 1255 1256 if (reflectionData) { 1257 var p = util.parseParams(reflectionData); 1258 $cnv = $('<canvas style="position:absolute"/>'); 1259 var b = $img[0].getBoundingClientRect(); 1260 var m = matrix.clone(); 1261 m.ty += b.height + b.height * p.y / 100; 1262 $cnv.matrix(m); 1263 1264 $img.before($cnv); 1265 this._reflection($img[0], $cnv, p); 1266 } 1267 if (filters.length) { 1268 $cnv = $('<canvas style="position:absolute"/>') 1269 .attr({width: $img[0].naturalWidth, height: $img[0].naturalHeight}); 1270 $cnv.matrix(matrix); 1271 $img.before($cnv); 1272 $img.css({opacity: 0}); 1273
1274 filters.forEach(function (p) { 1275 if (!this.hasOwnProperty('_' + p.type)) { 1276 sb.debug('no such filter: ' + p.type, $img[0]); 1277 return; 1278 } 1279 this['_' + p.type]($img, $cnv, p); 1280 }, this); 1281 } 1282 }, 1283 1284 addTint: function($img, matrix, tintData, elId) { 1285 if (!tintData) return; 1286 var $cnv = $('<canvas style="position:absolute;z-index: 100"/>').addClass('cbel cb-tint'); 1287 if(elId) { 1288 $('.colorTint-'+elId).remove(); 1289 $cnv.addClass('colorTint-'+elId); 1290 } 1291 var m = matrix.clone(); 1292 $img.before($cnv); 1293 $cnv.matrix(m); 1294 var w = $img[0].naturalWidth, h = $img[0].naturalHeight; 1295 $cnv.attr({width: w, height: h}); 1296 var ctx = $cnv[0].getContext('2d'); 1297 ctx.fillStyle = ''+tintData; 1298 ctx.fillRect(0, 0 , w, h); 1299 }, 1300 1301 _blur: function ($img, $cnv, p) { 1302 var ctx = $cnv[0].getContext('2d'); 1303 ctx.drawImage($img[0], 0, 0); 1304 util.Filter.do($cnv[0], 'blur', {amount: p.x}); 1305 }, 1306 1307 _sharpen: function ($img, $cnv, p) { 1308 var ctx = $cnv[0].getContext('2d'); 1309 ctx.drawImage($img[0], 0, 0); 1310 util.Filter.do($cnv[0], 'sharpen', {amount: p.multiply / 100}); 1311 }, 1312 1313 _colorMatrix: function ($img, $cnv, p) { 1314 var ctx = $cnv[0].getContext('2d'); 1315 ctx.drawImage($img[0], 0, 0); 1316 if (p.hue != 0 || p.saturation != 0) 1317 util.Filter.do($cnv[0], 'hsl', {hue: p.hue, saturation: p.saturation}); 1318 if (p.contrast != 0 || p.brightness != 0) 1319 util.Filter.do($cnv[0], 'brightness', {brightness: p.brightness, contrast: p.contrast / 100}) 1320 }, 1321 1322 _emboss: function ($img, $cnv, p) { 1323 var ctx = $cnv[0].getContext('2d'); 1324 ctx.drawImage($img[0], 0, 0); 1325 util.Filter.do($cnv[0], 'emboss', {strength: p.multiply / 100 * 2, blend: true, greyLevel: 0}) 1326 }, 1327 1328 _reflection: function (img, $cnv, p) { 1329 1330 var w = img.naturalWidth, h = img.naturalHeight; 1331 $cnv.attr({width: w, height: h}); 1332 1333 //sb.debug(p) 1334 var ctx = $cnv[0].getContext('2d'); 1335 1336 var g = ctx.createLinearGradient(0, 0, 0, h);
1337 [[0, 1], [0.2, 0.3], [0.3, 0.2], [1, 0]].forEach(function (a) { 1338 //var alpha = Math.pow(a[1],1-Math.pow(p.strength,4)); 1339 var alpha = a[1] * p.strength + Math.pow(p.strength, 6); 1340 //sb.debug(alpha, a[1]*p.strength, Math.pow(p.strength,6)) 1341 g.addColorStop(a[0], 'rgba(0,0,0,' + alpha + ')'); 1342 }); 1343 ctx.fillStyle = g; 1344 ctx.fillRect(0, 0, w, h); 1345 1346 ctx.globalCompositeOperation = 'source-in'; 1347 ctx.save(); 1348 ctx.transform(1, 0, 0, -1, 0, h); 1349 ctx.drawImage(img, 0, 0); 1350 ctx.restore(); 1351 1352 //blurCanvas($reflection[0], p.blur); 1353 util.Filter.do($cnv[0], 'blur', {amount: p.blur}); 1354 } 1355 }; 1356 1357 $.fn.isInViewport = function () { 1358 var el = this[0], s = false; 1359 if (!el) return; 1360 if (this.css('display') == 'none') { 1361 this.css({display: 'block', visibility:'hidden'}); 1362 s = true; 1363 } 1364 var rect = el.getBoundingClientRect(); 1365 if (s) this.css({display: 'none', visibility:'visible'}); 1366 return rect.top < $(window).height() && rect.left < $(window).width(); 1367 } 1368})();
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.