├── README.md ├── css ├── .DS_Store ├── base.css └── reset.css ├── docs.html ├── images ├── .DS_Store ├── attasi-logo.png ├── black-left-panel.svg ├── cover-1.png ├── cover-2.png ├── cover-3.png ├── cover-4.png ├── cover-5.png ├── cover-6.png ├── crane │ ├── .DS_Store │ ├── base-a.svg │ ├── base-b.svg │ ├── body-a.svg │ ├── body-b.svg │ ├── head-a.svg │ ├── neck-a.svg │ ├── tail-a.svg │ ├── tail-b.svg │ ├── wing-a.svg │ ├── wing-b.svg │ ├── wing-c.svg │ └── wing-d.svg ├── download-arrow.png ├── example-thumbs.png ├── map-2.png ├── map-cover.png ├── map.png ├── texture-2.png ├── texture.png └── toggle-button.png ├── index.html └── js ├── .DS_Store ├── base.js ├── jquery-1.7.1.min.js ├── modernizr.js ├── photon.js └── photon.min.js /README.md: -------------------------------------------------------------------------------- 1 | photon 2 | ====== 3 | 4 | CSS 3D Lighting Engine 5 | 6 | http://photon.attasi.com -------------------------------------------------------------------------------- /css/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thomasxiii/photon/a81364a90fd2dee765dbf204b54f761541bfe07a/css/.DS_Store -------------------------------------------------------------------------------- /css/base.css: -------------------------------------------------------------------------------- 1 | @charset "UTF-8"; 2 | /* CSS Document */ 3 | 4 | 5 | html, body, .scene { 6 | height: 100%; 7 | min-height: 600px; 8 | } 9 | 10 | body { 11 | font-family: 'museo-sans-1','museo-sans-2', sans-serif; 12 | font-weight: 500; 13 | font-size: 15px; 14 | line-height: 22px; 15 | color: #fff; 16 | background: #000; 17 | overflow-x: hidden; 18 | } 19 | 20 | a { 21 | text-decoration: none; 22 | } 23 | 24 | 25 | 26 | 27 | 28 | /*--------------------------------- 29 | 30 | Primary Nav 31 | 32 | ---------------------------------*/ 33 | 34 | .primary-menu { 35 | position: fixed; 36 | top: 30px; 37 | left: 30px; 38 | z-index: 9999; 39 | } 40 | 41 | h1 { 42 | margin-bottom: 3px; 43 | font-weight: 900; 44 | font-size: 26px; 45 | color: #ff0; 46 | text-transform: uppercase; 47 | } 48 | 49 | h2 { 50 | position: relative; 51 | padding-bottom: 6px; 52 | margin-bottom: 20px; 53 | font-weight: 900; 54 | text-transform: uppercase; 55 | } 56 | 57 | h2:after { 58 | content: ''; 59 | position: absolute; 60 | bottom: 0; 61 | left: 0; 62 | width: 50px; 63 | height: 1px; 64 | background: #fff; 65 | } 66 | 67 | .primary-menu a { 68 | display: block; 69 | float: left; 70 | clear: both; 71 | color: #999; 72 | -webkit-transition: color .2s; 73 | -moz-transition: color .2s; 74 | -ms-transition: color .2s; 75 | -o-transition: color .2s; 76 | transition: color .2s; 77 | } 78 | 79 | .primary-menu .download-btn { 80 | margin-top: 20px; 81 | padding: 6px 18px 9px 41px; 82 | background: url(../images/download-arrow.png) no-repeat 13px 11px #ff0; 83 | color: #000; 84 | border-radius: 2px; 85 | } 86 | 87 | .primary-menu .download-btn:hover { 88 | color: #000; 89 | } 90 | 91 | .primary-menu a:hover { 92 | color: #fff; 93 | } 94 | 95 | .primary-menu a.current { 96 | color: #fff; 97 | } 98 | 99 | .attasi { 100 | position: fixed; 101 | bottom: 30px; 102 | left: 30px; 103 | z-index: 9999; 104 | font-size: 11px; 105 | color: #fff; 106 | } 107 | 108 | .attasi a { 109 | display: block; 110 | color: #fff; 111 | line-height: 16px; 112 | -webkit-transition: color .3s; 113 | -moz-transition: color .3s; 114 | -ms-transition: color .3s; 115 | -o-transition: color .3s; 116 | transition: color .3s; 117 | } 118 | 119 | .attasi a:hover { 120 | color: #ff0; 121 | } 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | /*--------------------------------- 130 | 131 | Light Toggle 132 | 133 | ---------------------------------*/ 134 | 135 | .toggle { 136 | position: absolute; 137 | top: 50%; 138 | left: 50%; 139 | z-index: 9999; 140 | margin-top: 200px; 141 | margin-left: -115px; 142 | width: 270px; 143 | height: 70px; 144 | } 145 | 146 | .toggle a { 147 | display: block; 148 | float: left; 149 | color: #464646; 150 | line-height: 70px; 151 | } 152 | 153 | .toggle .label-on.current { 154 | color: #ff0; 155 | } 156 | 157 | .toggle .label-off.current { 158 | color: #7f7f7f; 159 | } 160 | 161 | .toggle-btn { 162 | width: 70px; 163 | height: 70px; 164 | margin: 0 10px; 165 | background: url(../images/toggle-button.png) no-repeat; 166 | background-position: 0 0; 167 | text-indent: 100%; 168 | overflow: hidden; 169 | } 170 | 171 | .toggle-btn.on { 172 | background-position: 0 -70px; 173 | } 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | /*--------------------------------- 182 | 183 | Example Menu 184 | 185 | ---------------------------------*/ 186 | 187 | .example-menu { 188 | position: absolute; 189 | top: 30px; 190 | right: 30px; 191 | z-index: 9999; 192 | } 193 | 194 | .example-menu li { 195 | float: left; 196 | margin-left: 10px; 197 | } 198 | 199 | .example-menu a { 200 | display: block; 201 | width: 132px; 202 | height: 87px; 203 | background: url(../images/example-thumbs.png) no-repeat rgba(0, 0, 0, .7); 204 | text-indent: 100%; 205 | overflow: hidden; 206 | border: 1px solid #555; 207 | -webkit-transition: border-color .2s; 208 | -moz-transition: border-color .2s; 209 | -ms-transition: border-color .2s; 210 | -o-transition: border-color .2s; 211 | transition: border-color .2s; 212 | } 213 | 214 | .example-menu a:hover { 215 | border-color: #fff; 216 | } 217 | 218 | .example-menu a.current { 219 | background: url(../images/example-thumbs.png) no-repeat rgba(128, 128, 128, .4); 220 | border-color: #ff0; 221 | } 222 | 223 | .example-menu a.current:hover { 224 | border-color: #ff0; 225 | } 226 | 227 | .example-menu a.crane-thumb { 228 | background-position: 0 0; 229 | } 230 | 231 | .example-menu a.crane-thumb:hover { 232 | background-position: 0 -87px; 233 | } 234 | 235 | .example-menu a.coverflow-thumb { 236 | background-position: -132px 0; 237 | } 238 | 239 | .example-menu a.coverflow-thumb:hover { 240 | background-position: -132px -87px; 241 | } 242 | 243 | .example-menu a.map-thumb { 244 | background-position: -264px 0; 245 | } 246 | 247 | .example-menu a.map-thumb:hover { 248 | background-position: -264px -87px; 249 | } 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | /*--------------------------------- 258 | 259 | Scene 260 | 261 | ---------------------------------*/ 262 | 263 | .scene { 264 | position: absolute; 265 | top: 0; 266 | left: 0; 267 | z-index: 0; 268 | width: 100%; 269 | height: 100%; 270 | -webkit-perspective: 1000px; 271 | -moz-perspective: 1000px; 272 | -ms-perspective: 1000px; 273 | -o-perspective: 1000px; 274 | perspective: 1000px; 275 | -webkit-transform-style: preserve-3d; 276 | -moz-transform-style: preserve-3d; 277 | -ms-transform-style: preserve-3d; 278 | -o-transform-style: preserve-3d; 279 | transform-style: preserve-3d; 280 | } 281 | 282 | .coverflow, 283 | .map { 284 | display: none; 285 | } 286 | 287 | 288 | 289 | 290 | 291 | 292 | 293 | 294 | 295 | 296 | /*--------------------------------- 297 | 298 | Crane 299 | 300 | ---------------------------------*/ 301 | 302 | .crane { 303 | position: absolute; 304 | top: 50%; 305 | left: 50%; 306 | margin-top: 50px; 307 | -webkit-transform-style: preserve-3d; 308 | -webkit-transform: rotateX(-15deg) rotateY(-42deg); 309 | } 310 | 311 | 312 | .crane .face { 313 | position: absolute; 314 | background: url(../images/texture-2.png) #ff0; 315 | } 316 | 317 | 318 | .crane .wing-1a { 319 | width: 132px; 320 | height: 346px; 321 | -webkit-mask: url(../images/crane/wing-a.svg) no-repeat; 322 | -webkit-transform-origin: bottom right; 323 | -webkit-transform: translate3d(-131px, -346px, -60px) rotateX(50deg) rotateY(10deg); 324 | } 325 | 326 | .crane .wing-1b { 327 | width: 132px; 328 | height: 346px; 329 | -webkit-mask: url(../images/crane/wing-b.svg) no-repeat; 330 | -webkit-transform-origin: bottom left; 331 | -webkit-transform: translate3d(0, -346px, -60px) rotateX(50deg) rotateY(-10deg); 332 | } 333 | 334 | .crane .wing-1c { 335 | width: 132px; 336 | height: 105px; 337 | -webkit-mask: url(../images/crane/wing-c.svg) no-repeat; 338 | -webkit-transform-origin: bottom left; 339 | -webkit-transform: translate3d(-128px, -22px, -34px) rotateY(6deg) rotateX(9deg); 340 | } 341 | 342 | .crane .wing-1d { 343 | width: 132px; 344 | height: 105px; 345 | -webkit-mask: url(../images/crane/wing-d.svg) no-repeat; 346 | -webkit-transform-origin: bottom right; 347 | -webkit-transform: translate3d(-1px, -22px, -34px) rotateY(-6deg) rotateX(9deg); 348 | } 349 | 350 | .crane .wing-2a { 351 | width: 132px; 352 | height: 346px; 353 | -webkit-mask: url(../images/crane/wing-a.svg) no-repeat; 354 | -webkit-transform-origin: bottom right; 355 | -webkit-transform: translate3d(-131px, -346px, 60px) rotateX(-50deg) rotateY(-10deg); 356 | } 357 | 358 | .crane .wing-2b { 359 | width: 132px; 360 | height: 346px; 361 | -webkit-mask: url(../images/crane/wing-b.svg) no-repeat; 362 | -webkit-transform-origin: bottom left; 363 | -webkit-transform: translate3d(0, -346px, 60px) rotateX(-50deg) rotateY(10deg); 364 | } 365 | 366 | .crane .wing-2c { 367 | width: 132px; 368 | height: 105px; 369 | -webkit-mask: url(../images/crane/wing-c.svg) no-repeat; 370 | -webkit-transform-origin: bottom left; 371 | -webkit-transform: translate3d(-128px, -22px, 34px) rotateY(-6deg) rotateX(-9deg); 372 | } 373 | 374 | .crane .wing-2d { 375 | width: 132px; 376 | height: 105px; 377 | -webkit-mask: url(../images/crane/wing-d.svg) no-repeat; 378 | -webkit-transform-origin: bottom right; 379 | -webkit-transform: translate3d(-1px, -22px, 34px) rotateY(6deg) rotateX(-9deg); 380 | } 381 | 382 | .crane .body-1a { 383 | width: 132px; 384 | height: 246px; 385 | -webkit-mask: url(../images/crane/body-a.svg) no-repeat; 386 | -webkit-transform-origin: bottom right; 387 | -webkit-transform: translate3d(-130px, -163px, 0) rotateY(15deg); 388 | } 389 | 390 | .crane .body-1b { 391 | width: 132px; 392 | height: 246px; 393 | -webkit-mask: url(../images/crane/body-b.svg) no-repeat; 394 | -webkit-transform-origin: bottom left; 395 | -webkit-transform: translate3d(0, -163px, 0) rotateY(-15deg); 396 | } 397 | 398 | .crane .body-1c { 399 | width: 132px; 400 | height: 246px; 401 | -webkit-mask: url(../images/crane/body-a.svg) no-repeat; 402 | -webkit-transform-origin: bottom right; 403 | -webkit-transform: translate3d(-130px, -163px, 0) rotateY(-15deg); 404 | } 405 | 406 | .crane .body-1d { 407 | width: 132px; 408 | height: 246px; 409 | -webkit-mask: url(../images/crane/body-b.svg) no-repeat; 410 | -webkit-transform-origin: bottom left; 411 | -webkit-transform: translate3d(0, -163px, 0) rotateY(15deg); 412 | } 413 | 414 | .crane .neck-a { 415 | width: 230px; 416 | height: 277px; 417 | -webkit-mask: url(../images/crane/neck-a.svg) no-repeat; 418 | -webkit-transform-origin: bottom left; 419 | -webkit-transform: translate3d(-1px, -194px, 7px) rotateY(-12deg) rotateX(11deg); 420 | } 421 | 422 | .crane .neck-b { 423 | width: 230px; 424 | height: 277px; 425 | -webkit-mask: url(../images/crane/neck-a.svg) no-repeat; 426 | -webkit-transform-origin: bottom left; 427 | -webkit-transform: translate3d(-1px, -194px, -7px) rotateY(12deg) rotateX(-11deg); 428 | } 429 | 430 | .crane .head-a { 431 | width: 95px; 432 | height: 35px; 433 | -webkit-mask: url(../images/crane/head-a.svg) no-repeat; 434 | -webkit-transform-origin: bottom left; 435 | -webkit-transform: translate3d(208px, -188px, -4px) rotateX(-8.5deg) rotateY(-2deg) rotateY(-1deg); 436 | } 437 | 438 | .crane .head-b { 439 | width: 95px; 440 | height: 35px; 441 | -webkit-mask: url(../images/crane/head-a.svg) no-repeat; 442 | -webkit-transform-origin: bottom left; 443 | -webkit-transform: translate3d(208px, -188px, 2px) rotateX(8.5deg) rotateY(1deg); 444 | } 445 | 446 | .crane .tail-a { 447 | width: 127px; 448 | height: 397px; 449 | -webkit-mask: url(../images/crane/tail-b.svg) no-repeat; 450 | -webkit-transform-origin: bottom left; 451 | -webkit-transform: translate3d(-90px, -269px, 33px) rotateY(12.5deg) rotateX(9.45deg) rotateZ(-37deg); 452 | } 453 | 454 | .crane .tail-b { 455 | width: 127px; 456 | height: 397px; 457 | -webkit-mask: url(../images/crane/tail-b.svg) no-repeat; 458 | -webkit-transform-origin: bottom left; 459 | -webkit-transform: translate3d(-90px, -269px, -34px) rotateY(-12.5deg) rotateX(-9.45deg) rotateZ(-37deg); 460 | } 461 | 462 | .crane .base-a { 463 | width: 172px; 464 | height: 61px; 465 | -webkit-mask: url(../images/crane/base-a.svg) no-repeat; 466 | -webkit-transform-origin: bottom left; 467 | -webkit-transform: translate3d(-2px, -8px, 1px) rotateX(90deg) rotateY(12deg); 468 | } 469 | 470 | .crane .base-b { 471 | width: 172px; 472 | height: 61px; 473 | -webkit-mask: url(../images/crane/base-a.svg) no-repeat; 474 | -webkit-transform-origin: bottom left; 475 | -webkit-transform: translate3d(-2px, -8px, -1px) rotateX(90deg) rotateY(12deg) rotateX(180deg); 476 | } 477 | 478 | .crane .base-c { 479 | width: 172px; 480 | height: 61px; 481 | -webkit-mask: url(../images/crane/base-a.svg) no-repeat; 482 | -webkit-transform-origin: bottom left; 483 | -webkit-transform: translate3d(-2px, -8px, 1px) rotateX(90deg) rotateY(12deg) rotateY(180deg); 484 | } 485 | 486 | .crane .base-d { 487 | width: 172px; 488 | height: 61px; 489 | -webkit-mask: url(../images/crane/base-a.svg) no-repeat; 490 | -webkit-transform-origin: bottom left; 491 | -webkit-transform: translate3d(-2px, -8px, 1px) rotateX(90deg) rotateY(12deg) rotateY(180deg) rotateX(180deg); 492 | } 493 | 494 | .crane .base-e { 495 | width: 22px; 496 | height: 107px; 497 | -webkit-mask: url(../images/crane/base-b.svg) no-repeat; 498 | -webkit-transform-origin: bottom left; 499 | -webkit-transform: translate3d(130px, -23px, 52px) rotateY(90deg) rotateX(5deg); 500 | } 501 | 502 | .crane .base-f { 503 | width: 22px; 504 | height: 107px; 505 | -webkit-mask: url(../images/crane/base-b.svg) no-repeat; 506 | -webkit-transform-origin: bottom left; 507 | -webkit-transform: translate3d(130px, -23px, -52px) rotateY(-90deg) rotateX(-5deg); 508 | } 509 | 510 | .crane .base-g { 511 | width: 22px; 512 | height: 107px; 513 | -webkit-mask: url(../images/crane/base-b.svg) no-repeat; 514 | -webkit-transform-origin: bottom left; 515 | -webkit-transform: translate3d(-128px, -23px, 52px) rotateY(90deg) rotateX(-5deg); 516 | } 517 | 518 | .crane .base-h { 519 | width: 22px; 520 | height: 107px; 521 | -webkit-mask: url(../images/crane/base-b.svg) no-repeat; 522 | -webkit-transform-origin: bottom left; 523 | -webkit-transform: translate3d(-128px, -23px, -52px) rotateY(-90deg) rotateX(5deg); 524 | } 525 | 526 | 527 | 528 | 529 | 530 | 531 | 532 | 533 | 534 | /*--------------------------------- 535 | 536 | Coverflow 537 | 538 | ---------------------------------*/ 539 | 540 | .coverflow { 541 | position: absolute; 542 | top: 0; 543 | left: 0; 544 | z-index: 0; 545 | width: 100%; 546 | height: 100%; 547 | -webkit-transform-style: preserve-3d; 548 | -moz-transform-style: preserve-3d; 549 | -ms-transform-style: preserve-3d; 550 | -o-transform-style: preserve-3d; 551 | transform-style: preserve-3d; 552 | } 553 | 554 | .coverflow li { 555 | position: absolute; 556 | left: 50%; 557 | top: 50%; 558 | z-index: 100; 559 | width: 400px; 560 | height: 400px; 561 | margin-left: -200px; 562 | margin-top: -250px; 563 | -webkit-transition: -webkit-transform .3s; 564 | -moz-transition: -moz-transform .3s; 565 | -ms-transition: -ms-transform .3s; 566 | -o-transition: -o-transform .3s; 567 | transition: transform .3s; 568 | pointer-events: none; 569 | } 570 | 571 | 572 | 573 | 574 | 575 | 576 | 577 | 578 | 579 | /*--------------------------------- 580 | 581 | Map 582 | 583 | ---------------------------------*/ 584 | 585 | .map { 586 | position: absolute; 587 | top: 50%; 588 | left: 50%; 589 | -webkit-transform-style: preserve-3d; 590 | -moz-transform-style: preserve-3d; 591 | -ms-transform-style: preserve-3d; 592 | -o-transform-style: preserve-3d; 593 | transform-style: preserve-3d; 594 | -webkit-transform: rotateX(10deg) rotateY(30deg) rotateZ(0); 595 | -moz-transform: rotateX(10deg) rotateY(30deg) rotateZ(0); 596 | -ms-transform: rotateX(10deg) rotateY(30deg) rotateZ(0); 597 | -o-transform: rotateX(10deg) rotateY(30deg) rotateZ(0); 598 | transform: rotateX(10deg) rotateY(30deg) rotateZ(0); 599 | } 600 | 601 | .panel-1, 602 | .panel-2, 603 | .panel-3 { 604 | position: absolute; 605 | top: -230px; 606 | width: 240px; 607 | height: 400px; 608 | background: url(../images/map.png) no-repeat; 609 | } 610 | 611 | .panel-1 { 612 | left: -360px; 613 | background-position: 0 0; 614 | -webkit-transform-origin: right; 615 | -moz-transform-origin: right; 616 | -ms-transform-origin: right; 617 | -o-transform-origin: right; 618 | transform-origin: right; 619 | -webkit-transform: rotateY(178deg); 620 | -moz-transform: rotateY(178deg); 621 | -ms-transform: rotateY(178deg); 622 | -o-transform: rotateY(178deg); 623 | transform: rotateY(178deg); 624 | } 625 | 626 | .map-cover { 627 | position: absolute; 628 | top: -230px; 629 | left: -360px; 630 | width: 240px; 631 | height: 400px; 632 | background: url(../images/map-cover.png) no-repeat; 633 | -webkit-transform-origin: right; 634 | -moz-transform-origin: right; 635 | -ms-transform-origin: right; 636 | -o-transform-origin: right; 637 | transform-origin: right; 638 | -webkit-transform: rotateY(178deg) translateZ(-2px) rotateY(180deg) translateX(240px); 639 | -moz-transform: rotateY(178deg) translateZ(-2px) rotateY(180deg) translateX(240px); 640 | -ms-transform: rotateY(178deg) translateZ(-2px) rotateY(180deg) translateX(240px); 641 | -o-transform: rotateY(178deg) translateZ(-2px) rotateY(180deg) translateX(240px); 642 | transform: rotateY(178deg) translateZ(-2px) rotateY(180deg) translateX(240px); 643 | } 644 | 645 | .map.is-open .panel-1 { 646 | -webkit-transform: rotateY(60deg); 647 | -moz-transform: rotateY(60deg); 648 | -ms-transform: rotateY(60deg); 649 | -o-transform: rotateY(60deg); 650 | transform: rotateY(60deg); 651 | } 652 | 653 | .panel-2 { 654 | left: -120px; 655 | background-position: -240px 0; 656 | } 657 | 658 | .panel-3 { 659 | left: 120px; 660 | background-position: -480px 0; 661 | -webkit-transform-origin: left; 662 | -moz-transform-origin: left; 663 | -ms-transform-origin: left; 664 | -o-transform-origin: left; 665 | transform-origin: left; 666 | -webkit-transform: rotateY(178deg); 667 | -moz-transform: rotateY(178deg); 668 | -ms-transform: rotateY(178deg); 669 | -o-transform: rotateY(178deg); 670 | transform: rotateY(178deg); 671 | } 672 | 673 | .map.is-open .panel-3 { 674 | -webkit-transform: rotateY(60deg); 675 | -moz-transform: rotateY(60deg); 676 | -ms-transform: rotateY(60deg); 677 | -o-transform: rotateY(60deg); 678 | transform: rotateY(60deg); 679 | } 680 | 681 | 682 | 683 | 684 | 685 | 686 | 687 | 688 | 689 | 690 | /*--------------------------------- 691 | 692 | Docs 693 | 694 | ---------------------------------*/ 695 | 696 | .docs-wrapper { 697 | width: 600px; 698 | margin: 30px 30px 30px 300px; 699 | padding-bottom: 60px; 700 | } 701 | 702 | .docs-wrapper a { 703 | color: #ff0; 704 | } 705 | 706 | .docs-wrapper > section { 707 | margin-bottom: 88px; 708 | } 709 | 710 | .docs-wrapper > section > section { 711 | margin-bottom: 60px; 712 | } 713 | 714 | h3 { 715 | margin: 0 0 16px -20px; 716 | font-weight: 900; 717 | font-size: 25px; 718 | color: #ff0; 719 | } 720 | 721 | h4 { 722 | margin: 24px 0 16px 0; 723 | padding-bottom: 3px; 724 | font-weight: 900; 725 | font-size: 16px; 726 | color: #fff; 727 | text-transform: uppercase; 728 | border-bottom: 2px solid #fff; 729 | } 730 | 731 | pre { 732 | margin: 16px 0; 733 | padding: 10px; 734 | border-radius: 2px; 735 | background: #333; 736 | } 737 | 738 | pre .comment { 739 | color: #777; 740 | } 741 | 742 | pre .var { 743 | color: #8de3fc; 744 | } 745 | 746 | pre .keyword { 747 | color: #dd668d; 748 | } 749 | 750 | pre .num, 751 | pre .boolean { 752 | color: #b370ff; 753 | } 754 | 755 | pre .string { 756 | color: #84d041; 757 | } 758 | 759 | code { 760 | padding: 1px 4px; 761 | border-radius: 2px; 762 | font-family: Monaco, monospace; 763 | font-size: 14px; 764 | color: #fff; 765 | background: #333; 766 | } 767 | 768 | pre code { 769 | background: none; 770 | } 771 | 772 | dt { 773 | margin-bottom: 10px; 774 | } 775 | 776 | dt code { 777 | font-size: 15px; 778 | } 779 | 780 | dt em { 781 | font-size: 15px; 782 | color: #666; 783 | } 784 | 785 | dd { 786 | margin-bottom: 48px; 787 | } 788 | 789 | .library dt code { 790 | background: #ff0; 791 | color: #000; 792 | } 793 | 794 | .property-list { 795 | margin: 24px 0 0 48px; 796 | font-size: 13px; 797 | } 798 | 799 | .property-list dd { 800 | margin: 0 0 24px 16px; 801 | line-height: 18px; 802 | } 803 | 804 | .property-list dt { 805 | clear: both; 806 | margin: 0 16px 0 0; 807 | } 808 | 809 | .property-list dt em { 810 | font-size: 13px; 811 | } 812 | 813 | .property-list dt code { 814 | margin-right: 3px; 815 | background: #333; 816 | font-size: 13px; 817 | color: #ff0; 818 | } 819 | 820 | .property-list dd code { 821 | font-size: 13px; 822 | } 823 | 824 | 825 | 826 | 827 | 828 | 829 | 830 | 831 | 832 | 833 | 834 | 835 | 836 | -------------------------------------------------------------------------------- /css/reset.css: -------------------------------------------------------------------------------- 1 | @charset "UTF-8"; 2 | /* CSS Document */ 3 | 4 | html, body, div, span, applet, object, iframe, 5 | h1, h2, h3, h4, h5, h6, p, blockquote, pre, 6 | a, abbr, acronym, address, big, cite, code, 7 | del, dfn, em, font, img, ins, kbd, q, s, samp, 8 | small, strike, strong, sub, sup, tt, var, 9 | dl, dt, dd, ol, ul, li, 10 | fieldset, form, label, legend, 11 | table, caption, tbody, tfoot, thead, tr, th, td { 12 | margin: 0; 13 | padding: 0; 14 | border: 0; 15 | outline: 0; 16 | font-weight: inherit; 17 | font-style: inherit; 18 | font-size: 100%; 19 | font-family: inherit; 20 | vertical-align: baseline; 21 | } 22 | /* remember to define focus styles! */ 23 | :focus { 24 | outline: 0; 25 | } 26 | body { 27 | line-height: 1; 28 | color: black; 29 | background: white; 30 | } 31 | ol, ul { 32 | list-style: none; 33 | } 34 | /* tables still need 'cellspacing="0"' in the markup */ 35 | table { 36 | border-collapse: separate; 37 | border-spacing: 0; 38 | } 39 | caption, th, td { 40 | text-align: left; 41 | font-weight: normal; 42 | } 43 | blockquote:before, blockquote:after, 44 | q:before, q:after { 45 | content: ""; 46 | } 47 | blockquote, q { 48 | quotes: "" ""; 49 | } 50 | -------------------------------------------------------------------------------- /docs.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Photon | CSS 3D Lighting Engine 7 | 8 | 9 | 10 | 11 | 22 | 23 | 24 | 25 | 35 | 36 |
37 | attasi.com 38 | tom giannattasio 39 | @attasi 40 |
41 | 42 |
43 | 44 |
45 |

