├── .gitignore ├── package.json ├── bower.json ├── LICENSE.MD ├── plugin ├── css │ └── mee-ink.css └── js │ ├── jquery.mee-ink.min.js │ └── jquery.mee-ink.js ├── demo ├── index.html └── css │ └── styles.css └── README.MD /.gitignore: -------------------------------------------------------------------------------- 1 | .idea/ 2 | bower_components/ 3 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "meeink", 3 | "version": "1.0.0", 4 | "description": "MeeInk is a jQuery plugin which allows you to easily add material design ink effect to elements when you click them.", 5 | "main": "plugin/js/jquery.mee-ink.js", 6 | "repository": { 7 | "type": "git", 8 | "url": "git+https://github.com/inferusvv/MeeInk.git" 9 | }, 10 | "keywords": [ 11 | "jquery", 12 | "plugin", 13 | "material", 14 | "design", 15 | "google", 16 | "css", 17 | "animation", 18 | "ui" 19 | ], 20 | "author": "Vladislav Bezenson", 21 | "license": "MIT", 22 | "bugs": { 23 | "url": "https://github.com/inferusvv/MeeInk/issues" 24 | }, 25 | "homepage": "https://github.com/inferusvv/MeeInk#readme" 26 | } 27 | -------------------------------------------------------------------------------- /bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "MeeInk", 3 | "version": "1.0.0", 4 | "homepage": "https://github.com/inferusvv/MeeInk", 5 | "authors": [ 6 | "Vladislav Bezenson " 7 | ], 8 | "description": "MeeInk is a jQuery plugin which allows you to easily add material design ink effect to elements when you click them.", 9 | "main": "plugin/js/jquery.mee-ink.js", 10 | "moduleType": [], 11 | "keywords": [ 12 | "jquery", 13 | "plugin", 14 | "material", 15 | "design", 16 | "google", 17 | "css", 18 | "animation", 19 | "ui" 20 | ], 21 | "license": "MIT", 22 | "ignore": [ 23 | "**/.*", 24 | "node_modules", 25 | "bower_components", 26 | "test", 27 | "tests" 28 | ], 29 | "dependencies": { 30 | "jquery": "^2.2.0" 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /LICENSE.MD: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 Vladislav Bezenson 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 | -------------------------------------------------------------------------------- /plugin/css/mee-ink.css: -------------------------------------------------------------------------------- 1 | @-moz-keyframes mee-ink { 2 | 100% { 3 | opacity: 0; 4 | -moz-transform: scale(2); 5 | transform: scale(2); 6 | } 7 | } 8 | @-webkit-keyframes mee-ink { 9 | 100% { 10 | opacity: 0; 11 | -webkit-transform: scale(2); 12 | transform: scale(2); 13 | } 14 | } 15 | @keyframes mee-ink { 16 | 100% { 17 | opacity: 0; 18 | -webkit-transform: scale(2); 19 | -moz-transform: scale(2); 20 | transform: scale(2); 21 | } 22 | } 23 | 24 | .mee-ink-el { 25 | -webkit-tap-highlight-color: rgba(0,0,0,0); 26 | } 27 | 28 | .mee-ink-animated { 29 | -webkit-animation-duration: .65s; 30 | -moz-animation-duration: .65s; 31 | animation-duration: .65s; 32 | -webkit-animation-fill-mode: both; 33 | -moz-animation-fill-mode: both; 34 | animation-fill-mode: both; 35 | } 36 | 37 | .mee-ink-animation { 38 | -webkit-animation-name: mee-ink; 39 | -moz-animation-name: mee-ink; 40 | animation-name: mee-ink; 41 | } 42 | 43 | .mee-ink-pos-relative { 44 | position: relative; 45 | } 46 | .mee-ink-overflow-hidden { 47 | overflow: hidden; 48 | } 49 | 50 | .mee-ink { 51 | -webkit-animation-timing-function: ease-out; 52 | -moz-animation-timing-function: ease-out; 53 | animation-timing-function: ease-out; 54 | background: rgba(255,255,255,.5); 55 | border-radius: 50%; 56 | display: block; 57 | position: absolute; 58 | -webkit-transform: scale(0); 59 | -moz-transform: scale(0); 60 | transform: scale(0); 61 | } 62 | -------------------------------------------------------------------------------- /demo/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | MeeInk 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 |
17 | 24 |
25 |
26 | 27 |
28 |
29 |

Demo

30 | 31 |
32 |
33 | 34 |
35 |
36 |

Documentation

37 |

All sources and documentation you can find on plugin GitHub page.

38 |
39 |
40 | 41 | 46 | 47 | 48 | 49 | 50 | 55 | 56 | 57 | -------------------------------------------------------------------------------- /README.MD: -------------------------------------------------------------------------------- 1 | # MeeInk v1.0.0 2 | 3 | MeeInk is a jQuery plugin which allows you to easily add **material design** ink effect to elements when you click them. 4 | 5 | Plugin is based on CSS animation what give you good performance including mobile devices. 6 | 7 | ## Demo 8 | 9 | Check out demo page [here][demo]. 10 | 11 | [demo]: http://inferusvv.github.io/meeink/index.html 12 | 13 | ## Setup 14 | 15 | ### Install with Bower 16 | 17 | ```sh 18 | bower install MeeInk --save 19 | ``` 20 | 21 | ### Install with NPM 22 | 23 | ```sh 24 | npm install meeink --save 25 | ``` 26 | 27 | ### Include scripts 28 | 29 | ```html 30 | 31 | 32 | ``` 33 | 34 | ### Include styles 35 | 36 | ```html 37 | 38 | ``` 39 | 40 | ### Initialize plugin 41 | 42 | ```javascript 43 | $(document).ready(function() { 44 | $('.btn').meeInk({ 45 | // options 46 | }); 47 | }); 48 | ``` 49 | 50 | ## Documentation 51 | 52 | Plugin have several number of options which allows you to customize it as you want. 53 | 54 | #### animationClass 55 | 56 | ```javascript 57 | animationClass: 'mee-ink-animated mee-ink-animation' 58 | ``` 59 | 60 | Class which triggers to start CSS animation. 61 | 62 | #### elementClass 63 | 64 | ```javascript 65 | elementClass: 'mee-ink-el' 66 | ``` 67 | 68 | Class that is added to initialized element. 69 | 70 | #### inkClass 71 | 72 | ```javascript 73 | inkClass: 'mee-ink' 74 | ``` 75 | 76 | Class for ink inside element with styles. 77 | 78 | #### overflowHiddenClass 79 | 80 | ```javascript 81 | overflowHiddenClass: 'mee-ink-overflow-hidden' 82 | ``` 83 | 84 | Class will be added if your element don't have ```overflow: hidden```. 85 | 86 | #### positionRelativeClass 87 | 88 | ```javascript 89 | positionRelativeClass: 'mee-ink-pos-relative' 90 | ``` 91 | 92 | Class will be added if your element have ```position: static```, because ink inside element positioned absolutely relative to element. 93 | 94 | ## Issues 95 | 96 | Found an issue? You are welcome [here][issues]. 97 | 98 | [issues]: https://github.com/inferusvv/MeeInk/issues 99 | -------------------------------------------------------------------------------- /plugin/js/jquery.mee-ink.min.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * Plugin: MeeInk 3 | * Version: 1.0.0 4 | * Author: Vladislav Bezenson 5 | * 6 | * @license: https://github.com/inferusvv/MeeInk/blob/master/LICENSE.MD 7 | * https://github.com/inferusvv/MeeInk 8 | */ 9 | (function($,window,document,undefined){"use strict";var pluginName="meeInk",defaults={animationClass:"mee-ink-animated mee-ink-animation",elementClass:"mee-ink-el",inkClass:"mee-ink",overflowHiddenClass:"mee-ink-overflow-hidden",positionRelativeClass:"mee-ink-pos-relative"},interactionEvent="ontouchstart"in window||navigator.maxTouchPoints?"touchstart":"click";function Plugin(element,options){this.element=element;this.$element=$(element);this.settings=$.extend({},defaults,options);this._defaults=defaults;this._name=pluginName;this.init()}$.extend(Plugin.prototype,{init:function(){this.injectInk();this.$ink=$(this.element).find("."+this.settings.inkClass);this.$element.addClass(this.settings.elementClass);this.$element.on(interactionEvent,$.proxy(this._onClick,this));if(this.$element.css("position")==="static"){this.$element.addClass(this.settings.positionRelativeClass)}if(this.$element.css("overflow")!=="hidden"){this.$element.addClass(this.settings.overflowHiddenClass)}},injectInk:function(){if(this.$element.find("."+this.settings.inkClass).length===0){this.$element.prepend('')}},setInkSize:function(width,height){height=typeof height!=="undefined"?height:width;this.$ink.css({height:height,width:width})},setInkPosition:function(x,y){this.$ink.css({top:y,left:x})},getInkSize:function(){return Math.max(this.$element.outerWidth(),this.$element.outerHeight())},getInkPosition:function(event){var position={};position.x=(event.originalEvent.pageX||event.originalEvent.touches[0].pageX)-this.$element.offset().left-this.$ink.width()/2;position.y=(event.originalEvent.pageY||event.originalEvent.touches[0].pageY)-this.$element.offset().top-this.$ink.height()/2;return position},_onClick:function(event){this.$ink.removeClass(this.settings.animationClass);this.setInkSize(this.getInkSize());var position=this.getInkPosition(event);this.setInkPosition(position.x,position.y);this.$ink.addClass(this.settings.animationClass)}});$.fn[pluginName]=function(options){return this.each(function(){if(!$.data(this,"plugin_"+pluginName)){$.data(this,"plugin_"+pluginName,new Plugin(this,options))}})}})(jQuery,window,document); -------------------------------------------------------------------------------- /demo/css/styles.css: -------------------------------------------------------------------------------- 1 | * { 2 | box-sizing: border-box; 3 | margin: 0; 4 | padding: 0; 5 | } 6 | 7 | html, body { 8 | height: 100%; 9 | } 10 | 11 | body { 12 | background: #fff; 13 | color: #333; 14 | font: 20px/1.5 'Roboto', Arial, sans-serif; 15 | } 16 | 17 | a { 18 | color: #1db4f7; 19 | text-decoration: underline; 20 | } 21 | 22 | a:hover { 23 | text-decoration: none; 24 | } 25 | 26 | a.text-muted { 27 | color: #b1e5fc; 28 | } 29 | 30 | h1, h2, h3 { 31 | color: #000; 32 | font-weight: 300; 33 | line-height: 1.1; 34 | } 35 | h1 { 36 | font-size: 55px; 37 | } 38 | 39 | h2 { 40 | font-size: 35px; 41 | margin: 35px 0 20px; 42 | } 43 | 44 | h3 { 45 | font-size: 25px; 46 | } 47 | 48 | small { 49 | font-size: 80%; 50 | } 51 | 52 | .text-center { 53 | text-align: center; 54 | } 55 | 56 | .text-muted { 57 | color: #aaa; 58 | } 59 | 60 | .btn { 61 | background: #1db4f7; 62 | border: 0; 63 | border-radius: 3px; 64 | box-shadow: 0 3px 5px rgba(0,0,0,.2); 65 | color: #fff; 66 | cursor: pointer; 67 | display: inline-block; 68 | font-family: 'Roboto', sans-serif; 69 | font-size: 24px; 70 | font-weight: bold; 71 | max-width: 310px; 72 | outline: 0; 73 | padding: 28px 50px; 74 | text-align: center; 75 | -moz-transition: all .2s ease; 76 | -webkit-transition: all .2s ease; 77 | transition: all .2s ease; 78 | width: 100%; 79 | } 80 | 81 | .btn:active { 82 | box-shadow: 0 2px 5px rgba(0,0,0,.2), inset 0 3px 5px rgba(0,0,0,0.1); 83 | -moz-transform: translate(0, 2px); 84 | -webkit-transform: translate(0, 2px); 85 | transform: translate(0, 2px); 86 | } 87 | 88 | .container { 89 | margin: 0 auto; 90 | max-width: 600px; 91 | padding: 0 15px; 92 | } 93 | 94 | .page-section { 95 | padding: 30px 0; 96 | text-align: center; 97 | } 98 | 99 | .page-header { 100 | margin: 30px 0; 101 | } 102 | 103 | .page-header h1 { 104 | margin: 0; 105 | } 106 | 107 | .page-header-descr { 108 | margin-top: 30px; 109 | } 110 | 111 | .page-footer { 112 | font-size: 16px; 113 | margin-top: 30px; 114 | } 115 | 116 | 117 | @media all and (min-width: 480px) { 118 | h1 { 119 | font-size: 80px; 120 | } 121 | h2 { 122 | font-size: 50px; 123 | } 124 | h3 { 125 | font-size: 30px; 126 | } 127 | 128 | .page-header { 129 | margin: 50px 0; 130 | } 131 | 132 | .page-section { 133 | padding: 50px 0; 134 | } 135 | 136 | .page-footer { 137 | margin-top: 50px; 138 | } 139 | } -------------------------------------------------------------------------------- /plugin/js/jquery.mee-ink.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * Plugin: MeeInk 3 | * Version: 1.0.0 4 | * Author: Vladislav Bezenson 5 | * 6 | * @license: https://github.com/inferusvv/MeeInk/blob/master/LICENSE.MD 7 | * https://github.com/inferusvv/MeeInk 8 | */ 9 | 10 | ;(function ( $, window, document, undefined ) { 11 | 12 | "use strict"; 13 | 14 | var pluginName = "meeInk", 15 | defaults = { 16 | animationClass: 'mee-ink-animated mee-ink-animation', 17 | elementClass: 'mee-ink-el', 18 | inkClass: 'mee-ink', 19 | overflowHiddenClass: 'mee-ink-overflow-hidden', 20 | positionRelativeClass: 'mee-ink-pos-relative' 21 | }, 22 | interactionEvent = ('ontouchstart' in window || navigator.maxTouchPoints) ? 'touchstart' : 'click'; 23 | 24 | function Plugin ( element, options ) { 25 | this.element = element; 26 | this.$element = $(element); 27 | this.settings = $.extend( {}, defaults, options ); 28 | this._defaults = defaults; 29 | this._name = pluginName; 30 | this.init(); 31 | } 32 | 33 | $.extend( Plugin.prototype, { 34 | init: function () { 35 | this.injectInk(); 36 | this.$ink = $(this.element).find( '.' + this.settings.inkClass ); 37 | 38 | this.$element.addClass( this.settings.elementClass ); 39 | this.$element.on( interactionEvent, $.proxy( this._onClick, this ) ); 40 | 41 | if ( this.$element.css( 'position' ) === 'static' ) { 42 | this.$element.addClass( this.settings.positionRelativeClass ); 43 | } 44 | if ( this.$element.css( 'overflow' ) !== 'hidden' ) { 45 | this.$element.addClass( this.settings.overflowHiddenClass ); 46 | } 47 | }, 48 | 49 | injectInk: function() { 50 | if ( this.$element.find( '.' + this.settings.inkClass ).length === 0 ) { 51 | this.$element.prepend( '' ); 52 | } 53 | }, 54 | 55 | setInkSize: function( width, height ) { 56 | height = typeof height !== 'undefined' ? height : width; 57 | 58 | this.$ink.css({ 59 | height: height, 60 | width: width 61 | }); 62 | }, 63 | 64 | setInkPosition: function( x, y ) { 65 | this.$ink.css({ 66 | top: y, 67 | left: x 68 | }); 69 | }, 70 | 71 | getInkSize: function() { 72 | return Math.max( this.$element.outerWidth(), this.$element.outerHeight() ); 73 | }, 74 | 75 | getInkPosition: function( event ) { 76 | var position = {}; 77 | 78 | position.x = (event.originalEvent.pageX || event.originalEvent.touches[0].pageX) - this.$element.offset().left - this.$ink.width() / 2; 79 | position.y = (event.originalEvent.pageY || event.originalEvent.touches[0].pageY) - this.$element.offset().top - this.$ink.height() / 2; 80 | 81 | return position; 82 | }, 83 | 84 | _onClick: function( event ) { 85 | this.$ink.removeClass( this.settings.animationClass ); 86 | 87 | this.setInkSize( this.getInkSize() ); 88 | 89 | var position = this.getInkPosition( event ); 90 | this.setInkPosition( position.x, position.y ); 91 | 92 | this.$ink.addClass( this.settings.animationClass ); 93 | } 94 | } ); 95 | 96 | $.fn[ pluginName ] = function ( options ) { 97 | return this.each( function() { 98 | if ( !$.data( this, "plugin_" + pluginName ) ) { 99 | $.data( this, "plugin_" + pluginName, new Plugin( this, options ) ); 100 | } 101 | } ); 102 | }; 103 | 104 | })( jQuery, window, document ); 105 | --------------------------------------------------------------------------------