Страницы

Поиск по вопросам

понедельник, 30 марта 2020 г.

3d анимация. При наведении на все, кроме основного блока, ломается эффект

#javascript #css


Для примера поставил два блока, чтобы вы увидели, как анимация должна работать и
как она работает.

Левый блок работает отлично: в зависимости от того, откуда наводят мышью, соответственно
от этой стороны срабатывает эффект.  

В правой стороне есть svg-иконка, которая при наведении выходит поверх синего окна.   

Если навести, не задевая иконку или текст, можно и не заметить глюк. Но если навести
сразу на svg-иконку, то глюк сразу можно увидеть. Немного "поигравшись" указателем
внутри svg-иконки, не выходя из рамки svg, можно легко заметить проблему.

Ссылка: Codepen .

Я считаю, что тут проблема в css

Мои попытки:

1. Пытался дать position absolute этому блоку, но тогда все ломалось, и глюк также был

2. Пытался убрать display block из класса icon-close. Это не сработало тоже 

И много других манипуляций с CSS, но ничего не помогло.

Очень прошу помогите.



var nodes  = document.querySelectorAll('li'),
    _nodes = [].slice.call(nodes, 0);

var getDirection = function (ev, obj) {
    var w = obj.offsetWidth,
        h = obj.offsetHeight,
        x = (ev.pageX - obj.offsetLeft - (w / 2) * (w > h ? (h / w) : 1)),
        y = (ev.pageY - obj.offsetTop - (h / 2) * (h > w ? (w / h) : 1)),
        d = Math.round( Math.atan2(y, x) / 1.57079633 + 5 ) % 4;
  
    return d;
};

var addClass = function ( ev, obj, state ) {
    var direction = getDirection( ev, obj ),
        class_suffix = "";
    
    obj.className = "";
    
    switch ( direction ) {
        case 0 : class_suffix = '-top';    break;
        case 1 : class_suffix = '-right';  break;
        case 2 : class_suffix = '-bottom'; break;
        case 3 : class_suffix = '-left';   break;
    }
    
    obj.classList.add( state + class_suffix );
};

// bind events
_nodes.forEach(function (el) {
    el.addEventListener('mouseover', function (ev) {
        addClass( ev, this, 'in' );
    }, false);

    el.addEventListener('mouseout', function (ev) {
        addClass( ev, this, 'out' );
    }, false);
});
.icon-close {
  display: block;
  text-align: center;
}
.icon-close svg {
  margin-top: calc(70% / 2);
  margin-bottom: 20px;
}

.txt {
  text-decoration: none;
  text-align: center;
  display: block;
  color: blue;
  font-size: 22px;
  transition: 0.5s all ease;
  position: relative;
  z-index: 50;
  line-height: 1;
}

.container-inner {
  float: left;
  width: 100%;
}
.container-inner ul {
  margin: 0 auto;
  padding: 0;
  display: -webkit-box;
  display: -moz-box;
  display: -ms-flexbox;
  display: -webkit-flex;
  display: flex;
  -webkit-flex-wrap: wrap;
  -ms-flex-wrap: wrap;
  flex-wrap: wrap;
}
.container-inner ul:after {
  content: "";
  display: table;
  clear: both;
}
.container-inner ul li {
  background-color: rgba(255, 18, 156, 0.9);
  -webkit-perspective: 540px;
  perspective: 540px;
  position: relative;
  width: calc(25% - 10px);
  height: 290px;
  margin: 5px;
  padding: 0;
  list-style: none;
}
.container-inner ul li:hover svg {
  position: relative;
  z-index: 5;
}
.container-inner ul li:hover svg path {
  fill: white;
}
.container-inner ul li:hover .txt {
  color: white;
}
.container-inner ul li .info {
  -webkit-transform: rotate3d(1, 0, 0, 90deg);
  transform: rotate3d(1, 0, 0, 90deg);
  width: 100%;
  height: 100%;
  padding: 0px 10px;
  position: absolute;
  top: 0;
  left: 0;
  border-radius: 4px;
  pointer-events: none;
  background-color: rgba(26, 88, 156, 0.9);
}
.container-inner ul li .info p {
  color: #fff;
}

.in-top .info {
  -webkit-transform-origin: 50% 0%;
  -ms-transform-origin: 50% 0%;
  transform-origin: 50% 0%;
  -webkit-animation: in-top 300ms ease 0ms 1 forwards;
  animation: in-top 300ms ease 0ms 1 forwards;
}

