Я новичок в CSS-анимации, и стараюсь в течение последних часов, чтобы анимация заработала. Пытаюсь понять код Material Design
, но пока не могу заставить его работать.
Я говорю об этом эффекте: https://angular.io/ (эффект меню). В принципе, это анимация при клике, которая распространяется по кругу от курсора мыши.
Кажется, это сводится к этим двум строкам:
transition: box-shadow .4s cubic-bezier(.25,.8,.25,1),background-color .4s cubic-bezier(.25,.8,.25,1),-webkit-transform .4s cubic-bezier(.25,.8,.25,1);
transition: box-shadow .4s cubic-bezier(.25,.8,.25,1),background-color .4s cubic-bezier(.25,.8,.25,1),transform .4s cubic-bezier(.25,.8,.25,1);
PS: Может быть, есть какой-то код jQuery
, который реализует эту анимацию.
Перевод ответа: How to create Ripple effect on Click - Material Design @topleft
jsBin demo
Чтобы создать UI Ripple effect, вам необходимо:
oveflow:hidden
, чтобы ограничить круг
пульсаций (так как вы не хотите изменять ваш исходный элемент и
поэтому с помощью overflow
не увидите, что эффект пульсации выходит
за пределы желаемого контейнера) overflow
просвечивающий радиальный элемент ripple wave
CSS3
оживить
масштабирование и непрозрачность ripple element
Основной код:
В основном добавьте data-ripple
(по умолчанию - белая рябь) или data-ripple
= "# 000"
для нужного элемента:
<a data-ripple> EDIT </a>
<div data-ripple="rgba(0,0,0, 0.3)">Lorem ipsum</div>
CSS:
/* MAD-RIPPLE EFFECT */
.ripple{
position: absolute;
top:0; left:0; bottom:0; right:0;
overflow: hidden;
-webkit-transform: translateZ(0); /* to contain zoomed ripple */
transform: translateZ(0);
border-radius: inherit; /* inherit from parent (rounded buttons etc) */
pointer-events: none; /* allow user interaction */
animation: ripple-shadow 0.4s forwards;
-webkit-animation: ripple-shadow 0.4s forwards;
}
.rippleWave{
backface-visibility: hidden;
position: absolute;
border-radius: 50%;
transform: scale(0.7); -webkit-transform: scale(0.7);
background: rgba(255,255,255, 1);
opacity: 0.45;
animation: ripple 2s forwards;
-webkit-animation: ripple 2s forwards;
}
@keyframes ripple-shadow {
0% {box-shadow: 0 0 0 rgba(0,0,0,0.0);}
20% {box-shadow: 0 4px 16px rgba(0,0,0,0.3);}
100% {box-shadow: 0 0 0 rgba(0,0,0,0.0);}
}
@-webkit-keyframes ripple-shadow {
0% {box-shadow: 0 0 0 rgba(0,0,0,0.0);}
20% {box-shadow: 0 4px 16px rgba(0,0,0,0.3);}
100% {box-shadow: 0 0 0 rgba(0,0,0,0.0);}
}
@keyframes ripple {
to {transform: scale(24); opacity:0;}
}
@-webkit-keyframes ripple {
to {-webkit-transform: scale(24); opacity:0;}
}
jQuery
jQuery(function($) {
// MAD-RIPPLE // (jQ+CSS)
$(document).on("mousedown", "[data-ripple]", function(e) {
var $self = $(this);
if($self.is(".btn-disabled")) {
return;
}
if($self.closest("[data-ripple]")) {
e.stopPropagation();
}
var initPos = $self.css("position"),
offs = $self.offset(),
x = e.pageX - offs.left,
y = e.pageY - offs.top,
dia = Math.min(this.offsetHeight, this.offsetWidth, 100), // start diameter
$ripple = $('<div/>', {class : "ripple",appendTo : $self });
if(!initPos || initPos==="static") {
$self.css({position:"relative"});
}
$('<div/>', {
class : "rippleWave",
css : {
background: $self.data("ripple"),
width: dia,
height: dia,
left: x - (dia/2),
top: y - (dia/2),
},
appendTo : $ripple,
one : {
animationend : function(){
$ripple.remove();
}
}
});
});
});
Вот полнофункциональная демонстрация:
jQuery(function($) {
// MAD-RIPPLE // (jQ+CSS)
$(document).on("mousedown", "[data-ripple]", function(e) {
var $self = $(this);
if($self.is(".btn-disabled")) {
return;
}
if($self.closest("[data-ripple]")) {
e.stopPropagation();
}
var initPos = $self.css("position"),
offs = $self.offset(),
x = e.pageX - offs.left,
y = e.pageY - offs.top,
dia = Math.min(this.offsetHeight, this.offsetWidth, 100), // start diameter
$ripple = $('<div/>', {class : "ripple",appendTo : $self });
if(!initPos || initPos==="static") {
$self.css({position:"relative"});
}
$('<div/>', {
class : "rippleWave",
css : {
background: $self.data("ripple"),
width: dia,
height: dia,
left: x - (dia/2),
top: y - (dia/2),
},
appendTo : $ripple,
one : {
animationend : function(){
$ripple.remove();
}
}
});
});
});
*{box-sizing:border-box; -webkit-box-sizing:border-box;}
html, body{height:100%; margin:0;}
body{background:#f5f5f5; font: 14px/20px Roboto, sans-serif;}
h1, h2{font-weight: 300;}
/* MAD-RIPPLE EFFECT */
.ripple{
position: absolute;
top:0; left:0; bottom:0; right:0;
overflow: hidden;
-webkit-transform: translateZ(0); /* to contain zoomed ripple */
transform: translateZ(0);
border-radius: inherit; /* inherit from parent (rounded buttons etc) */
pointer-events: none; /* allow user interaction */
animation: ripple-shadow 0.4s forwards;
-webkit-animation: ripple-shadow 0.4s forwards;
}
.rippleWave{
backface-visibility: hidden;
position: absolute;
border-radius: 50%;
transform: scale(0.7); -webkit-transform: scale(0.7);
background: rgba(255,255,255, 1);
opacity: 0.45;
animation: ripple 2s forwards;
-webkit-animation: ripple 2s forwards;
}
@keyframes ripple-shadow {
0% {box-shadow: 0 0 0 rgba(0,0,0,0.0);}
20% {box-shadow: 0 4px 16px rgba(0,0,0,0.3);}
100% {box-shadow: 0 0 0 rgba(0,0,0,0.0);}
}
@-webkit-keyframes ripple-shadow {
0% {box-shadow: 0 0 0 rgba(0,0,0,0.0);}
20% {box-shadow: 0 4px 16px rgba(0,0,0,0.3);}
100% {box-shadow: 0 0 0 rgba(0,0,0,0.0);}
}
@keyframes ripple {
to {transform: scale(24); opacity:0;}
}
@-webkit-keyframes ripple {
to {-webkit-transform: scale(24); opacity:0;}
}
/* MAD-BUTTONS (demo) */
[class*=mad-button-]{
display:inline-block;
text-align:center;
position: relative;
margin: 0;
white-space: nowrap;
vertical-align: middle;
font-family: "Roboto", sans-serif;
font-size: 14px;
font-weight: 500;
text-transform: uppercase;
text-decoration: none;
border: 0; outline: 0;
background: none;
transition: 0.3s;
cursor: pointer;
color: rgba(0,0,0, 0.82);
}
[class*=mad-button-] i.material-icons{
vertical-align:middle;
padding:0;
}
.mad-button-raised{
height: 36px;
padding: 0px 16px;
line-height: 36px;
border-radius: 2px;
box-shadow: /*amb*/ 0 0 2px rgba(0,0,0,0.15),
/*key*/ 0 1px 3px rgba(0,0,0,0.25);
}.mad-button-raised:hover{
box-shadow: /*amb*/ 0 0 2px rgba(0,0,0,0.13),
/*key*/ 0 2px 4px rgba(0,0,0,0.2);
}
.mad-button-action{
width: 56px; height:56px;
padding: 16px 0;
border-radius: 32px;
box-shadow: /*amb*/ 0 0 2px rgba(0,0,0,0.13),
/*key*/ 0 5px 7px rgba(0,0,0,0.2);
}.mad-button-action:hover{
box-shadow: /*amb*/ 0 0 2px rgba(0,0,0,0.11),
/*key*/ 0 6px 9px rgba(0,0,0,0.18);
}
[class*=mad-button-].mad-ico-left i.material-icons{ margin: 0 8px 0 -4px; }
[class*=mad-button-].mad-ico-right i.material-icons{ margin: 0 -4px 0 8px; }
/* MAD-COLORS */
.bg-primary-darker{background:#1976D2; color:#fff;}
.bg-primary{ background:#2196F3; color:#fff; }
.bg-primary.lighter{ background: #BBDEFB; color: rgba(0,0,0,0.82);}
.bg-accented{ background:#FF4081; color:#fff; }
/* MAD-CELL */
.cell{padding: 8px 16px; overflow:auto;}
<link href='https://fonts.googleapis.com/css?family=Roboto:500,400,300&subset=latin,latin-ext' rel='stylesheet' type='text/css'>
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
<script src="https://code.jquery.com/jquery-2.1.4.js"></script>
<div class="cell">
<button data-ripple class="mad-button-raised mad-ico-left bg-primary"><i class="material-icons">person</i>User settings</button>
<a data-ripple href="#" class="mad-button-action bg-accented"><i class="material-icons">search</i></a>
</div>
<div data-ripple class="cell bg-primary-darker">
<h1>Click to Ripple</h1>
<p>data-ripple</p>
</div>
<div data-ripple="rgba(0,0,0, 0.4)" class="cell bg-primary">
<p>data-ripple="rgba(0,0,0, 0.4)"</p>
<p> Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore....</p>
<p><a data-ripple class="mad-button-raised mad-ico-right bg-accented">Edit<i class="material-icons">edit</i></a></p>
</div>
Перевод ответа: How to create Ripple effect on Click - Material Design @Roko C. Buljan
Вариант с CSS-переменными, которые используются для раздельного использования свойства transform
. Разделять это свойство понадобилось для того, чтобы правильно перемещать элемент (translate3d
) и независимо от перемещения масштабировать (scale
). Через JS так можно очень удобно управлять этими параметрами.
С точки зрения производительности это достаточно хорошая анимация такого эффекта, поскольку не делаются вставки и удаления узлов в DOM и вся работа происходит исключительно со свойствами transform
и opacity
, которые не влияют на композитный слой, а значит не вызывают множество перерисовок страницы.
let span = document.querySelector('button span');
document.querySelector('button').addEventListener('click', function(e) {
span.style.setProperty('--x', e.clientX - this.getBoundingClientRect().left - span.offsetWidth/2 + 'px');
span.style.setProperty('--y', e.clientY - this.getBoundingClientRect().top - span.offsetHeight/2 + 'px');
let scaleCount = 0,
opacityCount = 1;
const animationTime = 500;
let scaleUp = setInterval(function() {
scaleCount += 0.25;
span.style.setProperty('--scale', scaleCount);
opacityCount -= 0.05;
span.style.opacity = opacityCount;
}, animationTime / 20);
setTimeout(function() {
clearInterval(scaleUp);
span.style.setProperty('--scale', 0);
}, animationTime);
});
body {
--x: 0px;
--y: 0px;
--scale: 0;
}
button {
padding: 10px 20px;
position: relative;
overflow: hidden;
border: 0;
border-radius: 3px;
background: linear-gradient(#c4e2fa, #c4effa);
outline: 0;
font: bold 17px arial;
text-shadow: 0 0 3px rgba(0,0,0,0.3);
color: #FFF;
}
button:hover {
background: linear-gradient(#c4e2fa, #c4e8fa);
}
span {
position: absolute;
width: 30px;
height: 30px;
border-radius: 50%;
background-color: rgba(0, 0, 0, 0.3);
top: 0;
left: 0;
transform: translate3d(var(--x), var(--y), 0) scale(var(--scale));
}
<button>This is text<span></span></button>
Такая анимация может быть достигнута с помощью box-shadows
. Размещение начала окружности под курсором мышки, при щелчке мышью потребуется JS
.
li{
font-size:2em;
background:rgba(51, 51, 254, 0.8);
list-style-type:none;
display:inline-block;
line-height:2em;
width:6em;
text-align:center;
color:#fff;
position:relative;
overflow:hidden;
}
a{color:#fff;}
a:after{
content:'';
position:absolute;
border-radius:50%;
height:10em; width:10em;
top: -4em; left:-2em;
box-shadow: inset 0 0 0 5em rgba(255,255,255,0.2);
transition: box-shadow 0.8s;
}
a:focus:after{
box-shadow: inset 0 0 0 0em rgba(255,255,255,0.2);
}
<ul>
<li><a href="#">button</a></li>
</ul>
Перевод ответа: How to create Ripple effect on Click - Material Design @web-tiki
Я использовал этот код раньше в нескольких моих проектах.
Используя jQuery
, мы можем поместить эффект на него не просто статически, но и затем добавить на элемент span
onclick
.
Я добавил комментарии, чтобы было проще понять код.
Demo Here
jQuery
$("div").click(function (e) {
// Remove any old one
$(".ripple").remove();
// Setup
var posX = $(this).offset().left,
posY = $(this).offset().top,
buttonWidth = $(this).width(),
buttonHeight = $(this).height();
// Add the element
$(this).prepend("<span class='ripple'></span>");
// Make it round!
if(buttonWidth >= buttonHeight) {
buttonHeight = buttonWidth;
} else {
buttonWidth = buttonHeight;
}
// Get the center of the element
var x = e.pageX - posX - buttonWidth / 2;
var y = e.pageY - posY - buttonHeight / 2;
// Add the ripples CSS and start the animation
$(".ripple").css({
width: buttonWidth,
height: buttonHeight,
top: y + 'px',
left: x + 'px'
}).addClass("rippleEffect");
});
CSS
.ripple {
width: 0;
height: 0;
border-radius: 50%;
background: rgba(255, 255, 255, 0.4);
transform: scale(0);
position: absolute;
opacity: 1;
}
.rippleEffect {
animation: rippleDrop .6s linear;
}
@keyframes rippleDrop {
100% {
transform: scale(2);
opacity: 0;
}
}
Перевод ответа: How to create Ripple effect on Click - Material Design @Ruddy
Зачем нужен "велосипед"? Я просто взял библиотеку MDL от Google, взял из нее и ripple и другое, а в конце исследовал ее и удалил из нее все, что не пригодилось, - для оптимизации.
Так проще.
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Перевод документов на английский язык: Важность и ключевые аспекты
Кто может помочь с кодом кнопки добавления записси в бд?
Есть программа на c# : сама программа + база данных созданная в MS SQL Server Manager StudioНа данный момент БД находится на моем ПК (Windows) но в дальнейшем...
Можно ли сказать чтоnet это обертка над языками с/с++? Поскольку например внутренно тот же класс File наверно вызывает WinApi функции для создания/удаления...