├── .gitignore ├── CHANGELOG.md ├── bower.json ├── package.json ├── LICENSE ├── README.md ├── jquery.ripple.css ├── jquery.ripple.scss ├── index.html └── jquery.ripple.js /.gitignore: -------------------------------------------------------------------------------- 1 | bower_components 2 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Change Log 2 | 3 | ## [0.2.1](https://github.com/adamsea/jquery-ripple/tree/0.2.1) (2015-05-05) 4 | 5 | [Full Changelog](https://github.com/adamsea/jquery-ripple/compare/0.2.0...0.2.1) 6 | 7 | - Fix end events to be more accurate for mobile vs desktop 8 | - Only run end event handlers if start events have been handled 9 | 10 | ## [0.2.0](https://github.com/adamsea/jquery-ripple/tree/0.2.0) (2015-05-05) 11 | 12 | [Full Changelog](https://github.com/adamsea/jquery-ripple/compare/0.1.4...0.2.0) 13 | 14 | - Removed 'ripple' event and its associated setTimeout 15 | - Removed default 40x40 height for ripple ink from CSS 16 | -------------------------------------------------------------------------------- /bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "jquery-ripple", 3 | "version": "0.2.1", 4 | "authors": [ 5 | "Eric Adams " 6 | ], 7 | "description": "jQuery Plugin for a ripple effect inspired by Google Material Design", 8 | "main": "jquery.ripple.js", 9 | "keywords": [ 10 | "jQuery", 11 | "Plugins", 12 | "effects" 13 | ], 14 | "license": "MIT", 15 | "homepage": "https://github.com/adamsea/jquery-ripple", 16 | "private": false, 17 | "ignore": [ 18 | "**/.*", 19 | "node_modules", 20 | "bower_components", 21 | "test", 22 | "tests" 23 | ], 24 | "dependencies": { 25 | "jquery": "~2.1.4", 26 | "normalize.css": "~3.0.2" 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "jquery-ripple", 3 | "version": "0.2.1", 4 | "description": "jQuery Plugin for a ripple effect inspired by Google Material Design", 5 | "main": "jquery.ripple.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "repository": { 10 | "type": "git", 11 | "url": "git+https://github.com/adamsea/jquery-ripple.git" 12 | }, 13 | "keywords": [ 14 | "jQuery", 15 | "Plugins", 16 | "effects" 17 | ], 18 | "author": "Eric Adams ", 19 | "license": "MIT", 20 | "bugs": { 21 | "url": "https://github.com/adamsea/jquery-ripple/issues" 22 | }, 23 | "homepage": "https://github.com/adamsea/jquery-ripple#readme" 24 | } 25 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 Eric Adams 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | jQuery-ripple 2 | ============= 3 | 4 | A jQuery Plugin for a ripple effect inspired by Google Material Design. 5 | 6 | ### Installation 7 | 8 | jQuery-ripple can be installed through [Bower](http://bower.io/). 9 | 10 | $ bower install jquery.ripple --save 11 | 12 | ### Usage 13 | 14 | 1. Include the required jquery.ripple.css in the head section of your document. 15 | 16 | ``` 17 | 18 | ``` 19 | 2. Include the latest version of jQuery and jQuery-ripple in your document. 20 | 21 | ``` 22 | 23 | 24 | ``` 25 | 3. Create an element with the `[data-ripple]` data attribute defined. 26 | 27 | ``` 28 | 29 | ``` 30 | 4. Call the plugin on the element. 31 | 32 | ``` 33 | $('[data-ripple]').ripple(); 34 | ``` 35 | 36 | ### Customization 37 | 38 | Optionally, you can pass a different CSS color to use for the ripple ink: 39 | 40 | ``` 41 | $('[data-ripple]').ripple({ color: '#EF5734' }); 42 | ``` 43 | 44 | ### Events 45 | 46 | jQuery-ripple introduces three events that you can hook into for additional functionality: 47 | 48 | | Event Name | Description | 49 | |----------------|-----------------------------------------------------------------------------------------------------| 50 | | *'beforeripple'* | Fired on touchstart/mousedown before ripple-active class is added to the DOM | 51 | | *'afterripple'* | Fired on touchend/mouseup/mouseleave before ripple-active class is removed from the DOM | 52 | -------------------------------------------------------------------------------- /jquery.ripple.css: -------------------------------------------------------------------------------- 1 | [data-ripple] { 2 | overflow: hidden; 3 | position: relative; 4 | 5 | -webkit-tap-highlight-color: rgba(0,0,0,0); 6 | } 7 | 8 | .ripple-effect { 9 | display: block; 10 | position: absolute; 11 | 12 | -webkit-animation: ripple 2s; 13 | -moz-animation: ripple 2s; 14 | -ms-animation: ripple 2s; 15 | -o-animation: ripple 2s; 16 | animation: ripple 2s; 17 | 18 | -webkit-animation-fill-mode: forwards; 19 | -moz-animation-fill-mode: forwards; 20 | animation-fill-mode: forwards; 21 | 22 | -webkit-border-radius: 50%; 23 | -moz-border-radius: 50%; 24 | border-radius: 50%; 25 | 26 | -webkit-transition: background-color .25s ease .1s; 27 | -moz-transition: background-color .25s ease .1s; 28 | -ms-transition: background-color .25s ease .1s; 29 | -o-transition: background-color .25s ease .1s; 30 | transition: background-color .25s ease .1s; 31 | } 32 | 33 | @-webkit-keyframes ripple { 34 | from { 35 | -webkit-transform: scale(1); 36 | opacity: 0.4; 37 | } 38 | to { 39 | -webkit-transform: scale(100); 40 | opacity: 0.25; 41 | } 42 | } 43 | 44 | @-moz-keyframes ripple { 45 | from { 46 | -moz-transform: scale(1); 47 | opacity: 0.4; 48 | } 49 | to { 50 | -moz-transform: scale(100); 51 | opacity: 0.25; 52 | } 53 | } 54 | 55 | @-ms-keyframes ripple { 56 | from { 57 | -ms-transform: scale(1); 58 | opacity: 0.4; 59 | } 60 | to { 61 | -ms-transform: scale(100); 62 | opacity: 0.25; 63 | } 64 | } 65 | 66 | @-o-keyframes ripple { 67 | from { 68 | -o-transform: scale(1); 69 | opacity: 0.4; 70 | } 71 | to { 72 | -o-transform: scale(100); 73 | opacity: 0.25; 74 | } 75 | } 76 | 77 | @keyframes ripple { 78 | from { 79 | transform: scale(1); 80 | opacity: 0.4; 81 | } 82 | to { 83 | transform: scale(100); 84 | opacity: 0.25; 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /jquery.ripple.scss: -------------------------------------------------------------------------------- 1 | // FOR COMPILING INTO YOUR SASS PROJECTS 2 | // Thank you Sass for not providing a way to do this with plain css. 3 | // No really. 4 | [data-ripple] { 5 | overflow: hidden; 6 | position: relative; 7 | 8 | -webkit-tap-highlight-color: rgba(0,0,0,0); 9 | } 10 | 11 | .ripple-effect { 12 | display: block; 13 | position: absolute; 14 | 15 | -webkit-animation: ripple 2s; 16 | -moz-animation: ripple 2s; 17 | -ms-animation: ripple 2s; 18 | -o-animation: ripple 2s; 19 | animation: ripple 2s; 20 | 21 | -webkit-animation-fill-mode: forwards; 22 | -moz-animation-fill-mode: forwards; 23 | animation-fill-mode: forwards; 24 | 25 | -webkit-border-radius: 50%; 26 | -moz-border-radius: 50%; 27 | border-radius: 50%; 28 | 29 | -webkit-transition: background-color .25s ease .1s; 30 | -moz-transition: background-color .25s ease .1s; 31 | -ms-transition: background-color .25s ease .1s; 32 | -o-transition: background-color .25s ease .1s; 33 | transition: background-color .25s ease .1s; 34 | } 35 | 36 | @-webkit-keyframes ripple { 37 | from { 38 | -webkit-transform: scale(1); 39 | opacity: 0.4; 40 | } 41 | to { 42 | -webkit-transform: scale(100); 43 | opacity: 0.25; 44 | } 45 | } 46 | 47 | @-moz-keyframes ripple { 48 | from { 49 | -moz-transform: scale(1); 50 | opacity: 0.4; 51 | } 52 | to { 53 | -moz-transform: scale(100); 54 | opacity: 0.25; 55 | } 56 | } 57 | 58 | @-ms-keyframes ripple { 59 | from { 60 | -ms-transform: scale(1); 61 | opacity: 0.4; 62 | } 63 | to { 64 | -ms-transform: scale(100); 65 | opacity: 0.25; 66 | } 67 | } 68 | 69 | @-o-keyframes ripple { 70 | from { 71 | -o-transform: scale(1); 72 | opacity: 0.4; 73 | } 74 | to { 75 | -o-transform: scale(100); 76 | opacity: 0.25; 77 | } 78 | } 79 | 80 | @keyframes ripple { 81 | from { 82 | transform: scale(1); 83 | opacity: 0.4; 84 | } 85 | to { 86 | transform: scale(100); 87 | opacity: 0.25; 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | jQuery Ripple 7 | 8 | 9 | 10 | 11 | 12 | 35 | 36 |
37 |

