Rotate animation hover but while moving mouse on hover -> cancel - javascript

I'm trying to trigger a rotate animation in an SVG on my website. It definetly work but the problem is when i'm moving my mouse when i'm on hover the element it cancels the animation.
So i include an object svg element:
<object type="image/svg+xml" data="branching4.svg" id="branching">
Your browser does not support SVG
</object>
which is a long SVG document but here is stylesheet attached to it:
#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 );
}
You can see the svg structure in the jsfiddle
And finally the script:
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");
});
};
I also tried with CSS, it's the same problem.
Here is a jsfiddle:
https://jsfiddle.net/7f7wjvvt/
1st question:
How can i have a fluid rotate transition when moving the mouse on the element ?
2nd question:
How can i have a Y rotation that stay on the spot and not translate to the left ? Try it in the fiddle
3rd question:
Why the jsfiddle display the svg well in firefox and not in chrome?
Also, perspective doesn't seem to work in chrome ... WHY ?
Any ideas ?

Unfortunately, I think many of the problems you're experiencing are simply the result of bad browser support for (3D) css transforms on svg elements.
Moving the cards <g> elements to their own <svg> inside an ordinary <div>, and applying the interactivity to the div element would make stuff a lot easier.
.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>
How can i have a fluid rotate transition when moving the mouse on the element ?
Once the card rotates, it easily looses hover. The hover state will be applied to underlying element though. If you make sure this is the card's parent, you can use this css rule for styling:
.card-inner:hover,
.card:hover > .card-inner {
transform: rotateY(180deg);
}
How can i have a Y rotation that stay on the spot and not translate to the left ? Try it in the fiddle
You'll have to use transform-origin, like you tried. It just doesn't work for svg elements...
transform-origin: center;
Why the jsfiddle display the svg well in firefox and not in chrome? Also, perspective doesn't seem to work in chrome ... WHY ?
Like I said, it just isn't supported properly...

Re your first problem with the flip
It looks like the problem is that when the cards spin, they shrink. Then the mouse is no longer over the card and when the card moves around again it re-enters and the mouseenter event fires again. Then the whole process repeats (as long as the mouse is moving).
The solution is to prevent the event from firing again until the animation i complete.
There are several ways to fix this, but here is one solution:
// 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);
}
});
Here's a fiddle showing this technique working on just rectangle1.
https://jsfiddle.net/7f7wjvvt/4/

I don't have a complete answer but for your first question I'd suggest replacing the .hover with a .mouseenter trigger, and for the second one just lose the perspective.
Also, I tried prefixing your css but to no avail, seems there's some compatibility issues between the browsers here.

Related

Text blurring only on firefox with animation [duplicate]

