UNPKG

toloframework

Version:

Javascript/HTML/CSS compiler for Firefox OS or nodewebkit apps using modules in the nodejs style.

151 lines (135 loc) 4.12 kB
"use strict"; /** * @module tfw.touchable * * @description * Turn a DOM element into a touchable one with material design * animation: a growing transparent disk. * * @example * var Touchable = require('tfw.touchable'); * var div = document.querySelector('#button'); * var touchable = new Touchable( div, { * opacity: .2, * color: "white" * }); * touchable.tap.add(function() { ... }); * touchable.press.add(function() { ... }); */ var $ = require( "dom" ); var Fx = require( "dom.fx" ); var Listeners = require( "tfw.listeners" ); var Touchable = function ( elem, opts ) { var that = this; if ( typeof opts === 'undefined' ) opts = {}; if ( typeof opts.enabled === 'undefined' ) opts.enabled = true; elem = $( elem ); this.enabled = opts.enabled; this.color = opts.color || "#fd8"; this.classToAdd = opts.classToAdd; this.opacity = opts.opacity || 0.4; this.element = $( elem ); this.tap = new Listeners(); this.press = new Listeners(); $.addClass( elem, 'tfw-touchable' ); var shadow = $.div( 'tfw-touchable-shadow' ); var fxDown = Fx().css( shadow, { transition: "none", transform: "scale(0)" } ) .exec( function ( session ) { var cls = that.classToAdd; if ( typeof cls === 'string' ) { $.addClass( elem, cls ); } // Position must not be `static`. var position = getComputedStyle( elem ).position; if ( [ 'relative', 'absolute', 'fixed' ].indexOf( position ) == -1 ) { elem.style.position = 'relative'; } elem.style.overflow = 'hidden'; var rect = elem.getBoundingClientRect(); var w = rect.width; var h = rect.height; w = Math.max( lastX, w - lastX ); h = Math.max( lastY, h - lastY ); var radius = Math.ceil( Math.sqrt( w * w + h * h ) ); $.css( shadow, { left: lastX + "px", top: lastY + "px", margin: "-" + radius + "px", width: 2 * radius + "px", height: 2 * radius + "px", opacity: 0, background: that.color, transform: "scale(0)", transition: "all .15s ease", "transition-timing-function": "cubic-bezier(0,1,0.780,1)", "-moz-transition-timing-function": "cubic-bezier(0,1,0.780,1)", "-webkit-transition-timing-function": "cubic-bezier(0,1,0.780,1)" } ); $.add( elem, shadow ); } ) .wait( 10 ) .css( shadow, { opacity: that.opacity, transform: "scale(.25)" } ) .wait( 150 ) .css( shadow, { transform: "scale(.2)" } ) .wait( 150 ) .css( shadow, { transition: "all .6s ease", transform: "scale(1)", opacity: 0 } ) .wait( 600 ) .detach( shadow ) .exec(function() { var cls = that.classToAdd; if ( typeof cls === 'string' ) { $.removeClass( elem, cls ); } }); var time = 0; var lastX, lastY; var removeShadow = 0; $.on( elem, { down: function ( evt ) { if ( !that.enabled ) return; evt.stopPropagation(); evt.preventDefault(); lastX = Math.floor( evt.x ); lastY = Math.floor( evt.y ); fxDown.start(); time = Date.now(); }, tap: function ( evt ) { if ( !that.enabled ) return; console.log( 'TAP', evt ); that.tap.fire( evt ); } } ); }; module.exports = Touchable; /* https://jsfiddle.net/mzmaczdn/7/ var div = document.createElement('div'); div.className = 'shadow'; var btn = document.querySelector('button'); btn.addEventListener('mousedown', function(evt) { btn.className = "press"; btn.appendChild( div ); div.style.left = evt.offsetX + "px"; div.style.top = evt.offsetY + "px"; window.setTimeout(function() { div.style.transform = "scale(1)"; }); }); btn.addEventListener('mouseup', function(evt) { div.style.transform = "scale(0)"; btn.removeChild(div); }); */