Reliable hover detection with animation in JavaScript? - javascript

It seems that jquery hover (and presumably the underlying browser events) cannot be reliably used to keep track of which element the mouse is over when animations are involved, since the events do not fire if an element moves under or away from the mouse (rather than the mouse moving into the element).
See this fiddle for an example of the issue I'm having. If you hover over the div, the state according to the hover tracking events always disagree with reality, at least by the end of the animation.
I haven't tested this outside chrome, but I'm assuming the same behaviour across browsers.
HTML:
<div>hover me</div>
<p>state</p>
CSS:
div {
-ms-transition: -ms-transform 1s;
-webkit-transition: -webkit-transform 1s;
transition: transform 1s;
}
div:hover {
position: relative;
-ms-transform: translateX(200px);
-webkit-transform: translateX(200px);
transform: translateX(200px);
}
JavaScript:
$('div').hover(function() {
$('p').text('over');
}, function() {
$('p').text('out');
});
While the fiddle isn't a realistic example, I'm experiencing this issue in a webpage with animations. The question I have is how do I ensure that my javascript correctly knows the hover state after animations? I'd like to do this without having a global mousemove event to follow the mouse (i.e. so that I can look for the element under the last coordinate at the end of each animation).

Related

Intense GPU usage for animations playing over blurred background