.in-right .info {
  -webkit-transform-origin: 100% 0%;
  -ms-transform-origin: 100% 0%;
  transform-origin: 100% 0%;
  -webkit-animation: in-right 300ms ease 0ms 1 forwards;
  animation: in-right 300ms ease 0ms 1 forwards;
}

.in-bottom .info {
  -webkit-transform-origin: 50% 100%;
  -ms-transform-origin: 50% 100%;
  transform-origin: 50% 100%;
  -webkit-animation: in-bottom 300ms ease 0ms 1 forwards;
  animation: in-bottom 300ms ease 0ms 1 forwards;
}

.in-left .info {
  -webkit-transform-origin: 0% 0%;
  -ms-transform-origin: 0% 0%;
  transform-origin: 0% 0%;
  -webkit-animation: in-left 300ms ease 0ms 1 forwards;
  animation: in-left 300ms ease 0ms 1 forwards;
}

.out-top .info {
  -webkit-transform-origin: 50% 0%;
  -ms-transform-origin: 50% 0%;
  transform-origin: 50% 0%;
  -webkit-animation: out-top 300ms ease 0ms 1 forwards;
  animation: out-top 300ms ease 0ms 1 forwards;
}

.out-right .info {
  -webkit-transform-origin: 100% 50%;
  -ms-transform-origin: 100% 50%;
  transform-origin: 100% 50%;
  -webkit-animation: out-right 300ms ease 0ms 1 forwards;
  animation: out-right 300ms ease 0ms 1 forwards;
}

.out-bottom .info {
  -webkit-transform-origin: 50% 100%;
  -ms-transform-origin: 50% 100%;
  transform-origin: 50% 100%;
  -webkit-animation: out-bottom 300ms ease 0ms 1 forwards;
  animation: out-bottom 300ms ease 0ms 1 forwards;
}

.out-left .info {
  -webkit-transform-origin: 0% 0%;
  -ms-transform-origin: 0% 0%;
  transform-origin: 0% 0%;
  -webkit-animation: out-left 300ms ease 0ms 1 forwards;
  animation: out-left 300ms ease 0ms 1 forwards;
}

