2015-11-25 2 views
-2

Я хочу добиться эффекта, чем когда пользователь навешивается над div, это цвет фона превращается в градиент, который плавно переключается из одного угла в другой, повторно, используя чисто CSS.Как оживить градиентный фон плавно

Эффект, который я хочу достичь, пытаясь выразить его словами, заключается в том, что более темная часть фона (с непрозрачностью 0,9) скользит от одного угла к другому несколько раз, пока курсор остается выше элемент.

На самом деле происходит то, что фон перескакивает из одного состояния в другое. Где я иду не так? Как я могу заставить это быть анимированным, гладким эффектом?

Вот мой код:

#test { 
 
    width: 200px; 
 
    height: 200px; 
 
    background-color: rgba(215, 54, 92, 0.7); 
 
} 
 
@keyframes test_hover { 
 
    from { 
 
    background: -webkit-linear-gradient(45deg, rgba(215, 54, 92, 0.9), rgba(215, 54, 92, 0.5)); /* For Safari 5.1 to 6.0 */ 
 
    background: -o-linear-gradient(45deg, rgba(215, 54, 92, 0.9), rgba(215, 54, 92, 0.5)); /* For Opera 11.1 to 12.0 */ 
 
    background: -moz-linear-gradient(45deg, rgba(215, 54, 92, 0.9), rgba(215, 54, 92, 0.5)); /* For Firefox 3.6 to 15 */ 
 
    background: linear-gradient(45deg, rgba(215, 54, 92, 0.9), rgba(215, 54, 92, 0.5)); /* Standard syntax (must be last) */ 
 
    } 
 
    to { 
 
    background: -webkit-linear-gradient(45deg, rgba(215, 54, 92, 0.5), rgba(215, 54, 92, 0.9)); /* For Safari 5.1 to 6.0 */ 
 
    background: -o-linear-gradient(45deg, rgba(215, 54, 92, 0.5), rgba(215, 54, 92, 0.9)); /* For Opera 11.1 to 12.0 */ 
 
    background: -moz-linear-gradient(45deg, rgba(215, 54, 92, 0.5), rgba(215, 54, 92, 0.9)); /* For Firefox 3.6 to 15 */ 
 
    background: linear-gradient(45deg, rgba(215, 54, 92, 0.5), rgba(215, 54, 92, 0.9)); /* Standard syntax (must be last) */ 
 
    } 
 
} 
 
#test:hover { 
 
    cursor: pointer; 
 
    animation-name: test_hover; 
 
    animation-duration: 4s; 
 
    animation-delay: 1s; 
 
    animation-iteration-count: infinite; 
 
}
<div id="test"></div>

Вот JSFiddle

Этот вопрос был ссылаться дубликатом из here, но я думаю, что это не так. Для начала в этом вопросе нет кода, который затрудняет его понимание. Кроме того, в ответ на этот вопрос он использует переход, но мне не нужен переход, потому что он применяется только один раз, я хочу, чтобы моя анимация постоянно повторялась, когда пользователь зависал div.

+0

То же самое действительно, анимация или переход ... это не transitionable/анимируемым. Думаю, вам нужно что-то делать с позиции bg. –

+0

@ pablito.aven Он помог и объяснил. Фоновые градиенты не являются переходными. Вы можете использовать изображение и играть с фоновой позицией, но это все. – CaldwellYSR

+0

Вы можете достичь этого с помощью javascript http://stackoverflow.com/questions/33892656/how-change-css-using-variables-to-make-an-animation –

ответ

4

Как уже отмечалось в комментариях, линейные градиенты не являются переходными или анимируемыми, в отличие от цветов (background-color), поскольку они рассматриваются как изображение (background-image). Эффекты переходов обычно достигаются UA, вычисляющим значение на каждом промежуточном этапе, а затем применяя это значение к элементу. В случае изображения невозможно рассчитать значения на промежуточных этапах и, следовательно, они не могут быть преобразованы.

Чтобы добиться эффекта, вам нужно переместить положение (background-position). Это можно сделать, используя псевдоэлемент, фон которого содержит linear-gradient и анимирует его позицию на hover. Градиент должен идти в обоих направлениях (то есть он должен идти от rgba(215,54,92,0.9) до rgba(215,54,92,0.5), а затем до rgba(215,54,92,0.9)), поскольку он должен учитывать обе фазы анимации, а его background-size также должен быть двойным (то есть 200% 200%). Затем путем оживления положения от 0% 100% до 100% 0% может быть достигнут необходимый эффект.

