Animating moving an object within a grid - javascript

Working on a little web game. Within this, I have a grid made from cells as divs. The player moves cell by cell by appending the player as a child of that div. I can't figure out how to animate the player while it moves such that instead of just "teleporting" when it becomes a child of the other div, is there any way to have the player slide over to the other cell or do I need to reevaluate the fundamental design?
No results from attempting typical CSS animations and transitions.

Instead of moving the player character about via appending that element to a new parent, I would recommend putting the character in one large parent div, and using absolute positioning in CSS to move the character:
This would also enable easier animations, letting you use standard CSS transitions!
div#character {
position: absolute;
left: 0px;
bottom: 0px;
transition-property: left, bottom;
transition-duration: 100ms;
}
You could then update the player .style.left and .style.bottom properties to apply movement.
player.style.left = `${xCoord}px`;
player.style.bottom = `${yCoord}px`;
(player is the player element)

Related

Element disappears when animating relative wrapper width with jQuery

I have a strange problem that happens when I animate the width of a relative positioned element which contains an absolute element. While the animation is running, inner element dissapears. When the animation is complete, inner element shows.
Here is the demo:
http://jsfiddle.net/R4Cj5/
When I remove parent element position: relative then inner element is shown while animation is running, but then I can't position it relatively to the parent.
Basically box with the % should be visible al the time
Does anyone have any idea whats happening here?
FIXED : I just added overflow: visible !important; to relative
positioned element
working example : http://jsfiddle.net/R4Cj5/26/
I think it might be a jQuery animate thing. I would love to see a working solution without any hacks, but for now here is something you might find useful! :-)
I basically added another function in the animate, upon completion it will animate the 90% to hover above the progress-bar
complete: function() {
$percent.animate({top: "-26px"})
}
in this use-case scenario, you can also remove/comment out the top: -26px from .progressbar .percent in the stylesheet. Also I added height: 20px; to the styling for .progressbar .percentage so you could see the % change as it glides across.

How to insert an html element before another without shifting the originals position

I would like to be able to insert an element that a user can navigate (left) to without disturbing what the user currently sees. that is, the new element will be inserted offscreen, to the left, but the currently "focused" element (and the other visible ones) shouldn't be seen to move.
Currently I am doing this using insertbefore, measuring the clientWidth of the new element and subtracting that from the margin of the container element. However, clientWidth is expensive to get, and this method is proving problematic when I add transitions. Is there a cleverer way to do this? I would have thought it's a fairly common problem - insert an element before another without shifting everything else.
You could use some CSS to achieve this. Insert a wrapping div with no height, but overflow: visible, insert the elements you want inside this div:
.wrapper {
height: 0;
overflow: visible;
}
.wrapper div {
margin-left: 100%;
}

Fixed div as background on mobile devices

I want to use a div as a background for a website.
If I use position:fixed and set the width & size to the viewport size the design breaks on mobile devices/tablets as they do not support the fixed position.
What's the best way to set a div as a static background, so that it works on mobile devices too?
I'm not entirely sure how you intend to use the background, but I created a loose way to do this here. The tacky background is applied to a div the size of the screen, and it will not move (as long as you're careful with what you put inside it). However, the same effect could be done just by direct styles on the body - I'm not sure what exactly you need the div for, so I can't guarantee this technique will work for your use case.
How it Works
With disclaimers out of the way, here are a few details on how it works. All content will have to appear within two divs: one outer one that has the background, and an inner one to hold all of the content. The outer one is set to the size of the page and can have the background applied to it. The inner one then is set to the size of the parent, and all overflow is set to scroll. Since the outer one has no scrollbar, any interior content that exceeds the size of the background tag will cause a scrollbar to appear as though it were on the whole page, not just on a section of it. In effect, this then recreates what the body is on the average web page within the "content" div.
If you have any specific question on the styles, let me know and I'll flesh out the mechanics in more detail.
With jQuery
I suppose there's still one remaining option: use similar style rules, but absent the ability to nest everything within the background, instead prepend it, and change it's position whenever the user scrolls, like so.
Then, just inject this code:
<style>
#bg {
width: 100%;
height: 100%;
position: absolute;
top: 0px;
background-image: url(http://cdn6.staztic.com/cdn/logos/comsanzenpattern-2.png:w48h48);
margin: 0px;
padding: 0px;
overflow: hidden;
}
</style>
<script>
$("body").prepend("<div id='bg'></div>");
$(document).on("scroll", function () {
$("#bg").css("top", $(document).scrollTop())
.css("left", $(document).scrollLeft());
});
</script>
modifying the style rules for the background div accordingly, and you should be good. It will not have a good framerate since this will always appear after the scroll paint, but you're running low on options if you have so little control over the rest of the document structure and style.
You don't have to use jquery. I was able to get this effect with just CSS.
You set the div just below the initial tag. Then apply the image to the html within the div. Give the div and id attribute as well (#background_wrap in this case).
...I tried this without applying the actual image link within the html and it never worked properly because you still have to use "background-image:" attribute when applying the image to the background within css. The trick to getting this to work on the mobile device is not using any background image settings. These values were specific for my project but it worked perfectly for my fixed background image to remain centered and responsive for mobile as well as larger computer viewports. Might have to tweak the values a bit for your specific project, but its worth a try! I hope this helps.
<body>
<div id="background_wrap"><img src="~/images/yourimage.png"/></div>
</body>
Then apply these settings in the CSS.
#background_wrap {
margin-left: auto;
margin-right: auto;
}
#background_wrap img {
z-index: -1;
position: fixed;
padding-top: 4.7em;
padding-left: 10%;
width: 90%;
}