Introduction

46 | 47 |

Photon is a JavaScript library that adds simple lighting effects to DOM elements in 3D space. It's rather processor-intensive, so please use responsibly.

48 | 49 |

Contribute

50 |

If you'd like to help, please do so on GitHub or chat me up on twitter.

51 |
52 | 53 |
54 |

Quick Start

55 | 56 |
57 |

Create a Light

58 |

The Light object represents a point in 3D space from which faces are lit.

59 |
// creates a light at x: 0, y: 0, z: 100
 60 | var light = new Photon.Light();
61 |
62 | 63 |
64 |

Define Faces

65 |

Face objects specify which DOM elements should be shaded or tinted by the light.

66 | 67 |
// create a face with a max shade of .5
 68 | var face = new Photon.Face( $('.face-1')[0] );
69 |
70 | 71 |
72 |

Render

73 |

Call the render method on your faces to shade or tint them based on their angle from the specified light.

74 | 75 |
// shade face by its relation to light
 76 | face.render(light, true);
77 |
78 |
79 | 80 |
81 |

Library Reference

82 | 83 |
84 |

Light

85 | 86 |
87 |
Photon.Light( x = 0, y = 0, z = 100 )
constructor
88 |

Creates a new Light object. The default coordinates position the light straight towards the viewport.

89 | 90 |
moveTo( x, y, z )
method
91 |

Moves the light to a new set of coordinates.

92 |
93 |
94 | 95 |
96 |

Face

97 | 98 |
99 |
Photon.Face( element, maxShade = .5, maxTint = 0, isBackfaced = false )
constructor
100 |
101 |

Creates a new Face object. By default, the light will subtly shade each element.

102 | 103 |
104 |
element:object
105 |
106 |

The DOM object to which shading should be applied.

107 |
108 | 109 |
maxShade:float
110 |
111 |

The maximum amount of black that can be added to an element: 0–1.

112 |
113 | 114 |
maxTint:float
115 |
116 |

The maximum amount of white that can be added to an element: 0–1.

117 |
118 | 119 |
isBackfaced:boolean
120 |
121 |

Determines if the backface of the element should be shaded as if it were its own face. Rule of thumb: If the opposite side the element is visible, you probably want to set this to true.

122 |
123 |
124 |
125 | 126 |
render( light, getNewRotations, parentRotations )
method
127 |
128 |

Shades or tints the element based on its angle relative to the Light object. Shades and tints are applied to an empty div within the element with a class of photon-shader.

129 | 130 |
131 |
light :Light
132 |
The Light object to use to calculate shading or tinting.
133 | 134 |
getNewRotations :boolean
135 |
If true, a new rotation vector is calculated before shading is applied. Use this when the element's transform property has changed.
136 | 137 |
parentRotations :object
138 |
The parent object's rotations (x, y and z in radians). These are used primarily for FaceGroup objects.
139 |
140 |
141 | 142 |
setMaxShade( value )
method
143 |
144 |

Sets the maximum shade value: 0–1.

145 | 146 |
147 |
value :float
148 |
149 |
150 | 151 |
setMaxTint( value )
method
152 |
153 |

Sets the maximum tint value: 0–1.

154 | 155 |
156 |
value :float
157 |
158 |
159 |
160 |
161 | 162 |
163 |

FaceGroup

164 |
165 |
Photon.FaceGroup( parent, faces, maxShade = .5, maxTint = 0, isBackfaced = false )
constructor
166 |
167 |

Creates a new FaceGroup object, which allows one call of render to shade multiple faces. It also calculates the rotations of nested elements (i.e., if the parent element is rotated, the calculated rotations of the elements within it will be adjusted accordingly).

168 | 169 |
170 |
parent:object
171 |
172 |

The DOM object containing the faces to be shaded. Note: this element, itself, will not be shaded.

173 |
174 | 175 |
faces:array
176 |
177 |

An array of DOM elements within the parent object, which should be shaded.

178 |
179 | 180 |
maxShade:float
181 |
182 |

The maximum amount of black that can be added to the faces: 0–1.

183 |
184 | 185 |
maxTint:float
186 |
187 |

The maximum amount of white that can be added to the faces: 0–1.

188 |
189 | 190 |
isBackfaced:boolean
191 |
192 |

Determines if the backface of the faces should be shaded as if it were its own face. Rule of thumb: If the opposite side the element is visible, you probably want to set this to true.

193 |
194 |
195 |
196 | 197 |
render( light, getNewGroupRotations, getNewFaceRotations )
method
198 |
199 |

Shades or tints the element based on its angle relative to the Light object. Shades and tints are applied to an empty div within the element with a class of photon-shader.

200 | 201 |
202 |
light :Light
203 |
The Light object to use to calculate shading or tinting.
204 | 205 |
getNewGroupRotations :boolean
206 |
If true, a new rotation vector is calculated for the parent element before shading is applied. The new vector will affect the rotations of all faces. Use this when the parent's transform property has changed.
207 | 208 |
getNewFaceRotations :boolean
209 |
If true, new rotation vectors are calculated for all of the faces. Use this when the transform properties of thefaces have changed.
210 |
211 |
212 | 213 |
setMaxShade( value )
method
214 |
215 |

Sets the maximum shade value: 0–1.

216 | 217 |
218 |
value :float
219 |
220 |
221 | 222 |
setMaxTint( value )
method
223 |
224 |

Sets the maximum tint value: 0–1.