Considering this paragraph from calibreapp.com:
Browsers make optimizations by creating separate layers for elements
with CSS transitions or animations on Position, Scale, Rotation and
Opacity. When you have an animated element on its own layer, moving it
around doesn’t affect the positions of surrounding elements, the only
thing that moves is that layer. This way the browser avoids repaints
and does only compositing.
Now imagine we want to blur the whole background, the blur animation starts progresses and finally it finishes, ok?
Now on this blurred background we want to add a simple scale animation like this: (note that this is a separate div with no connection with background we already blurred)
.beaton {
animation: beatonAnime .5s infinite alternate;
}
#keyframes beatonAnime {
0% { transform: scale(1); }
100% { transform: scale(0.96); }
}
The confusing issue is:
Without that blurred background I get 1-2% GPU usage.
With that blurred background (which is not animating now and has finished seconds ago) I get 68% GPU usage!!!
As the paragraph said we should not see any difference between theses two as the blurred animation of background is not running when we add the scaling animation and they are in separate layers.
Here is the link to live example: (Note the GPU not CPU usage)
https://langfox.ir/test/beat/index.html
By the way this is the blur animation on the background:
.overlay {
animation: overlayShow 0.25s ease-in-out;
animation-fill-mode: forwards;
}
#keyframes overlayShow {
from {
backdrop-filter: blur(0);
background-color: rgba(35, 33, 36, 0);
}
to {
backdrop-filter: blur(80px);
background-color: rgba(35, 33, 36, 0.7);
}
}
Is there any solution for this?
NOTE: There is no such issue when I use filter: blur(80px) instead of backdrop-filter: blur(80px);. So what's wrong with backdrop-filter?
i get the same problem when play an animation above a blurred overlay.My final solution is to get a static blur image,it's formate cant be .png and shoule be .jpg.Then i set the overlay css property as 'background-image:url('../xxx.jpg)'.Since the background of the overlay is static,it wont take a lot gpu resource.Its a silly solution.

How to add zoom in / out on click to all img html tags?

What is the simplest way to add zoom in / out on click to all images in an html document (img tags)?
I'm editing a document in HTML and would like to stay focused on the content of this document. Due to this I would rather avoid adding any additional div elements around img element, at least in the source document.
Is there any simple javascript module which I can just plug-in for this purpose?
To clarify. Simple:
img:hover {
height: 400px;
}
would almost do the job for me but:
it cracks the layout
works with hover and I would prefer work on click.
Based on Paulie_D answer here is what I eventually came up with:
Works fine in Chrome & IE9. I tried to add this script to Paulie_D answer but my edit was rejected there - so here it is:
<style>
img {
cursor: pointer;
transition: -webkit-transform 0.1s ease
}
img:focus {
-webkit-transform: scale(2);
-ms-transform: scale(2);
}
</style>
<script>
document.addEventListener('DOMContentLoaded', function(){
var imgs = document.querySelectorAll('img');
Array.prototype.forEach.call(imgs, function(el, i) {
if (el.tabIndex <= 0) el.tabIndex = 10000;
});
});
</script>
Anything that changes the height of the image is likely to break your layout.
Accordingly you should be looking at (IMO) transform: scale(x)
JSFiddle Demo (using :active as mousedown - just click & hold)
CSS
img {
transition: -webkit-transform 0.25s ease;
transition: transform 0.25s ease;
}
img:active {
-webkit-transform: scale(2);
transform: scale(2);
}
add zoom in / out on click to all images in an html document (img tags)
See this fiddle
JQuery
$('img').each(function(){
$(this).click(function(){
$(this).width($(this).width()+$(this).width())
});
});
The above code will add zoom-in functionality to all img tags.
There are many jQuery plugins are available for zooming the images. Few are
http://plugins.jquery.com/image-zoom/
http://www.elevateweb.co.uk/image-zoom/examples

Getting CSS transition animation to work

I'm currently playing around with CSS animations and I'm looking to take a flat hand and have the hand move down the page i.e have a blank page and have a hand move down the page. As such I have been unsuccessful.
Here is my HTML code:
<div id ="splash" data-role="page">
<center>
<img id='Hand' style="position:absolute;top:-30%;" src="css/images/hand.gif">
</center>
</div>
Now I've been following a tutorial and have been using the following CSS:
.handmove{
transform: translate(0,1000px);
-webkit-transform: translate(0,1000px); /** Safari & Chrome **/
-o-transform: translate(0,1000px); /** Opera **/
-moz-transform: translate(0,1000px); /** Firefox **/
}
.objecttransition{
transition: all 2s ease-in-out;
-webkit-transition: all 2s ease-in-out; /** Chrome & Safari **/
-moz-transition: all 2s ease-in-out; /** Firefox **/
-o-transition: all 2s ease-in-out; /** Opera **/
}
From what I understand is .handmove is used to move the images position from -30% to 1000px down the screen. But the objecttransition class is to allow this movement to animate from point -30% to 1000px down. Correct me if I'm wrong?
Now what I look to do is as the page loads I want to add these classes to the hand using jQuery:
$(document).on('pagebeforeshow','#splash',
function()
{
$("#hand").addClass("objecttransition");
$("#hand").addClass("handmove");
});
I've also used the .ready() event but that also doesn't seem to work. I'm not to sure why the animation isn't working? Any ideas?
I would guess, the problem is the spelling,
id='Hand'
vs
$("#hand")
Use the same capitalization in both places.
Sigh... Silly Error!! With the .addClass() I used hand instead of Hand.Change .addClass('hand') to .addClass('Hand'). I then used the .ready() instead of on('pagebeforeshow','#splash',. Thus we have:
$(document).ready(
function()
{
$("#Hand").addClass("objecttransition");
$("#Hand").addClass("handmove");
});

Draggable JS Bootstrap modal - performance issues

For a project at work we use Bootstrap Modal windows in JavaScript. We would like to make some of the windows movable, but we are running into performance issues with JQuery.
$("#myModal").draggable({
handle: ".modal-header"
});
Example ,
Source .
In IE9, it works as expected.
In Chrome, horizontal dragging works as expected, and vertical dragging is rather slow but not problematic.
In Firefox, horizontal dragging works as expected, but vertical dragging is extremely slow.
It's strange, because the example window is not graphically heavy and JQuery is supposed to normalize browser behavior. I tried solving this without using JQuery's draggable, but I ran into the same issue.
So I have a couple of questions:
Is the slow performance the fault of the browser, JQuery, Bootstrap or is my code not optimal?
Why is there a difference between horizontal and vertical dragging?
Should I find a workaround, or just avoid Bootstrap altogether for dynamic popups?
Kind regards,
Guido
I found a few ways to fix this.
Adding this to your CSS file will disable the transition effects while the modal is being dragged. It appears however that once the user drags the box the fly in will not occur correctly but rather it will just fade in.
.modal.fade.ui-draggable-dragging {
-moz-transition: none;
-o-transition: none;
-webkit-transition: none;
transition: none;
}
Alternatively adding the following to your CSS file and the nofly class to your model will disable the fly in all together but not the fade in:
.modal.fade.nofly {
top: 10%;
-webkit-transition: opacity 0.3s linear;
-moz-transition: opacity 0.3s linear;
-o-transition: opacity 0.3s linear;
transition: opacity 0.3s linear;
}
I found that at bootstrap 3 I had to override these css properties of the modal dialog:
.modal
{
overflow: hidden;
bottom: auto;
right: auto;
}
.modal-dialog{
margin-right: 0;
margin-left: 0;
}
Fiddle
Full screen demo
This does not exactly answer your questions, but you may try to disable the *-transition properties or decreasing the time value from the specified 0.3s. This is defined in .modal.fade. But this will mess with the initial pop-up animation too. If this is not acceptable, you may use the start event of the draggable widget to apply the new style.
With Bootstrap 3.3 and jQuery UI 1.1 I'm adding a class called "modal-draggable" to the element with the "modal" class.
It binds to the .modal-dialog element inside containers with the .modal-draggable class (unlike some examples here which bind to the actual container).
There is some CSS so scrolling for long dialogs still work across devices of all screen sizes.
CSS:
.modal-draggable .modal-backdrop {
position: fixed;
}
.modal.modal-draggable {
overflow: overflow-y;
}
.modal-draggable .modal-header:hover {
cursor: move;
}
JavaScript:
$(".modal-draggable .modal-dialog").draggable({
handle: ".modal-header"
});
See the JS Fiddle here for a demo:
http://jsfiddle.net/jcosnn6u/3/
NB: So far I have only tested this in Chrome, Firefox and Safari and mobile devices, so can't comment on Internet Explorer compatibility.
I prefer using jqueryui. More detail about draggable API here: http://api.jqueryui.com/draggable/
Although the suggested CSS changes worked for me, I didn't like the dialog being shown on the left initially. Upgrading jquery UI from 1.9 to 1.11 fixed the issue I was seeing

I need to find prototype.js based slide out tab?

I have founded this -> http://www.building58.com/examples/tabSlideOut.html
But there are some reasons that i dont want to use it:
i need prototype framework instead of jquery
i need an image to open slider (click to open) and when it opened image will change to "click to close"
Maybe someone has already the same solution of my question?
thank for you help!
CSS transitions were made for this sort of thing! For a demonstration of what you're looking for see http://jsfiddle.net/Fw7MQ/ (The 'handle' changes background colour but you could easily make that a background image instead)
The crucial parts of CSS are;
#drawer {
position: relative;
left: -200px;
/* transition is repeated for all supporting browsers */
-webkit-transition: left 0.5s ease-in-out;
-moz-transition: left 0.5s ease-in-out;
-o-transition: left 0.5s ease-in-out;
-ms-transition: left 0.5s ease-in-out;
transition: left 0.5s ease-in-out;
}
#drawer.open {
left: 0;
}
The 'drawer' has a class name added or removed as necessary using this tiny javascript snippet;
Event.observe('handle', 'click', Element.toggleClassName.curry('drawer', 'open'))
...but you could dispense with even that if the animation was done on mouseover instead - change the CSS selector from #drawer.open to #drawer:hover.
For older browsers it degrades gracefully, the animation doesn't play but the drawer still appears in the right place.

Categories