#test { 
 
    position: relative; 
 
    width: 200px; 
 
    height: 200px; 
 
    background-color: rgba(215, 54, 92, 0.7); 
 
    transition: background-color .1s; 
 
} 
 
#test:hover { 
 
    background-color: transparent; 
 
    cursor: pointer; 
 
} 
 
#test:hover:after { 
 
    position: absolute; 
 
    content: ''; 
 
    height: 100%; 
 
    width: 100%; 
 
    background: linear-gradient(45deg, rgba(215, 54, 92, 0.9), rgba(215, 54, 92, 0.5), rgba(215, 54, 92, 0.9)); 
 
    background-size: 200% 200%; 
 
    background-position: 0% 100%; 
 
    animation-name: test_hover; 
 
    animation-duration: 4s; 
 
    animation-iteration-count: infinite; 
 
    animation-timing-function: linear; 
 
    animation-direction: alternate; 
 
} 
 
@keyframes test_hover { 
 
    from { 
 
    background-position: 0% 100%; 
 
    } 
 
    to { 
 
    background-position: 100% 0%; 
 
    } 
 
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/prefixfree/1.0.7/prefixfree.min.js"></script> 
 
<div id="test"></div>


Другой несколько иной подход, который может быть использован, чтобы добавить два псевдо-элементов с каждой имеющей одну стадию градиента анимации, а затем анимировать их opacity таким образом, что в любой точке время будет видно только одно из них.Это также даст аналогичный эффект.

#test { 
 
    position: absolute; 
 
    width: 200px; 
 
    height: 200px; 
 
    background-color: rgba(215, 54, 92, 0.7); 
 
    transition: background-color .1s; 
 
} 
 
#test:before, 
 
#test:after { 
 
    position: absolute; 
 
    content: ''; 
 
    height: 100%; 
 
    width: 100%; 
 
    z-index: 1; 
 
} 
 
#test:before { 
 
    background: linear-gradient(45deg, rgba(215, 54, 92, 0.9), rgba(215, 54, 92, 0.5)); 
 
    opacity: 0; 
 
} 
 
#test:after { 
 
    background: linear-gradient(45deg, rgba(215, 54, 92, 0.5), rgba(215, 54, 92, 0.9)); 
 
    opacity: 0; 
 
} 
 
@keyframes test_hover { 
 
    0%, 100% { 
 
    opacity: 0; 
 
    } 
 
    50% { 
 
    opacity: 1; 
 
    } 
 
} 
 
#test:hover:before, 
 
#test:hover:after { 
 
    cursor: pointer; 
 
    animation-name: test_hover; 
 
    animation-duration: 4s; 
 
    animation-iteration-count: infinite; 
 
    animation-fill-mode: backwards; 
 
} 
 
#test:hover:before { 
 
    animation-delay: 1s; 
 
} 
 
#test:hover:after { 
 
    animation-delay: 3s; 
 
} 
 
#test:hover { 
 
    background-color: transparent; 
 
    transition: background-color 2s 1s; 
 
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/prefixfree/1.0.7/prefixfree.min.js"></script> 
 
<div id="test"></div>

2

Чтобы оживить фон, вам необходимо изменить положение фона.

Чтобы сделать плавный переход, вы должны играть с непрозрачностью - и так как вы не хотите, чтобы все элемент исчезать, вы должны использовать псевдо-элемент для этого

#test{ 
 
    width: 200px; 
 
    height: 200px; 
 
    position: relative; 
 
    background-color: rgba(215,54,92,0.7); 
 
    transition: background-color 1s; 
 
} 
 
#test:hover{ 
 
    background-color: transparent; 
 
} 
 

 
#test:after { 
 
    content: ""; 
 
    position: absolute; 
 
    left: 0px; 
 
    top: 0px; 
 
    right: 0px; 
 
    bottom: 0px; 
 
    z-index: -1; 
 
    background-image: linear-gradient(45deg, 
 
        rgba(215,54,92,0.5), 
 
        rgba(215,54,92,0.9), 
 
        rgba(215,54,92,0.5), 
 
        rgba(215,54,92,0.9), 
 
        rgba(215,54,92,0.5) 
 
        ); 
 
    background-size: 800px 800px; 
 
    background-position: 0px 0px; 
 
    animation: move 2s infinite linear; 
 
    opacity: 0; 
 
    transition: opacity 1s; 
 
} 
 

 
#test:hover:after { 
 
    opacity: 1; 
 
} 
 
@keyframes move { 
 
    from {background-position: 0px 600px;} 
 
    to {background-position: -800px 600px;} 
 
}
<div id="test"></div>

+1

Космическое совпадение .... Но ваш ответ всегда более совершенен! – vals