悬停时旋转动画,但在悬停时移动鼠标 -> 取消

5

我正在尝试在我的网站上触发SVG中的旋转动画。它肯定可以工作,但问题是当我鼠标悬停在元素上移动时,它会取消动画。

所以我包含了一个对象SVG元素:

<object type="image/svg+xml" data="branching4.svg" id="branching">
    Your browser does not support SVG
</object> 

这是一个很长的SVG文档,但它附带了样式表:

#rectangle1, #rectangle2, #rectangle3{
    perspective: 1500px;
}
#rectangle1.flip .card, #rectangle2.flip .card, #rectangle3.flip .card {
    transform: rotateX(180deg);
}
#rectangle1 .card, #rectangle2 .card, #rectangle3 .card{
    transform-style:preserve-3d;
    transition:1s;
}
#rectangle1 .face, #rectangle2 .face, #rectangle3 .face{
    backface-visibility: hidden;
}
#rectangle1 #front1{
    transform: rotateX(0deg);
}
#rectangle1 #back1{
    transform: rotateX( 180deg );
}
#rectangle2 #front2{
    transform: rotateX(0deg);
}
#rectangle2 #back2{
    transform: rotateX( 180deg );
}
#rectangle3 #front3{
    transform: rotateX(0deg);
}
#rectangle3 #back3{
    transform: rotateX( 180deg );
}
#rectangle1.flipped, #rectangle2.flipped, #rectangle3.flipped {
    transform: rotateX( 180deg );
}

您可以在 jsfiddle 中查看 svg 结构。
最后是脚本:
window.onload=function() {
    var svgDoc = $("#branching")[0].contentDocument; // Get the document object for the SVG
    $(".st4", svgDoc).css("font-family", "robotolight,Helvetica Neue,Helvetica,Arial,sans-serif");
    $("#rectangle1", svgDoc).hover(function(){
        $(this, svgDoc).toggleClass("flip");
    });
    $("#rectangle2", svgDoc).hover(function(){
        $(this, svgDoc).toggleClass("flip");
    });
    $("#rectangle3", svgDoc).hover(function(){
        $(this, svgDoc).toggleClass("flip");
    });

};

我还尝试了使用CSS,但出现了相同的问题。

这是一个JSFiddle:

https://jsfiddle.net/7f7wjvvt/

第一个问题:

如何在鼠标移动到元素上时实现流畅的旋转过渡效果?

第二个问题:

如何使Y轴旋转保持在原地而不向左平移? 在fiddle中尝试一下

第三个问题:

为什么JSFiddle在Firefox中显示SVG正常却在Chrome中不正常? 此外,透视在Chrome中似乎无法工作... 为什么?

有什么想法吗?


对于问题1,您可以尝试添加一个标志,以确定动画何时结束。您可以使用transitionend监听CSS结束动画。以下是一些有用的文章链接:https://davidwalsh.name/css-animation-callback 和 https://developer.mozilla.org/en-US/docs/Web/Events/transitionend - GibboK
3个回答

3

很遗憾,我认为你遇到的许多问题只是由于浏览器对于SVG元素上(3D) CSS变换支持不佳所导致。

将卡片<g>元素移动到它们自己的<svg>中,放在普通的<div>内,并将交互应用于

元素会使事情变得更容易。

.card {
  display: inline-block;
  transform-origin: center;
  perspective: 1000px;
  background: grey;
}
.card-inner {
  width: 100px;
  height: 200px;
  transition: transform .4s;
}
.card-inner:hover,
.card:hover > .card-inner {
  transform: rotateY(180deg);
}
<div class="card">
  <div class="card-inner" style="background: yellow">
    Add svg card here
  </div>
</div>

<div class="card">
  <div class="card-inner" style="background: blue">
    Add svg card here
  </div>
</div>

<div class="card">
  <div class="card-inner" style="background: green">
    Add svg card here
  </div>
</div>

当鼠标移动到元素上时,如何实现流畅的旋转过渡?
一旦卡片旋转,就很容易失去悬停状态。但是,悬停状态将会应用于底层元素。如果您确保这是卡片的父级,请使用以下CSS规则进行样式设置:
.card-inner:hover,
.card:hover > .card-inner {
  transform: rotateY(180deg);
}

如何进行Y轴旋转而不改变左侧的位置?在fiddle中尝试一下。

您需要使用transform-origin,就像您尝试的那样。但是它对于svg元素无效...

transform-origin: center;

为什么在Firefox中jsfiddle可以正常显示svg而在Chrome中却不能?此外,在Chrome中似乎无法使用perspective...为什么?
就像我说的,这只是没有得到完全支持...

谢谢你,伙计。你做到了。 - Baptiste Arnaud

1

关于翻转的第一个问题

看起来问题在于当卡片旋转时,它们会缩小。然后鼠标不再悬停在卡片上,当卡片再次移动时,它重新进入并触发mouseenter事件。只要鼠标移动,整个过程就会重复。

解决方法是在动画完成之前防止事件再次触发。

有几种方法可以解决这个问题,但以下是一种解决方案:

// Flag to keep track of whether rectangle1 is flipping
var flipping1 = false;
$("#rectangle1").mouseenter(function() {
    // Only toggle the animation if we aren't already doing so
    if (!flipping1) {
        // Add the class to start the flip
        $(this).toggleClass("flip");
        // Set flag to mark that we are flipping
        flipping1 = true;
        // Then in just over a second, turn the flag off again
        setTimeout(function () {
            flipping1 = false;
        }, 1010);
    }
});

这里有一个演示,展示了如何在矩形1上运用这种技术。

https://jsfiddle.net/7f7wjvvt/4/


0

我没有完整的答案,但对于你的第一个问题,我建议用.mouseenter触发器替换.hover,并且对于第二个问题,只需取消透视。此外,我尝试为您的CSS添加前缀,但无济于事,似乎浏览器之间存在一些兼容性问题。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接