@-webkit-keyframes in-top {
  from {
    -webkit-transform: rotate3d(-1, 0, 0, 90deg);
    transform: rotate3d(-1, 0, 0, 90deg);
  }
  to {
    -webkit-transform: rotate3d(0, 0, 0, 0deg);
    transform: rotate3d(0, 0, 0, 0deg);
  }
}
@keyframes in-top {
  from {
    -webkit-transform: rotate3d(-1, 0, 0, 90deg);
    transform: rotate3d(-1, 0, 0, 90deg);
  }
  to {
    -webkit-transform: rotate3d(0, 0, 0, 0deg);
    transform: rotate3d(0, 0, 0, 0deg);
  }
}
@-webkit-keyframes in-right {
  from {
    -webkit-transform: rotate3d(0, -1, 0, 90deg);
    transform: rotate3d(0, -1, 0, 90deg);
  }
  to {
    -webkit-transform: rotate3d(0, 0, 0, 0deg);
    transform: rotate3d(0, 0, 0, 0deg);
  }
}
@keyframes in-right {
  from {
    -webkit-transform: rotate3d(0, -1, 0, 90deg);
    transform: rotate3d(0, -1, 0, 90deg);
  }
  to {
    -webkit-transform: rotate3d(0, 0, 0, 0deg);
    transform: rotate3d(0, 0, 0, 0deg);
  }
}
@-webkit-keyframes in-bottom {
  from {
    -webkit-transform: rotate3d(1, 0, 0, 90deg);
    transform: rotate3d(1, 0, 0, 90deg);
  }
  to {
    -webkit-transform: rotate3d(0, 0, 0, 0deg);
    transform: rotate3d(0, 0, 0, 0deg);
  }
}
@keyframes in-bottom {
  from {
    -webkit-transform: rotate3d(1, 0, 0, 90deg);
    transform: rotate3d(1, 0, 0, 90deg);
  }
  to {
    -webkit-transform: rotate3d(0, 0, 0, 0deg);
    transform: rotate3d(0, 0, 0, 0deg);
  }
}
@-webkit-keyframes in-left {
  from {
    -webkit-transform: rotate3d(0, 1, 0, 90deg);
    transform: rotate3d(0, 1, 0, 90deg);
  }
  to {
    -webkit-transform: rotate3d(0, 0, 0, 0deg);
    transform: rotate3d(0, 0, 0, 0deg);
  }
}
@keyframes in-left {
  from {
    -webkit-transform: rotate3d(0, 1, 0, 90deg);
    transform: rotate3d(0, 1, 0, 90deg);
  }
  to {
    -webkit-transform: rotate3d(0, 0, 0, 0deg);
    transform: rotate3d(0, 0, 0, 0deg);
  }
}
@-webkit-keyframes out-top {
  from {
    -webkit-transform: rotate3d(0, 0, 0, 0deg);
    transform: rotate3d(0, 0, 0, 0deg);
  }
  to {
    -webkit-transform: rotate3d(-1, 0, 0, 104deg);
    transform: rotate3d(-1, 0, 0, 104deg);
  }
}
@keyframes out-top {
  from {
    -webkit-transform: rotate3d(0, 0, 0, 0deg);
    transform: rotate3d(0, 0, 0, 0deg);
  }
  to {
    -webkit-transform: rotate3d(-1, 0, 0, 104deg);
    transform: rotate3d(-1, 0, 0, 104deg);
  }
}
@-webkit-keyframes out-right {
  from {
    -webkit-transform: rotate3d(0, 0, 0, 0deg);
    transform: rotate3d(0, 0, 0, 0deg);
  }
  to {
    -webkit-transform: rotate3d(0, -1, 0, 104deg);
    transform: rotate3d(0, -1, 0, 104deg);
  }
}
@keyframes out-right {
  from {
    -webkit-transform: rotate3d(0, 0, 0, 0deg);
    transform: rotate3d(0, 0, 0, 0deg);
  }
  to {
    -webkit-transform: rotate3d(0, -1, 0, 104deg);
    transform: rotate3d(0, -1, 0, 104deg);
  }
}
@-webkit-keyframes out-bottom {
  from {
    -webkit-transform: rotate3d(0, 0, 0, 0deg);
    transform: rotate3d(0, 0, 0, 0deg);
  }
  to {
    -webkit-transform: rotate3d(1, 0, 0, 104deg);
    transform: rotate3d(1, 0, 0, 104deg);
  }
}
@keyframes out-bottom {
  from {
    -webkit-transform: rotate3d(0, 0, 0, 0deg);
    transform: rotate3d(0, 0, 0, 0deg);
  }
  to {
    -webkit-transform: rotate3d(1, 0, 0, 104deg);
    transform: rotate3d(1, 0, 0, 104deg);
  }
}
@-webkit-keyframes out-left {
  from {
    -webkit-transform: rotate3d(0, 0, 0, 0deg);
    transform: rotate3d(0, 0, 0, 0deg);
  }
  to {
    -webkit-transform: rotate3d(0, 1, 0, 104deg);
    transform: rotate3d(0, 1, 0, 104deg);
  }
}
@keyframes out-left {
  from {
    -webkit-transform: rotate3d(0, 0, 0, 0deg);
    transform: rotate3d(0, 0, 0, 0deg);
  }
  to {
    -webkit-transform: rotate3d(0, 1, 0, 104deg);
    transform: rotate3d(0, 1, 0, 104deg);
  }
}
  • Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper.

  • contact
    us •


Ответы

Ответ 1



