I'm making a webpage just for a bit of amusement. I want the background image to endlessly scroll to the left when the page is first loaded. The image is set to repeat-x in CSS and is seamless when laid end-to-end. Is this code I wrote aiming in the right direction?
I'm hoping to keep the JS vanilla just for simplicity but if this is better handled by JQuery, CSS or another library I'll be all ears.
I'll be very grateful for the help!
I've already tried some vanilla JavaScript code in a simple HTML document. My efforts so far haven't made the image move at all.
document.addEventListener("DOMContentLoaded", function() {
var y = 0;
while (true) {
y -= 1;
document.getElementById("bgImg").left = y;
}
})
#bgImg {
background-image: url("img1.jpg");
background-repeat: repeat-x;
width: 100%;
height: 660px;
display: inline;
}
<div id="bgImg">
</div>
This simply freezes my browser and doesn't scroll at all. Likely thanks to the "while(true)".
This is best accomplished with a CSS animation instead of JavaScript. CSS keyframed animations are designed to loop smooth transitions between pre-set property states with minimal memory overhead (and no synchronous while loops :P).
The only added bit of information you need to include is the width of your image. If you use this value as the x-coordinate of background-position in the to state of the animation, as soon as the background travels that many pixels, it will jump back to the from position. This jump will be invisible to the viewer, provided you've set the width correctly.
#bg {
background: url('https://www.gravatar.com/avatar/e47523b278f15afd925a473e2ac0b966?s=120&d=identicon&r=PG&f=1');
background-repeat: repeat-x;
width: 240px;
height: 120px;
animation: bgScrollLeft 5s linear infinite;
}
#keyframes bgScrollLeft {
from {
background-position: 0 0;
}
to {
background-position: -120px 0;
}
}
<div id="bg"></div>
I just implemented this on my own site after seeing your question. cool idea!
function animateBg(px=0){
requestAnimationFrame(()=>{
document.body.style.backgroundPosition = `${px}px 0px`;
animateBg(px+0.5);
});
}
animateBg();
It assumes you have a bg image set in CSS. Change the 0.5 to change the speed.
You are moving the element left, but in fact you should move your background position. Next to that with a while(1) loop it will run infinitly. So 2 task, create an animation frame to not run infinite. And change the background-position property.
var left = 0;
// You might want to add a time delta
function animate() {
requestAnimationFrame( animate );
document.getElementById("bgImg").style.backgroundPosition = '0 ' +left-- + 'px';
}
animate();
Note the code probably wont work, but gives you an idea of an solution.
Look into requestAnimationFrame to know what it does.
edit
Look at IronFlare solution, which is more beautiful with css.
Related
Do any web browsers support animated cursors?
I've been searching the web to add custom cursors to my web application. I've been finding a lot of non animated (.cur) and animated (.ani) cursors, and using the correct CSS so that my application has custom cursors! It seems that the animated cursors are not supported in the web browsers I tried and I was wondering if there is any way possible to put animated cursors into my web application.
You can make it happen with the help of a bit of javascript:
Add to your css
#container {
cursor : none;
}
#cursor {
position : absolute;
z-index : 10000;
width : 40px;
height : 40px;
background: transparent url(../images/cursor.gif) 0 0 no-repeat;
}
Then add to your js
Straight Javascript Version
// Set the offset so the the mouse pointer matches your gif's pointer
var cursorOffset = {
left : -30
, top : -20
}
document.getElementById('container').addEventListener("mousemove", function (e) {
var $cursor = document.getElementById('cursor')
$cursor.style.left = (e.pageX - cursorOffset.left) + 'px';
$cursor.style.top = (e.pageY - cursorOffset.top) + 'px';
}, false);
Jquery Version
$('#container').on("mousemove", function (e) {
$('#cursor').offset({
left: (e.pageX - cursorOffset.left)
, top : (e.pageY - cursorOffset.top)
})
});
I managed to accomplish this using CSS keyframes, animating the source image of the cursor. It works in Chrome and Safari (though it can get a little glitchy if you've got a ton of stuff running). Good enough for my personal site!
* {
cursor: url(frame1.png), auto;
-webkit-animation: cursor 400ms infinite;
animation: cursor 400ms infinite;
}
#-webkit-keyframes cursor {
0% {cursor: url(frame1.png), auto;}
20% {cursor: url(frame2.png), auto;}
40% {cursor: url(frame3.png), auto;}
60% {cursor: url(frame4.png), auto;}
80% {cursor: url(frame5.png), auto;}
100% {cursor: url(frame6.png), auto;}
}
#keyframes cursor {
0% {cursor: url(frame1.png), auto;}
20% {cursor: url(frame2.png), auto;}
40% {cursor: url(frame3.png), auto;}
60% {cursor: url(frame4.png), auto;}
80% {cursor: url(frame5.png), auto;}
100% {cursor: url(frame6.png), auto;}
}
After doing some more research, I don't think it's possible at the moment. It doesn't seem that any of the browsers support animated cursors as of 2/8/2012 using the CSS cursor property. I suppose it could be done using JavaScript to repeatedly change the value of the cursor property every few frames to make it appear animated, but that may be more trouble than it is worth.
Animated cursor files .ani files do not work. All 5 major web browsers will not show the cursor. If you try some CSS like, cursor: url('animated.ani'), that cursor will not show up!
If you make the cursor an animated gif file, it only shows up on some browsers and it's temperamental, like cursor: url('animated.gif'), the cursor works in Firefox and Chrome but it is not animated, the cursor does not work at all in IE9 or Opera, and it did something really weird in the Windows version of Safari - it works but is only animated when I move the cursor vertically on the screen, and did not animate at all when the cursor was not moving or was moving horizontally. Credit to Brutallus for the idea to use an animated gif even though it did not work!
It doesn't seem that browsers support animated cursors at this time which is a shame because I really think it would add some depth to certain web applications. I don't advocate using animated cursors for most websites because they are extremely annoying, but there are some rare situations where they can be useful, such as a HTML5 game where the cursor can potentially add to the theme of the game.
To answer your question
Do any web browsers support animated cursors?
Yes.According to MDN, IE supports .cur and .ani formats.
As a suggestion,have you considered using an animated gif image instead?
Try this in your css
cursor: url(img/animated_cursor.gif), auto;
-->it flickers for some reason when you move the mouse in a downwards direction
It happens because the cursor goes over the animated gif (over the #mycursor image, look the code) and exits the element on which you call the function.
I was able to get .ani cursors rendering in modern browsers by using JavaScript to extract the individual animation frames from the .ani file and convert them to data URIs which I then compose into a CSS animation similar to the solution proposed by Laura above.
I've published it as an NPM module called ani-cursor.
Some limitations of this approach:
The .ani file must be served from the same domain, or include proper CORS headers.
CSS cursor animation does not currently work in Safari, but a fix has landed so it should be in the next release.
I've also written a blog post with some details about how it works: https://jordaneldredge.com/blog/rendering-animated-ani-cursors-in-the-browser/
No major browser actually supports animated cursors (of type .ani) as of 2017, and I don't think any are really planning to add them in the future. However, some random browser may support this feature (a not really well known browser), so you should add a feature that will make the cursor work in those browsers:
body {
cursor: url("hand-pointing.ani"), pointer;
}
This way, if the animated cursor doesn't work in a user's browser, at least the normal pointer cursor is enabled. If you don't add the pointer part, than browsers without animated cursor support would load an ENTIRELY DIFFERENT cursor from what you wanted. Also, note that the default browser cursors kind of suck. I know that many people want animated cursor support added to major browsers, but it won't happen unless lots of people petition for it or something.
In other words, there is no answer to this question right now. Please comment if this changes.
Full code without bugs
<body id="body" onmousemove="showCoords(event)" onmouseout="clearCoor()">
<div id="mini_mouse">
</div>
<script src="lib/js/jquery-3.3.1.min.js"></script>
<script>
function showCoords(event) {
var elmnt = document.getElementById("html");
var scrollTop = elmnt.scrollTop;
var x = (event.clientX) - (10);
var y = (event.clientY) - (10) + (scrollTop);
document.getElementById("mini_mouse")
.style = ("top: " + y + "px ;" + "left: " +
x + "px ;" + "
background-color: red;
width: 20px;
height: 20px;
opacity: .5 ;
position: absolute;
z-index: 100;
border-radius: 100px ;
");
}
function clearCoor() {
document.getElementById("mini_mouse").style = "";
}
</script>
A possible alternative: you could convert the ANI into a GIF and then have the GIF follow your (hidden) mouse cursor around.
// Have the cursor follow the mouse
$(document).mousemove(function (e) {
$(".pointer").css({ left: e.pageX, top: e.pageY });
});
/* Hide original cursor; add whatever elements necessary */
html, input, textarea {
cursor: none;
}
.pointer { /* Set cursor location */
position: absolute;
height: 480px; top: 100px;
width: 480px; left: 50%;
z-index: 9999; /* Put cursor on top of everything */
pointer-events: none; /* Make sure cursor doesn't change */
}
.pointer img { /* Set cursor size constraints if desired */
height: 50px;
width: auto;
}
<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8">
<script src="https://code.jquery.com/jquery-3.4.1.min.js"></script></head>
<body>
<div class="pointer">
<img src="https://i.imgur.com/K5ufqqA.gif">
</div>
</body>
I'm using JavaScript's .toggle() to have this appear/ disappear:
{
display: none;
position: fixed;
top: 100px;
right: 0;
left: 0;
background: rgba(0,0,0,0.75);
padding: 15px;
}
However, over the duration of the animation it starts from the top-left corner and expands out to the bottom-right corner of the div.
Ideally, I'd like to start it from the both top corners and expand downwards to both bottom corners evenly.
I thought the CSS transition-origin property might have an effect, but it doesn't seem to be the case.
Any ideas? Thanks in advance. :)
I would start a height of 0 and the animate the height property.
function toggle() {
var el = document.getElementsByTagName('div')[0];
if (el.className) {
el.className = '';
} else {
el.className = 'grow';
}
}
div {
background-color: black;
width:200px;
height: 0;
}
.grow {
height: 200px;
transition: height 2s;
}
<button onclick="toggle()">Toggle</button>
<div></div>
I don't know much about jQuery's toggle method, so I looked in the docs, and sure enough it gives some helpful info. (This is a gentle hint that before coming to StackOverflow you should try solving the problem on your own, including looking at any relevant documentation online).
The .toggle() method animates the width, height, and opacity of the
matched elements simultaneously.
The documentation doesn't give any info about customizing how toggle does its animation, so it looks like you're stuck. If I'm understanding you correctly, it seems like you want the element to animate only the height and not the width, so it stays the same width as it toggles and just animates the height. I don't see any way of doing that with jQuery's toggle.
BUT WAIT! It looks like jQuery has another method called slideToggle which does exactly what you want. It's just like toggle except it only animates the height and keeps the width the same. Hooray!
http://api.jquery.com/slidetoggle/
Moral of the story: if you're using a third party Javascript library like jQuery, you really need to get comfortable finding the information you need in the online documentation my friend. :)
It's somewhat hard to explain because it's a mouthful but I'll try to give you the context as best as I can.
I have a little character, facing north, south, east, and west, on a CSS sprite sheet. In my game. you can control his movements with WASD, causing him to visibly move X amount of pixels up, down, left, or right. Depending on that direction, the CSS sprite changes to accommodate accordingly so that he's always "facing" the direction he's travelling.
My problem is that I want to use the CSS transition property, but when I do so, it causes the movement I want however it scrolls through the CSS sprite, which I do not want.
My question is, what CSS property controls the pixel movement on the screen, because setting it to "All" transitions everything, including the background position which I do not want.
I have the following CSS code:
.player {
background: url(character.png) no-repeat top left;
width: 48px;
height: 48px;
position: absolute;
margin: 0;
z-index: 100;
transition: all .25s ease;
}
.player.playerFront {
background-position: 0 0;
}
.player.playerBack {
background-position: -48px 0;
}
.player.playerLeft {
background-position: -96px 0;
}
.player.playerRight {
background-position: -144px 0;
}
Javascript:
player.className = 'player playerRight';
player.style.left = parseInt(player.style.left) + 48 + 'px'; // Example of the JS when the player moves right
I've tried a variety of possibilities... none of which have worked. Everything on StackOverflow and online only talk about animation or hover effects and don't apply to my specific problem.
The reason you don't see a smooth transition in movement is that your JS is moving the character in 48px increments. When you set a style like that directly in JS, you won't see it animate because it sets it to the new value immediately - even if you put a transition property on it.
Edit:
If you only want to transition the position and not the background-position, you'd do it like this:
transition-property: top, bottom, left, right;
transition-duration: 0.25s;
transition-timing-function: ease;
That said, it still won't have an effect if you're using JS to set the style. When you set style.left += 48px, it's going to move that 48px all in one go.
Alternatively, you might have an issue with how your spritesheet is set up. Make sure each "sprite area" (ie, each segment of the sheet that might be visible at once) has the sprite centered in it, not against any of the edges. (It might be helpful to make a codepen showing what you've got, if you want more detailed answers.)
I have a really strange problem: I am using jQuery v11 on the latest Chrome on localhost. While I manage to use jQuery.animate() on my website with any elements and features (including opacity), I have one element that I just can't.
I tried to trigger the animation within and outside the $(document).ready() function and they both resulted in the same thing. I tried with fadeTo, fadeIn/fadeOut, animate opacity, all of them the same thing. The animation starts but after a certain percentage it just doesn't continue and jumps right to the end. I also tried it with e.g. padding and it works perfectly.
I am using the callback too but removing or adding it did not affect performance on either cases. Also, I have browsed through dozens or even more questions already, so I feel I did my research.
Thank you for your help!
JavaScript:
$("#nb_copy").stop().animate({ opacity: 0 }, 300, function()
{
$(this).css("background-position", "-16px").stop().animate({ opacity: 1 }, 300);
});
HTML:
<div id='notes_buttons'>
<a id='nb_copy' data-info=''>C</a>
</div>
CSS:
div#notes_buttons
{
width: 18px;
position: absolute;
top: 180px;
right: -24px;
opacity: 0;
filter: alpha(opacity=0);
}
div#notes_buttons a
{
cursor: pointer;
display: block;
width: 18px;
height: 18px;
margin-bottom: 1px;
background: red url("/db/sprite.png") no-repeat;
background-position: 0px 0px;
}
Note: I would like to use this animation in the following situation: I am animating the opacity (see, here it works...) of the parent div, then when the nb_copy button is pressed, it fades out, changes the bg position and fades back.
If I use really long animations (3000) and add a delay, the first animation interrupts after about 40%, then after the 3000 ms are over, it counts the delay and then the new animation. This way I have no problem with the animation. Also, if I do not use the callback, it is working. But the two interrupt each other somehow...
if I only use the .css in the callback, it applies instantly (the background position) but the animation runs smoothly.
I already spent about 1.5 hours on such a small thing... Well, if I reproduce the code above in JSfiddle, it is working: https://jsfiddle.net/g6z4xx16/. I am also using Zeroclipboard with the same button, may it be the problem?
In case I get it out of the Zeroclipboard nest, and put it into a simple click trigger, the same result.
Why to make simple work complicated, just use fadeToggle() instead.
Simply change your code to this :
$("#nb_copy").fadeToggle(function()
{
$(this).css("background-position", "-16px").fadeToggle();
});
Using fadeToggle() is better because animate() is used to make custom animations.
In your code place your <style> tag before the <script> tag.
I'm relatively new to Web development and wouldn't even know where to start in coding a JavaScript that fades a grayscale thumbnail image into a color thumbnail image on mouseover, and vice versa on mouseoff (<--or whatever this is called).
I've looked all over and can't find a script that does this. Is this possible? Could I use jQuery to do this? Other thoughts?
I think all you could do is load two thumbnails into a container at once, with the black and white laying over top of the colour. Then, you could use jquery to fade the opacity of the to thumbnail to 0.0. Here is a working example (it just uses a click to change it once, but I'll leave the mouseover / mouseout to you - you may want to speed up the animation):
some html:
<div class="container">
<img src="blackandwhite.jpg" class="bw" />
<img src="colour.jpg" class="colour" />
</div>
some css:
.container { position: relative; }
.container img { position: absolute; }
.bw { z-index: 101; }
.colour { z-index: 100; }
some jquery:
$(function() {
$(".bw").click(function() {
$(this).animate({ opacity: 0.0 }, 800);
});
});
The best way to do this would be to actually have two versions of the image. One that's grayscale and one that's color. To keep it strictly within javascript and html, I don't believe there's any other way than with the two image method. Flash, Silverlight, and maybe even HTML 5, can do it easily.
Do you really want to fade, or just to swap?
Typically the swap is done via CSS
<a class="btn"></a>
and the CSS
a.btn {
background: url(../images/button-image.png) no-repeat 0 0;
width: 110px;
height: 16px;
margin: 10px 0 0;
}
a.btn:hover {
background-position: 0 -16px;
}
In this case there's a little performance improvement going on where button-image contains both images vertically stacked, and the css is sliding the background image around, but it's the same idea. It's a performance enhancement because the browser only needs to download 1 image, not 2.