UNPKG

foam-framework

Version:
198 lines (187 loc) 5.5 kB
/** * @license * Copyright 2015 Google Inc. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ CLASS({ package: 'foam.ui.md', name: 'Halo', extends: 'foam.graphics.Circle', constant: { RING_INNER_COLOR: 'rgba(0, 0, 0, 0)' }, properties: [ { name: 'style', documentation: 'solid|ring', defaultValue: 'solid', postSet: function(_, style) { if ( style !== this.RING_INNER_COLOR ) this.setColorAndBorder(); } }, { name: 'state_', defaultValue: 'default' // pressed, released }, { name: 'nextColor_', defaultValueFn: function() { return this.color; } }, { name: 'color', preSet: function(old, nu) { if ( this.state_ !== 'default' ) { // store it for next animation this.nextColor_ = nu; return old; } return nu; } }, { name: 'easeInTime', defaultValue: 200 }, { name: 'easeOutTime', defaultValue: 150 }, { name: 'startAlpha', defaultValue: 0.8 }, { name: 'pressedAlpha', defaultValue: 0.4 }, { name: 'finishAlpha', defaultValue: 0 }, { name: 'alpha', defaultValue: 0 }, { name: 'recentering', defaultValue: true }, { model_: 'FunctionProperty', name: 'isEnabled', defaultValue: function() { return true; } } ], methods: [ { name: 'setColorAndBorder', code: function() { if ( this.style === 'ring' ) { var color = this.color; this.border = color; this.borderWidth = 12; this.color = this.RING_INNER_COLOR; } } }, { name: 'initCView', code: function() { this.$.addEventListener('mousedown', this.onMouseDown); this.$.addEventListener('mouseup', this.onMouseUp); this.$.addEventListener('mouseleave', this.onMouseUp); this.$.addEventListener('touchstart', this.onMouseDown); this.$.addEventListener('touchend', this.onMouseUp); this.$.addEventListener('touchleave', this.onMouseUp); this.$.addEventListener('touchcancel', this.onMouseUp); } }, { name: 'isTouchInRect', code: function(t, rect) { return t.clientX >= rect.left && t.clientX <= rect.right && t.clientY >= rect.top && t.clientY <= rect.bottom; } } ], listeners: [ { name: 'onMouseDown', code: function(evt) { if ( this.state_ !== 'default' || ! this.isEnabled() ) return; this.state_ = 'pressing'; if ( evt.type === 'touchstart' ) { var rect = this.$.getBoundingClientRect(), touchFound = false, t; for ( var i = 0; i < evt.touches.length; ++i ) { t = evt.touches[i]; if ( this.isTouchInRect(t, rect) ) { touchFound = true; break; } } if ( touchFound ) { this.x = (t.clientX - rect.left); this.y = (t.clientY - rect.top); } else { // Default to center of element. console.warn('No touches', evt.touches, 'in element rect', rect); this.x = rect.width / 2; this.y = rect.height / 2; } } else { this.x = evt.offsetX; this.y = evt.offsetY; } this.r = 2; this.alpha = this.startAlpha; var recentering = this.recentering; this.X.animate(this.easeInTime, function() { if ( recentering ) { this.x = this.parent.width/2; this.y = this.parent.height/2; this.r = Math.min(28, Math.min(this.$.clientWidth, this.parent.height)/2); } else { this.r = Math.max(28, Math.max(this.$.clientWidth, this.parent.height)); } this.alpha = this.pressedAlpha; }.bind(this), undefined, function() { if ( this.state_ === 'cancelled' ) { this.state_ = 'pressed'; this.onMouseUp(); } else { this.state_ = 'pressed'; } }.bind(this))(); } }, { name: 'onMouseUp', code: function(evt) { // This line shouldn't be necessary but we're getting stray // onMouseUp events when the cursor moves over the button. if ( this.state_ === 'default' ) return; if ( this.state_ === 'pressing' ) { this.state_ = 'cancelled'; return; } if ( this.state_ === 'cancelled' ) return; this.state_ = 'released'; this.X.animate( this.easeOutTime, function() { this.alpha = this.finishAlpha; }.bind(this), Movement.easeIn(.5), function() { if ( this.state_ === 'released' ) { this.state_ = 'default'; this.color = this.nextColor_; } }.bind(this))(); } } ] });