I want to animate between "default" states/positions for a div. For example:
Div absolutely positioned with a class, to be on the left of the screen. Class is removed via JS (or replaced) and position is now relative. The default relative position is actually on the opposite side of the screen. I want to animate this.
Something like a dock, various divs as icons in display-inline, centered horizontally on the dock. If I "delete" one of the icons, the rest will shift a bit to recenter. I want to animate them shifting to fill the gap.
Transition: all does not work (I assume because there was no predefined values for the position) so is this even possible? Are there JS solutions to this?
It's possible exactly the way you described it. Here's a live example of how it's done.
http://jsfiddle.net/nDr4y/3/
You can also remove the transition from css and use jquery to animate the element with pure JS. The syntax looks like this:
// in the object are the css properties you want to animate,
// the second argument is how long you want it to take in ms
$('.el').animate({ left: 100 }, 1000);
You just need to figure out the destination coordinates and set it using jQuery, or whatever framework you use. Other than that, it's totally possible.
http://jsfiddle.net/Kd72u/
Related
I have some elements whose properties are altered via the jQuery animate() method like that:
$('#mySidenav').animate({"width": '-=190'});
$('#main_address').animate({"padding-left": '-=190'});
$('.oberflaeche').animate({'margin-left':'-=190'});
Additionally I have another absolute positioned element within the .oberflaeche element which needs to be extended after the content moves to the left due to the operations named above in order to still properly fit into its container.
To do so I use the css property clip-path which works fine:
clip-path: inset(0px var(--clipSize) 0px 0px);
The only problem that occurs is that I have to alter the clip-path property dynamically as the window sizes are differing. Currently I am doing that via class-based css as I am not sure if it is possible with jQuery. Because of the different approaches (jQuery vs. css) the two effects are not being displayed simultaneously - the css clip-path effect is incongruous. I already tried to cover that problem using the transition-delay property as well as a transition-timing-function but I had no luck.
So the question is: Is it possible to animate the clip-path property like it can be done with the css properties of width or padding to achieve a consistent effect? I am looking for something like
$('#dynamic_element').animate({'clip-path': 'inset(0px '+variable_pixel+' 0px 0px)'});
which I can call where I also call the other animations.
Any help is highly appreciated. Thanks in advance!
Based on georg's proposal (see: https://stackoverflow.com/a/16857838/7323120) I was able to figure it out myself. Using the animate method you can iterate over custom value ranges and adjust the respective css in the method's callback like:
$({step: 0}).animate({step: 80}, {
step: function(val) {
// val equals the current step
$('#target').css('clip-path', "inset(0px "+val+"px 0px 0px)")
}
});
All,
I've got a situation in which I'm using CSS transforms/transitions to animate the horizontal position of a div element. Specifically, I'm using...
// in CSS
myDiv {
transition: transform 0.4s ease-in;
}
// in JavaScript, where "div" contains a reference to the div element
div.style.transform = translate3d(Npx, 0px, 0px);
...and it works well. That is, every time I call that line of JavaScript with a new value for N, the div smoothly animates from its current position to its new position.
However, there are times when I need position the div first WITHOUT a transition, then MOVE it WITH a transition. E.g.,
Have the div JUMP (instantly) to 100px, then transition (over 400ms) to 200px
Later, JUMP the div to 500px (without a transition), then transition it to 600px
In other words, I'd like to be able to move a div, and be able to control whether the new position is applied instantaneously, or with a transition.
Complicating matters, I have event listeners that fire when the transition is complete; these listeners should NOT fire if/when I move the div without a transition. I'm also supporting multiple browsers, so I have to deal with all the vendor prefixes.
In pseudo-code, I guess it would look something like this:
Remove the event listeners for the transitionEnd event
Set the transition property to none
Change the position of the div (e.g., [div].style.transform = translate3d([starting position]px, 0px, 0px))
Add the event listeners for the transitionEnd event
Set the transition property to have a transition (e.g., [div].style.transition:all 0.4s ease-in)
Change the position of the div (e.g., [div].style.transform = translate3d([ending position]px, 0px, 0px))
With all the vendor prefixes, that's too messy and complicated to be the best way to accomplish this. (I'm not even sure if it works...)
So, what's the best way to toggle transitions/transformations on and off?
[UPDATE]
Thanks to a suggestion from Chandranshu, I've tried toggling a class that includes the transitions.
So, my pseudocode looks like this:
Remove the transitions class
Apply the starting position
Restore the transitions class
Apply the ending position
However, it looks like, if I execute all four steps in a single JavaScript function - it seems to ignore steps 1-2, as though it's "netting" the results of all four steps.
Here's a jsfiddle that demonstrates this: http://jsfiddle.net/bUvX3/
Instead - if I execute steps 1 and 2, then execute steps 3 and 4 after a short delay (e.g., by using a setTimeout), it works: http://jsfiddle.net/2mhcv/
So, I guess that's a solution, except that I really don't like having to add an arbitrary delay, especially when so much emphasis is placed on fast, responsive UIs.
Thanks in advance!
I think you have over-complicated this :). Here's how I'd approach this problem:
Add a class to your divs, say movable.
Declare all your transition rules and transitionEnd callbacks for .movable.
Nothing to do if you want to move your div smoothly.
When you need to move your div w/o a transition, remove this class, move your div and add this class back: $('div').removeClass('movable').animate({transform: 'translate3d(...)' }).addClass('movable')
UPDATE:
Finally, I've got what you wanted: http://jsfiddle.net/2mhcv/1/. The only change here is that instead of a delay of 20ms, I'm using a delay of 0! setTimeout() causes a repaint to be triggered and that ensures that the first animation is executed before the next one begins.
UPDATE 2:
This version works without a setTimeout() call: http://jsfiddle.net/2mhcv/2/. Realizing that a repaint is all that is needed, I just added a line there to read a compute CSS property such as display. You could have read any other computed property to get the same effect.
jQuery's .width() method doesn't seem to account for scroll bars. This is problematic for me, since I'd like to set the width of some children to equal the width of their parent. I used jQuery similar to the following:
$('#contentDiv').width($('#containerDiv').width())
In this example, #contentDiv is the element I'd like to size, and I want to set it to have the width of #containerDiv, which is its parent element. My problem is that this cuts off the side of #contentDiv, as seen in this fiddle.
In my actual code, I have several elements that I'm sizing with jQuery, which all need to fit in the scrollable div, so just setting the css of #contentDiv to 100% is not an option. What's the best way of dealing with scroll bar widths of divs in jQuery?
The best solution I found while working around this solution is this:
http://chris-spittles.co.uk/?p=531
jQuery is all powerful and everything but sometimes a small dash of native JS is all you need to render pixel perfect pages... I hope you will find this solution helpful!
UPDATED:
None of the jQuery width-finding methods account for the scroll bar. In my original example, using .innerWidth(true) LOOKS like it works, but only because it returns and object, which causes width to fail and the inner contents size themselves to fit in the available space, because the example wasn't very good. However, it's possible to write a function to compute the available space in a div with a scroll bar in it, which can then be used to position the contents as you wish.
To write that function, I took advantage of the fact that, when a div is appended to a div with a scroll bar in it, it takes up the full available width (i.e. the inner width of the parent minus the width of the scroll bar).
The function looks like this:
function noScrollWidth(div){
var measureDiv = $('<div id="measureDiv">');
div.append(measureDiv);
var width = measureDiv.outerWidth();
measureDiv.remove();
return width
};
I then use this to size my content div:
$('#contentDiv').width(noScrollWidth($('#containerDiv')));
Working fiddle.
Try this:
$('#contentDiv').width($('#containerDiv')[0].clientWidth)
For more information about that solution, see this StackOverflow answer.
Another approach I'd try is setting both elements' box-sizing property to 'border-box', and see whether setting your contentDiv's width to 100% then works the way you want.
Now that fewer projects worry about crufty old browsers anymore, 'border-box' can make things easier to work with. Be sure to test multiple browsers on multiple platforms, though, because I'm not sure they all handle scrollbars the same way.
Is there a way to invert only part of an image? I have a "selector bar" sort of thing, and I want the icon that's selected to be inverted. Unfortunately, this looks really bad when the bar is transitioning to a different selection, as the icon immediately changes color. The "selector" should slide along the bar while transitioning.
Simple example of what I'm talking about can be found here
The best solution I can come up with right now is to put a new, inverted image on the selector element, and move the image the opposite direction the selector is moving. That would give the illusion that the slice of the image that's covered is inverted. Is that really the best way to do it?
Create an element with zero width and height, and outline: 8px solid invert. Then move this element around with your selector, and this will invert the stuff that it passes over.
I have a grid of elements (3 x 3) formation which toggle visibility on hover, easy.
However my next step is to grow said elements to fill their container when hovered upon, I'm assuming I would need to get current (x,y) values and then grow this to the (x,y) values of the parent container and use css positioning, however every approach I take is hitting a brick wall. I have a fiddle here which demonstrates the layout / intended functionality - http://jsfiddle.net/u2w7J/
Any help would be gratefully appreciated!
The way your HTML is set up currently, this is kind of hard to accomplish while having it look smooth. A first try is to use the .toggleClass function and toggle "box" and "miniBox" for the hovered element. See http://jsfiddle.net/u2w7J/6/ for a demo.
Positioning is harder since the miniBoxes are not positioned absolutely. Hence, adding animation is causing weird results (see above demo).
I would suggest to have the miniBoxes positioned absolutely. When hovering, get the parents div left and top values and animate the miniBox using these values. Additionally, raise z-index during or before the animation to prevent other miniBoxes being visible.