jQuery Ripple

38 | 39 |
40 |

Simple Button

41 | 42 |
Code:
43 | 44 | $('.example-1[data-ripple]').ripple(); 45 | 46 |
47 | 48 |
49 |

Alternate Colors

50 | 51 |
Code:
52 | 53 | $('.example-2[data-ripple]').ripple({ color: 'rgba(14,98,221,0.7)' }); 54 | 55 |
56 |
57 | 58 | 59 | 60 | 61 | 65 | 66 | -------------------------------------------------------------------------------- /jquery.ripple.js: -------------------------------------------------------------------------------- 1 | /** 2 | * jQuery plugin to produce the ripple effect from the Google Material Design spec: 3 | * http://www.google.com/design/spec/animation/responsive-interaction.html 4 | * 5 | * This plugin was modified from a codepen simulating the effect: 6 | * http://codepen.io/Craigtut/pen/dIfzv 7 | */ 8 | (function($, ua) { 9 | 10 | var 11 | // Better testing of touch support 12 | // See https://github.com/ngryman/jquery.finger/blob/v0.1.2/dist/jquery.finger.js#L7 13 | isChrome = /chrome/i.exec(ua), 14 | isAndroid = /android/i.exec(ua), 15 | hasTouch = 'ontouchstart' in window && !(isChrome && !isAndroid); 16 | 17 | /** 18 | * jQuery.fn.ripple 19 | * @param {Object} options 20 | * @param {String} [options.color=#fff] The ripple effect color 21 | */ 22 | $.fn.ripple = function(options) { 23 | var rippled = false, 24 | opts = $.extend({}, { color: '#fff' }, options); 25 | opts.event = (hasTouch && 'touchstart.ripple') || 'mousedown.ripple'; 26 | opts.end_event = (hasTouch && 'touchend.ripple touchcancel.ripple') || 'mouseup.ripple mouseleave.ripple'; 27 | 28 | $(this) 29 | // Bind the event to run the effect 30 | .on(opts.event, function(ev) { 31 | var x, y, touch_ev, 32 | $paper = $(this), 33 | $ink = $('
'), 34 | size = Math.max($paper.width(), $paper.height()); 35 | 36 | rippled = true; 37 | 38 | // Set up ripple effect styles 39 | $paper 40 | .trigger('beforeripple') 41 | .addClass('ripple-active'); 42 | $ink 43 | .addClass('ripple-effect') 44 | .css({height: size, width: size}); 45 | 46 | // get click coordinates 47 | // logic = click coordinates relative to page 48 | // - position relative to page - half of self height/width to make it controllable from the center 49 | touch_ev = hasTouch ? ev.originalEvent.touches[0] : ev; 50 | x = touch_ev.pageX - $paper.offset().left - $ink.width()/2; 51 | y = touch_ev.pageY - $paper.offset().top - $ink.height()/2; 52 | 53 | // Set up ripple position and place it in the DOM 54 | $ink 55 | .css({top: y + 'px', left: x + 'px', backgroundColor: opts.color}) 56 | .appendTo($paper); 57 | }) 58 | // Bind the event to end the paper-press ripple 59 | .on(opts.end_event, function() { 60 | var $paper = $(this), 61 | $ink = $paper.find('.ripple-effect'); 62 | 63 | // We don't want to run the afterripple 64 | // events if the user hasn't started a ripple 65 | if (!rippled) { 66 | return; 67 | } 68 | rippled = false; 69 | 70 | // Remove ripple effect styles 71 | $paper 72 | .trigger('afterripple') 73 | .removeClass('ripple-active'); 74 | $ink 75 | .css({backgroundColor: 'transparent'}) 76 | .one('webkitTransitionEnd otransitionend oTransitionEnd msTransitionEnd transitionend', function() { 77 | $ink.remove(); 78 | }); 79 | }); 80 | 81 | // Chaining 82 | return $(this); 83 | }; 84 | 85 | }(window.jQuery, navigator.userAgent)); 86 | --------------------------------------------------------------------------------