| OLD | NEW |
| 1 | 1 |
| 2 (function() { | 2 (function() { |
| 3 var Utility = { | 3 var Utility = { |
| 4 cssColorWithAlpha: function(cssColor, alpha) { | 4 cssColorWithAlpha: function(cssColor, alpha) { |
| 5 var parts = cssColor.match(/^rgb\((\d+),\s*(\d+),\s*(\d+)\)$/); | 5 var parts = cssColor.match(/^rgb\((\d+),\s*(\d+),\s*(\d+)\)$/); |
| 6 | 6 |
| 7 if (typeof alpha == 'undefined') { | 7 if (typeof alpha == 'undefined') { |
| 8 alpha = 1; | 8 alpha = 1; |
| 9 } | 9 } |
| 10 | 10 |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 76 this.resetInteractionState(); | 76 this.resetInteractionState(); |
| 77 } | 77 } |
| 78 | 78 |
| 79 Ripple.MAX_RADIUS = 300; | 79 Ripple.MAX_RADIUS = 300; |
| 80 | 80 |
| 81 Ripple.prototype = { | 81 Ripple.prototype = { |
| 82 get recenters() { | 82 get recenters() { |
| 83 return this.element.recenters; | 83 return this.element.recenters; |
| 84 }, | 84 }, |
| 85 | 85 |
| 86 get center() { |
| 87 return this.element.center; |
| 88 }, |
| 89 |
| 86 get mouseDownElapsed() { | 90 get mouseDownElapsed() { |
| 87 var elapsed; | 91 var elapsed; |
| 88 | 92 |
| 89 if (!this.mouseDownStart) { | 93 if (!this.mouseDownStart) { |
| 90 return 0; | 94 return 0; |
| 91 } | 95 } |
| 92 | 96 |
| 93 elapsed = Utility.now() - this.mouseDownStart; | 97 elapsed = Utility.now() - this.mouseDownStart; |
| 94 | 98 |
| 95 if (this.mouseUpStart) { | 99 if (this.mouseUpStart) { |
| (...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 232 | 236 |
| 233 | 237 |
| 234 // 2d transform for safari because of border-radius and overflow:hidden
clipping bug. | 238 // 2d transform for safari because of border-radius and overflow:hidden
clipping bug. |
| 235 // https://bugs.webkit.org/show_bug.cgi?id=98538 | 239 // https://bugs.webkit.org/show_bug.cgi?id=98538 |
| 236 this.waveContainer.style.webkitTransform = 'translate(' + dx + 'px, ' +
dy + 'px)'; | 240 this.waveContainer.style.webkitTransform = 'translate(' + dx + 'px, ' +
dy + 'px)'; |
| 237 this.waveContainer.style.transform = 'translate3d(' + dx + 'px, ' + dy +
'px, 0)'; | 241 this.waveContainer.style.transform = 'translate3d(' + dx + 'px, ' + dy +
'px, 0)'; |
| 238 this.wave.style.webkitTransform = 'scale(' + scale + ',' + scale + ')'; | 242 this.wave.style.webkitTransform = 'scale(' + scale + ',' + scale + ')'; |
| 239 this.wave.style.transform = 'scale3d(' + scale + ',' + scale + ',1)'; | 243 this.wave.style.transform = 'scale3d(' + scale + ',' + scale + ',1)'; |
| 240 }, | 244 }, |
| 241 | 245 |
| 242 mousedownAction: function(event) { | 246 downAction: function(event) { |
| 247 var xCenter = this.containerMetrics.width / 2; |
| 248 var yCenter = this.containerMetrics.height / 2; |
| 249 |
| 243 this.resetInteractionState(); | 250 this.resetInteractionState(); |
| 244 this.mouseDownStart = Utility.now(); | 251 this.mouseDownStart = Utility.now(); |
| 245 | 252 |
| 246 this.xStart = event ? | 253 if (this.center) { |
| 247 event.x - this.containerMetrics.boundingRect.left : | 254 this.xStart = xCenter; |
| 248 this.containerMetrics.width / 2; | 255 this.yStart = yCenter; |
| 249 this.yStart = event ? | |
| 250 event.y - this.containerMetrics.boundingRect.top : | |
| 251 this.containerMetrics.height / 2; | |
| 252 | |
| 253 if (this.recenters) { | |
| 254 this.xEnd = this.containerMetrics.width / 2; | |
| 255 this.yEnd = this.containerMetrics.height / 2; | |
| 256 this.slideDistance = Utility.distance( | 256 this.slideDistance = Utility.distance( |
| 257 this.xStart, this.yStart, this.xEnd, this.yEnd | 257 this.xStart, this.yStart, this.xEnd, this.yEnd |
| 258 ); | 258 ); |
| 259 } else { |
| 260 this.xStart = event ? |
| 261 event.detail.x - this.containerMetrics.boundingRect.left : |
| 262 this.containerMetrics.width / 2; |
| 263 this.yStart = event ? |
| 264 event.detail.y - this.containerMetrics.boundingRect.top : |
| 265 this.containerMetrics.height / 2; |
| 266 } |
| 267 |
| 268 if (this.recenters) { |
| 269 this.xEnd = xCenter; |
| 270 this.yEnd = yCenter; |
| 271 this.slideDistance = Utility.distance( |
| 272 this.xStart, this.yStart, this.xEnd, this.yEnd |
| 273 ); |
| 259 } | 274 } |
| 260 | 275 |
| 261 this.maxRadius = this.containerMetrics.furthestCornerDistanceFrom( | 276 this.maxRadius = this.containerMetrics.furthestCornerDistanceFrom( |
| 262 this.xStart, | 277 this.xStart, |
| 263 this.yStart | 278 this.yStart |
| 264 ); | 279 ); |
| 265 | 280 |
| 266 this.waveContainer.style.top = | 281 this.waveContainer.style.top = |
| 267 (this.containerMetrics.height - this.containerMetrics.size) / 2 + 'px'
; | 282 (this.containerMetrics.height - this.containerMetrics.size) / 2 + 'px'
; |
| 268 this.waveContainer.style.left = | 283 this.waveContainer.style.left = |
| 269 (this.containerMetrics.width - this.containerMetrics.size) / 2 + 'px'; | 284 (this.containerMetrics.width - this.containerMetrics.size) / 2 + 'px'; |
| 270 | 285 |
| 271 this.waveContainer.style.width = this.containerMetrics.size + 'px'; | 286 this.waveContainer.style.width = this.containerMetrics.size + 'px'; |
| 272 this.waveContainer.style.height = this.containerMetrics.size + 'px'; | 287 this.waveContainer.style.height = this.containerMetrics.size + 'px'; |
| 273 }, | 288 }, |
| 274 | 289 |
| 275 mouseupAction: function(event) { | 290 upAction: function(event) { |
| 276 if (!this.isMouseDown) { | 291 if (!this.isMouseDown) { |
| 277 return; | 292 return; |
| 278 } | 293 } |
| 279 | 294 |
| 280 this.mouseUpStart = Utility.now(); | 295 this.mouseUpStart = Utility.now(); |
| 281 }, | 296 }, |
| 282 | 297 |
| 283 remove: function() { | 298 remove: function() { |
| 284 Polymer.dom(this.waveContainer.parentNode).removeChild( | 299 Polymer.dom(this.waveContainer.parentNode).removeChild( |
| 285 this.waveContainer | 300 this.waveContainer |
| 286 ); | 301 ); |
| 287 } | 302 } |
| 288 }; | 303 }; |
| 289 | 304 |
| 290 Polymer({ | 305 Polymer({ |
| 291 is: 'paper-ripple', | 306 is: 'paper-ripple', |
| 292 | 307 |
| 308 behaviors: [ |
| 309 Polymer.IronA11yKeysBehavior |
| 310 ], |
| 311 |
| 293 properties: { | 312 properties: { |
| 294 /** | 313 /** |
| 295 * The initial opacity set on the wave. | 314 * The initial opacity set on the wave. |
| 296 * | 315 * |
| 297 * @attribute initialOpacity | 316 * @attribute initialOpacity |
| 298 * @type number | 317 * @type number |
| 299 * @default 0.25 | 318 * @default 0.25 |
| 300 */ | 319 */ |
| 301 initialOpacity: { | 320 initialOpacity: { |
| 302 type: Number, | 321 type: Number, |
| (...skipping 19 matching lines...) Expand all Loading... |
| 322 * @attribute recenters | 341 * @attribute recenters |
| 323 * @type boolean | 342 * @type boolean |
| 324 * @default false | 343 * @default false |
| 325 */ | 344 */ |
| 326 recenters: { | 345 recenters: { |
| 327 type: Boolean, | 346 type: Boolean, |
| 328 value: false | 347 value: false |
| 329 }, | 348 }, |
| 330 | 349 |
| 331 /** | 350 /** |
| 351 * If true, ripples will center inside its container |
| 352 * |
| 353 * @attribute recenters |
| 354 * @type boolean |
| 355 * @default false |
| 356 */ |
| 357 center: { |
| 358 type: Boolean, |
| 359 value: false |
| 360 }, |
| 361 |
| 362 /** |
| 332 * A list of the visual ripples. | 363 * A list of the visual ripples. |
| 333 * | 364 * |
| 334 * @attribute ripples | 365 * @attribute ripples |
| 335 * @type Array | 366 * @type Array |
| 336 * @default [] | 367 * @default [] |
| 337 */ | 368 */ |
| 338 ripples: { | 369 ripples: { |
| 339 type: Array, | 370 type: Array, |
| 340 value: function() { | 371 value: function() { |
| 341 return []; | 372 return []; |
| 342 } | 373 } |
| 343 }, | 374 }, |
| 344 | 375 |
| 376 /** |
| 377 * True when there are visible ripples animating within the |
| 378 * element. |
| 379 */ |
| 380 animating: { |
| 381 type: Boolean, |
| 382 readOnly: true, |
| 383 reflectToAttribute: true, |
| 384 value: false |
| 385 }, |
| 386 |
| 387 /** |
| 388 * If true, the ripple will remain in the "down" state until `holdDown` |
| 389 * is set to false again. |
| 390 */ |
| 391 holdDown: { |
| 392 type: Boolean, |
| 393 value: false, |
| 394 observer: '_holdDownChanged' |
| 395 }, |
| 396 |
| 345 _animating: { | 397 _animating: { |
| 346 type: Boolean | 398 type: Boolean |
| 347 }, | 399 }, |
| 348 | 400 |
| 349 _boundAnimate: { | 401 _boundAnimate: { |
| 350 type: Function, | 402 type: Function, |
| 351 value: function() { | 403 value: function() { |
| 352 return this.animate.bind(this); | 404 return this.animate.bind(this); |
| 353 } | 405 } |
| 354 }, | |
| 355 | |
| 356 _boundMousedownAction: { | |
| 357 type: Function, | |
| 358 value: function() { | |
| 359 return this.mousedownAction.bind(this); | |
| 360 } | |
| 361 }, | |
| 362 | |
| 363 _boundMouseupAction: { | |
| 364 type: Function, | |
| 365 value: function() { | |
| 366 return this.mouseupAction.bind(this); | |
| 367 } | |
| 368 } | 406 } |
| 369 }, | 407 }, |
| 370 | 408 |
| 371 get target () { | 409 get target () { |
| 372 return this.host || this.parentNode; | 410 var ownerRoot = Polymer.dom(this).getOwnerRoot(); |
| 411 var target; |
| 412 |
| 413 if (ownerRoot) { |
| 414 target = ownerRoot.host; |
| 415 } |
| 416 |
| 417 if (!target) { |
| 418 target = this.parentNode; |
| 419 } |
| 420 |
| 421 return target; |
| 422 }, |
| 423 |
| 424 keyBindings: { |
| 425 'enter:keydown': '_onEnterKeydown', |
| 426 'space:keydown': '_onSpaceKeydown', |
| 427 'space:keyup': '_onSpaceKeyup' |
| 373 }, | 428 }, |
| 374 | 429 |
| 375 attached: function() { | 430 attached: function() { |
| 376 this.target.addEventListener('mousedown', this._boundMousedownAction); | 431 this._listen(this.target, 'up', this.upAction.bind(this)); |
| 377 this.target.addEventListener('mouseup', this._boundMouseupAction); | 432 this._listen(this.target, 'down', this.downAction.bind(this)); |
| 433 |
| 434 if (!this.target.hasAttribute('noink')) { |
| 435 this.keyEventTarget = this.target; |
| 436 } |
| 378 }, | 437 }, |
| 379 | 438 |
| 380 detached: function() { | |
| 381 this.target.removeEventListener('mousedown', this._boundMousedownAction)
; | |
| 382 this.target.removeEventListener('mouseup', this._boundMouseupAction); | |
| 383 }, | |
| 384 | |
| 385 /* TODO(cdata): Replace the above attached / detached listeners when | |
| 386 PolymerGestures equivalent lands in 0.8. | |
| 387 listeners: { | |
| 388 mousedown: 'mousedownAction', | |
| 389 mouseup: 'mouseupAction' | |
| 390 }, | |
| 391 */ | |
| 392 | |
| 393 get shouldKeepAnimating () { | 439 get shouldKeepAnimating () { |
| 394 for (var index = 0; index < this.ripples.length; ++index) { | 440 for (var index = 0; index < this.ripples.length; ++index) { |
| 395 if (!this.ripples[index].isAnimationComplete) { | 441 if (!this.ripples[index].isAnimationComplete) { |
| 396 return true; | 442 return true; |
| 397 } | 443 } |
| 398 } | 444 } |
| 399 | 445 |
| 400 return false; | 446 return false; |
| 401 }, | 447 }, |
| 402 | 448 |
| 403 simulatedRipple: function() { | 449 simulatedRipple: function() { |
| 404 this.mousedownAction(null); | 450 this.downAction(null); |
| 405 | 451 |
| 406 // Please see polymer/polymer#1305 | 452 // Please see polymer/polymer#1305 |
| 407 this.async(function() { | 453 this.async(function() { |
| 408 this.mouseupAction(); | 454 this.upAction(); |
| 409 }, 1); | 455 }, 1); |
| 410 }, | 456 }, |
| 411 | 457 |
| 412 mousedownAction: function(event) { | 458 downAction: function(event) { |
| 459 if (this.holdDown && this.ripples.length > 0) { |
| 460 return; |
| 461 } |
| 462 |
| 413 var ripple = this.addRipple(); | 463 var ripple = this.addRipple(); |
| 414 | 464 |
| 415 ripple.mousedownAction(event); | 465 ripple.downAction(event); |
| 416 | 466 |
| 417 if (!this._animating) { | 467 if (!this._animating) { |
| 418 this.animate(); | 468 this.animate(); |
| 419 } | 469 } |
| 420 }, | 470 }, |
| 421 | 471 |
| 422 mouseupAction: function(event) { | 472 upAction: function(event) { |
| 473 if (this.holdDown) { |
| 474 return; |
| 475 } |
| 476 |
| 423 this.ripples.forEach(function(ripple) { | 477 this.ripples.forEach(function(ripple) { |
| 424 ripple.mouseupAction(event); | 478 ripple.upAction(event); |
| 425 }); | 479 }); |
| 426 | 480 |
| 427 this.animate(); | 481 this.animate(); |
| 428 }, | 482 }, |
| 429 | 483 |
| 430 onAnimationComplete: function() { | 484 onAnimationComplete: function() { |
| 431 this._animating = false; | 485 this._animating = false; |
| 432 this.$.background.style.backgroundColor = null; | 486 this.$.background.style.backgroundColor = null; |
| 433 this.fire('transitionend'); | 487 this.fire('transitionend'); |
| 434 }, | 488 }, |
| 435 | 489 |
| 436 addRipple: function() { | 490 addRipple: function() { |
| 437 var ripple = new Ripple(this); | 491 var ripple = new Ripple(this); |
| 438 | 492 |
| 439 Polymer.dom(this.$.waves).appendChild(ripple.waveContainer); | 493 Polymer.dom(this.$.waves).appendChild(ripple.waveContainer); |
| 440 this.$.background.style.backgroundColor = ripple.color; | 494 this.$.background.style.backgroundColor = ripple.color; |
| 441 this.ripples.push(ripple); | 495 this.ripples.push(ripple); |
| 442 | 496 |
| 497 this._setAnimating(true); |
| 498 |
| 443 return ripple; | 499 return ripple; |
| 444 }, | 500 }, |
| 445 | 501 |
| 446 removeRipple: function(ripple) { | 502 removeRipple: function(ripple) { |
| 447 var rippleIndex = this.ripples.indexOf(ripple); | 503 var rippleIndex = this.ripples.indexOf(ripple); |
| 448 | 504 |
| 449 if (rippleIndex < 0) { | 505 if (rippleIndex < 0) { |
| 450 return; | 506 return; |
| 451 } | 507 } |
| 452 | 508 |
| 453 this.ripples.splice(rippleIndex, 1); | 509 this.ripples.splice(rippleIndex, 1); |
| 454 | 510 |
| 455 ripple.remove(); | 511 ripple.remove(); |
| 512 |
| 513 if (!this.ripples.length) { |
| 514 this._setAnimating(false); |
| 515 } |
| 456 }, | 516 }, |
| 457 | 517 |
| 458 animate: function() { | 518 animate: function() { |
| 459 var index; | 519 var index; |
| 460 var ripple; | 520 var ripple; |
| 461 | 521 |
| 462 this._animating = true; | 522 this._animating = true; |
| 463 | 523 |
| 464 for (index = 0; index < this.ripples.length; ++index) { | 524 for (index = 0; index < this.ripples.length; ++index) { |
| 465 ripple = this.ripples[index]; | 525 ripple = this.ripples[index]; |
| 466 | 526 |
| 467 ripple.draw(); | 527 ripple.draw(); |
| 468 | 528 |
| 469 this.$.background.style.opacity = ripple.outerOpacity; | 529 this.$.background.style.opacity = ripple.outerOpacity; |
| 470 | 530 |
| 471 if (ripple.isOpacityFullyDecayed && !ripple.isRestingAtMaxRadius) { | 531 if (ripple.isOpacityFullyDecayed && !ripple.isRestingAtMaxRadius) { |
| 472 this.removeRipple(ripple); | 532 this.removeRipple(ripple); |
| 473 } | 533 } |
| 474 } | 534 } |
| 475 | 535 |
| 476 if (this.shouldKeepAnimating) { | 536 if (!this.shouldKeepAnimating && this.ripples.length === 0) { |
| 537 this.onAnimationComplete(); |
| 538 } else { |
| 477 window.requestAnimationFrame(this._boundAnimate); | 539 window.requestAnimationFrame(this._boundAnimate); |
| 478 } else if (this.ripples.length === 0) { | 540 } |
| 479 this.onAnimationComplete(); | 541 }, |
| 542 |
| 543 _onEnterKeydown: function() { |
| 544 this.downAction(); |
| 545 this.async(this.upAction, 1); |
| 546 }, |
| 547 |
| 548 _onSpaceKeydown: function() { |
| 549 this.downAction(); |
| 550 }, |
| 551 |
| 552 _onSpaceKeyup: function() { |
| 553 this.upAction(); |
| 554 }, |
| 555 |
| 556 _holdDownChanged: function(holdDown) { |
| 557 if (holdDown) { |
| 558 this.downAction(); |
| 559 } else { |
| 560 this.upAction(); |
| 480 } | 561 } |
| 481 } | 562 } |
| 482 }); | 563 }); |
| 483 })(); | 564 })(); |
| OLD | NEW |