mirror of
https://github.com/Hopiu/vue-material.git
synced 2026-05-24 23:03:45 +00:00
Start the creation of ink ripple
This commit is contained in:
parent
3fed7ddf33
commit
c36ee6005f
12 changed files with 275 additions and 8 deletions
1
.babelrc
1
.babelrc
|
|
@ -1,4 +1,3 @@
|
|||
{
|
||||
"plugins": ["transform-runtime"],
|
||||
"presets": ["es2015", "stage-0"]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@
|
|||
<body>
|
||||
<div class="container" id="app" v-cloak>
|
||||
<md-button class="md-primary" @click="clickAction">My first component</md-button>
|
||||
<md-link-button class="md-primary md-raised" href="/" target="_blank">My second component</md-link-button>
|
||||
<md-link-button class="md-primary md-raised" href="/">My second component</md-link-button>
|
||||
</div>
|
||||
|
||||
<script src="components/main.js"></script>
|
||||
|
|
|
|||
|
|
@ -49,6 +49,7 @@
|
|||
"xtend": "^4.0.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"vue": "^1.0.25"
|
||||
"vue": "^1.0.25",
|
||||
"vue-ripple": "^1.0.2"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,9 @@
|
|||
import Vue from 'vue/dist/vue.min';
|
||||
import MdButton from './mdButton';
|
||||
import MdInkRipple from './mdInkRipple';
|
||||
|
||||
Vue.use(MdButton);
|
||||
Vue.use(MdInkRipple);
|
||||
|
||||
new Vue({
|
||||
el: '#app',
|
||||
|
|
|
|||
|
|
@ -4,3 +4,4 @@ export default {
|
|||
disabled: Boolean
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,134 @@
|
|||
@import '../../stylesheets/variables.scss';
|
||||
|
||||
$button-width: 88px;
|
||||
$button-height: 36px;
|
||||
|
||||
$button-icon-size: 40px;
|
||||
|
||||
.md-button {
|
||||
height: 36px;
|
||||
padding: 0 8px;
|
||||
border: none;
|
||||
border-radius: 2px;
|
||||
min-width: $button-width;
|
||||
min-height: $button-height;
|
||||
margin: 6px 8px;
|
||||
padding: 0 6px;
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
align-items: center;
|
||||
overflow: hidden;
|
||||
user-select: none;
|
||||
cursor: pointer;
|
||||
outline: none;
|
||||
background: none;
|
||||
border: 0;
|
||||
border-radius: 3px;
|
||||
transition: box-shadow $swift-ease-out-duration $swift-ease-out-timing-function,
|
||||
background-color $swift-ease-out-duration $swift-ease-out-timing-function;
|
||||
color: currentColor;
|
||||
font-family: inherit;
|
||||
font-size: 14px;
|
||||
font-style: inherit;
|
||||
font-variant: inherit;
|
||||
font-weight: 500;
|
||||
line-height: $button-height;
|
||||
text-align: center;
|
||||
text-transform: uppercase;
|
||||
text-decoration: none;
|
||||
vertical-align: top;
|
||||
white-space: nowrap;
|
||||
|
||||
&:focus {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
&:hover,
|
||||
&:focus {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
&.ng-hide,
|
||||
&.ng-leave {
|
||||
transition: none;
|
||||
}
|
||||
|
||||
&.md-raised:not([disabled]) {
|
||||
box-shadow: $material-shadow-z1;
|
||||
}
|
||||
|
||||
&.md-icon-button {
|
||||
width: $button-icon-size;
|
||||
min-width: 0;
|
||||
height: $button-icon-size;
|
||||
margin: 0 6px;
|
||||
padding: 8px;
|
||||
border-radius: 50%;
|
||||
line-height: 24px;
|
||||
}
|
||||
|
||||
/*
|
||||
&.md-cornered {
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
&.md-icon {
|
||||
padding: 0;
|
||||
background: none;
|
||||
}
|
||||
|
||||
&.md-fab {
|
||||
|
||||
// Include the top/left/bottom/right fab positions
|
||||
@include fab-all-positions();
|
||||
|
||||
z-index: $z-index-fab;
|
||||
|
||||
line-height: $button-fab-line-height;
|
||||
|
||||
min-width: 0;
|
||||
width: $button-fab-width;
|
||||
height: $button-fab-height;
|
||||
vertical-align: middle;
|
||||
|
||||
@include md-shadow-bottom-z-1();
|
||||
border-radius: $button-fab-border-radius;
|
||||
background-clip: padding-box;
|
||||
overflow: hidden;
|
||||
|
||||
transition: $swift-ease-in;
|
||||
transition-property: background-color, box-shadow, transform;
|
||||
.md-ripple-container {
|
||||
border-radius: $button-fab-border-radius;
|
||||
background-clip: padding-box;
|
||||
overflow: hidden;
|
||||
// The following hack causes Safari/Chrome to respect overflow hidden for ripples
|
||||
-webkit-mask-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAA5JREFUeNpiYGBgAAgwAAAEAAGbA+oJAAAAAElFTkSuQmCC');
|
||||
}
|
||||
|
||||
&.md-mini {
|
||||
line-height: $button-fab-mini-line-height;
|
||||
width: $button-fab-mini-width;
|
||||
height: $button-fab-mini-height;
|
||||
}
|
||||
|
||||
&.ng-hide, &.ng-leave {
|
||||
transition: none;
|
||||
}
|
||||
}
|
||||
|
||||
&:not([disabled]) {
|
||||
&.md-raised,
|
||||
&.md-fab {
|
||||
&.md-focused {
|
||||
@include md-shadow-bottom-z-1();
|
||||
}
|
||||
&:active {
|
||||
@include md-shadow-bottom-z-2();
|
||||
}
|
||||
}
|
||||
} */
|
||||
|
||||
.md-ripple-container {
|
||||
border-radius: 3px;
|
||||
background-clip: padding-box;
|
||||
overflow: hidden;
|
||||
-webkit-mask-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAA5JREFUeNpiYGBgAAgwAAAEAAGbA+oJAAAAAElFTkSuQmCC');
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
<template>
|
||||
<button :type="type || 'button'" :disabled="disabled" class="md-button">
|
||||
<button :type="type || 'button'" :disabled="disabled" class="md-button" v-md-ink-ripple>
|
||||
<slot></slot>
|
||||
</button>
|
||||
</template>
|
||||
|
|
|
|||
59
src/components/mdInkRipple/index.js
Normal file
59
src/components/mdInkRipple/index.js
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
import './mdInkRipple.vue';
|
||||
|
||||
export default function install(Vue) {
|
||||
let rippleParentClass = 'md-ink-ripple';
|
||||
let rippleClass = 'md-ripple';
|
||||
let rippleActiveClass = 'md-active';
|
||||
|
||||
let registerMouseEvent = (element) => {
|
||||
Vue.nextTick(() => {
|
||||
let rect = element.getBoundingClientRect();
|
||||
let ripple = element.querySelector('.' + rippleClass);
|
||||
|
||||
element.addEventListener('mousedown', function(event) {
|
||||
ripple.classList.remove(rippleActiveClass);
|
||||
|
||||
let top = event.pageY - rect.top - ripple.offsetHeight / 2 - document.body.scrollTop;
|
||||
let left = event.pageX - rect.left - ripple.offsetWidth / 2 - document.body.scrollLeft;
|
||||
|
||||
ripple.style.top = top + 'px';
|
||||
ripple.style.left = left + 'px';
|
||||
|
||||
ripple.classList.add(rippleActiveClass);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
let createElement = (ripple, className, size) => {
|
||||
ripple = document.createElement('div');
|
||||
ripple.className = className;
|
||||
|
||||
if (size) {
|
||||
ripple.style.width = size;
|
||||
ripple.style.height = size;
|
||||
}
|
||||
|
||||
return ripple;
|
||||
};
|
||||
|
||||
let createRipple = (element) => {
|
||||
let ripple = element.querySelector('.' + rippleClass);
|
||||
|
||||
if (!ripple) {
|
||||
Vue.nextTick(() => {
|
||||
let elementSize = Math.round(Math.max(element.offsetWidth, element.offsetHeight)) + 'px';
|
||||
let rippleParent = createElement(ripple, rippleParentClass);
|
||||
let rippleElement = createElement(ripple, rippleClass, elementSize);
|
||||
|
||||
rippleParent.appendChild(rippleElement);
|
||||
element.appendChild(rippleParent);
|
||||
|
||||
registerMouseEvent(element);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
Vue.directive('mdInkRipple', function() {
|
||||
createRipple(this.el);
|
||||
});
|
||||
}
|
||||
28
src/components/mdInkRipple/mdInkRipple.scss
Normal file
28
src/components/mdInkRipple/mdInkRipple.scss
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
@import '../../stylesheets/variables.scss';
|
||||
|
||||
.md-ink-ripple {
|
||||
pointer-events: none;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
}
|
||||
|
||||
.md-ripple {
|
||||
position: absolute;
|
||||
transform: scale(0);
|
||||
background: rgba(0, 0, 0, .26);
|
||||
border-radius: 50%;
|
||||
|
||||
&.md-active {
|
||||
animation: ripple 1.2s $swift-ease-out-timing-function;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes ripple {
|
||||
to {
|
||||
transform: scale(1.5);
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
1
src/components/mdInkRipple/mdInkRipple.vue
Normal file
1
src/components/mdInkRipple/mdInkRipple.vue
Normal file
|
|
@ -0,0 +1 @@
|
|||
<style lang="scss" src="mdInkRipple.scss"></style>
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
body {
|
||||
min-height: 100%;
|
||||
position: relative;
|
||||
-webkit-tap-highlight-color: transparent;
|
||||
-webkit-touch-callout: none;
|
||||
-webkit-text-size-adjust: 100%;
|
||||
-ms-text-size-adjust: 100%;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
font-size: 14px;
|
||||
font-family: $font-roboto;
|
||||
}
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
/* Transitions
|
||||
========================================================================== */
|
||||
|
||||
$swift-ease-out-duration: .4s !default;
|
||||
$swift-ease-out-timing-function: cubic-bezier(.25, .8, .25, 1) !default;
|
||||
$swift-ease-out: all $swift-ease-out-duration $swift-ease-out-timing-function !default;
|
||||
|
||||
$swift-ease-in-duration: .3s !default;
|
||||
$swift-ease-in-timing-function: cubic-bezier(.55, 0, .55, .2) !default;
|
||||
$swift-ease-in: all $swift-ease-in-duration $swift-ease-in-timing-function !default;
|
||||
|
||||
$swift-ease-in-out-duration: .5s !default;
|
||||
$swift-ease-in-out-timing-function: cubic-bezier(.35, 0, .25, 1) !default;
|
||||
$swift-ease-in-out: all $swift-ease-in-out-duration $swift-ease-in-out-timing-function !default;
|
||||
|
||||
$swift-linear-duration: .08s !default;
|
||||
$swift-linear-timing-function: linear !default;
|
||||
$swift-linear: all $swift-linear-duration $swift-linear-timing-function !default;
|
||||
|
||||
$material-enter-duration: .3s;
|
||||
$material-enter-timing-function: cubic-bezier(.0, .0, .2, 1);
|
||||
$material-enter: all $material-enter-duration $material-enter-timing-function;
|
||||
|
||||
$material-leave-duration: .3s;
|
||||
$material-leave-timing-function: cubic-bezier(.4, .0, 1, 1);
|
||||
$material-leave: all $material-leave-duration $material-leave-timing-function;
|
||||
|
||||
|
||||
|
||||
/* Common
|
||||
========================================================================== */
|
||||
|
||||
$material-shadow-z1: 0 2px 5px rgba(0, 0, 0, .26);
|
||||
$material-shadow-z2: 0 4px 8px rgba(0, 0, 0, .4);
|
||||
|
||||
$font-roboto: Roboto, "Helvetica Neue", sans-serif;
|
||||
Loading…
Reference in a new issue