I just want to skew the parent and skew it back on the child.
Example : HTML
<div class="parent"> <!-- skew(-10deg) -->
<div class="child">Hello</div> <!-- skew(10deg) (skew back) -->
</div>
Example : CSS
.parent {
transform: skew(-10deg);
}
.child {
transform: skew(10deg);
}
Text inside seems ok with Firefox, Safari. But not Chrome and Opera its a bit blurry
I have to use -webkit-backface-visibility: hidden; for reduce box pixelated in Chrome
Firefox :
Chrome :
Firefox vs Chrome :
or zoomed by Photoshop
Live example : http://jsfiddle.net/1tpj1kka/
Any idea ?
NOTE !!! : web-tiki's answer is an another way solution to prevent the problem. But if any answered a real solution to resolved this skew back problem (real fix), I will accept the answer.
The "blurry text" after 2d or 3d transforms with webkit browsers has been discused many times. But in your case, you can apply the transform only on a pseudo element so that your text isn't affected by the skew property.
It will also alow you to use only one tag in your markup :
#import url(https://fonts.googleapis.com/css?family=Oswald);
body{color:#fff;font-weight: bold;font-size:50px;font-family:'Oswald',sans-serif;}
.parent {
width: 300px;
overflow: hidden;
padding-left: 5%;
position:relative;
}
.parent::before {
content :'';
position:absolute;
top:0;left:0;
width:100%; height:100%;
background: rgba(90,190,230,0.9);
transform-origin:0 0;
transform:skew(-10deg);
z-index:-1;
}
<div class="parent">
Hello
</div>
Adding the 'translateZ(0)' before transformations like below forces the gpu to re-render the text and removes blurry-ness on Chrome.
This:
transform: translateZ(0) skew(-10deg);
Not This:
transform: skew(-10deg);
You can try the text-rendering: geometricPrecision CSS property. This will force your text to not be anti-aliased, thus making the blurriness less important.
inp.onchange = function(){
document.querySelector('.child').classList.toggle('geo');
}
#import url(https://fonts.googleapis.com/css?family=Oswald);body{color:#fff;font-weight:bold;font-size:50px;font-family:'Oswald',sans-serif;}
.geo{
text-rendering: geometricPrecision;
}
.parent {
transform: skew(-10deg);
-webkit-backface-visibility: hidden;
width:300px;padding-left:15%;margin-left:-15%;overflow:hidden;
}
.child {
transform: skew(10deg);
width:300px;background: rgba(90, 190, 230, 0.9);padding-left: 5%;padding-right: 15%;
}
<div class="parent"> <!-- skew(-10deg) -->
<div class="child geo">Hello</div> <!-- skew(10deg) (skew back) -->
</div>
<input type="checkbox" id="inp" checked="true"/> geometricPrecision

How can I create a triangle div with CSS which will disappear when clicked but not when the 'overflow' part is clicked?

This answer on a different thread: https://stackoverflow.com/a/24808936/6401041 says that this method for creating a CSS triangle is good because you can 'trigger the hover state or click event only when the cursor is inside the triangle' and then a demo is shown for how this can be done with the hover state.
My problem is basically this one:
https://i.stack.imgur.com/zYIS7.png
I don't want the user to be able to click in that area and trigger my onclick function which makes my triangle disappear. I have seen how to do this with :hover and :active but not with a click event. How can I make it so that only when the user clicks inside the triangle, does the function get called, making the triangle disappear for good with
style.visibility = "hidden";
Any help is greatly appreciated
You can make the triangle with a divelement, instead of a pseudoelement.
fiddle
document.querySelector('.triangle').onclick = function() {
this.style.display = "none";
}
.triangle-container {
overflow: hidden;
height: 100px;
}
.triangle {
width: 100%;
height: 100%;
background-color: #0079C6;
transform-origin: 0 100%;
transform: rotate(45deg);
}
<div class="triangle-container">
<div class="triangle"></div>
</div>

Is there a way to smooth closeby text transitions when using jQuery animations (namely drop)?

I found it a little difficult to word exactly what I was trying to ask, so I just made a fiddle instead. On my website I currently have a button that triggers a jQuery "drop" effect on a hidden div that has some text under it...like so:
<div id="toggle"></div>
<p>Some text under the div</p>
When the drop happens, my text shoots to the position it's supposed to be in rather than smoothly transitioning.
Code snippet:
$(document).click(function() {
$("#toggle").toggle("drop", {
direction: "up"
}, 600);
});
#toggle {
width: 100px;
height: 100px;
background: #ccc;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.9.1/jquery-ui.min.js"></script>
<body>
<p>Click anywhere to toggle the box.</p>
<div id="toggle"></div>
<p>Some text under the div</p>
</body>
Fiddle: https://jsfiddle.net/42cdxz83/10/
Is there a way to make the text transition/slide smoothly instead of going instantly from one position to the next? Using .slideDown() on the text is awesome, but is obviously tripped up by my "drop" animation. Looking for any way I can stop the jumpy text.
Thanks!
I think your problem was due to the fact that you were toggling the <div>, which included the paragraph, and expecting both to work separately. Here's an updated JSFiddle with a result I think you'd like: https://jsfiddle.net/42cdxz83/15/
Problem:
When you use toggle, you are removing your #toggle element from the
DOM. That's why your <p> element jumps to the top.
Solution:
Instead of using toggle, you can use CSS transitions for this, along with the property transform.
Code snippet:
$(document).click(function() {
$("#toggle").addClass("drop");
$("#toggle + p").addClass("up");
});
#toggle {
width: 100px;
height: 100px;
background: #ccc;
transition: transform 600ms ease-out, opacity 200ms linear;
}
.drop {
opacity: 0;
transform: translateY(-100px);
}
#toggle + p {
transition: transform 600ms ease-out;
}
.up {
transform: translateY(-100px);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<body>
<p>Click anywhere to toggle the box.</p>
<div id="toggle"></div>
<p>Some text under the div</p>
</body>
Notes:
The transformation in the Y axis of your <p> element should be equal to the height of your #toggle element multiplied by -1. (negative value)

weird behaviour in css transform:rotate

i trying to make this item draggable and rotatable.
however if i set transform:rotate(0deg);
i can drag everywhere in the parent container.
but if i set it to 90deg. there are some area became undraggable and it extended out of the parent container as well.
<div id="container">
<div id="myitem"><p>my rotate/drag</p></div>
CSS:
#container{
width:500px;
height:500px;
background:red;
}
#myitem{
width:115px;
height 50px;
background:black;
transform-origin:top left;
transform: rotate("90deg);
-ms-transform-origin:top left;
-ms-transform: rotate(90deg);
-webkit-transform: rotate(90deg);
-webkit-transform-origin:top left;
}
look for the example here
click here for sample of the problem
Have solucioned the problem!
If capture $(foo).offset().left when set css scale the value is not equals to real position if use transform-origin: top left;
To fix this replace
$(foo).offset().left by parseInt($(foo).css('left').replace('px',))
but need set
position after run: foo{ top: 0; left: 0; position: absolute; }
:)
The problem is who detect transform-origin and difference of positions when apply an scale(). Calculate by %?
I just running around your question, basically you want a draggable and rotatable with container...
I have done some changes to your fiddle and try to achieve this, http://jsfiddle.net/28WG3/19/
Some changes to the html too:-
<div id="container">
<div id="main"><div id="myitem"><p>my rotate/drag</p></div>
</div>
</div>
Hope this works for you...