225 | 226 |
227 |
value :float
228 |
229 |
230 |
231 |
232 | 233 |
234 |
235 | 236 | 237 | -------------------------------------------------------------------------------- /images/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thomasxiii/photon/a81364a90fd2dee765dbf204b54f761541bfe07a/images/.DS_Store -------------------------------------------------------------------------------- /images/attasi-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thomasxiii/photon/a81364a90fd2dee765dbf204b54f761541bfe07a/images/attasi-logo.png -------------------------------------------------------------------------------- /images/black-left-panel.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /images/cover-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thomasxiii/photon/a81364a90fd2dee765dbf204b54f761541bfe07a/images/cover-1.png -------------------------------------------------------------------------------- /images/cover-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thomasxiii/photon/a81364a90fd2dee765dbf204b54f761541bfe07a/images/cover-2.png -------------------------------------------------------------------------------- /images/cover-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thomasxiii/photon/a81364a90fd2dee765dbf204b54f761541bfe07a/images/cover-3.png -------------------------------------------------------------------------------- /images/cover-4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thomasxiii/photon/a81364a90fd2dee765dbf204b54f761541bfe07a/images/cover-4.png -------------------------------------------------------------------------------- /images/cover-5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thomasxiii/photon/a81364a90fd2dee765dbf204b54f761541bfe07a/images/cover-5.png -------------------------------------------------------------------------------- /images/cover-6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thomasxiii/photon/a81364a90fd2dee765dbf204b54f761541bfe07a/images/cover-6.png -------------------------------------------------------------------------------- /images/crane/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thomasxiii/photon/a81364a90fd2dee765dbf204b54f761541bfe07a/images/crane/.DS_Store -------------------------------------------------------------------------------- /images/crane/base-a.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /images/crane/base-b.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /images/crane/body-a.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /images/crane/body-b.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /images/crane/head-a.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /images/crane/neck-a.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /images/crane/tail-a.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /images/crane/tail-b.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /images/crane/wing-a.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /images/crane/wing-b.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /images/crane/wing-c.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /images/crane/wing-d.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /images/download-arrow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thomasxiii/photon/a81364a90fd2dee765dbf204b54f761541bfe07a/images/download-arrow.png -------------------------------------------------------------------------------- /images/example-thumbs.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thomasxiii/photon/a81364a90fd2dee765dbf204b54f761541bfe07a/images/example-thumbs.png -------------------------------------------------------------------------------- /images/map-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thomasxiii/photon/a81364a90fd2dee765dbf204b54f761541bfe07a/images/map-2.png -------------------------------------------------------------------------------- /images/map-cover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thomasxiii/photon/a81364a90fd2dee765dbf204b54f761541bfe07a/images/map-cover.png -------------------------------------------------------------------------------- /images/map.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thomasxiii/photon/a81364a90fd2dee765dbf204b54f761541bfe07a/images/map.png -------------------------------------------------------------------------------- /images/texture-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thomasxiii/photon/a81364a90fd2dee765dbf204b54f761541bfe07a/images/texture-2.png -------------------------------------------------------------------------------- /images/texture.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thomasxiii/photon/a81364a90fd2dee765dbf204b54f761541bfe07a/images/texture.png -------------------------------------------------------------------------------- /images/toggle-button.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thomasxiii/photon/a81364a90fd2dee765dbf204b54f761541bfe07a/images/toggle-button.png -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Photon | CSS 3D Lighting Engine 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 26 | 27 | 28 | 29 | 39 | 40 |
41 | attasi.com 42 | tom giannattasio 43 | @attasi 44 |
45 | 46 | 53 | 54 |
55 | photon on 56 | toggle 57 | photon off 58 |
59 | 60 |
61 |
62 |
63 |
64 |
65 |
66 | 67 |
68 |
69 |
70 |
71 | 72 |
73 |
74 |
75 |
76 | 77 |
78 |
79 | 80 |
81 |
82 | 83 |
84 |
85 | 86 |
87 |
88 |
89 |
90 |
91 | 92 | 100 | 101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 | 109 | 110 | -------------------------------------------------------------------------------- /js/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thomasxiii/photon/a81364a90fd2dee765dbf204b54f761541bfe07a/js/.DS_Store -------------------------------------------------------------------------------- /js/base.js: -------------------------------------------------------------------------------- 1 | var $body, 2 | $demos, 3 | $crane, 4 | $map, 5 | $mapPanel1, 6 | $mapPanel2, 7 | $mapPanel3, 8 | $mapCover, 9 | $coverflow, 10 | $toggleBtn, 11 | $toggleOn, 12 | $toggleOff, 13 | crane, 14 | craneFaces, 15 | cubeFaces, 16 | map, 17 | diamondFaces, 18 | coverflowFaces, 19 | shadeAmount, 20 | tintAmount, 21 | light, 22 | currentCover, 23 | renderTimer, 24 | isLit, 25 | domTransformProperty, 26 | cssTransformProperty, 27 | domTransitionProperty, 28 | cssTransitionProperty, 29 | transitionEndEvent, 30 | transitionEndEvents = { 31 | 'WebkitTransition' : 'webkitTransitionEnd', 32 | 'MozTransition' : 'transitionend', 33 | 'OTransition' : 'oTransitionEnd', 34 | 'msTransition' : 'MSTransitionEnd', 35 | 'transition' : 'transitionend' 36 | }; 37 | 38 | 39 | 40 | 41 | 42 | $(document).ready(function() { 43 | $body = $('body'); 44 | $demos = $('.demo'); 45 | light = new Photon.Light(); 46 | shadeAmount = .5; 47 | tintAmount = 0; 48 | coverflowFaces = []; 49 | cubeFaces = []; 50 | diamondFaces = []; 51 | currentCover = 0; 52 | renderCurrent = renderCrane; 53 | $toggleBtn = $('.toggle-btn'); 54 | $toggleOn = $('.toggle .label-on'); 55 | $toggleOff = $('.toggle .label-off'); 56 | isLit = true; 57 | domTransformProperty = Modernizr.prefixed('transform'); 58 | cssTransformProperty = domToCss(domTransformProperty); 59 | domTransitionProperty = Modernizr.prefixed('transition'); 60 | cssTransitionProperty = domToCss(domTransitionProperty); 61 | transitionEndEvent = transitionEndEvents[domTransitionProperty]; 62 | 63 | setupLightControls(); 64 | setupCoverflow(); 65 | setupCrane(); 66 | setupMap(); 67 | 68 | // demo menu 69 | $('.example-menu a').bind('click', onDemoNav); 70 | 71 | if(cssTransformProperty == '-webkit-transform') { 72 | showCrane(); 73 | } else { 74 | $('.map-thumb').click(); 75 | showMap(); 76 | $('.crane').hide(); 77 | $('.crane-thumb').hide(); 78 | } 79 | }); 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | /*--------------------------------- 88 | 89 | Light Controls 90 | 91 | ---------------------------------*/ 92 | 93 | function setupLightControls() { 94 | $('.toggle a').bind('click', toggleLight); 95 | } 96 | 97 | function toggleLight(e) { 98 | e.preventDefault(); 99 | 100 | switch($(e.target).attr('id')) { 101 | case 'label-on': 102 | isLit = true; 103 | $toggleBtn.addClass('on'); 104 | $toggleOn.addClass('current'); 105 | $toggleOff.removeClass('current'); 106 | $('.photon-shader').show(); 107 | break; 108 | case 'label-off': 109 | isLit = false; 110 | $toggleBtn.removeClass('on'); 111 | $toggleOn.removeClass('current'); 112 | $toggleOff.addClass('current'); 113 | $('.photon-shader').hide(); 114 | break; 115 | case 'toggle-btn': 116 | isLit = !isLit; 117 | $toggleBtn.toggleClass('on'); 118 | $toggleOn.toggleClass('current'); 119 | $toggleOff.toggleClass('current'); 120 | $('.photon-shader').toggle(); 121 | break; 122 | } 123 | } 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | /*--------------------------------- 133 | 134 | Menus 135 | 136 | ---------------------------------*/ 137 | 138 | function onDemoNav(e) { 139 | e.preventDefault(); 140 | 141 | var demo = $(e.target).attr('data-demo'); 142 | 143 | $('.example-menu .current').removeClass('current'); 144 | $(this).addClass('current'); 145 | 146 | switch(demo) { 147 | case 'coverflow': 148 | hideCrane(); 149 | hideMap(); 150 | showCoverflow(); 151 | renderCurrent = renderCoverflow; 152 | break; 153 | case 'crane': 154 | hideCoverflow(); 155 | hideMap(); 156 | showCrane(); 157 | renderCurrent = renderCrane; 158 | break; 159 | case 'map': 160 | hideCoverflow(); 161 | hideCrane(); 162 | showMap(); 163 | renderCurrent = renderMap; 164 | break; 165 | } 166 | 167 | renderCurrent(); 168 | if(!isLit) { 169 | $('.photon-shader').hide(); 170 | } 171 | } 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | /*--------------------------------- 182 | 183 | Crane 184 | 185 | ---------------------------------*/ 186 | 187 | function setupCrane() { 188 | $crane = $('.crane'); 189 | crane = new Photon.FaceGroup($('.crane')[0], $('.crane .face'), .6, .1, true); 190 | renderCrane(); 191 | } 192 | 193 | function renderCrane() { 194 | crane.render(light, true); 195 | } 196 | 197 | function showCrane() { 198 | $body.bind('mousemove', rotateCrane); 199 | $crane.show(); 200 | } 201 | 202 | function hideCrane() { 203 | $body.unbind('mousemove', rotateCrane); 204 | $crane.hide(); 205 | } 206 | 207 | function rotateCrane(e) { 208 | var xPer = e.pageX / $body.width(); 209 | 210 | $(crane.element).css(cssTransformProperty, 'rotateX(-15deg) rotateY(' + (-180 + (xPer * 360)) + 'deg)'); 211 | renderCrane(); 212 | } 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | /*--------------------------------- 223 | 224 | Map 225 | 226 | ---------------------------------*/ 227 | 228 | function setupMap() { 229 | $map = $('.map'); 230 | $mapPanel1 = $('.panel-1'); 231 | $mapPanel2 = $('.panel-2'); 232 | $mapPanel3 = $('.panel-3'); 233 | $mapCover = $('.map-cover'); 234 | $map.bind('click', toggleMap); 235 | 236 | map = new Photon.FaceGroup($('.map')[0], $('.map .face'), 1.5, .2, true); 237 | renderMap(); 238 | } 239 | 240 | function toggleMap() { 241 | $map.toggleClass('is-open'); 242 | 243 | $map.unbind(); 244 | $map.bind(transitionEndEvent, stopRenderTimer); 245 | 246 | if(!renderTimer) { 247 | renderTimer = setInterval(renderMap, 34); 248 | } 249 | } 250 | 251 | function renderMap() { 252 | map.render(light, true, true); 253 | } 254 | 255 | function showMap() { 256 | $body.bind('mousemove', rotateMap); 257 | $map.show(); 258 | } 259 | 260 | function hideMap() { 261 | $body.unbind('mousemove', rotateMap); 262 | $map.hide(); 263 | } 264 | 265 | function rotateMap(e) { 266 | var xPer = e.pageX / $body.width(); 267 | var yPer = e.pageY / $body.height(); 268 | 269 | $mapPanel1.css(cssTransformProperty, 'rotateY(' + (178 - (138 * xPer)) + 'deg)'); 270 | $mapCover.css(cssTransformProperty, 'rotateY(' + (178 - (138 * xPer)) + 'deg) translateZ(-2px) rotateY(180deg) translateX(240px)'); 271 | $mapPanel3.css(cssTransformProperty, 'rotateY(' + (178 - (138 * xPer)) + 'deg)'); 272 | $map.css(cssTransformProperty, 'rotateX(' + (40 - (yPer * 70)) + 'deg) rotateY(' + (20 - (xPer * 60)) + 'deg) rotateZ(0)'); 273 | 274 | renderMap(); 275 | } 276 | 277 | 278 | 279 | 280 | 281 | 282 | 283 | 284 | 285 | /*--------------------------------- 286 | 287 | Coverflow 288 | 289 | ---------------------------------*/ 290 | 291 | function setupCoverflow() { 292 | $coverflow = $('.coverflow'); 293 | var $coverflowItems = $coverflow.find('li'); 294 | 295 | $coverflowItems.each(function(i) { 296 | coverflowFaces[i] = new Photon.Face($(this)[0], shadeAmount); 297 | }); 298 | 299 | console.log(transitionEndEvent); 300 | $coverflowItems.eq(1).bind(transitionEndEvent, stopRenderTimer); 301 | 302 | setCoverTransforms(); 303 | } 304 | 305 | function changeCover() { 306 | currentCover = currentCover < coverflowFaces.length - 1 ? currentCover + 1 : 0; 307 | setCoverTransforms(true); 308 | } 309 | 310 | function setCoverTransforms(animate) { 311 | if(!renderTimer && animate) { 312 | renderTimer = setInterval(renderCoverflow, 34); 313 | } 314 | for(var i = 0; i < coverflowFaces.length; i++) { 315 | var element = coverflowFaces[i].element; 316 | var offset = Math.abs(currentCover - i); 317 | var x = i == currentCover ? 0 : (150 + (100 * offset)) * (i < currentCover ? -1 : 1); 318 | var z = i == currentCover ? 0 : -200; 319 | 320 | var rotationY = i == currentCover ? 0 : (80 + (offset * -5)) * (i < currentCover ? 1 : -1); 321 | 322 | $(element).css(cssTransformProperty, 'translateX(' + x +'px) translateZ(' + z + 'px) rotateY(' + rotationY + 'deg)'); 323 | } 324 | } 325 | 326 | function rotateCoverflow(e) { 327 | var xPer = e.pageX / $body.width(); 328 | 329 | var newIndex = (coverflowFaces.length -1) - Math.round((coverflowFaces.length -1) * xPer); 330 | 331 | if(!renderTimer && newIndex != currentCover) { 332 | renderTimer = setInterval(renderCoverflow, 34); 333 | currentCover = newIndex; 334 | } 335 | for(var i = 0; i < coverflowFaces.length; i++) { 336 | var element = coverflowFaces[i].element; 337 | var offset = Math.abs(currentCover - i); 338 | var x = i == currentCover ? 0 : (150 + (100 * offset)) * (i < currentCover ? -1 : 1); 339 | var z = i == currentCover ? 0 : -200; 340 | 341 | var rotationY = i == currentCover ? 0 : (80 + (offset * -5)) * (i < currentCover ? 1 : -1); 342 | 343 | $(element).css(cssTransformProperty, 'translateX(' + x +'px) translateZ(' + z + 'px) rotateY(' + rotationY + 'deg)'); 344 | } 345 | } 346 | 347 | function stopRenderTimer() { 348 | if(renderTimer) { 349 | clearInterval(renderTimer); 350 | renderTimer = null; 351 | } 352 | } 353 | 354 | function renderCoverflow() { 355 | for(var i = 0; i < coverflowFaces.length; i++) { 356 | coverflowFaces[i].render(light, true); 357 | } 358 | } 359 | 360 | function hideCoverflow() { 361 | $coverflow.hide(); 362 | $body.unbind(); 363 | } 364 | 365 | function showCoverflow() { 366 | $coverflow.show(); 367 | $body.bind('mousemove', rotateCoverflow); 368 | } 369 | 370 | 371 | 372 | 373 | 374 | 375 | 376 | 377 | 378 | /*--------------------------------- 379 | 380 | Utilities 381 | 382 | ---------------------------------*/ 383 | 384 | function domToCss(property) { 385 | var css = property.replace(/([A-Z])/g, function (str, m1) { 386 | return '-' + m1.toLowerCase(); 387 | }).replace(/^ms-/,'-ms-'); 388 | 389 | return css; 390 | } 391 | 392 | function clamp(val, min, max) { 393 | if(val > max) return max; 394 | if(val < min) return min; 395 | return val; 396 | } 397 | -------------------------------------------------------------------------------- /js/jquery-1.7.1.min.js: -------------------------------------------------------------------------------- 1 | /*! jQuery v1.7.1 jquery.com | jquery.org/license */ 2 | (function(a,b){function cy(a){return f.isWindow(a)?a:a.nodeType===9?a.defaultView||a.parentWindow:!1}function cv(a){if(!ck[a]){var b=c.body,d=f("<"+a+">").appendTo(b),e=d.css("display");d.remove();if(e==="none"||e===""){cl||(cl=c.createElement("iframe"),cl.frameBorder=cl.width=cl.height=0),b.appendChild(cl);if(!cm||!cl.createElement)cm=(cl.contentWindow||cl.contentDocument).document,cm.write((c.compatMode==="CSS1Compat"?"":"")+""),cm.close();d=cm.createElement(a),cm.body.appendChild(d),e=f.css(d,"display"),b.removeChild(cl)}ck[a]=e}return ck[a]}function cu(a,b){var c={};f.each(cq.concat.apply([],cq.slice(0,b)),function(){c[this]=a});return c}function ct(){cr=b}function cs(){setTimeout(ct,0);return cr=f.now()}function cj(){try{return new a.ActiveXObject("Microsoft.XMLHTTP")}catch(b){}}function ci(){try{return new a.XMLHttpRequest}catch(b){}}function cc(a,c){a.dataFilter&&(c=a.dataFilter(c,a.dataType));var d=a.dataTypes,e={},g,h,i=d.length,j,k=d[0],l,m,n,o,p;for(g=1;g0){if(c!=="border")for(;g=0===c})}function S(a){return!a||!a.parentNode||a.parentNode.nodeType===11}function K(){return!0}function J(){return!1}function n(a,b,c){var d=b+"defer",e=b+"queue",g=b+"mark",h=f._data(a,d);h&&(c==="queue"||!f._data(a,e))&&(c==="mark"||!f._data(a,g))&&setTimeout(function(){!f._data(a,e)&&!f._data(a,g)&&(f.removeData(a,d,!0),h.fire())},0)}function m(a){for(var b in a){if(b==="data"&&f.isEmptyObject(a[b]))continue;if(b!=="toJSON")return!1}return!0}function l(a,c,d){if(d===b&&a.nodeType===1){var e="data-"+c.replace(k,"-$1").toLowerCase();d=a.getAttribute(e);if(typeof d=="string"){try{d=d==="true"?!0:d==="false"?!1:d==="null"?null:f.isNumeric(d)?parseFloat(d):j.test(d)?f.parseJSON(d):d}catch(g){}f.data(a,c,d)}else d=b}return d}function h(a){var b=g[a]={},c,d;a=a.split(/\s+/);for(c=0,d=a.length;c)[^>]*$|#([\w\-]*)$)/,j=/\S/,k=/^\s+/,l=/\s+$/,m=/^<(\w+)\s*\/?>(?:<\/\1>)?$/,n=/^[\],:{}\s]*$/,o=/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,p=/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,q=/(?:^|:|,)(?:\s*\[)+/g,r=/(webkit)[ \/]([\w.]+)/,s=/(opera)(?:.*version)?[ \/]([\w.]+)/,t=/(msie) ([\w.]+)/,u=/(mozilla)(?:.*? rv:([\w.]+))?/,v=/-([a-z]|[0-9])/ig,w=/^-ms-/,x=function(a,b){return(b+"").toUpperCase()},y=d.userAgent,z,A,B,C=Object.prototype.toString,D=Object.prototype.hasOwnProperty,E=Array.prototype.push,F=Array.prototype.slice,G=String.prototype.trim,H=Array.prototype.indexOf,I={};e.fn=e.prototype={constructor:e,init:function(a,d,f){var g,h,j,k;if(!a)return this;if(a.nodeType){this.context=this[0]=a,this.length=1;return this}if(a==="body"&&!d&&c.body){this.context=c,this[0]=c.body,this.selector=a,this.length=1;return this}if(typeof a=="string"){a.charAt(0)!=="<"||a.charAt(a.length-1)!==">"||a.length<3?g=i.exec(a):g=[null,a,null];if(g&&(g[1]||!d)){if(g[1]){d=d instanceof e?d[0]:d,k=d?d.ownerDocument||d:c,j=m.exec(a),j?e.isPlainObject(d)?(a=[c.createElement(j[1])],e.fn.attr.call(a,d,!0)):a=[k.createElement(j[1])]:(j=e.buildFragment([g[1]],[k]),a=(j.cacheable?e.clone(j.fragment):j.fragment).childNodes);return e.merge(this,a)}h=c.getElementById(g[2]);if(h&&h.parentNode){if(h.id!==g[2])return f.find(a);this.length=1,this[0]=h}this.context=c,this.selector=a;return this}return!d||d.jquery?(d||f).find(a):this.constructor(d).find(a)}if(e.isFunction(a))return f.ready(a);a.selector!==b&&(this.selector=a.selector,this.context=a.context);return e.makeArray(a,this)},selector:"",jquery:"1.7.1",length:0,size:function(){return this.length},toArray:function(){return F.call(this,0)},get:function(a){return a==null?this.toArray():a<0?this[this.length+a]:this[a]},pushStack:function(a,b,c){var d=this.constructor();e.isArray(a)?E.apply(d,a):e.merge(d,a),d.prevObject=this,d.context=this.context,b==="find"?d.selector=this.selector+(this.selector?" ":"")+c:b&&(d.selector=this.selector+"."+b+"("+c+")");return d},each:function(a,b){return e.each(this,a,b)},ready:function(a){e.bindReady(),A.add(a);return this},eq:function(a){a=+a;return a===-1?this.slice(a):this.slice(a,a+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(F.apply(this,arguments),"slice",F.call(arguments).join(","))},map:function(a){return this.pushStack(e.map(this,function(b,c){return a.call(b,c,b)}))},end:function(){return this.prevObject||this.constructor(null)},push:E,sort:[].sort,splice:[].splice},e.fn.init.prototype=e.fn,e.extend=e.fn.extend=function(){var a,c,d,f,g,h,i=arguments[0]||{},j=1,k=arguments.length,l=!1;typeof i=="boolean"&&(l=i,i=arguments[1]||{},j=2),typeof i!="object"&&!e.isFunction(i)&&(i={}),k===j&&(i=this,--j);for(;j0)return;A.fireWith(c,[e]),e.fn.trigger&&e(c).trigger("ready").off("ready")}},bindReady:function(){if(!A){A=e.Callbacks("once memory");if(c.readyState==="complete")return setTimeout(e.ready,1);if(c.addEventListener)c.addEventListener("DOMContentLoaded",B,!1),a.addEventListener("load",e.ready,!1);else if(c.attachEvent){c.attachEvent("onreadystatechange",B),a.attachEvent("onload",e.ready);var b=!1;try{b=a.frameElement==null}catch(d){}c.documentElement.doScroll&&b&&J()}}},isFunction:function(a){return e.type(a)==="function"},isArray:Array.isArray||function(a){return e.type(a)==="array"},isWindow:function(a){return a&&typeof a=="object"&&"setInterval"in a},isNumeric:function(a){return!isNaN(parseFloat(a))&&isFinite(a)},type:function(a){return a==null?String(a):I[C.call(a)]||"object"},isPlainObject:function(a){if(!a||e.type(a)!=="object"||a.nodeType||e.isWindow(a))return!1;try{if(a.constructor&&!D.call(a,"constructor")&&!D.call(a.constructor.prototype,"isPrototypeOf"))return!1}catch(c){return!1}var d;for(d in a);return d===b||D.call(a,d)},isEmptyObject:function(a){for(var b in a)return!1;return!0},error:function(a){throw new Error(a)},parseJSON:function(b){if(typeof b!="string"||!b)return null;b=e.trim(b);if(a.JSON&&a.JSON.parse)return a.JSON.parse(b);if(n.test(b.replace(o,"@").replace(p,"]").replace(q,"")))return(new Function("return "+b))();e.error("Invalid JSON: "+b)},parseXML:function(c){var d,f;try{a.DOMParser?(f=new DOMParser,d=f.parseFromString(c,"text/xml")):(d=new ActiveXObject("Microsoft.XMLDOM"),d.async="false",d.loadXML(c))}catch(g){d=b}(!d||!d.documentElement||d.getElementsByTagName("parsererror").length)&&e.error("Invalid XML: "+c);return d},noop:function(){},globalEval:function(b){b&&j.test(b)&&(a.execScript||function(b){a.eval.call(a,b)})(b)},camelCase:function(a){return a.replace(w,"ms-").replace(v,x)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toUpperCase()===b.toUpperCase()},each:function(a,c,d){var f,g=0,h=a.length,i=h===b||e.isFunction(a);if(d){if(i){for(f in a)if(c.apply(a[f],d)===!1)break}else for(;g0&&a[0]&&a[j-1]||j===0||e.isArray(a));if(k)for(;i1?i.call(arguments,0):b,j.notifyWith(k,e)}}function l(a){return function(c){b[a]=arguments.length>1?i.call(arguments,0):c,--g||j.resolveWith(j,b)}}var b=i.call(arguments,0),c=0,d=b.length,e=Array(d),g=d,h=d,j=d<=1&&a&&f.isFunction(a.promise)?a:f.Deferred(),k=j.promise();if(d>1){for(;c
a",d=q.getElementsByTagName("*"),e=q.getElementsByTagName("a")[0];if(!d||!d.length||!e)return{};g=c.createElement("select"),h=g.appendChild(c.createElement("option")),i=q.getElementsByTagName("input")[0],b={leadingWhitespace:q.firstChild.nodeType===3,tbody:!q.getElementsByTagName("tbody").length,htmlSerialize:!!q.getElementsByTagName("link").length,style:/top/.test(e.getAttribute("style")),hrefNormalized:e.getAttribute("href")==="/a",opacity:/^0.55/.test(e.style.opacity),cssFloat:!!e.style.cssFloat,checkOn:i.value==="on",optSelected:h.selected,getSetAttribute:q.className!=="t",enctype:!!c.createElement("form").enctype,html5Clone:c.createElement("nav").cloneNode(!0).outerHTML!=="<:nav>",submitBubbles:!0,changeBubbles:!0,focusinBubbles:!1,deleteExpando:!0,noCloneEvent:!0,inlineBlockNeedsLayout:!1,shrinkWrapBlocks:!1,reliableMarginRight:!0},i.checked=!0,b.noCloneChecked=i.cloneNode(!0).checked,g.disabled=!0,b.optDisabled=!h.disabled;try{delete q.test}catch(s){b.deleteExpando=!1}!q.addEventListener&&q.attachEvent&&q.fireEvent&&(q.attachEvent("onclick",function(){b.noCloneEvent=!1}),q.cloneNode(!0).fireEvent("onclick")),i=c.createElement("input"),i.value="t",i.setAttribute("type","radio"),b.radioValue=i.value==="t",i.setAttribute("checked","checked"),q.appendChild(i),k=c.createDocumentFragment(),k.appendChild(q.lastChild),b.checkClone=k.cloneNode(!0).cloneNode(!0).lastChild.checked,b.appendChecked=i.checked,k.removeChild(i),k.appendChild(q),q.innerHTML="",a.getComputedStyle&&(j=c.createElement("div"),j.style.width="0",j.style.marginRight="0",q.style.width="2px",q.appendChild(j),b.reliableMarginRight=(parseInt((a.getComputedStyle(j,null)||{marginRight:0}).marginRight,10)||0)===0);if(q.attachEvent)for(o in{submit:1,change:1,focusin:1})n="on"+o,p=n in q,p||(q.setAttribute(n,"return;"),p=typeof q[n]=="function"),b[o+"Bubbles"]=p;k.removeChild(q),k=g=h=j=q=i=null,f(function(){var a,d,e,g,h,i,j,k,m,n,o,r=c.getElementsByTagName("body")[0];!r||(j=1,k="position:absolute;top:0;left:0;width:1px;height:1px;margin:0;",m="visibility:hidden;border:0;",n="style='"+k+"border:5px solid #000;padding:0;'",o="
"+""+"
",a=c.createElement("div"),a.style.cssText=m+"width:0;height:0;position:static;top:0;margin-top:"+j+"px",r.insertBefore(a,r.firstChild),q=c.createElement("div"),a.appendChild(q),q.innerHTML="
t
",l=q.getElementsByTagName("td"),p=l[0].offsetHeight===0,l[0].style.display="",l[1].style.display="none",b.reliableHiddenOffsets=p&&l[0].offsetHeight===0,q.innerHTML="",q.style.width=q.style.paddingLeft="1px",f.boxModel=b.boxModel=q.offsetWidth===2,typeof q.style.zoom!="undefined"&&(q.style.display="inline",q.style.zoom=1,b.inlineBlockNeedsLayout=q.offsetWidth===2,q.style.display="",q.innerHTML="
",b.shrinkWrapBlocks=q.offsetWidth!==2),q.style.cssText=k+m,q.innerHTML=o,d=q.firstChild,e=d.firstChild,h=d.nextSibling.firstChild.firstChild,i={doesNotAddBorder:e.offsetTop!==5,doesAddBorderForTableAndCells:h.offsetTop===5},e.style.position="fixed",e.style.top="20px",i.fixedPosition=e.offsetTop===20||e.offsetTop===15,e.style.position=e.style.top="",d.style.overflow="hidden",d.style.position="relative",i.subtractsBorderForOverflowNotVisible=e.offsetTop===-5,i.doesNotIncludeMarginInBodyOffset=r.offsetTop!==j,r.removeChild(a),q=a=null,f.extend(b,i))});return b}();var j=/^(?:\{.*\}|\[.*\])$/,k=/([A-Z])/g;f.extend({cache:{},uuid:0,expando:"jQuery"+(f.fn.jquery+Math.random()).replace(/\D/g,""),noData:{embed:!0,object:"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",applet:!0},hasData:function(a){a=a.nodeType?f.cache[a[f.expando]]:a[f.expando];return!!a&&!m(a)},data:function(a,c,d,e){if(!!f.acceptData(a)){var g,h,i,j=f.expando,k=typeof c=="string",l=a.nodeType,m=l?f.cache:a,n=l?a[j]:a[j]&&j,o=c==="events";if((!n||!m[n]||!o&&!e&&!m[n].data)&&k&&d===b)return;n||(l?a[j]=n=++f.uuid:n=j),m[n]||(m[n]={},l||(m[n].toJSON=f.noop));if(typeof c=="object"||typeof c=="function")e?m[n]=f.extend(m[n],c):m[n].data=f.extend(m[n].data,c);g=h=m[n],e||(h.data||(h.data={}),h=h.data),d!==b&&(h[f.camelCase(c)]=d);if(o&&!h[c])return g.events;k?(i=h[c],i==null&&(i=h[f.camelCase(c)])):i=h;return i}},removeData:function(a,b,c){if(!!f.acceptData(a)){var d,e,g,h=f.expando,i=a.nodeType,j=i?f.cache:a,k=i?a[h]:h;if(!j[k])return;if(b){d=c?j[k]:j[k].data;if(d){f.isArray(b)||(b in d?b=[b]:(b=f.camelCase(b),b in d?b=[b]:b=b.split(" ")));for(e=0,g=b.length;e-1)return!0;return!1},val:function(a){var c,d,e,g=this[0];{if(!!arguments.length){e=f.isFunction(a);return this.each(function(d){var g=f(this),h;if(this.nodeType===1){e?h=a.call(this,d,g.val()):h=a,h==null?h="":typeof h=="number"?h+="":f.isArray(h)&&(h=f.map(h,function(a){return a==null?"":a+""})),c=f.valHooks[this.nodeName.toLowerCase()]||f.valHooks[this.type];if(!c||!("set"in c)||c.set(this,h,"value")===b)this.value=h}})}if(g){c=f.valHooks[g.nodeName.toLowerCase()]||f.valHooks[g.type];if(c&&"get"in c&&(d=c.get(g,"value"))!==b)return d;d=g.value;return typeof d=="string"?d.replace(q,""):d==null?"":d}}}}),f.extend({valHooks:{option:{get:function(a){var b=a.attributes.value;return!b||b.specified?a.value:a.text}},select:{get:function(a){var b,c,d,e,g=a.selectedIndex,h=[],i=a.options,j=a.type==="select-one";if(g<0)return null;c=j?g:0,d=j?g+1:i.length;for(;c=0}),c.length||(a.selectedIndex=-1);return c}}},attrFn:{val:!0,css:!0,html:!0,text:!0,data:!0,width:!0,height:!0,offset:!0},attr:function(a,c,d,e){var g,h,i,j=a.nodeType;if(!!a&&j!==3&&j!==8&&j!==2){if(e&&c in f.attrFn)return f(a)[c](d);if(typeof a.getAttribute=="undefined")return f.prop(a,c,d);i=j!==1||!f.isXMLDoc(a),i&&(c=c.toLowerCase(),h=f.attrHooks[c]||(u.test(c)?x:w));if(d!==b){if(d===null){f.removeAttr(a,c);return}if(h&&"set"in h&&i&&(g=h.set(a,d,c))!==b)return g;a.setAttribute(c,""+d);return d}if(h&&"get"in h&&i&&(g=h.get(a,c))!==null)return g;g=a.getAttribute(c);return g===null?b:g}},removeAttr:function(a,b){var c,d,e,g,h=0;if(b&&a.nodeType===1){d=b.toLowerCase().split(p),g=d.length;for(;h=0}})});var z=/^(?:textarea|input|select)$/i,A=/^([^\.]*)?(?:\.(.+))?$/,B=/\bhover(\.\S+)?\b/,C=/^key/,D=/^(?:mouse|contextmenu)|click/,E=/^(?:focusinfocus|focusoutblur)$/,F=/^(\w*)(?:#([\w\-]+))?(?:\.([\w\-]+))?$/,G=function(a){var b=F.exec(a);b&&(b[1]=(b[1]||"").toLowerCase(),b[3]=b[3]&&new RegExp("(?:^|\\s)"+b[3]+"(?:\\s|$)"));return b},H=function(a,b){var c=a.attributes||{};return(!b[1]||a.nodeName.toLowerCase()===b[1])&&(!b[2]||(c.id||{}).value===b[2])&&(!b[3]||b[3].test((c["class"]||{}).value))},I=function(a){return f.event.special.hover?a:a.replace(B,"mouseenter$1 mouseleave$1")}; 3 | f.event={add:function(a,c,d,e,g){var h,i,j,k,l,m,n,o,p,q,r,s;if(!(a.nodeType===3||a.nodeType===8||!c||!d||!(h=f._data(a)))){d.handler&&(p=d,d=p.handler),d.guid||(d.guid=f.guid++),j=h.events,j||(h.events=j={}),i=h.handle,i||(h.handle=i=function(a){return typeof f!="undefined"&&(!a||f.event.triggered!==a.type)?f.event.dispatch.apply(i.elem,arguments):b},i.elem=a),c=f.trim(I(c)).split(" ");for(k=0;k=0&&(h=h.slice(0,-1),k=!0),h.indexOf(".")>=0&&(i=h.split("."),h=i.shift(),i.sort());if((!e||f.event.customEvent[h])&&!f.event.global[h])return;c=typeof c=="object"?c[f.expando]?c:new f.Event(h,c):new f.Event(h),c.type=h,c.isTrigger=!0,c.exclusive=k,c.namespace=i.join("."),c.namespace_re=c.namespace?new RegExp("(^|\\.)"+i.join("\\.(?:.*\\.)?")+"(\\.|$)"):null,o=h.indexOf(":")<0?"on"+h:"";if(!e){j=f.cache;for(l in j)j[l].events&&j[l].events[h]&&f.event.trigger(c,d,j[l].handle.elem,!0);return}c.result=b,c.target||(c.target=e),d=d!=null?f.makeArray(d):[],d.unshift(c),p=f.event.special[h]||{};if(p.trigger&&p.trigger.apply(e,d)===!1)return;r=[[e,p.bindType||h]];if(!g&&!p.noBubble&&!f.isWindow(e)){s=p.delegateType||h,m=E.test(s+h)?e:e.parentNode,n=null;for(;m;m=m.parentNode)r.push([m,s]),n=m;n&&n===e.ownerDocument&&r.push([n.defaultView||n.parentWindow||a,s])}for(l=0;le&&i.push({elem:this,matches:d.slice(e)});for(j=0;j0?this.on(b,null,a,c):this.trigger(b)},f.attrFn&&(f.attrFn[b]=!0),C.test(b)&&(f.event.fixHooks[b]=f.event.keyHooks),D.test(b)&&(f.event.fixHooks[b]=f.event.mouseHooks)}),function(){function x(a,b,c,e,f,g){for(var h=0,i=e.length;h0){k=j;break}}j=j[a]}e[h]=k}}}function w(a,b,c,e,f,g){for(var h=0,i=e.length;h+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,d="sizcache"+(Math.random()+"").replace(".",""),e=0,g=Object.prototype.toString,h=!1,i=!0,j=/\\/g,k=/\r\n/g,l=/\W/;[0,0].sort(function(){i=!1;return 0});var m=function(b,d,e,f){e=e||[],d=d||c;var h=d;if(d.nodeType!==1&&d.nodeType!==9)return[];if(!b||typeof b!="string")return e;var i,j,k,l,n,q,r,t,u=!0,v=m.isXML(d),w=[],x=b;do{a.exec(""),i=a.exec(x);if(i){x=i[3],w.push(i[1]);if(i[2]){l=i[3];break}}}while(i);if(w.length>1&&p.exec(b))if(w.length===2&&o.relative[w[0]])j=y(w[0]+w[1],d,f);else{j=o.relative[w[0]]?[d]:m(w.shift(),d);while(w.length)b=w.shift(),o.relative[b]&&(b+=w.shift()),j=y(b,j,f)}else{!f&&w.length>1&&d.nodeType===9&&!v&&o.match.ID.test(w[0])&&!o.match.ID.test(w[w.length-1])&&(n=m.find(w.shift(),d,v),d=n.expr?m.filter(n.expr,n.set)[0]:n.set[0]);if(d){n=f?{expr:w.pop(),set:s(f)}:m.find(w.pop(),w.length===1&&(w[0]==="~"||w[0]==="+")&&d.parentNode?d.parentNode:d,v),j=n.expr?m.filter(n.expr,n.set):n.set,w.length>0?k=s(j):u=!1;while(w.length)q=w.pop(),r=q,o.relative[q]?r=w.pop():q="",r==null&&(r=d),o.relative[q](k,r,v)}else k=w=[]}k||(k=j),k||m.error(q||b);if(g.call(k)==="[object Array]")if(!u)e.push.apply(e,k);else if(d&&d.nodeType===1)for(t=0;k[t]!=null;t++)k[t]&&(k[t]===!0||k[t].nodeType===1&&m.contains(d,k[t]))&&e.push(j[t]);else for(t=0;k[t]!=null;t++)k[t]&&k[t].nodeType===1&&e.push(j[t]);else s(k,e);l&&(m(l,h,e,f),m.uniqueSort(e));return e};m.uniqueSort=function(a){if(u){h=i,a.sort(u);if(h)for(var b=1;b0},m.find=function(a,b,c){var d,e,f,g,h,i;if(!a)return[];for(e=0,f=o.order.length;e":function(a,b){var c,d=typeof b=="string",e=0,f=a.length;if(d&&!l.test(b)){b=b.toLowerCase();for(;e=0)?c||d.push(h):c&&(b[g]=!1));return!1},ID:function(a){return a[1].replace(j,"")},TAG:function(a,b){return a[1].replace(j,"").toLowerCase()},CHILD:function(a){if(a[1]==="nth"){a[2]||m.error(a[0]),a[2]=a[2].replace(/^\+|\s*/g,"");var b=/(-?)(\d*)(?:n([+\-]?\d*))?/.exec(a[2]==="even"&&"2n"||a[2]==="odd"&&"2n+1"||!/\D/.test(a[2])&&"0n+"+a[2]||a[2]);a[2]=b[1]+(b[2]||1)-0,a[3]=b[3]-0}else a[2]&&m.error(a[0]);a[0]=e++;return a},ATTR:function(a,b,c,d,e,f){var g=a[1]=a[1].replace(j,"");!f&&o.attrMap[g]&&(a[1]=o.attrMap[g]),a[4]=(a[4]||a[5]||"").replace(j,""),a[2]==="~="&&(a[4]=" "+a[4]+" ");return a},PSEUDO:function(b,c,d,e,f){if(b[1]==="not")if((a.exec(b[3])||"").length>1||/^\w/.test(b[3]))b[3]=m(b[3],null,null,c);else{var g=m.filter(b[3],c,d,!0^f);d||e.push.apply(e,g);return!1}else if(o.match.POS.test(b[0])||o.match.CHILD.test(b[0]))return!0;return b},POS:function(a){a.unshift(!0);return a}},filters:{enabled:function(a){return a.disabled===!1&&a.type!=="hidden"},disabled:function(a){return a.disabled===!0},checked:function(a){return a.checked===!0},selected:function(a){a.parentNode&&a.parentNode.selectedIndex;return a.selected===!0},parent:function(a){return!!a.firstChild},empty:function(a){return!a.firstChild},has:function(a,b,c){return!!m(c[3],a).length},header:function(a){return/h\d/i.test(a.nodeName)},text:function(a){var b=a.getAttribute("type"),c=a.type;return a.nodeName.toLowerCase()==="input"&&"text"===c&&(b===c||b===null)},radio:function(a){return a.nodeName.toLowerCase()==="input"&&"radio"===a.type},checkbox:function(a){return a.nodeName.toLowerCase()==="input"&&"checkbox"===a.type},file:function(a){return a.nodeName.toLowerCase()==="input"&&"file"===a.type},password:function(a){return a.nodeName.toLowerCase()==="input"&&"password"===a.type},submit:function(a){var b=a.nodeName.toLowerCase();return(b==="input"||b==="button")&&"submit"===a.type},image:function(a){return a.nodeName.toLowerCase()==="input"&&"image"===a.type},reset:function(a){var b=a.nodeName.toLowerCase();return(b==="input"||b==="button")&&"reset"===a.type},button:function(a){var b=a.nodeName.toLowerCase();return b==="input"&&"button"===a.type||b==="button"},input:function(a){return/input|select|textarea|button/i.test(a.nodeName)},focus:function(a){return a===a.ownerDocument.activeElement}},setFilters:{first:function(a,b){return b===0},last:function(a,b,c,d){return b===d.length-1},even:function(a,b){return b%2===0},odd:function(a,b){return b%2===1},lt:function(a,b,c){return bc[3]-0},nth:function(a,b,c){return c[3]-0===b},eq:function(a,b,c){return c[3]-0===b}},filter:{PSEUDO:function(a,b,c,d){var e=b[1],f=o.filters[e];if(f)return f(a,c,b,d);if(e==="contains")return(a.textContent||a.innerText||n([a])||"").indexOf(b[3])>=0;if(e==="not"){var g=b[3];for(var h=0,i=g.length;h=0}},ID:function(a,b){return a.nodeType===1&&a.getAttribute("id")===b},TAG:function(a,b){return b==="*"&&a.nodeType===1||!!a.nodeName&&a.nodeName.toLowerCase()===b},CLASS:function(a,b){return(" "+(a.className||a.getAttribute("class"))+" ").indexOf(b)>-1},ATTR:function(a,b){var c=b[1],d=m.attr?m.attr(a,c):o.attrHandle[c]?o.attrHandle[c](a):a[c]!=null?a[c]:a.getAttribute(c),e=d+"",f=b[2],g=b[4];return d==null?f==="!=":!f&&m.attr?d!=null:f==="="?e===g:f==="*="?e.indexOf(g)>=0:f==="~="?(" "+e+" ").indexOf(g)>=0:g?f==="!="?e!==g:f==="^="?e.indexOf(g)===0:f==="$="?e.substr(e.length-g.length)===g:f==="|="?e===g||e.substr(0,g.length+1)===g+"-":!1:e&&d!==!1},POS:function(a,b,c,d){var e=b[2],f=o.setFilters[e];if(f)return f(a,c,b,d)}}},p=o.match.POS,q=function(a,b){return"\\"+(b-0+1)};for(var r in o.match)o.match[r]=new RegExp(o.match[r].source+/(?![^\[]*\])(?![^\(]*\))/.source),o.leftMatch[r]=new RegExp(/(^(?:.|\r|\n)*?)/.source+o.match[r].source.replace(/\\(\d+)/g,q));var s=function(a,b){a=Array.prototype.slice.call(a,0);if(b){b.push.apply(b,a);return b}return a};try{Array.prototype.slice.call(c.documentElement.childNodes,0)[0].nodeType}catch(t){s=function(a,b){var c=0,d=b||[];if(g.call(a)==="[object Array]")Array.prototype.push.apply(d,a);else if(typeof a.length=="number")for(var e=a.length;c",e.insertBefore(a,e.firstChild),c.getElementById(d)&&(o.find.ID=function(a,c,d){if(typeof c.getElementById!="undefined"&&!d){var e=c.getElementById(a[1]);return e?e.id===a[1]||typeof e.getAttributeNode!="undefined"&&e.getAttributeNode("id").nodeValue===a[1]?[e]:b:[]}},o.filter.ID=function(a,b){var c=typeof a.getAttributeNode!="undefined"&&a.getAttributeNode("id");return a.nodeType===1&&c&&c.nodeValue===b}),e.removeChild(a),e=a=null}(),function(){var a=c.createElement("div");a.appendChild(c.createComment("")),a.getElementsByTagName("*").length>0&&(o.find.TAG=function(a,b){var c=b.getElementsByTagName(a[1]);if(a[1]==="*"){var d=[];for(var e=0;c[e];e++)c[e].nodeType===1&&d.push(c[e]);c=d}return c}),a.innerHTML="",a.firstChild&&typeof a.firstChild.getAttribute!="undefined"&&a.firstChild.getAttribute("href")!=="#"&&(o.attrHandle.href=function(a){return a.getAttribute("href",2)}),a=null}(),c.querySelectorAll&&function(){var a=m,b=c.createElement("div"),d="__sizzle__";b.innerHTML="

";if(!b.querySelectorAll||b.querySelectorAll(".TEST").length!==0){m=function(b,e,f,g){e=e||c;if(!g&&!m.isXML(e)){var h=/^(\w+$)|^\.([\w\-]+$)|^#([\w\-]+$)/.exec(b);if(h&&(e.nodeType===1||e.nodeType===9)){if(h[1])return s(e.getElementsByTagName(b),f);if(h[2]&&o.find.CLASS&&e.getElementsByClassName)return s(e.getElementsByClassName(h[2]),f)}if(e.nodeType===9){if(b==="body"&&e.body)return s([e.body],f);if(h&&h[3]){var i=e.getElementById(h[3]);if(!i||!i.parentNode)return s([],f);if(i.id===h[3])return s([i],f)}try{return s(e.querySelectorAll(b),f)}catch(j){}}else if(e.nodeType===1&&e.nodeName.toLowerCase()!=="object"){var k=e,l=e.getAttribute("id"),n=l||d,p=e.parentNode,q=/^\s*[+~]/.test(b);l?n=n.replace(/'/g,"\\$&"):e.setAttribute("id",n),q&&p&&(e=e.parentNode);try{if(!q||p)return s(e.querySelectorAll("[id='"+n+"'] "+b),f)}catch(r){}finally{l||k.removeAttribute("id")}}}return a(b,e,f,g)};for(var e in a)m[e]=a[e];b=null}}(),function(){var a=c.documentElement,b=a.matchesSelector||a.mozMatchesSelector||a.webkitMatchesSelector||a.msMatchesSelector;if(b){var d=!b.call(c.createElement("div"),"div"),e=!1;try{b.call(c.documentElement,"[test!='']:sizzle")}catch(f){e=!0}m.matchesSelector=function(a,c){c=c.replace(/\=\s*([^'"\]]*)\s*\]/g,"='$1']");if(!m.isXML(a))try{if(e||!o.match.PSEUDO.test(c)&&!/!=/.test(c)){var f=b.call(a,c);if(f||!d||a.document&&a.document.nodeType!==11)return f}}catch(g){}return m(c,null,null,[a]).length>0}}}(),function(){var a=c.createElement("div");a.innerHTML="
";if(!!a.getElementsByClassName&&a.getElementsByClassName("e").length!==0){a.lastChild.className="e";if(a.getElementsByClassName("e").length===1)return;o.order.splice(1,0,"CLASS"),o.find.CLASS=function(a,b,c){if(typeof b.getElementsByClassName!="undefined"&&!c)return b.getElementsByClassName(a[1])},a=null}}(),c.documentElement.contains?m.contains=function(a,b){return a!==b&&(a.contains?a.contains(b):!0)}:c.documentElement.compareDocumentPosition?m.contains=function(a,b){return!!(a.compareDocumentPosition(b)&16)}:m.contains=function(){return!1},m.isXML=function(a){var b=(a?a.ownerDocument||a:0).documentElement;return b?b.nodeName!=="HTML":!1};var y=function(a,b,c){var d,e=[],f="",g=b.nodeType?[b]:b;while(d=o.match.PSEUDO.exec(a))f+=d[0],a=a.replace(o.match.PSEUDO,"");a=o.relative[a]?a+"*":a;for(var h=0,i=g.length;h0)for(h=g;h=0:f.filter(a,this).length>0:this.filter(a).length>0)},closest:function(a,b){var c=[],d,e,g=this[0];if(f.isArray(a)){var h=1;while(g&&g.ownerDocument&&g!==b){for(d=0;d-1:f.find.matchesSelector(g,a)){c.push(g);break}g=g.parentNode;if(!g||!g.ownerDocument||g===b||g.nodeType===11)break}}c=c.length>1?f.unique(c):c;return this.pushStack(c,"closest",a)},index:function(a){if(!a)return this[0]&&this[0].parentNode?this.prevAll().length:-1;if(typeof a=="string")return f.inArray(this[0],f(a));return f.inArray(a.jquery?a[0]:a,this)},add:function(a,b){var c=typeof a=="string"?f(a,b):f.makeArray(a&&a.nodeType?[a]:a),d=f.merge(this.get(),c);return this.pushStack(S(c[0])||S(d[0])?d:f.unique(d))},andSelf:function(){return this.add(this.prevObject)}}),f.each({parent:function(a){var b=a.parentNode;return b&&b.nodeType!==11?b:null},parents:function(a){return f.dir(a,"parentNode")},parentsUntil:function(a,b,c){return f.dir(a,"parentNode",c)},next:function(a){return f.nth(a,2,"nextSibling")},prev:function(a){return f.nth(a,2,"previousSibling")},nextAll:function(a){return f.dir(a,"nextSibling")},prevAll:function(a){return f.dir(a,"previousSibling")},nextUntil:function(a,b,c){return f.dir(a,"nextSibling",c)},prevUntil:function(a,b,c){return f.dir(a,"previousSibling",c)},siblings:function(a){return f.sibling(a.parentNode.firstChild,a)},children:function(a){return f.sibling(a.firstChild)},contents:function(a){return f.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document:f.makeArray(a.childNodes)}},function(a,b){f.fn[a]=function(c,d){var e=f.map(this,b,c);L.test(a)||(d=c),d&&typeof d=="string"&&(e=f.filter(d,e)),e=this.length>1&&!R[a]?f.unique(e):e,(this.length>1||N.test(d))&&M.test(a)&&(e=e.reverse());return this.pushStack(e,a,P.call(arguments).join(","))}}),f.extend({filter:function(a,b,c){c&&(a=":not("+a+")");return b.length===1?f.find.matchesSelector(b[0],a)?[b[0]]:[]:f.find.matches(a,b)},dir:function(a,c,d){var e=[],g=a[c];while(g&&g.nodeType!==9&&(d===b||g.nodeType!==1||!f(g).is(d)))g.nodeType===1&&e.push(g),g=g[c];return e},nth:function(a,b,c,d){b=b||1;var e=0;for(;a;a=a[c])if(a.nodeType===1&&++e===b)break;return a},sibling:function(a,b){var c=[];for(;a;a=a.nextSibling)a.nodeType===1&&a!==b&&c.push(a);return c}});var V="abbr|article|aside|audio|canvas|datalist|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",W=/ jQuery\d+="(?:\d+|null)"/g,X=/^\s+/,Y=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig,Z=/<([\w:]+)/,$=/",""],legend:[1,"
","
"],thead:[1,"","
"],tr:[2,"","
"],td:[3,"","
"],col:[2,"","
"],area:[1,"",""],_default:[0,"",""]},bh=U(c);bg.optgroup=bg.option,bg.tbody=bg.tfoot=bg.colgroup=bg.caption=bg.thead,bg.th=bg.td,f.support.htmlSerialize||(bg._default=[1,"div
","
"]),f.fn.extend({text:function(a){if(f.isFunction(a))return this.each(function(b){var c=f(this);c.text(a.call(this,b,c.text()))});if(typeof a!="object"&&a!==b)return this.empty().append((this[0]&&this[0].ownerDocument||c).createTextNode(a));return f.text(this)},wrapAll:function(a){if(f.isFunction(a))return this.each(function(b){f(this).wrapAll(a.call(this,b))});if(this[0]){var b=f(a,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstChild&&a.firstChild.nodeType===1)a=a.firstChild;return a}).append(this)}return this},wrapInner:function(a){if(f.isFunction(a))return this.each(function(b){f(this).wrapInner(a.call(this,b))});return this.each(function(){var b=f(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){var b=f.isFunction(a);return this.each(function(c){f(this).wrapAll(b?a.call(this,c):a)})},unwrap:function(){return this.parent().each(function(){f.nodeName(this,"body")||f(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,!0,function(a){this.nodeType===1&&this.appendChild(a)})},prepend:function(){return this.domManip(arguments,!0,function(a){this.nodeType===1&&this.insertBefore(a,this.firstChild)})},before:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this)});if(arguments.length){var a=f.clean(arguments);a.push.apply(a,this.toArray());return this.pushStack(a,"before",arguments)}},after:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this.nextSibling)});if(arguments.length){var a=this.pushStack(this,"after",arguments);a.push.apply(a,f.clean(arguments));return a}},remove:function(a,b){for(var c=0,d;(d=this[c])!=null;c++)if(!a||f.filter(a,[d]).length)!b&&d.nodeType===1&&(f.cleanData(d.getElementsByTagName("*")),f.cleanData([d])),d.parentNode&&d.parentNode.removeChild(d);return this},empty:function() 4 | {for(var a=0,b;(b=this[a])!=null;a++){b.nodeType===1&&f.cleanData(b.getElementsByTagName("*"));while(b.firstChild)b.removeChild(b.firstChild)}return this},clone:function(a,b){a=a==null?!1:a,b=b==null?a:b;return this.map(function(){return f.clone(this,a,b)})},html:function(a){if(a===b)return this[0]&&this[0].nodeType===1?this[0].innerHTML.replace(W,""):null;if(typeof a=="string"&&!ba.test(a)&&(f.support.leadingWhitespace||!X.test(a))&&!bg[(Z.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(Y,"<$1>");try{for(var c=0,d=this.length;c1&&l0?this.clone(!0):this).get();f(e[h])[b](j),d=d.concat(j)}return this.pushStack(d,a,e.selector)}}),f.extend({clone:function(a,b,c){var d,e,g,h=f.support.html5Clone||!bc.test("<"+a.nodeName)?a.cloneNode(!0):bo(a);if((!f.support.noCloneEvent||!f.support.noCloneChecked)&&(a.nodeType===1||a.nodeType===11)&&!f.isXMLDoc(a)){bk(a,h),d=bl(a),e=bl(h);for(g=0;d[g];++g)e[g]&&bk(d[g],e[g])}if(b){bj(a,h);if(c){d=bl(a),e=bl(h);for(g=0;d[g];++g)bj(d[g],e[g])}}d=e=null;return h},clean:function(a,b,d,e){var g;b=b||c,typeof b.createElement=="undefined"&&(b=b.ownerDocument||b[0]&&b[0].ownerDocument||c);var h=[],i;for(var j=0,k;(k=a[j])!=null;j++){typeof k=="number"&&(k+="");if(!k)continue;if(typeof k=="string")if(!_.test(k))k=b.createTextNode(k);else{k=k.replace(Y,"<$1>");var l=(Z.exec(k)||["",""])[1].toLowerCase(),m=bg[l]||bg._default,n=m[0],o=b.createElement("div");b===c?bh.appendChild(o):U(b).appendChild(o),o.innerHTML=m[1]+k+m[2];while(n--)o=o.lastChild;if(!f.support.tbody){var p=$.test(k),q=l==="table"&&!p?o.firstChild&&o.firstChild.childNodes:m[1]===""&&!p?o.childNodes:[];for(i=q.length-1;i>=0;--i)f.nodeName(q[i],"tbody")&&!q[i].childNodes.length&&q[i].parentNode.removeChild(q[i])}!f.support.leadingWhitespace&&X.test(k)&&o.insertBefore(b.createTextNode(X.exec(k)[0]),o.firstChild),k=o.childNodes}var r;if(!f.support.appendChecked)if(k[0]&&typeof (r=k.length)=="number")for(i=0;i=0)return b+"px"}}}),f.support.opacity||(f.cssHooks.opacity={get:function(a,b){return br.test((b&&a.currentStyle?a.currentStyle.filter:a.style.filter)||"")?parseFloat(RegExp.$1)/100+"":b?"1":""},set:function(a,b){var c=a.style,d=a.currentStyle,e=f.isNumeric(b)?"alpha(opacity="+b*100+")":"",g=d&&d.filter||c.filter||"";c.zoom=1;if(b>=1&&f.trim(g.replace(bq,""))===""){c.removeAttribute("filter");if(d&&!d.filter)return}c.filter=bq.test(g)?g.replace(bq,e):g+" "+e}}),f(function(){f.support.reliableMarginRight||(f.cssHooks.marginRight={get:function(a,b){var c;f.swap(a,{display:"inline-block"},function(){b?c=bz(a,"margin-right","marginRight"):c=a.style.marginRight});return c}})}),c.defaultView&&c.defaultView.getComputedStyle&&(bA=function(a,b){var c,d,e;b=b.replace(bs,"-$1").toLowerCase(),(d=a.ownerDocument.defaultView)&&(e=d.getComputedStyle(a,null))&&(c=e.getPropertyValue(b),c===""&&!f.contains(a.ownerDocument.documentElement,a)&&(c=f.style(a,b)));return c}),c.documentElement.currentStyle&&(bB=function(a,b){var c,d,e,f=a.currentStyle&&a.currentStyle[b],g=a.style;f===null&&g&&(e=g[b])&&(f=e),!bt.test(f)&&bu.test(f)&&(c=g.left,d=a.runtimeStyle&&a.runtimeStyle.left,d&&(a.runtimeStyle.left=a.currentStyle.left),g.left=b==="fontSize"?"1em":f||0,f=g.pixelLeft+"px",g.left=c,d&&(a.runtimeStyle.left=d));return f===""?"auto":f}),bz=bA||bB,f.expr&&f.expr.filters&&(f.expr.filters.hidden=function(a){var b=a.offsetWidth,c=a.offsetHeight;return b===0&&c===0||!f.support.reliableHiddenOffsets&&(a.style&&a.style.display||f.css(a,"display"))==="none"},f.expr.filters.visible=function(a){return!f.expr.filters.hidden(a)});var bD=/%20/g,bE=/\[\]$/,bF=/\r?\n/g,bG=/#.*$/,bH=/^(.*?):[ \t]*([^\r\n]*)\r?$/mg,bI=/^(?:color|date|datetime|datetime-local|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,bJ=/^(?:about|app|app\-storage|.+\-extension|file|res|widget):$/,bK=/^(?:GET|HEAD)$/,bL=/^\/\//,bM=/\?/,bN=/)<[^<]*)*<\/script>/gi,bO=/^(?:select|textarea)/i,bP=/\s+/,bQ=/([?&])_=[^&]*/,bR=/^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+))?)?/,bS=f.fn.load,bT={},bU={},bV,bW,bX=["*/"]+["*"];try{bV=e.href}catch(bY){bV=c.createElement("a"),bV.href="",bV=bV.href}bW=bR.exec(bV.toLowerCase())||[],f.fn.extend({load:function(a,c,d){if(typeof a!="string"&&bS)return bS.apply(this,arguments);if(!this.length)return this;var e=a.indexOf(" ");if(e>=0){var g=a.slice(e,a.length);a=a.slice(0,e)}var h="GET";c&&(f.isFunction(c)?(d=c,c=b):typeof c=="object"&&(c=f.param(c,f.ajaxSettings.traditional),h="POST"));var i=this;f.ajax({url:a,type:h,dataType:"html",data:c,complete:function(a,b,c){c=a.responseText,a.isResolved()&&(a.done(function(a){c=a}),i.html(g?f("
").append(c.replace(bN,"")).find(g):c)),d&&i.each(d,[c,b,a])}});return this},serialize:function(){return f.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?f.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||bO.test(this.nodeName)||bI.test(this.type))}).map(function(a,b){var c=f(this).val();return c==null?null:f.isArray(c)?f.map(c,function(a,c){return{name:b.name,value:a.replace(bF,"\r\n")}}):{name:b.name,value:c.replace(bF,"\r\n")}}).get()}}),f.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),function(a,b){f.fn[b]=function(a){return this.on(b,a)}}),f.each(["get","post"],function(a,c){f[c]=function(a,d,e,g){f.isFunction(d)&&(g=g||e,e=d,d=b);return f.ajax({type:c,url:a,data:d,success:e,dataType:g})}}),f.extend({getScript:function(a,c){return f.get(a,b,c,"script")},getJSON:function(a,b,c){return f.get(a,b,c,"json")},ajaxSetup:function(a,b){b?b_(a,f.ajaxSettings):(b=a,a=f.ajaxSettings),b_(a,b);return a},ajaxSettings:{url:bV,isLocal:bJ.test(bW[1]),global:!0,type:"GET",contentType:"application/x-www-form-urlencoded",processData:!0,async:!0,accepts:{xml:"application/xml, text/xml",html:"text/html",text:"text/plain",json:"application/json, text/javascript","*":bX},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText"},converters:{"* text":a.String,"text html":!0,"text json":f.parseJSON,"text xml":f.parseXML},flatOptions:{context:!0,url:!0}},ajaxPrefilter:bZ(bT),ajaxTransport:bZ(bU),ajax:function(a,c){function w(a,c,l,m){if(s!==2){s=2,q&&clearTimeout(q),p=b,n=m||"",v.readyState=a>0?4:0;var o,r,u,w=c,x=l?cb(d,v,l):b,y,z;if(a>=200&&a<300||a===304){if(d.ifModified){if(y=v.getResponseHeader("Last-Modified"))f.lastModified[k]=y;if(z=v.getResponseHeader("Etag"))f.etag[k]=z}if(a===304)w="notmodified",o=!0;else try{r=cc(d,x),w="success",o=!0}catch(A){w="parsererror",u=A}}else{u=w;if(!w||a)w="error",a<0&&(a=0)}v.status=a,v.statusText=""+(c||w),o?h.resolveWith(e,[r,w,v]):h.rejectWith(e,[v,w,u]),v.statusCode(j),j=b,t&&g.trigger("ajax"+(o?"Success":"Error"),[v,d,o?r:u]),i.fireWith(e,[v,w]),t&&(g.trigger("ajaxComplete",[v,d]),--f.active||f.event.trigger("ajaxStop"))}}typeof a=="object"&&(c=a,a=b),c=c||{};var d=f.ajaxSetup({},c),e=d.context||d,g=e!==d&&(e.nodeType||e instanceof f)?f(e):f.event,h=f.Deferred(),i=f.Callbacks("once memory"),j=d.statusCode||{},k,l={},m={},n,o,p,q,r,s=0,t,u,v={readyState:0,setRequestHeader:function(a,b){if(!s){var c=a.toLowerCase();a=m[c]=m[c]||a,l[a]=b}return this},getAllResponseHeaders:function(){return s===2?n:null},getResponseHeader:function(a){var c;if(s===2){if(!o){o={};while(c=bH.exec(n))o[c[1].toLowerCase()]=c[2]}c=o[a.toLowerCase()]}return c===b?null:c},overrideMimeType:function(a){s||(d.mimeType=a);return this},abort:function(a){a=a||"abort",p&&p.abort(a),w(0,a);return this}};h.promise(v),v.success=v.done,v.error=v.fail,v.complete=i.add,v.statusCode=function(a){if(a){var b;if(s<2)for(b in a)j[b]=[j[b],a[b]];else b=a[v.status],v.then(b,b)}return this},d.url=((a||d.url)+"").replace(bG,"").replace(bL,bW[1]+"//"),d.dataTypes=f.trim(d.dataType||"*").toLowerCase().split(bP),d.crossDomain==null&&(r=bR.exec(d.url.toLowerCase()),d.crossDomain=!(!r||r[1]==bW[1]&&r[2]==bW[2]&&(r[3]||(r[1]==="http:"?80:443))==(bW[3]||(bW[1]==="http:"?80:443)))),d.data&&d.processData&&typeof d.data!="string"&&(d.data=f.param(d.data,d.traditional)),b$(bT,d,c,v);if(s===2)return!1;t=d.global,d.type=d.type.toUpperCase(),d.hasContent=!bK.test(d.type),t&&f.active++===0&&f.event.trigger("ajaxStart");if(!d.hasContent){d.data&&(d.url+=(bM.test(d.url)?"&":"?")+d.data,delete d.data),k=d.url;if(d.cache===!1){var x=f.now(),y=d.url.replace(bQ,"$1_="+x);d.url=y+(y===d.url?(bM.test(d.url)?"&":"?")+"_="+x:"")}}(d.data&&d.hasContent&&d.contentType!==!1||c.contentType)&&v.setRequestHeader("Content-Type",d.contentType),d.ifModified&&(k=k||d.url,f.lastModified[k]&&v.setRequestHeader("If-Modified-Since",f.lastModified[k]),f.etag[k]&&v.setRequestHeader("If-None-Match",f.etag[k])),v.setRequestHeader("Accept",d.dataTypes[0]&&d.accepts[d.dataTypes[0]]?d.accepts[d.dataTypes[0]]+(d.dataTypes[0]!=="*"?", "+bX+"; q=0.01":""):d.accepts["*"]);for(u in d.headers)v.setRequestHeader(u,d.headers[u]);if(d.beforeSend&&(d.beforeSend.call(e,v,d)===!1||s===2)){v.abort();return!1}for(u in{success:1,error:1,complete:1})v[u](d[u]);p=b$(bU,d,c,v);if(!p)w(-1,"No Transport");else{v.readyState=1,t&&g.trigger("ajaxSend",[v,d]),d.async&&d.timeout>0&&(q=setTimeout(function(){v.abort("timeout")},d.timeout));try{s=1,p.send(l,w)}catch(z){if(s<2)w(-1,z);else throw z}}return v},param:function(a,c){var d=[],e=function(a,b){b=f.isFunction(b)?b():b,d[d.length]=encodeURIComponent(a)+"="+encodeURIComponent(b)};c===b&&(c=f.ajaxSettings.traditional);if(f.isArray(a)||a.jquery&&!f.isPlainObject(a))f.each(a,function(){e(this.name,this.value)});else for(var g in a)ca(g,a[g],c,e);return d.join("&").replace(bD,"+")}}),f.extend({active:0,lastModified:{},etag:{}});var cd=f.now(),ce=/(\=)\?(&|$)|\?\?/i;f.ajaxSetup({jsonp:"callback",jsonpCallback:function(){return f.expando+"_"+cd++}}),f.ajaxPrefilter("json jsonp",function(b,c,d){var e=b.contentType==="application/x-www-form-urlencoded"&&typeof b.data=="string";if(b.dataTypes[0]==="jsonp"||b.jsonp!==!1&&(ce.test(b.url)||e&&ce.test(b.data))){var g,h=b.jsonpCallback=f.isFunction(b.jsonpCallback)?b.jsonpCallback():b.jsonpCallback,i=a[h],j=b.url,k=b.data,l="$1"+h+"$2";b.jsonp!==!1&&(j=j.replace(ce,l),b.url===j&&(e&&(k=k.replace(ce,l)),b.data===k&&(j+=(/\?/.test(j)?"&":"?")+b.jsonp+"="+h))),b.url=j,b.data=k,a[h]=function(a){g=[a]},d.always(function(){a[h]=i,g&&f.isFunction(i)&&a[h](g[0])}),b.converters["script json"]=function(){g||f.error(h+" was not called");return g[0]},b.dataTypes[0]="json";return"script"}}),f.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/javascript|ecmascript/},converters:{"text script":function(a){f.globalEval(a);return a}}}),f.ajaxPrefilter("script",function(a){a.cache===b&&(a.cache=!1),a.crossDomain&&(a.type="GET",a.global=!1)}),f.ajaxTransport("script",function(a){if(a.crossDomain){var d,e=c.head||c.getElementsByTagName("head")[0]||c.documentElement;return{send:function(f,g){d=c.createElement("script"),d.async="async",a.scriptCharset&&(d.charset=a.scriptCharset),d.src=a.url,d.onload=d.onreadystatechange=function(a,c){if(c||!d.readyState||/loaded|complete/.test(d.readyState))d.onload=d.onreadystatechange=null,e&&d.parentNode&&e.removeChild(d),d=b,c||g(200,"success")},e.insertBefore(d,e.firstChild)},abort:function(){d&&d.onload(0,1)}}}});var cf=a.ActiveXObject?function(){for(var a in ch)ch[a](0,1)}:!1,cg=0,ch;f.ajaxSettings.xhr=a.ActiveXObject?function(){return!this.isLocal&&ci()||cj()}:ci,function(a){f.extend(f.support,{ajax:!!a,cors:!!a&&"withCredentials"in a})}(f.ajaxSettings.xhr()),f.support.ajax&&f.ajaxTransport(function(c){if(!c.crossDomain||f.support.cors){var d;return{send:function(e,g){var h=c.xhr(),i,j;c.username?h.open(c.type,c.url,c.async,c.username,c.password):h.open(c.type,c.url,c.async);if(c.xhrFields)for(j in c.xhrFields)h[j]=c.xhrFields[j];c.mimeType&&h.overrideMimeType&&h.overrideMimeType(c.mimeType),!c.crossDomain&&!e["X-Requested-With"]&&(e["X-Requested-With"]="XMLHttpRequest");try{for(j in e)h.setRequestHeader(j,e[j])}catch(k){}h.send(c.hasContent&&c.data||null),d=function(a,e){var j,k,l,m,n;try{if(d&&(e||h.readyState===4)){d=b,i&&(h.onreadystatechange=f.noop,cf&&delete ch[i]);if(e)h.readyState!==4&&h.abort();else{j=h.status,l=h.getAllResponseHeaders(),m={},n=h.responseXML,n&&n.documentElement&&(m.xml=n),m.text=h.responseText;try{k=h.statusText}catch(o){k=""}!j&&c.isLocal&&!c.crossDomain?j=m.text?200:404:j===1223&&(j=204)}}}catch(p){e||g(-1,p)}m&&g(j,k,m,l)},!c.async||h.readyState===4?d():(i=++cg,cf&&(ch||(ch={},f(a).unload(cf)),ch[i]=d),h.onreadystatechange=d)},abort:function(){d&&d(0,1)}}}});var ck={},cl,cm,cn=/^(?:toggle|show|hide)$/,co=/^([+\-]=)?([\d+.\-]+)([a-z%]*)$/i,cp,cq=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]],cr;f.fn.extend({show:function(a,b,c){var d,e;if(a||a===0)return this.animate(cu("show",3),a,b,c);for(var g=0,h=this.length;g=i.duration+this.startTime){this.now=this.end,this.pos=this.state=1,this.update(),i.animatedProperties[this.prop]=!0;for(b in i.animatedProperties)i.animatedProperties[b]!==!0&&(g=!1);if(g){i.overflow!=null&&!f.support.shrinkWrapBlocks&&f.each(["","X","Y"],function(a,b){h.style["overflow"+b]=i.overflow[a]}),i.hide&&f(h).hide();if(i.hide||i.show)for(b in i.animatedProperties)f.style(h,b,i.orig[b]),f.removeData(h,"fxshow"+b,!0),f.removeData(h,"toggle"+b,!0);d=i.complete,d&&(i.complete=!1,d.call(h))}return!1}i.duration==Infinity?this.now=e:(c=e-this.startTime,this.state=c/i.duration,this.pos=f.easing[i.animatedProperties[this.prop]](this.state,c,0,1,i.duration),this.now=this.start+(this.end-this.start)*this.pos),this.update();return!0}},f.extend(f.fx,{tick:function(){var a,b=f.timers,c=0;for(;c-1,k={},l={},m,n;j?(l=e.position(),m=l.top,n=l.left):(m=parseFloat(h)||0,n=parseFloat(i)||0),f.isFunction(b)&&(b=b.call(a,c,g)),b.top!=null&&(k.top=b.top-g.top+m),b.left!=null&&(k.left=b.left-g.left+n),"using"in b?b.using.call(a,k):e.css(k)}},f.fn.extend({position:function(){if(!this[0])return null;var a=this[0],b=this.offsetParent(),c=this.offset(),d=cx.test(b[0].nodeName)?{top:0,left:0}:b.offset();c.top-=parseFloat(f.css(a,"marginTop"))||0,c.left-=parseFloat(f.css(a,"marginLeft"))||0,d.top+=parseFloat(f.css(b[0],"borderTopWidth"))||0,d.left+=parseFloat(f.css(b[0],"borderLeftWidth"))||0;return{top:c.top-d.top,left:c.left-d.left}},offsetParent:function(){return this.map(function(){var a=this.offsetParent||c.body;while(a&&!cx.test(a.nodeName)&&f.css(a,"position")==="static")a=a.offsetParent;return a})}}),f.each(["Left","Top"],function(a,c){var d="scroll"+c;f.fn[d]=function(c){var e,g;if(c===b){e=this[0];if(!e)return null;g=cy(e);return g?"pageXOffset"in g?g[a?"pageYOffset":"pageXOffset"]:f.support.boxModel&&g.document.documentElement[d]||g.document.body[d]:e[d]}return this.each(function(){g=cy(this),g?g.scrollTo(a?f(g).scrollLeft():c,a?c:f(g).scrollTop()):this[d]=c})}}),f.each(["Height","Width"],function(a,c){var d=c.toLowerCase();f.fn["inner"+c]=function(){var a=this[0];return a?a.style?parseFloat(f.css(a,d,"padding")):this[d]():null},f.fn["outer"+c]=function(a){var b=this[0];return b?b.style?parseFloat(f.css(b,d,a?"margin":"border")):this[d]():null},f.fn[d]=function(a){var e=this[0];if(!e)return a==null?null:this;if(f.isFunction(a))return this.each(function(b){var c=f(this);c[d](a.call(this,b,c[d]()))});if(f.isWindow(e)){var g=e.document.documentElement["client"+c],h=e.document.body;return e.document.compatMode==="CSS1Compat"&&g||h&&h["client"+c]||g}if(e.nodeType===9)return Math.max(e.documentElement["client"+c],e.body["scroll"+c],e.documentElement["scroll"+c],e.body["offset"+c],e.documentElement["offset"+c]);if(a===b){var i=f.css(e,d),j=parseFloat(i);return f.isNumeric(j)?j:i}return this.css(d,typeof a=="string"?a:a+"px")}}),a.jQuery=a.$=f,typeof define=="function"&&define.amd&&define.amd.jQuery&&define("jquery",[],function(){return f})})(window); -------------------------------------------------------------------------------- /js/modernizr.js: -------------------------------------------------------------------------------- 1 | /* Modernizr 2.5.3 (Custom Build) | MIT & BSD 2 | * Build: http://modernizr.com/download/#-csstransforms3d-svg-shiv-cssclasses-prefixed-teststyles-testprop-testallprops-prefixes-domprefixes-load 3 | */ 4 | ;window.Modernizr=function(a,b,c){function A(a){j.cssText=a}function B(a,b){return A(m.join(a+";")+(b||""))}function C(a,b){return typeof a===b}function D(a,b){return!!~(""+a).indexOf(b)}function E(a,b){for(var d in a)if(j[a[d]]!==c)return b=="pfx"?a[d]:!0;return!1}function F(a,b,d){for(var e in a){var f=b[a[e]];if(f!==c)return d===!1?a[e]:C(f,"function")?f.bind(d||b):f}return!1}function G(a,b,c){var d=a.charAt(0).toUpperCase()+a.substr(1),e=(a+" "+o.join(d+" ")+d).split(" ");return C(b,"string")||C(b,"undefined")?E(e,b):(e=(a+" "+p.join(d+" ")+d).split(" "),F(e,b,c))}var d="2.5.3",e={},f=!0,g=b.documentElement,h="modernizr",i=b.createElement(h),j=i.style,k,l={}.toString,m=" -webkit- -moz- -o- -ms- ".split(" "),n="Webkit Moz O ms",o=n.split(" "),p=n.toLowerCase().split(" "),q={svg:"http://www.w3.org/2000/svg"},r={},s={},t={},u=[],v=u.slice,w,x=function(a,c,d,e){var f,i,j,k=b.createElement("div"),l=b.body,m=l?l:b.createElement("body");if(parseInt(d,10))while(d--)j=b.createElement("div"),j.id=e?e[d]:h+(d+1),k.appendChild(j);return f=["­",""].join(""),k.id=h,(l?k:m).innerHTML+=f,m.appendChild(k),l||(m.style.background="",g.appendChild(m)),i=c(k,a),l?k.parentNode.removeChild(k):m.parentNode.removeChild(m),!!i},y={}.hasOwnProperty,z;!C(y,"undefined")&&!C(y.call,"undefined")?z=function(a,b){return y.call(a,b)}:z=function(a,b){return b in a&&C(a.constructor.prototype[b],"undefined")},Function.prototype.bind||(Function.prototype.bind=function(b){var c=this;if(typeof c!="function")throw new TypeError;var d=v.call(arguments,1),e=function(){if(this instanceof e){var a=function(){};a.prototype=c.prototype;var f=new a,g=c.apply(f,d.concat(v.call(arguments)));return Object(g)===g?g:f}return c.apply(b,d.concat(v.call(arguments)))};return e});var H=function(a,c){var d=a.join(""),f=c.length;x(d,function(a,c){var d=b.styleSheets[b.styleSheets.length-1],g=d?d.cssRules&&d.cssRules[0]?d.cssRules[0].cssText:d.cssText||"":"",h=a.childNodes,i={};while(f--)i[h[f].id]=h[f];e.csstransforms3d=(i.csstransforms3d&&i.csstransforms3d.offsetLeft)===9&&i.csstransforms3d.offsetHeight===3},f,c)}([,["@media (",m.join("transform-3d),("),h,")","{#csstransforms3d{left:9px;position:absolute;height:3px;}}"].join("")],[,"csstransforms3d"]);r.csstransforms3d=function(){var a=!!G("perspective");return a&&"webkitPerspective"in g.style&&(a=e.csstransforms3d),a},r.svg=function(){return!!b.createElementNS&&!!b.createElementNS(q.svg,"svg").createSVGRect};for(var I in r)z(r,I)&&(w=I.toLowerCase(),e[w]=r[I](),u.push((e[w]?"":"no-")+w));return A(""),i=k=null,function(a,b){function g(a,b){var c=a.createElement("p"),d=a.getElementsByTagName("head")[0]||a.documentElement;return c.innerHTML="x",d.insertBefore(c.lastChild,d.firstChild)}function h(){var a=k.elements;return typeof a=="string"?a.split(" "):a}function i(a){var b={},c=a.createElement,e=a.createDocumentFragment,f=e();a.createElement=function(a){var e=(b[a]||(b[a]=c(a))).cloneNode();return k.shivMethods&&e.canHaveChildren&&!d.test(a)?f.appendChild(e):e},a.createDocumentFragment=Function("h,f","return function(){var n=f.cloneNode(),c=n.createElement;h.shivMethods&&("+h().join().replace(/\w+/g,function(a){return b[a]=c(a),f.createElement(a),'c("'+a+'")'})+");return n}")(k,f)}function j(a){var b;return a.documentShived?a:(k.shivCSS&&!e&&(b=!!g(a,"article,aside,details,figcaption,figure,footer,header,hgroup,nav,section{display:block}audio{display:none}canvas,video{display:inline-block;*display:inline;*zoom:1}[hidden]{display:none}audio[controls]{display:inline-block;*display:inline;*zoom:1}mark{background:#FF0;color:#000}")),f||(b=!i(a)),b&&(a.documentShived=b),a)}var c=a.html5||{},d=/^<|^(?:button|form|map|select|textarea)$/i,e,f;(function(){var a=b.createElement("a");a.innerHTML="",e="hidden"in a,f=a.childNodes.length==1||function(){try{b.createElement("a")}catch(a){return!0}var c=b.createDocumentFragment();return typeof c.cloneNode=="undefined"||typeof c.createDocumentFragment=="undefined"||typeof c.createElement=="undefined"}()})();var k={elements:c.elements||"abbr article aside audio bdi canvas data datalist details figcaption figure footer header hgroup mark meter nav output progress section summary time video",shivCSS:c.shivCSS!==!1,shivMethods:c.shivMethods!==!1,type:"default",shivDocument:j};a.html5=k,j(b)}(this,b),e._version=d,e._prefixes=m,e._domPrefixes=p,e._cssomPrefixes=o,e.testProp=function(a){return E([a])},e.testAllProps=G,e.testStyles=x,e.prefixed=function(a,b,c){return b?G(a,b,c):G(a,"pfx")},g.className=g.className.replace(/(^|\s)no-js(\s|$)/,"$1$2")+(f?" js "+u.join(" "):""),e}(this,this.document),function(a,b,c){function d(a){return o.call(a)=="[object Function]"}function e(a){return typeof a=="string"}function f(){}function g(a){return!a||a=="loaded"||a=="complete"||a=="uninitialized"}function h(){var a=p.shift();q=1,a?a.t?m(function(){(a.t=="c"?B.injectCss:B.injectJs)(a.s,0,a.a,a.x,a.e,1)},0):(a(),h()):q=0}function i(a,c,d,e,f,i,j){function k(b){if(!o&&g(l.readyState)&&(u.r=o=1,!q&&h(),l.onload=l.onreadystatechange=null,b)){a!="img"&&m(function(){t.removeChild(l)},50);for(var d in y[c])y[c].hasOwnProperty(d)&&y[c][d].onload()}}var j=j||B.errorTimeout,l={},o=0,r=0,u={t:d,s:c,e:f,a:i,x:j};y[c]===1&&(r=1,y[c]=[],l=b.createElement(a)),a=="object"?l.data=c:(l.src=c,l.type=a),l.width=l.height="0",l.onerror=l.onload=l.onreadystatechange=function(){k.call(this,r)},p.splice(e,0,u),a!="img"&&(r||y[c]===2?(t.insertBefore(l,s?null:n),m(k,j)):y[c].push(l))}function j(a,b,c,d,f){return q=0,b=b||"j",e(a)?i(b=="c"?v:u,a,b,this.i++,c,d,f):(p.splice(this.i++,0,a),p.length==1&&h()),this}function k(){var a=B;return a.loader={load:j,i:0},a}var l=b.documentElement,m=a.setTimeout,n=b.getElementsByTagName("script")[0],o={}.toString,p=[],q=0,r="MozAppearance"in l.style,s=r&&!!b.createRange().compareNode,t=s?l:n.parentNode,l=a.opera&&o.call(a.opera)=="[object Opera]",l=!!b.attachEvent&&!l,u=r?"object":l?"script":"img",v=l?"script":u,w=Array.isArray||function(a){return o.call(a)=="[object Array]"},x=[],y={},z={timeout:function(a,b){return b.length&&(a.timeout=b[0]),a}},A,B;B=function(a){function b(a){var a=a.split("!"),b=x.length,c=a.pop(),d=a.length,c={url:c,origUrl:c,prefixes:a},e,f,g;for(f=0;f .5) { 160 | anglePercentage = 1 - anglePercentage; 161 | } 162 | var range = Math.abs(this.maxShade + this.maxTint); 163 | var rangedPercentage = range * anglePercentage; 164 | this.rangedPercentage = rangedPercentage; 165 | 166 | // determine whether to shade or tint 167 | if(rangedPercentage <= this.maxTint) { 168 | background = 'rgba(255, 255, 255, ' + Math.abs(this.maxTint - rangedPercentage) + ')'; 169 | } else { 170 | background = 'rgba(0, 0, 0, ' + Math.abs(rangedPercentage - this.maxTint) + ')'; 171 | } 172 | 173 | // apply the shading 174 | this.shaderElement.style.background = background; 175 | }, 176 | 177 | setMaxShade: function(value) { 178 | this.maxShade = value; 179 | }, 180 | 181 | setMaxTint: function(value) { 182 | this.maxTint = value; 183 | } 184 | }; 185 | 186 | 187 | // create the element to used for shading and tinting 188 | Photon.ShaderElement = function(parent) { 189 | var shaderElement = document.createElement('div'); 190 | shaderElement.className = 'photon-shader'; 191 | shaderElement.style.position = 'absolute'; 192 | shaderElement.style.top = '0'; 193 | shaderElement.style.left = '0'; 194 | shaderElement.style.width = window.getComputedStyle(parent).width; 195 | shaderElement.style.height = window.getComputedStyle(parent).height; 196 | 197 | return shaderElement; 198 | } 199 | 200 | 201 | // a group of faces within a single parent object 202 | Photon.FaceGroup = function(parent, faces, maxShade, maxTint, isBackfaced) { 203 | this.element = parent; 204 | this.faces = []; 205 | this.transformString = Photon.getTransformString(); 206 | 207 | var childFaces = faces; 208 | for(var i = 0; i < childFaces.length; i++) { 209 | this.faces[i] = new Photon.Face(childFaces[i], maxShade, maxTint, isBackfaced); 210 | } 211 | } 212 | 213 | Photon.FaceGroup.prototype = { 214 | getRotations: function() { 215 | var faceTransform = window.getComputedStyle(this.element)[this.transformString] || 'matrix3d(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)'; 216 | 217 | this.matrix = Photon.buildMatrix(faceTransform); 218 | var faceDecomp = this.matrix.decompose(); 219 | 220 | this.rotations = { 221 | x: faceDecomp.rotate.x, 222 | y: faceDecomp.rotate.y, 223 | z: faceDecomp.rotate.z 224 | }; 225 | 226 | this.vector = Photon.getRotationVector($V([0, 0, 1]), this.rotations); 227 | }, 228 | 229 | render: function(light, getNewGroupRotations, getNewFaceRotations) { 230 | if(getNewGroupRotations) { 231 | this.getRotations(); 232 | } 233 | 234 | this.angleFrom = Photon.radToDeg(light.vector.angleFrom(this.vector)); 235 | 236 | for(var i = 0, length = this.faces.length; i < length; i++) { 237 | this.faces[i].render(light, getNewFaceRotations, this.rotations); 238 | } 239 | }, 240 | 241 | setMaxShade: function(value) { 242 | for(var i = 0; i < this.faces.length; i++) { 243 | this.faces[i].setMaxShade(value); 244 | } 245 | }, 246 | 247 | setMaxTint: function(value) { 248 | for(var i = 0; i < this.faces.length; i++) { 249 | this.faces[i].setMaxTint(value); 250 | } 251 | } 252 | }; 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | // === Sylvester === 266 | // Vector and Matrix mathematics modules for JavaScript 267 | // Copyright (c) 2007 James Coglan 268 | // 269 | // Permission is hereby granted, free of charge, to any person obtaining 270 | // a copy of this software and associated documentation files (the "Software"), 271 | // to deal in the Software without restriction, including without limitation 272 | // the rights to use, copy, modify, merge, publish, distribute, sublicense, 273 | // and/or sell copies of the Software, and to permit persons to whom the 274 | // Software is furnished to do so, subject to the following conditions: 275 | // 276 | // The above copyright notice and this permission notice shall be included 277 | // in all copies or substantial portions of the Software. 278 | // 279 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 280 | // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 281 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 282 | // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 283 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 284 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 285 | // DEALINGS IN THE SOFTWARE. 286 | 287 | 288 | var Sylvester = { 289 | version: '0.1.3', 290 | precision: 1e-6 291 | }; 292 | 293 | 294 | 295 | function Vector() {} 296 | Vector.prototype = { 297 | 298 | // Returns the modulus ('length') of the vector 299 | modulus: function() { 300 | return Math.sqrt(this.dot(this)); 301 | }, 302 | 303 | // Returns a copy of the vector 304 | dup: function() { 305 | return Vector.create(this.elements); 306 | }, 307 | 308 | // Calls the iterator for each element of the vector in turn 309 | each: function(fn) { 310 | var n = this.elements.length, k = n, i; 311 | do { i = k - n; 312 | fn(this.elements[i], i+1); 313 | } while (--n); 314 | }, 315 | 316 | // Returns the angle between the vector and the argument (also a vector) 317 | angleFrom: function(vector) { 318 | var V = vector.elements || vector; 319 | var n = this.elements.length, k = n, i; 320 | if (n != V.length) { return null; } 321 | var dot = 0, mod1 = 0, mod2 = 0; 322 | // Work things out in parallel to save time 323 | this.each(function(x, i) { 324 | dot += x * V[i-1]; 325 | mod1 += x * x; 326 | mod2 += V[i-1] * V[i-1]; 327 | }); 328 | mod1 = Math.sqrt(mod1); mod2 = Math.sqrt(mod2); 329 | if (mod1*mod2 === 0) { return null; } 330 | var theta = dot / (mod1*mod2); 331 | if (theta < -1) { theta = -1; } 332 | if (theta > 1) { theta = 1; } 333 | return Math.acos(theta); 334 | }, 335 | 336 | // Returns the scalar product of the vector with the argument 337 | // Both vectors must have equal dimensionality 338 | dot: function(vector) { 339 | var V = vector.elements || vector; 340 | var i, product = 0, n = this.elements.length; 341 | if (n != V.length) { return null; } 342 | do { product += this.elements[n-1] * V[n-1]; } while (--n); 343 | return product; 344 | }, 345 | 346 | // Rotates the vector about the given object. The object should be a 347 | // point if the vector is 2D, and a line if it is 3D. Be careful with line directions! 348 | rotate: function(t, obj) { 349 | var V, R, x, y, z; 350 | switch (this.elements.length) { 351 | case 2: 352 | V = obj.elements || obj; 353 | if (V.length != 2) { return null; } 354 | R = Matrix.Rotation(t).elements; 355 | x = this.elements[0] - V[0]; 356 | y = this.elements[1] - V[1]; 357 | return Vector.create([ 358 | V[0] + R[0][0] * x + R[0][1] * y, 359 | V[1] + R[1][0] * x + R[1][1] * y 360 | ]); 361 | break; 362 | case 3: 363 | if (!obj.direction) { return null; } 364 | var C = obj.pointClosestTo(this).elements; 365 | R = Matrix.Rotation(t, obj.direction).elements; 366 | x = this.elements[0] - C[0]; 367 | y = this.elements[1] - C[1]; 368 | z = this.elements[2] - C[2]; 369 | return Vector.create([ 370 | C[0] + R[0][0] * x + R[0][1] * y + R[0][2] * z, 371 | C[1] + R[1][0] * x + R[1][1] * y + R[1][2] * z, 372 | C[2] + R[2][0] * x + R[2][1] * y + R[2][2] * z 373 | ]); 374 | break; 375 | default: 376 | return null; 377 | } 378 | }, 379 | 380 | // Set vector's elements from an array 381 | setElements: function(els) { 382 | this.elements = (els.elements || els).slice(); 383 | return this; 384 | } 385 | }; 386 | 387 | // Constructor function 388 | Vector.create = function(elements) { 389 | var V = new Vector(); 390 | return V.setElements(elements); 391 | }; 392 | 393 | var $V = Vector.create; 394 | 395 | 396 | 397 | function Line() {} 398 | Line.prototype = { 399 | 400 | // Returns the line's perpendicular distance from the argument, 401 | // which can be a point, a line or a plane 402 | distanceFrom: function(obj) { 403 | if (obj.normal) { return obj.distanceFrom(this); } 404 | if (obj.direction) { 405 | // obj is a line 406 | if (this.isParallelTo(obj)) { return this.distanceFrom(obj.anchor); } 407 | var N = this.direction.cross(obj.direction).toUnitVector().elements; 408 | var A = this.anchor.elements, B = obj.anchor.elements; 409 | return Math.abs((A[0] - B[0]) * N[0] + (A[1] - B[1]) * N[1] + (A[2] - B[2]) * N[2]); 410 | } else { 411 | // obj is a point 412 | var P = obj.elements || obj; 413 | var A = this.anchor.elements, D = this.direction.elements; 414 | var PA1 = P[0] - A[0], PA2 = P[1] - A[1], PA3 = (P[2] || 0) - A[2]; 415 | var modPA = Math.sqrt(PA1*PA1 + PA2*PA2 + PA3*PA3); 416 | if (modPA === 0) return 0; 417 | // Assumes direction vector is normalized 418 | var cosTheta = (PA1 * D[0] + PA2 * D[1] + PA3 * D[2]) / modPA; 419 | var sin2 = 1 - cosTheta*cosTheta; 420 | return Math.abs(modPA * Math.sqrt(sin2 < 0 ? 0 : sin2)); 421 | } 422 | }, 423 | 424 | // Returns true iff the argument is a point on the line 425 | contains: function(point) { 426 | var dist = this.distanceFrom(point); 427 | return (dist !== null && dist <= Sylvester.precision); 428 | }, 429 | 430 | // Returns the point on the line that is closest to the given point or line 431 | pointClosestTo: function(obj) { 432 | if (obj.direction) { 433 | // obj is a line 434 | if (this.intersects(obj)) { return this.intersectionWith(obj); } 435 | if (this.isParallelTo(obj)) { return null; } 436 | var D = this.direction.elements, E = obj.direction.elements; 437 | var D1 = D[0], D2 = D[1], D3 = D[2], E1 = E[0], E2 = E[1], E3 = E[2]; 438 | // Create plane containing obj and the shared normal and intersect this with it 439 | // Thank you: http://www.cgafaq.info/wiki/Line-line_distance 440 | var x = (D3 * E1 - D1 * E3), y = (D1 * E2 - D2 * E1), z = (D2 * E3 - D3 * E2); 441 | var N = Vector.create([x * E3 - y * E2, y * E1 - z * E3, z * E2 - x * E1]); 442 | var P = Plane.create(obj.anchor, N); 443 | return P.intersectionWith(this); 444 | } else { 445 | // obj is a point 446 | var P = obj.elements || obj; 447 | if (this.contains(P)) { return Vector.create(P); } 448 | var A = this.anchor.elements, D = this.direction.elements; 449 | var D1 = D[0], D2 = D[1], D3 = D[2], A1 = A[0], A2 = A[1], A3 = A[2]; 450 | var x = D1 * (P[1]-A2) - D2 * (P[0]-A1), y = D2 * ((P[2] || 0) - A3) - D3 * (P[1]-A2), 451 | z = D3 * (P[0]-A1) - D1 * ((P[2] || 0) - A3); 452 | var V = Vector.create([D2 * x - D3 * z, D3 * y - D1 * x, D1 * z - D2 * y]); 453 | var k = this.distanceFrom(P) / V.modulus(); 454 | return Vector.create([ 455 | P[0] + V.elements[0] * k, 456 | P[1] + V.elements[1] * k, 457 | (P[2] || 0) + V.elements[2] * k 458 | ]); 459 | } 460 | }, 461 | 462 | // Returns a copy of the line rotated by t radians about the given line. Works by 463 | // finding the argument's closest point to this line's anchor point (call this C) and 464 | // rotating the anchor about C. Also rotates the line's direction about the argument's. 465 | // Be careful with this - the rotation axis' direction affects the outcome! 466 | rotate: function(t, line) { 467 | // If we're working in 2D 468 | if (typeof(line.direction) == 'undefined') { line = Line.create(line.to3D(), Vector.k); } 469 | var R = Matrix.Rotation(t, line.direction).elements; 470 | var C = line.pointClosestTo(this.anchor).elements; 471 | var A = this.anchor.elements, D = this.direction.elements; 472 | var C1 = C[0], C2 = C[1], C3 = C[2], A1 = A[0], A2 = A[1], A3 = A[2]; 473 | var x = A1 - C1, y = A2 - C2, z = A3 - C3; 474 | return Line.create([ 475 | C1 + R[0][0] * x + R[0][1] * y + R[0][2] * z, 476 | C2 + R[1][0] * x + R[1][1] * y + R[1][2] * z, 477 | C3 + R[2][0] * x + R[2][1] * y + R[2][2] * z 478 | ], [ 479 | R[0][0] * D[0] + R[0][1] * D[1] + R[0][2] * D[2], 480 | R[1][0] * D[0] + R[1][1] * D[1] + R[1][2] * D[2], 481 | R[2][0] * D[0] + R[2][1] * D[1] + R[2][2] * D[2] 482 | ]); 483 | }, 484 | 485 | // Set the line's anchor point and direction. 486 | setVectors: function(anchor, direction) { 487 | // Need to do this so that line's properties are not 488 | // references to the arguments passed in 489 | anchor = Vector.create(anchor); 490 | direction = Vector.create(direction); 491 | if (anchor.elements.length == 2) {anchor.elements.push(0); } 492 | if (direction.elements.length == 2) { direction.elements.push(0); } 493 | if (anchor.elements.length > 3 || direction.elements.length > 3) { return null; } 494 | var mod = direction.modulus(); 495 | if (mod === 0) { return null; } 496 | this.anchor = anchor; 497 | this.direction = Vector.create([ 498 | direction.elements[0] / mod, 499 | direction.elements[1] / mod, 500 | direction.elements[2] / mod 501 | ]); 502 | return this; 503 | } 504 | }; 505 | 506 | // Constructor function 507 | Line.create = function(anchor, direction) { 508 | var L = new Line(); 509 | return L.setVectors(anchor, direction); 510 | }; 511 | 512 | 513 | 514 | function Matrix() {} 515 | Matrix.prototype = { 516 | // Set the matrix's elements from an array. If the argument passed 517 | // is a vector, the resulting matrix will be a single column. 518 | setElements: function(els) { 519 | var i, elements = els.elements || els; 520 | if (typeof(elements[0][0]) != 'undefined') { 521 | var ni = elements.length, ki = ni, nj, kj, j; 522 | this.elements = []; 523 | do { i = ki - ni; 524 | nj = elements[i].length; kj = nj; 525 | this.elements[i] = []; 526 | do { j = kj - nj; 527 | this.elements[i][j] = elements[i][j]; 528 | } while (--nj); 529 | } while(--ni); 530 | return this; 531 | } 532 | var n = elements.length, k = n; 533 | this.elements = []; 534 | do { i = k - n; 535 | this.elements.push([elements[i]]); 536 | } while (--n); 537 | return this; 538 | } 539 | }; 540 | 541 | // Constructor function 542 | Matrix.create = function(elements) { 543 | var M = new Matrix(); 544 | return M.setElements(elements); 545 | }; 546 | 547 | Matrix.Rotation = function(theta, a) { 548 | if (!a) { 549 | return Matrix.create([ 550 | [Math.cos(theta), -Math.sin(theta)], 551 | [Math.sin(theta), Math.cos(theta)] 552 | ]); 553 | } 554 | var axis = a.dup(); 555 | if (axis.elements.length != 3) { return null; } 556 | var mod = axis.modulus(); 557 | var x = axis.elements[0]/mod, y = axis.elements[1]/mod, z = axis.elements[2]/mod; 558 | var s = Math.sin(theta), c = Math.cos(theta), t = 1 - c; 559 | // Formula derived here: http://www.gamedev.net/reference/articles/article1199.asp 560 | // That proof rotates the co-ordinate system so theta 561 | // becomes -theta and sin becomes -sin here. 562 | return Matrix.create([ 563 | [ t*x*x + c, t*x*y - s*z, t*x*z + s*y ], 564 | [ t*x*y + s*z, t*y*y + c, t*y*z - s*x ], 565 | [ t*x*z - s*y, t*y*z + s*x, t*z*z + c ] 566 | ]); 567 | }; 568 | 569 | 570 | 571 | 572 | 573 | 574 | 575 | 576 | 577 | 578 | 579 | 580 | 581 | /** 582 | * class FirminCSSMatrix 583 | * 584 | * The [[FirminCSSMatrix]] class is a concrete implementation of the 585 | * `CSSMatrix` interface defined in the [CSS 2D Transforms][2d] and 586 | * [CSS 3D Transforms][3d] Module specifications. 587 | * 588 | * [2d]: http://www.w3.org/TR/css3-2d-transforms/ 589 | * [3d]: http://www.w3.org/TR/css3-3d-transforms/ 590 | * 591 | * The implementation was largely copied from the `WebKitCSSMatrix` class, and 592 | * the supparting maths libraries in the [WebKit][webkit] project. This is one 593 | * reason why much of the code looks more like C++ than JavaScript. 594 | * 595 | * [webkit]: http://webkit.org/ 596 | * 597 | * Its API is a superset of that provided by `WebKitCSSMatrix`, largely 598 | * because various pieces of supporting code have been added as instance 599 | * methods rather than pollute the global namespace. Examples of these include 600 | * [[FirminCSSMatrix#isAffine]], [[FirminCSSMatrix#isIdentityOrTranslation]] 601 | * and [[FirminCSSMatrix#adjoint]]. 602 | **/ 603 | 604 | /** 605 | * new FirminCSSMatrix(domstr) 606 | * - domstr (String): a string representation of a 2D or 3D transform matrix 607 | * in the form given by the CSS transform property, i.e. just like the 608 | * output from [[FirminCSSMatrix#toString]]. 609 | **/ 610 | FirminCSSMatrix = function(domstr) { 611 | this.m11 = this.m22 = this.m33 = this.m44 = 1; 612 | 613 | this.m12 = this.m13 = this.m14 = 614 | this.m21 = this.m23 = this.m24 = 615 | this.m31 = this.m32 = this.m34 = 616 | this.m41 = this.m42 = this.m43 = 0; 617 | 618 | if (typeof domstr == "string") { 619 | this.setMatrixValue(domstr); 620 | } 621 | }; 622 | 623 | /** 624 | * FirminCSSMatrix.displayName = "FirminCSSMatrix" 625 | **/ 626 | FirminCSSMatrix.displayName = "FirminCSSMatrix"; 627 | 628 | /** 629 | * FirminCSSMatrix.degreesToRadians(angle) -> Number 630 | * - angle (Number): an angle in degrees. 631 | * 632 | * Converts angles in degrees, which are used by the external API, to angles 633 | * in radians used in internal calculations. 634 | **/ 635 | FirminCSSMatrix.degreesToRadians = function(angle) { 636 | return angle * Math.PI / 180; 637 | }; 638 | 639 | /** 640 | * FirminCSSMatrix#isAffine() -> Boolean 641 | * 642 | * Determines whether the matrix is affine. 643 | **/ 644 | FirminCSSMatrix.prototype.isAffine = function() { 645 | return this.m13 === 0 && this.m14 === 0 && 646 | this.m23 === 0 && this.m24 === 0 && 647 | this.m31 === 0 && this.m32 === 0 && 648 | this.m33 === 1 && this.m34 === 0 && 649 | this.m43 === 0 && this.m44 === 1; 650 | }; 651 | 652 | 653 | 654 | /** 655 | * FirminCSSMatrix#setMatrixValue(domstr) -> undefined 656 | * - domstr (String): a string representation of a 2D or 3D transform matrix 657 | * in the form given by the CSS transform property, i.e. just like the 658 | * output from [[FirminCSSMatrix#toString]]. 659 | * 660 | * Sets the matrix values using a string representation, such as that produced 661 | * by the [[FirminCSSMatrix#toString]] method. 662 | **/ 663 | FirminCSSMatrix.prototype.setMatrixValue = function(domstr) { 664 | domstr = domstr.trim(); 665 | var mstr = domstr.match(/^matrix(3d)?\(\s*(.+)\s*\)$/), 666 | is3d, chunks, len, points, i, chunk; 667 | 668 | if (!mstr) return; 669 | 670 | is3d = !!mstr[1]; 671 | chunks = mstr[2].split(/\s*,\s*/); 672 | len = chunks.length; 673 | points = new Array(len); 674 | 675 | if ((is3d && len !== 16) || !(is3d || len === 6)) return; 676 | 677 | for (i = 0; i < len; i++) { 678 | chunk = chunks[i]; 679 | if (chunk.match(/^-?\d+(\.\d+)?$/)) { 680 | points[i] = parseFloat(chunk); 681 | } else return; 682 | } 683 | 684 | for (i = 0; i < len; i++) { 685 | point = is3d ? 686 | ("m" + (Math.floor(i / 4) + 1)) + (i % 4 + 1) : 687 | String.fromCharCode(i + 97); // ASCII char 97 == 'a' 688 | this[point] = points[i]; 689 | } 690 | }; 691 | 692 | /** 693 | * FirminCSSMatrix#toString() -> String 694 | * 695 | * Returns a string representation of the matrix. 696 | **/ 697 | FirminCSSMatrix.prototype.toString = function() { 698 | var self = this, points, prefix; 699 | 700 | if (this.isAffine()) { 701 | prefix = "matrix("; 702 | points = ["a", "b", "c", "d", "e", "f"]; 703 | } else { 704 | prefix = "matrix3d("; 705 | points = ["m11", "m12", "m13", "m14", 706 | "m21", "m22", "m23", "m24", 707 | "m31", "m32", "m33", "m34", 708 | "m41", "m42", "m43", "m44"]; 709 | } 710 | 711 | return prefix + points.map(function(p) { 712 | return self[p].toFixed(6); 713 | }).join(", ") + ")"; 714 | }; 715 | 716 | 717 | 718 | 719 | 720 | 721 | 722 | 723 | 724 | 725 | 726 | 727 | 728 | 729 | /* 730 | * @preserve Morf v0.1.5 731 | * http://www.joelambert.co.uk/morf 732 | * 733 | * Copyright 2011, Joe Lambert. 734 | * Free to use under the MIT license. 735 | * http://www.opensource.org/licenses/mit-license.php 736 | */ 737 | 738 | var CSSMatrixDecomposed = function(obj) { 739 | obj === undefined ? obj = {} : null; 740 | var components = {perspective: null, translate: null, skew: null, scale: null, rotate: null}; 741 | 742 | for(var i in components) 743 | this[i] = obj[i] ? obj[i] : new Vector4(); 744 | 745 | /** 746 | * Tween between two decomposed matrices 747 | * @param {CSSMatrixDecomposed} dm The destination decomposed matrix 748 | * @param {float} progress A float value between 0-1, representing the percentage of completion 749 | * @param {function} fn An easing function following the prototype function(pos){} 750 | * @author Joe Lambert 751 | * @returns {WebKitCSSMatrix} A new matrix for the tweened state 752 | */ 753 | 754 | this.tween = function(dm, progress, fn) { 755 | if(fn === undefined) 756 | fn = function(pos) {return pos;}; // Default to a linear easing 757 | 758 | if(!dm) 759 | dm = new CSSMatrixDecomposed(new FirminCSSMatrix().decompose()); 760 | 761 | var r = new CSSMatrixDecomposed(), 762 | i = index = null, 763 | trans = ''; 764 | 765 | progress = fn(progress); 766 | 767 | for(index in components) 768 | for(i in {x:'x', y:'y', z:'z', w:'w'}) 769 | r[index][i] = (this[index][i] + (dm[index][i] - this[index][i]) * progress ).toFixed(5); 770 | 771 | trans = 'matrix3d(1,0,0,0, 0,1,0,0, 0,0,1,0, '+r.perspective.x+', '+r.perspective.y+', '+r.perspective.z+', '+r.perspective.w+') ' + 772 | 'translate3d('+r.translate.x+'px, '+r.translate.y+'px, '+r.translate.y+'px) ' + 773 | 'rotateX('+r.rotate.x+'rad) rotateY('+r.rotate.y+'rad) rotateZ('+r.rotate.z+'rad) ' + 774 | 'matrix3d(1,0,0,0, 0,1,0,0, 0,'+r.skew.z+',1,0, 0,0,0,1) ' + 775 | 'matrix3d(1,0,0,0, 0,1,0,0, '+r.skew.y+',0,1,0, 0,0,0,1) ' + 776 | 'matrix3d(1,0,0,0, '+r.skew.x+',1,0,0, 0,0,1,0, 0,0,0,1) ' + 777 | 'scale3d('+r.scale.x+', '+r.scale.y+', '+r.scale.z+')'; 778 | 779 | try { r = new FirminCSSMatrix(trans); return r; } 780 | catch(e) { console.error('Invalid matrix string: '+trans); return '' }; 781 | }; 782 | }; 783 | 784 | var Vector4 = function(x, y, z, w) 785 | { 786 | this.x = x ? x : 0; 787 | this.y = y ? y : 0; 788 | this.z = z ? z : 0; 789 | this.w = w ? w : 0; 790 | 791 | 792 | /** 793 | * Ensure that values are not undefined 794 | * @author Joe Lambert 795 | * @returns null 796 | */ 797 | 798 | this.checkValues = function() { 799 | this.x = this.x ? this.x : 0; 800 | this.y = this.y ? this.y : 0; 801 | this.z = this.z ? this.z : 0; 802 | this.w = this.w ? this.w : 0; 803 | }; 804 | 805 | 806 | /** 807 | * Get the length of the vector 808 | * @author Joe Lambert 809 | * @returns {float} 810 | */ 811 | 812 | this.length = function() { 813 | this.checkValues(); 814 | return Math.sqrt(this.x*this.x + this.y*this.y + this.z*this.z); 815 | }; 816 | 817 | 818 | /** 819 | * Get a normalised representation of the vector 820 | * @author Joe Lambert 821 | * @returns {Vector4} 822 | */ 823 | 824 | this.normalise = function() { 825 | var len = this.length(), 826 | v = new Vector4(this.x / len, this.y / len, this.z / len); 827 | 828 | return v; 829 | }; 830 | 831 | 832 | /** 833 | * Vector Dot-Product 834 | * @param {Vector4} v The second vector to apply the product to 835 | * @author Joe Lambert 836 | * @returns {float} The Dot-Product of this and v. 837 | */ 838 | 839 | this.dot = function(v) { 840 | return this.x*v.x + this.y*v.y + this.z*v.z + this.w*v.w; 841 | }; 842 | 843 | 844 | /** 845 | * Vector Cross-Product 846 | * @param {Vector4} v The second vector to apply the product to 847 | * @author Joe Lambert 848 | * @returns {Vector4} The Cross-Product of this and v. 849 | */ 850 | 851 | this.cross = function(v) { 852 | return new Vector4(this.y*v.z - this.z*v.y, this.z*v.x - this.x*v.z, this.x*v.y - this.y*v.x); 853 | }; 854 | 855 | 856 | /** 857 | * Helper function required for matrix decomposition 858 | * A Javascript implementation of pseudo code available from http://www.w3.org/TR/css3-2d-transforms/#matrix-decomposition 859 | * @param {Vector4} aPoint A 3D point 860 | * @param {float} ascl 861 | * @param {float} bscl 862 | * @author Joe Lambert 863 | * @returns {Vector4} 864 | */ 865 | 866 | this.combine = function(aPoint, ascl, bscl) { 867 | return new Vector4( (ascl * this.x) + (bscl * aPoint.x), 868 | (ascl * this.y) + (bscl * aPoint.y), 869 | (ascl * this.z) + (bscl * aPoint.z) ); 870 | } 871 | }; 872 | 873 | FirminCSSMatrix.prototype.determinant = function() { 874 | return this.m14 * this.m23 * this.m32 * this.m41-this.m13 * this.m24 * this.m32 * this.m41 - 875 | this.m14 * this.m22 * this.m33 * this.m41+this.m12 * this.m24 * this.m33 * this.m41 + 876 | this.m13 * this.m22 * this.m34 * this.m41-this.m12 * this.m23 * this.m34 * this.m41 - 877 | this.m14 * this.m23 * this.m31 * this.m42+this.m13 * this.m24 * this.m31 * this.m42 + 878 | this.m14 * this.m21 * this.m33 * this.m42-this.m11 * this.m24 * this.m33 * this.m42 - 879 | this.m13 * this.m21 * this.m34 * this.m42+this.m11 * this.m23 * this.m34 * this.m42 + 880 | this.m14 * this.m22 * this.m31 * this.m43-this.m12 * this.m24 * this.m31 * this.m43 - 881 | this.m14 * this.m21 * this.m32 * this.m43+this.m11 * this.m24 * this.m32 * this.m43 + 882 | this.m12 * this.m21 * this.m34 * this.m43-this.m11 * this.m22 * this.m34 * this.m43 - 883 | this.m13 * this.m22 * this.m31 * this.m44+this.m12 * this.m23 * this.m31 * this.m44 + 884 | this.m13 * this.m21 * this.m32 * this.m44-this.m11 * this.m23 * this.m32 * this.m44 - 885 | this.m12 * this.m21 * this.m33 * this.m44+this.m11 * this.m22 * this.m33 * this.m44; 886 | }; 887 | 888 | FirminCSSMatrix.prototype.decompose = function() { 889 | var matrix = new FirminCSSMatrix(this.toString()), 890 | perspectiveMatrix = rightHandSide = inversePerspectiveMatrix = transposedInversePerspectiveMatrix = 891 | perspective = translate = row = i = scale = skew = pdum3 = rotate = null; 892 | 893 | if (matrix.m33 == 0) 894 | return new CSSMatrixDecomposed(new FirminCSSMatrix().decompose()); // Return the identity matrix 895 | 896 | // Normalize the matrix. 897 | for (i = 1; i <= 4; i++) 898 | for (j = 1; j <= 4; j++) 899 | matrix['m'+i+j] /= matrix.m44; 900 | 901 | // perspectiveMatrix is used to solve for perspective, but it also provides 902 | // an easy way to test for singularity of the upper 3x3 component. 903 | perspectiveMatrix = matrix; 904 | 905 | for (i = 1; i <= 3; i++) 906 | perspectiveMatrix['m'+i+'4'] = 0; 907 | 908 | perspectiveMatrix.m44 = 1; 909 | 910 | if (perspectiveMatrix.determinant() == 0) 911 | return new CSSMatrixDecomposed(new FirminCSSMatrix().decompose()); // Return the identity matrix 912 | 913 | // First, isolate perspective. 914 | if (matrix.m14 != 0 || matrix.m24 != 0 || matrix.m34 != 0) 915 | { 916 | // rightHandSide is the right hand side of the equation. 917 | rightHandSide = new Vector4(matrix.m14, matrix.m24, matrix.m34, matrix.m44); 918 | 919 | // Solve the equation by inverting perspectiveMatrix and multiplying 920 | // rightHandSide by the inverse. 921 | inversePerspectiveMatrix = perspectiveMatrix.inverse(); 922 | transposedInversePerspectiveMatrix = inversePerspectiveMatrix.transpose(); 923 | perspective = transposedInversePerspectiveMatrix.transformVector(rightHandSide); 924 | 925 | // Clear the perspective partition 926 | matrix.m14 = matrix.m24 = matrix.m34 = 0; 927 | matrix.m44 = 1; 928 | } 929 | else 930 | { 931 | // No perspective. 932 | perspective = new Vector4(0,0,0,1); 933 | } 934 | 935 | // Next take care of translation 936 | translate = new Vector4(matrix.m41, matrix.m42, matrix.m43); 937 | 938 | matrix.m41 = 0; 939 | matrix.m42 = 0; 940 | matrix.m43 = 0; 941 | 942 | // Now get scale and shear. 'row' is a 3 element array of 3 component vectors 943 | row = [ 944 | new Vector4(), new Vector4(), new Vector4() 945 | ]; 946 | 947 | for (i = 1; i <= 3; i++) 948 | { 949 | row[i-1].x = matrix['m'+i+'1']; 950 | row[i-1].y = matrix['m'+i+'2']; 951 | row[i-1].z = matrix['m'+i+'3']; 952 | } 953 | 954 | // Compute X scale factor and normalize first row. 955 | scale = new Vector4(); 956 | skew = new Vector4(); 957 | 958 | scale.x = row[0].length(); 959 | row[0] = row[0].normalise(); 960 | 961 | // Compute XY shear factor and make 2nd row orthogonal to 1st. 962 | skew.x = row[0].dot(row[1]); 963 | row[1] = row[1].combine(row[0], 1.0, -skew.x); 964 | 965 | // Now, compute Y scale and normalize 2nd row. 966 | scale.y = row[1].length(); 967 | row[1] = row[1].normalise(); 968 | skew.x /= scale.y; 969 | 970 | // Compute XZ and YZ shears, orthogonalize 3rd row 971 | skew.y = row[0].dot(row[2]); 972 | row[2] = row[2].combine(row[0], 1.0, -skew.y); 973 | skew.z = row[1].dot(row[2]); 974 | row[2] = row[2].combine(row[1], 1.0, -skew.z); 975 | 976 | // Next, get Z scale and normalize 3rd row. 977 | scale.z = row[2].length(); 978 | row[2] = row[2].normalise(); 979 | skew.y /= scale.z; 980 | skew.y /= scale.z; 981 | 982 | // At this point, the matrix (in rows) is orthonormal. 983 | // Check for a coordinate system flip. If the determinant 984 | // is -1, then negate the matrix and the scaling factors. 985 | pdum3 = row[1].cross(row[2]) 986 | if (row[0].dot(pdum3) < 0) 987 | { 988 | for (i = 0; i < 3; i++) 989 | { 990 | scale.x *= -1; 991 | row[i].x *= -1; 992 | row[i].y *= -1; 993 | row[i].z *= -1; 994 | } 995 | } 996 | 997 | // Now, get the rotations out 998 | rotate = new Vector4(); 999 | rotate.y = Math.asin(-row[0].z); 1000 | if (Math.cos(rotate.y) != 0) 1001 | { 1002 | rotate.x = Math.atan2(row[1].z, row[2].z); 1003 | rotate.z = Math.atan2(row[0].y, row[0].x); 1004 | } 1005 | else 1006 | { 1007 | rotate.x = Math.atan2(-row[2].x, row[1].y); 1008 | rotate.z = 0; 1009 | } 1010 | 1011 | return new CSSMatrixDecomposed({ 1012 | perspective: perspective, 1013 | translate: translate, 1014 | skew: skew, 1015 | scale: scale, 1016 | rotate: rotate 1017 | }); 1018 | }; -------------------------------------------------------------------------------- /js/photon.min.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Photon 3 | * http://photon.attasi.com 4 | * 5 | * Licensed under the MIT license. 6 | * Copyright 2012 Tom Giannattasio 7 | */ 8 | 9 | var Photon={version:"0.0.3",degToRad:function(a){return a*Math.PI/180},radToDeg:function(a){return a*180/Math.PI},getRotationVector:function(b,a){var e=b.rotate(a.x,Line.create([0,0,0],[1,0,0]));var c=e.rotate(a.y,Line.create([0,0,0],[0,1,0]));var d=c.rotate(a.z,Line.create([0,0,0],[0,0,1]));return d},getTransformString:function(){if(Photon.transformString){return Photon.transformString}var c;var d=["transform","webkitTransform","MozTransform","msTransform","OTransform"];var b=document.createElement("div");for(var a=0;a0.5){d=1-d}var c=Math.abs(this.maxShade+this.maxTint);var a=c*d;this.rangedPercentage=a;if(a<=this.maxTint){f="rgba(255, 255, 255, "+Math.abs(this.maxTint-a)+")"}else{f="rgba(0, 0, 0, "+Math.abs(a-this.maxTint)+")"}this.shaderElement.style.background=f},setMaxShade:function(a){this.maxShade=a},setMaxTint:function(a){this.maxTint=a}};Photon.ShaderElement=function(a){var b=document.createElement("div");b.className="photon-shader";b.style.position="absolute";b.style.top="0";b.style.left="0";b.style.width=window.getComputedStyle(a).width;b.style.height=window.getComputedStyle(a).height;return b};Photon.FaceGroup=function(f,a,c,b,d){this.element=f;this.faces=[];this.transformString=Photon.getTransformString();var g=a;for(var e=0;e1){b=1}return Math.acos(b)},dot:function(b){var a=b.elements||b;var c,d=0,e=this.elements.length;if(e!=a.length){return null}do{d+=this.elements[e-1]*a[e-1]}while(--e);return d},rotate:function(c,e){var b,d,a,h,g;switch(this.elements.length){case 2:b=e.elements||e;if(b.length!=2){return null}d=Matrix.Rotation(c).elements;a=this.elements[0]-b[0];h=this.elements[1]-b[1];return Vector.create([b[0]+d[0][0]*a+d[0][1]*h,b[1]+d[1][0]*a+d[1][1]*h]);break;case 3:if(!e.direction){return null}var f=e.pointClosestTo(this).elements;d=Matrix.Rotation(c,e.direction).elements;a=this.elements[0]-f[0];h=this.elements[1]-f[1];g=this.elements[2]-f[2];return Vector.create([f[0]+d[0][0]*a+d[0][1]*h+d[0][2]*g,f[1]+d[1][0]*a+d[1][1]*h+d[1][2]*g,f[2]+d[2][0]*a+d[2][1]*h+d[2][2]*g]);break;default:return null}},setElements:function(a){this.elements=(a.elements||a).slice();return this}};Vector.create=function(b){var a=new Vector();return a.setElements(b)};var $V=Vector.create;function Line(){}Line.prototype={distanceFrom:function(e){if(e.normal){return e.distanceFrom(this)}if(e.direction){if(this.isParallelTo(e)){return this.distanceFrom(e.anchor)}var k=this.direction.cross(e.direction).toUnitVector().elements;var c=this.anchor.elements,b=e.anchor.elements;return Math.abs((c[0]-b[0])*k[0]+(c[1]-b[1])*k[1]+(c[2]-b[2])*k[2])}else{var f=e.elements||e;var c=this.anchor.elements,a=this.direction.elements;var n=f[0]-c[0],l=f[1]-c[1],g=(f[2]||0)-c[2];var m=Math.sqrt(n*n+l*l+g*g);if(m===0){return 0}var h=(n*a[0]+l*a[1]+g*a[2])/m;var d=1-h*h;return Math.abs(m*Math.sqrt(d<0?0:d))}},contains:function(a){var b=this.distanceFrom(a);return(b!==null&&b<=Sylvester.precision)},pointClosestTo:function(s){if(s.direction){if(this.intersects(s)){return this.intersectionWith(s)}if(this.isParallelTo(s)){return null}var u=this.direction.elements,t=s.direction.elements;var f=u[0],e=u[1],c=u[2],q=t[0],o=t[1],m=t[2];var r=(c*q-f*m),p=(f*o-e*q),n=(e*m-c*o);var l=Vector.create([r*m-p*o,p*q-n*m,n*o-r*q]);var h=Plane.create(s.anchor,l);return h.intersectionWith(this)}else{var h=s.elements||s;if(this.contains(h)){return Vector.create(h)}var v=this.anchor.elements,u=this.direction.elements;var f=u[0],e=u[1],c=u[2],d=v[0],b=v[1],a=v[2];var r=f*(h[1]-b)-e*(h[0]-d),p=e*((h[2]||0)-a)-c*(h[1]-b),n=c*(h[0]-d)-f*((h[2]||0)-a);var g=Vector.create([e*r-c*n,c*p-f*r,f*n-e*p]);var w=this.distanceFrom(h)/g.modulus();return Vector.create([h[0]+g.elements[0]*w,h[1]+g.elements[1]*w,(h[2]||0)+g.elements[2]*w])}},rotate:function(p,q){if(typeof(q.direction)=="undefined"){q=Line.create(q.to3D(),Vector.k)}var g=Matrix.Rotation(p,q.direction).elements;var b=q.pointClosestTo(this.anchor).elements;var d=this.anchor.elements,a=this.direction.elements;var l=b[0],k=b[1],h=b[2],f=d[0],e=d[1],c=d[2];var o=f-l,n=e-k,m=c-h;return Line.create([l+g[0][0]*o+g[0][1]*n+g[0][2]*m,k+g[1][0]*o+g[1][1]*n+g[1][2]*m,h+g[2][0]*o+g[2][1]*n+g[2][2]*m],[g[0][0]*a[0]+g[0][1]*a[1]+g[0][2]*a[2],g[1][0]*a[0]+g[1][1]*a[1]+g[1][2]*a[2],g[2][0]*a[0]+g[2][1]*a[1]+g[2][2]*a[2]])},setVectors:function(a,c){a=Vector.create(a);c=Vector.create(c);if(a.elements.length==2){a.elements.push(0)}if(c.elements.length==2){c.elements.push(0)}if(a.elements.length>3||c.elements.length>3){return null}var b=c.modulus();if(b===0){return null}this.anchor=a;this.direction=Vector.create([c.elements[0]/b,c.elements[1]/b,c.elements[2]/b]);return this}};Line.create=function(b,c){var a=new Line();return a.setVectors(b,c)};function Matrix(){}Matrix.prototype={setElements:function(h){var m,a=h.elements||h;if(typeof(a[0][0])!="undefined"){var d=a.length,f=d,b,c,l;this.elements=[];do{m=f-d;b=a[m].length;c=b;this.elements[m]=[];do{l=c-b;this.elements[m][l]=a[m][l]}while(--b)}while(--d);return this}var e=a.length,g=e;this.elements=[];do{m=g-e;this.elements.push([a[m]])}while(--e);return this}};Matrix.create=function(a){var b=new Matrix();return b.setElements(a)};Matrix.Rotation=function(b,k){if(!k){return Matrix.create([[Math.cos(b),-Math.sin(b)],[Math.sin(b),Math.cos(b)]])}var d=k.dup();if(d.elements.length!=3){return null}var h=d.modulus();var l=d.elements[0]/h,g=d.elements[1]/h,f=d.elements[2]/h;var n=Math.sin(b),e=Math.cos(b),m=1-e;return Matrix.create([[m*l*l+e,m*l*g-n*f,m*l*f+n*g],[m*l*g+n*f,m*g*g+e,m*g*f-n*l],[m*l*f-n*g,m*g*f+n*l,m*f*f+e]])};FirminCSSMatrix=function(a){this.m11=this.m22=this.m33=this.m44=1;this.m12=this.m13=this.m14=this.m21=this.m23=this.m24=this.m31=this.m32=this.m34=this.m41=this.m42=this.m43=0;if(typeof a=="string"){this.setMatrixValue(a)}};FirminCSSMatrix.displayName="FirminCSSMatrix";FirminCSSMatrix.degreesToRadians=function(a){return a*Math.PI/180};FirminCSSMatrix.prototype.isAffine=function(){return this.m13===0&&this.m14===0&&this.m23===0&&this.m24===0&&this.m31===0&&this.m32===0&&this.m33===1&&this.m34===0&&this.m43===0&&this.m44===1};FirminCSSMatrix.prototype.setMatrixValue=function(g){g=g.trim();var b=g.match(/^matrix(3d)?\(\s*(.+)\s*\)$/),f,h,a,e,d,c;if(!b){return}f=!!b[1];h=b[2].split(/\s*,\s*/);a=h.length;e=new Array(a);if((f&&a!==16)||!(f||a===6)){return}for(d=0;d