Я считаю, что тут проблема в css тут проблема в том, что mouseover и mouseout срабатывает на дочернем элементе mouseout UPD: НЕ берём немного магии отсюда https://stackoverflow.com/a/4698240/4794368 т.к. при динамическом добавлении/удалении элементов могут возникнуть проблемы лучше сделать так el.addEventListener('mouseout', function (ev) { if (ev.currentTarget.contains(ev.relatedTarget))return; }, false); https://developer.mozilla.org/en-US/docs/Web/Events/mouseout https://developer.mozilla.org/ru/docs/Web/API/Node/contains ev.relatedTarget - куда ушла мышь ev.currentTarget - нода, которая подписана на событие (el) node.contains( otherNode ) - Возвращает true если otherNode является потомком node, или непосредственно самим node. В противном случае возвращает false. mouseover чуть-чуть пишем сами let qwa = false el.addEventListener('mouseover', function (ev) { if(qwa)return; qwa=!qwa }, false); el.addEventListener('mouseout', function (ev) { qwa=!qwa }, false); результат var nodes = document.querySelectorAll('li'), _nodes = [].slice.call(nodes, 0); var getDirection = function(ev, obj) { var w = obj.offsetWidth, h = obj.offsetHeight, x = (ev.pageX - obj.offsetLeft - (w / 2) * (w > h ? (h / w) : 1)), y = (ev.pageY - obj.offsetTop - (h / 2) * (h > w ? (w / h) : 1)), d = Math.round(Math.atan2(y, x) / 1.57079633 + 5) % 4; return d; }; var addClass = function(ev, obj, state) { var direction = getDirection(ev, obj), class_suffix = ""; obj.className = ""; switch (direction) { case 0: class_suffix = '-top'; break; case 1: class_suffix = '-right'; break; case 2: class_suffix = '-bottom'; break; case 3: class_suffix = '-left'; break; } obj.classList.add(state + class_suffix); }; // bind events _nodes.forEach(function(el) { let qwa = false el.addEventListener('mouseover', function(ev) { if (qwa) return; qwa = !qwa addClass(ev, this, 'in'); }, false); el.addEventListener('mouseout', function(ev) { if (ev.currentTarget.contains(ev.relatedTarget)) return; qwa = !qwa addClass(ev, this, 'out'); }, false); }); .icon-close { display: block; text-align: center; } .icon-close svg { margin-top: calc(70% / 2); margin-bottom: 20px; } .txt { text-decoration: none; text-align: center; display: block; color: blue; font-size: 22px; transition: 0.5s all ease; position: relative; z-index: 50; line-height: 1; } .container-inner { float: left; width: 100%; } .container-inner ul { margin: 0 auto; padding: 0; display: -webkit-box; display: -moz-box; display: -ms-flexbox; display: -webkit-flex; display: flex; -webkit-flex-wrap: wrap; -ms-flex-wrap: wrap; flex-wrap: wrap; } .container-inner ul:after { content: ""; display: table; clear: both; } .container-inner ul li { background-color: rgba(255, 18, 156, 0.9); -webkit-perspective: 540px; perspective: 540px; position: relative; width: calc(25% - 10px); height: 290px; margin: 5px; padding: 0; list-style: none; } .container-inner ul li:hover svg { position: relative; z-index: 5; } .container-inner ul li:hover svg path { fill: white; } .container-inner ul li:hover .txt { color: white; } .container-inner ul li .info { -webkit-transform: rotate3d(1, 0, 0, 90deg); transform: rotate3d(1, 0, 0, 90deg); width: 100%; height: 100%; padding: 0px 10px; position: absolute; top: 0; left: 0; border-radius: 4px; pointer-events: none; background-color: rgba(26, 88, 156, 0.9); } .container-inner ul li .info p { color: #fff; } .in-top .info { -webkit-transform-origin: 50% 0%; -ms-transform-origin: 50% 0%; transform-origin: 50% 0%; -webkit-animation: in-top 300ms ease 0ms 1 forwards; animation: in-top 300ms ease 0ms 1 forwards; } .in-right .info { -webkit-transform-origin: 100% 0%; -ms-transform-origin: 100% 0%; transform-origin: 100% 0%; -webkit-animation: in-right 300ms ease 0ms 1 forwards; animation: in-right 300ms ease 0ms 1 forwards; } .in-bottom .info { -webkit-transform-origin: 50% 100%; -ms-transform-origin: 50% 100%; transform-origin: 50% 100%; -webkit-animation: in-bottom 300ms ease 0ms 1 forwards; animation: in-bottom 300ms ease 0ms 1 forwards; } .in-left .info { -webkit-transform-origin: 0% 0%; -ms-transform-origin: 0% 0%; transform-origin: 0% 0%; -webkit-animation: in-left 300ms ease 0ms 1 forwards; animation: in-left 300ms ease 0ms 1 forwards; } .out-top .info { -webkit-transform-origin: 50% 0%; -ms-transform-origin: 50% 0%; transform-origin: 50% 0%; -webkit-animation: out-top 300ms ease 0ms 1 forwards; animation: out-top 300ms ease 0ms 1 forwards; } .out-right .info { -webkit-transform-origin: 100% 50%; -ms-transform-origin: 100% 50%; transform-origin: 100% 50%; -webkit-animation: out-right 300ms ease 0ms 1 forwards; animation: out-right 300ms ease 0ms 1 forwards; } .out-bottom .info { -webkit-transform-origin: 50% 100%; -ms-transform-origin: 50% 100%; transform-origin: 50% 100%; -webkit-animation: out-bottom 300ms ease 0ms 1 forwards; animation: out-bottom 300ms ease 0ms 1 forwards; } .out-left .info { -webkit-transform-origin: 0% 0%; -ms-transform-origin: 0% 0%; transform-origin: 0% 0%; -webkit-animation: out-left 300ms ease 0ms 1 forwards; animation: out-left 300ms ease 0ms 1 forwards; } @-webkit-keyframes in-top { from { -webkit-transform: rotate3d(-1, 0, 0, 90deg); transform: rotate3d(-1, 0, 0, 90deg); } to { -webkit-transform: rotate3d(0, 0, 0, 0deg); transform: rotate3d(0, 0, 0, 0deg); } } @keyframes in-top { from { -webkit-transform: rotate3d(-1, 0, 0, 90deg); transform: rotate3d(-1, 0, 0, 90deg); } to { -webkit-transform: rotate3d(0, 0, 0, 0deg); transform: rotate3d(0, 0, 0, 0deg); } } @-webkit-keyframes in-right { from { -webkit-transform: rotate3d(0, -1, 0, 90deg); transform: rotate3d(0, -1, 0, 90deg); } to { -webkit-transform: rotate3d(0, 0, 0, 0deg); transform: rotate3d(0, 0, 0, 0deg); } } @keyframes in-right { from { -webkit-transform: rotate3d(0, -1, 0, 90deg); transform: rotate3d(0, -1, 0, 90deg); } to { -webkit-transform: rotate3d(0, 0, 0, 0deg); transform: rotate3d(0, 0, 0, 0deg); } } @-webkit-keyframes in-bottom { from { -webkit-transform: rotate3d(1, 0, 0, 90deg); transform: rotate3d(1, 0, 0, 90deg); } to { -webkit-transform: rotate3d(0, 0, 0, 0deg); transform: rotate3d(0, 0, 0, 0deg); } } @keyframes in-bottom { from { -webkit-transform: rotate3d(1, 0, 0, 90deg); transform: rotate3d(1, 0, 0, 90deg); } to { -webkit-transform: rotate3d(0, 0, 0, 0deg); transform: rotate3d(0, 0, 0, 0deg); } } @-webkit-keyframes in-left { from { -webkit-transform: rotate3d(0, 1, 0, 90deg); transform: rotate3d(0, 1, 0, 90deg); } to { -webkit-transform: rotate3d(0, 0, 0, 0deg); transform: rotate3d(0, 0, 0, 0deg); } } @keyframes in-left { from { -webkit-transform: rotate3d(0, 1, 0, 90deg); transform: rotate3d(0, 1, 0, 90deg); } to { -webkit-transform: rotate3d(0, 0, 0, 0deg); transform: rotate3d(0, 0, 0, 0deg); } } @-webkit-keyframes out-top { from { -webkit-transform: rotate3d(0, 0, 0, 0deg); transform: rotate3d(0, 0, 0, 0deg); } to { -webkit-transform: rotate3d(-1, 0, 0, 104deg); transform: rotate3d(-1, 0, 0, 104deg); } } @keyframes out-top { from { -webkit-transform: rotate3d(0, 0, 0, 0deg); transform: rotate3d(0, 0, 0, 0deg); } to { -webkit-transform: rotate3d(-1, 0, 0, 104deg); transform: rotate3d(-1, 0, 0, 104deg); } } @-webkit-keyframes out-right { from { -webkit-transform: rotate3d(0, 0, 0, 0deg); transform: rotate3d(0, 0, 0, 0deg); } to { -webkit-transform: rotate3d(0, -1, 0, 104deg); transform: rotate3d(0, -1, 0, 104deg); } } @keyframes out-right { from { -webkit-transform: rotate3d(0, 0, 0, 0deg); transform: rotate3d(0, 0, 0, 0deg); } to { -webkit-transform: rotate3d(0, -1, 0, 104deg); transform: rotate3d(0, -1, 0, 104deg); } } @-webkit-keyframes out-bottom { from { -webkit-transform: rotate3d(0, 0, 0, 0deg); transform: rotate3d(0, 0, 0, 0deg); } to { -webkit-transform: rotate3d(1, 0, 0, 104deg); transform: rotate3d(1, 0, 0, 104deg); } } @keyframes out-bottom { from { -webkit-transform: rotate3d(0, 0, 0, 0deg); transform: rotate3d(0, 0, 0, 0deg); } to { -webkit-transform: rotate3d(1, 0, 0, 104deg); transform: rotate3d(1, 0, 0, 104deg); } } @-webkit-keyframes out-left { from { -webkit-transform: rotate3d(0, 0, 0, 0deg); transform: rotate3d(0, 0, 0, 0deg); } to { -webkit-transform: rotate3d(0, 1, 0, 104deg); transform: rotate3d(0, 1, 0, 104deg); } } @keyframes out-left { from { -webkit-transform: rotate3d(0, 0, 0, 0deg); transform: rotate3d(0, 0, 0, 0deg); } to { -webkit-transform: rotate3d(0, 1, 0, 104deg); transform: rotate3d(0, 1, 0, 104deg); } }
  • Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper.

  • contact
    us •


Комментариев нет:

Отправить комментарий