How can I flip a Div when an image within that div is clicked?

OK so I know very little about writing Javascript, I can edit it a little, and have dabbled a bit in CSS3 animations.
I will give you an image of the sort of thing I am trying to achieve and then explain it below.
the website layout will be this: http://i.imgur.com/XyhaxNP.jpg
I have found a few ways of doing it on Google but most of them seem to flip the div when the user hovers over the div, I need it to be on click event as it will also need to work on mobile.
the third demo with the toggle button is what I was looking at, but that seems to not work when I add the event to an image.
This is what I have so far, I have moved the onclick event to the image (it used to be on a button in the demo I found) but it doesnt work on the image.
HTML:
<div class="flip-container">
<div class="flipper">
<div class="front">
<img class="teamlogo" onclick="document.querySelector('#flip-toggle').classList.toggle('flip');" src="images/logo/niners.png"/>
</div>
<div class="back">
Back of div content
</div>
</div>
</div>
CSS:
.teamlogo{
padding-left: 5%;
}
/* entire container, keeps perspective */
.flip-container {
perspective: 1000;
}
/* flip the pane when hovered */
.flip-container:hover .flipper, .flip-container.hover .flipper {
transform: rotateY(180deg);
}
.flip-container, .front, .back {
width: 320px;
height: 480px;
}
/* flip speed goes here */
.flipper {
transition: 0.6s;
transform-style: preserve-3d;
position: relative;
}
/* hide back of pane during swap */
.front, .back {
backface-visibility: hidden;
position: absolute;
top: 0;
left: 0;
}
/* front pane, placed above back */
.front {
z-index: 2;
}
/* back, initially hidden pane */
.back {
transform: rotateY(180deg);
}
So at this current point, it flips when you hover over it, and I need it just to flip when you click on the image.
Here is a working demo: http://jsfiddle.net/wvveY/1/
Generally you want to keep JavaScript separate from the HTML, but if you want it inside the tag, then better put on the tag the code is referencing, i.e. the tag. This way any clicks inside that div, be it on the image or text, will trigger the flip.
<div class="flip-container">
<div class="flipper" onclick="this.classList.toggle('flipped')">
<div class="front">
Front
</div>
<div class="back">
Back
</div>
</div>
</div>
and then you have the CSS class:
.flipped {
-webkit-transform:rotateY(180deg);
-moz-transform:rotateY(180deg);
-ms-transform:rotateY(180deg);
-o-transform:rotateY(180deg);
transform:rotateY(180deg);
}
see it working here: http://jsfiddle.net/wvveY/4/
http://jsfiddle.net/wvveY/3/
Make it .flip-container:active instead of .flip-container:hover

Categories

Resources