Rotating images based on CSS nth-child

I was able to write a JavaScript carousel and thought it might be more compact to use CSS transitions with nth-child selectors like this:
img {
transition: all 1s linear; /* or corresponding vendor prefixes */
position:absolute;
}
img:nth-child(1) {
top: 0%;
left: 0%;
}
img:nth-child(2) {
top: 0%;
left: 50%;
}
/*and so on...*/
The items would then be rotated by appending the first child or prepending the last child of the container:
parent.appendChild(parent.children[0]);
This approach works well for all but the appended element. It is removed entirely and then reattached, so it ends up in the right spot but does not use the transition effect. Is there a way to use CSS transitions even when relocating an element in the DOM?
jsFiddle Demo - Click the document to advance the images.
What you can do is you can add or remove a class name from an element. Example you have a div element. And its class value is class="item". If you add another class name which has animation to that element's class name list, then that div element will show that animation at that moment immediately.
eg. div.className += " animatedClass";
A very interesting issue indeed. And here is the solution I came up with. Adds some markup and some CSS, but accomplishes it while still using nth-child. Honestly, I may work on this some more later and see if I can't come up with a more elegant solution, but for now, I forked off a jsFiddle.
The core of it is switching a class on a wrapper div, and using that to rotate through the styles.
However, as far as your actual question of can you animate an append image, you can, but not in the way you're thinking here. It would be an initial append animation, which would mean when the page first loaded it will animate. You can do this using #keyframes, and set it so that the image you want slides into place from a starting position of where it would be. But, again, this will happen on first load as well. You can fake it by 'spinning into place' for the first load. So, have all images spin once on load.
I ended up using a data-* attribute and selector. It is a little more verbose than nth-child, but has the advantage of working. It is also cleaner than parsing through class lists.
Each element has a data-order attribute, which can be assigned with HTML or JavaScript:
<img src="http://placekitten.com/203/203" data-order=0 />
Replace nth-child with the attribute selector:
img[data-order="1"] {
top: 0%;
left: 50%;
}
When rotating, increment the order in the dataset. This seems to update the attribute, even though we are modifying the property:
var forEach = [].forEach,
nodes = document.body.children,
length = nodes.length;
//On rotate:
forEach.call(nodes, function(node) {
node.dataset.order++;
node.dataset.order %= length;
});
Here is the final result.

Hide an element without masking item over top

I've created an effect whereby an HTML element is initially hidden behind another HTML element, and the CSS 'top' value of the hidden element is animated to expose it from beneath the masking element in a smooth sliding motion.
Does anyone know if there is a way to recreate this effect without the masking element on top?
I want to avoid the jQuery'esque slideDown where the height of the element being shown is animated.
I have the feeling that this just isn't possible, but if someone is otherwise aware, your advise would be much appreciated.
You can easily do this with a wrapper that has overflow set to hidden
http://jsfiddle.net/xvNf6/1/
HTML
<div id="wrapper" style="height:0px;">
<div>content</div>
</div>
Sample CSS
#wrapper{width:300px;height:280px;margin:0 auto; overflow:hidden; background:#eee}
Javascript
//if you must not use jQuery
var animationTimer = setInterval(function(){
var wrapper = document.getElementById("wrapper");
wrapper.style.height = (parseInt(wrapper.style.height) + 1) + "px";
if(parseInt(wrapper.style.height) >= 280)
clearInterval(animationTimer)
},1);
//if you can use jQuery
$("#wrapper").animate({height:"280px"},1000);
Place your element within a parent div with overflow:hidden. Then, position your element beyond bounds of the parent div so that it is hidden.
#wrapper { overflow: hidden; }
#target { height: 100px; top: -100px; } /* shift element out of view */
You can then reveal it by animating to {"top":0} to get the slidedown effect that doesn't resize the height of the element.
Here's a rather crude demo: http://jsfiddle.net/7RSWZ/
Update: Here's another demo that attempts to deal better with different content sizes by dynamically setting the heights and top values. http://jsfiddle.net/7RSWZ/2/

Categories