I want to slide an image (of a boomerang) off screen and then 5 seconds later slide it back into place. I want the image to right next to some text to begin with and end.
Ideally I'd like the animation to be smooth. I can find many examples doing things like this, but none that seem to do this very simple thing. Any pointers in the right direction would be greatly appreciated.
$(document).ready(function()
{
var my_div = $("#target");
var div_top = my_div.offset().top;
$(document).scroll(function()
{
if (div_top <= $(document).scrollTop()+($(window).height() /2))
{
// EVENT TO SEND IMAGE OFF SCREEN TO THE RIGHT
// EVENT TO WAIT 5 SECONDS
// EVENT TO SEND THE IMAGE BACK
}
});
});
<div id="target;">
<p style="font-size:32px; display: inline;">TEXT</p>
<img id="foo" style="height:35px;" src="https://upload.wikimedia.org/wikipedia/commons/4/46/Ic_account_box_48px.svgg">
You've tagged the question with javascript and provide code that's an incomplete javascript solution, but you also mention you want it to be smooth.
Perhaps declaring a CSS animation using transforms would be better?
Check out https://daneden.github.io/animate.css/ for some examples of what a CSS animation can do. And they can be quite complex, as you can define as many steps as needed.
Now if in some of your animation steps you need to perform calculations, you're stuck with JS, but you can still use a library that uses CSS transitions under the hood get get a smooth frame-rate.
I've used move.js for such a task in the past, and worked pretty well.
https://visionmedia.github.io/move.js/
Related
I was creating a 2048 clone from scratch as a project. I have got the game pretty much working only problem is that my animations look janky. I have used css grid to construct my game board and after every move (user input) all the tiles are meant to slide across the board in a direction. That part works fine, it's when they start the slide animation that for whatever reason some of the elements flicker.
I'm not the best with css animations but I have tried to look at every resource I could and I couldn't find any solutions suited to my code. I tried switching the animation timing, delaying the animation etc to no avail. I did use a package animate-css-grid (because animating css grid is hard) which only handles the tiles sliding across the grid and I do not suspect that it is causing the issue.
I have put the code on js fiddle if anyone is interested to try and see the problem https://jsfiddle.net/codedjourney/uv1o48L6/3/ hello
Also if anyone has a better way of animating css grid let me know the package while helpful is a bit odd to work with. Thanks for the help
I managed to get rid of the flickering by commenting out the hidden class in the addTile method
addTile(tile) {
// create the tile
const tileElm = document.createElement("div")
tileElm.classList.add(
"cell",
"tile",
// "hidden",
`cell-${tile.x}-${tile.y}`
)
const valueElm = document.createElement("div")
valueElm.classList.add("tile-container", `value-${tile.value}`)
valueElm.textContent = tile.value
tileElm.appendChild(valueElm)
this.display.appendChild(tileElm)
this.cells[tile.x][tile.y] = new Tile(
tileElm,
tile.x,
tile.y,
tile.value
)
// request frame to allow transition to play
window.requestAnimationFrame(() => {
tileElm.classList.remove("hidden")
})
}
As I saw your code All I see is that it's getting larger while colliding and it's happening because you have added css the one which scales your box while colliding.
Transform: Scale
Try using this css style and you might get your problem solved.
I have a test page to better explain my problem. I have several items on a list (they're images on the test page); when I click on one of them, a corresponding slideshow, using flexslider, sldes down.
The problem is that, on page load, the slideshow shows all slides at once, at a much smaller size than intended. But then, if I switch the focus from the window (i.e. switch between browser tabs or move to another program and come back), the slideshow is now working and the slides are the proper size. This happens in mobile devices too.
When I check with firebug, there's an element.style rule applying to ul.slides:
transform: translate3d(-89px, 0px, 0px);
Which hides one of the slides. Additionally, there's another rule for the list items inside ul.slides that gives them their initial width, which is not even the same for all sliders so I don't understand where it is coming from.
Can someone take a look and suggest a fix? I've tried overriding the element.style rule but so far unsuccessfully.
I think I've figured it out, in principal at least...
.flexslider{display:none;} seems throw off the re-size function of Flexslider.
You could just remove it, but that makes for some ugly loading.
To avoid said ugly loading I put together a quick, work-around- jsFiddle
$(document).ready(function(){
$(".flexslider").css('display','block').slideUp();
});
There's a still a quick glitch while loading, but hopefully it will at least steer you in the right direction.
Another method I played with a bit was to try and force the re-size function like so-
$(".client").click(function () {
$('.flexslider').resize(); // Problematic but promising
var project = this.id;
var project_id = '#' + project + '-project';
var elem = $(".flexslider:visible").length ? $(".flexslider:visible"): $(".flexslider:first");
elem.slideUp('slow', function () {
$(project_id).slideDown('slow');
});
});
This sort of solved the mini-picture issue, but was spotty at best.
See the following fiddle:
[edit: updated fiddle => http://jsfiddle.net/NYZf8/5/ ]
http://jsfiddle.net/NYZf8/1/ (view in different screen sizes, so that ideally the image fits inside the %-width layouted div)
The image should start the animation from the position where it correctly appears after the animation is done.
I don't understand why the first call to setMargin() sets a negative margin even though the logged height for container div and img are the very same ones, that after the jqueryui show() call set the image where I would want it (from the start on). My guess is that somehow the image height is 0/undefined after all, even though it logs fine :?
js:
console.log('img: ' + $('img').height());
console.log('div: ' + $('div').height());
$('img').show('blind', 1500, setMargin);
function setMargin() {
var marginTop =
( $('img').closest('div').height() - $('img').height() ) / 2;
console.log('marginTop: ' + marginTop);
$('img').css('marginTop', marginTop + 'px');
}
setMargin();
Interesting problem...after playing around with your code for a while (latest update), I saw that the blind animation was not actually firing in my browser (I'm testing on Chrome, and maybe it was firing but I wasn't seeing it as the image was never hidden in the first place), so I tried moving it inside the binded load function:
$('img').bind('load', function() {
...
$(this).show('blind', 500);
});
Now that it was animating, it seemed to 'snap' or 'jump' after the animation was complete, and also seemed to appear with an incorrect margin. This smacks of jQuery not being able to correctly calculate the dimensions of something that hadn't been displayed on the screen yet. On top of that, blind seems to need more explicit dimensions to operate correctly. So therein lies the problem: how to calculate elements' rendered dimensions before they've actually appeared on the screen?
One way to do this is to fade in the element whose dimensions you're trying to calculate very slightly - not enough to see yet - do some calculations, then hide it again and prep it for the appearance animation. You can achieve this with jQuery using the fadeTo function:
$('img').bind('load', function() {
$(this).fadeTo(0, 0.01, function() {
// do calculations...
}
}
You would need to work out dimensions, apply them with the css() function, blind the image in and then reset the image styles back to their original states, all thanks to a blind animation that needs these dimensions explicitly. I would also recommend using classes in the css to help you manage things a little better. Here's a detailed working example: jsfiddle working example
Not the most elegant way of doing things, but it's a start. There are a lot more easier ways to achieve seemingly better results, and I guess I just want to know why you're looking to do image blinds and explicit alignment this way? It's just a lot more challenging achieving it with the code you used...anyways, hope this helps! :)
Hey, I'm just wondering how to cycle through a bunch of images, and set them as the background for a div.
What I'm looking to do is: set the first image as the background to a div. Wait X seconds. Set the next image as the background. Wait X seconds … etc. and continue
I've got the following code which works for 1 image.
$(document).ready(function() {
var source = $(".field-field-background img:first").attr("src");
$('.field-field-background img:first').remove();
$('#main-inner').css('background', 'url('+ source +') no-repeat');
});
I'm guessing I need to get an array of the image sources, loop through the array and set it as the background, with a delay somewhere in the loop. Any ideas how I'd do this?
One of the biggest advantages of jQuery is that it has a very robust plug-in community. Many tasks that you might want to accomplished have been tackled by others before you. Particularly with a common task like this, I would recommend looking for a plug-in first, before trying to reinvent the wheel. Many plug-ins have the advantage of having gone through rigorous testing and multiple versions, to result in a polished product.
The jQuery Cycle plug-in would be a good candidate, if you are looking to do a slideshow type effect. If what you want is to cycle the background, while keeping foreground elements, you might look at something more like this: Advanced jQuery background image slideshow
$(document).ready(function() {
Cycler={};
Cycler.src=['path/to/img1', 'path/to/img2', 'path/to/img3'];
Cycler.cur=0;
Cycler.cycle=function() {
if(++Cycler.cur>=Cycler.src.length) {
Cycler.cur=0;
}
$('#main-inner').css('background', 'url('+ Cycler.src[Cycler.cur] +') no-repeat');
setTimeout(Cycler.cycle, 5000);//5 seconds
}
Cycler.cycle();
});
try this:
setInterval(function(){
var source = $(".field-field-background img:first").attr("src");
$('.field-field-background img:first').remove();
$('#main-inner').css('background', 'url('+ source +') no-repeat');
},4000);
The issue I am having is fairly complicated to explain. I have written up a javascript that displays an image slideshow, and it works fairly well, despite using up more resources than I would like
// imgArr[] is populated before
var i = 0;
var pageLoaded = 0;
window.onload = function() {pageLoaded = 1;}
function loaded(i,f) {
if (document.getElementById(i) != null) f();
else if (!pageLoaded) setTimeout('loaded(\''+i+'\','+f+')',100);
}
}
function displaySlideshow() {
document.getElementById(destinationId).innerHTML = '<div id="slideWindow"><img src="'+imgArr[i]+'" />' + '<img src="'+imgArr[i + 1]+'" /></div>';
setTimeout('displaySlideshow()',1000*3);
i++;
if (i >= imgArr.length - 1)
i = 0;
}
loaded(destinationId,displaySlideshow);
So, this script dynamically adds two images to a HTML element, and it is wrapped in a div.
The div is styled with the height and width of the image, with the overflow (the second image) hidden.
The second image is below the first, and the slideshow is meant to go from RIGHT to LEFT.
My inquiry is twofold:
1) Is there a more efficient way of doing this?
2) How would I animate the images? Would I need to put the second image on the right of the first with CSS somehow, and then set a timer to pull the images (via a style) leftward?
I really don't recommend rolling your own animation library. The Facebook Animation Library written by the wonderful Marcel Laverdet is simple to use and comes with a lot of tutorials to get what you want out of your slideshow. (Note: ignore the FBJS stuff, it's exactly the same even if you're using it on your own site.)
If you're not using a framework, I think you'll find a lot of pain ahead of you. If you still don't want to use a framework, at least find one that is liberally licensed, and take a look at the source code. Here's one, for example.
The basic theory is, yes, you set a timer that moves the image on some sort of interval, either fixed or based on some sort of mathematical equation (eg, sin, cos, etc). By setting these intervals close together, and making lots of them, you get an "animation" in javascript. Typically, you'd use some sort of absolute positioning, moving one element off the screen as the other moves on.