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 |