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>
Related
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.
I have a div with scrollable content that at a certain scrollTop value goes back to top.
var container = document.getElementById('container');
function scroll_function() {
var new_position_top = container.scrollTop;
if (new_position_top > 600) {
container.scrollTop = 0;
}
}
container.addEventListener('scroll', scroll_function);
#container {
width: 300px;
height: 300px;
overflow: auto;
border: 1px solid black;
-webkit-overflow-scrolling: touch;
}
span {
width: 100%;
height: 1200px;
float: left;
background: red;
background: -webkit-linear-gradient(red, yellow);
background: -o-linear-gradient(red, yellow);
background: -moz-linear-gradient(red, yellow);
background: linear-gradient(red, yellow);
}
<div id="container">
<span></span>
</div>
JSFiddle.
Using a MacBook trackpad I am getting different behaviours:
Chrome and Safari work as I would expect, continuing the inertia after going back to the top.
Firefox, however, goes back to the top and stops the inertia.
Using iOS Safari a similar issue appears too, as the scrollTop position is not updated until the inertia finishes.
Is there a better way of approaching it or a way to fix desktop Firefox and iOS Safari behaviour?
Using a library to handle smooth scroll would help at some point.
However, the inertia that is induced by the trackpad cannot be stopped because it is not controlled by the browser.
Depending on the device type (mouse wheel, trackpad) or operating system (Windows, OSX) and browser type (Chrome, Safari, Firefox), the inertia of the scroll will be handled differently.
Unfortunately, you cannot truly control the inertia from the javascript sandbox. You may try to circumvent it or create an artificial one, but you cannot go against the user trackpad.
Well, it should be an issue with iOS. Please check these resources below for more information first.
javascript scroll event for iPhone/iPad?
http://developer.telerik.com/featured/scroll-event-change-ios-8-big-deal/
My experience in the past is to use a library named iScroll and then you can apply its function scrollTo
What I would suggest you is to use external JS library like iScroll to deal with scroll event on iOS
When clicking on the thumbnail on the image on this site: http://www.grouprecipes.com/138587/banana-oatmeal-chocolate-chip-cookies.html, it expands and loads the original (full-size) version of the image.
I think they are using prototype or something similar. I've been looking around on here and have only mainly found examples that just increase the size of the original image and don't actually load another version of the image (like the linked example does).
Anyone care to help me figure out what techniques I should use for this? Combination of CSS3 and some .animate()?
Here is a simple example using CSS3, a bit of JavaScript.
Explanation:
Initially both the thumbnail and the enlarged version of the picture are placed on the same space using absolute positioning.
The enlarged version is not loaded until the thumbnail is clicked because the enlarged img tag doesn't have any src to begin with. It is assigned dynamically through the JS.
The image move to a different position is achieved using the translateX and translateY options which moves the absolutely positioned enlarged version of the image by the mentioned no. of pixels in both X and Y axes.
JavaScript is used to add a show class to the enlarged picture which triggers the transition effect and also set the src of the img tag to the newer/bigger image.
The enlarged version would return back to its original position when clicked anywhere on the enlarged image.
The JS code is written using class name instead of id just in case you need multiple such thumbnails on the same page. If that is the case, you may want to remove the [0], put it inside a for loop and replace the [0] with the counter variable. Also the enlarged image's source for each such thumbnail image can be maintained through a key-value pair mapping.
The z-index: -1 on the image originally (prior to adding .show through JS) is to make sure that it stays in the background and doesn't hinder the click on the thumbnail.
Points to note:
transform, translateX and translateY are all CSS3 properties/functions and hence have no support in IE8 and less. For older versions of Chrome, Firefox, Opera and Safari, browser prefixes like -webkit-, -moz would be required.
The classList.add and classList.remove functions are HTML5 standard and are not supported in IE9 but they equivalent IE9 code to add or remove class (like className += ..) can be easily done.
var images = {'img1': 'http://placehold.it/400/400'};
document.getElementsByClassName('thumbnail')[0].onclick = function(){
document.getElementById('enlarged').src = images[this.id];
document.getElementById('zoomed').classList.add('show');
}
document.getElementById('enlarged').onclick = function(event){
if(event.target != document.getElementsByClassName('thumbnail')[0])
document.getElementById('zoomed').classList.remove('show');
}
.container{
position: relative;
}
.thumbnail{
height: 200px;
width: 200px;
}
#zoomed .enlarged{
opacity: 0;
z-index: -1;
min-height: 200px;
min-width: 200px;
height: 200px;
width: 200px;
position: absolute;
transition: all 1s;
left: 0px; top: 0px;
}
#zoomed.show .enlarged{
opacity: 1;
z-index: 2;
height: auto;
width: auto;
min-height: 400px;
min-width: 400px;
transform: translateX(200px) translateY(200px);
}
<div class="container">
<img src="http://placehold.it/200/200" alt="" class="thumbnail" id='img1'/>
<div id='zoomed'>
<img src="" alt="" class="enlarged" id='enlarged'/>
</div>
</div>
Additional Resource:
Here is a good article on how to pre-load images (the enlarged versions if needed) using CSS + JS, only JS and AJAX.
my code is like this :
script:
<script type="text/javascript">
$(document).ready(function () {
$("#Pencil_a").click(function () {
$("body").addClass("pencil_cursor");
});
});
</script>
style:
.Pencil
{
background-image: url("images/globaleImg.png");
background-position: -88px -415px;
display: block;
height: 15px;
position: relative;
width: 15px;
}
.pencil_cursor
{
cursor:url("images/globaleImg.png") -88px -415px;
display:block;
}
when I click on the link the cursor don't change it's default image what am I doing wrong?
Problem #1
The coordinates of the cursor's hotspot, which will be clamped to the
boundaries of the cursor image. If none are specified, the coordinates
of the hotspot are read from the file itself (for CUR and XBM files)
or are set to the top left corner of the image.
An example of the CSS3 syntax is:
.foo {
cursor: auto;
//no pixel value, or negative
cursor: url(cursor1.png) 4 12, auto;
}
Problem #2
From Mozilla MDN
In Gecko (Firefox) the limit of the cursor size is 128×128px. Larger
cursor images are ignored. However, you should limit yourself to the
size 32×32 for maximum compatibility with operating systems and
platforms.
(Due to a bug in Gecko 1.9.2-1.9.2.6, Firefox 3.6-3.6.6 on Windows
limits to 32x32px. This is fixed in later versions.)
Fiddle:
Check this fiddle and you will see that is working, you just need an smaller image:
http://jsfiddle.net/F4uU5/1/
you need to add cursor:url("images/globaleImg.png"),auto;
.pencil_cursor
{
cursor:url("images/globaleImg.png"),auto;
display:block;
}
see stackoverflow ques
JSFiddle
The issue is down to the px in the cursor CSS. The px isn't required, just the numbers.
Change;
cursor:url("images/globaleImg.png") -88px -415px;
To;
cursor:url("images/globaleImg.png") -88 -415;
FYI, the X Y co-ords are to change the hotspot of the cursor, not the actual position of the image.
You should also add a fallback cursor, in case the browser can't load the custom one from the URL;
cursor:url("images/globaleImg.png") -88 -415, auto;
Fixed: http://jsfiddle.net/e8qVS/8/
As a side note, currently it thinks the body of the page is only as high as the href tag. If you want to change the cursor for whole body of the page, you need to add the following to make sure the body is 100% of the height of the page;
html, body {
height: 100%;
}
http://jsfiddle.net/e8qVS/3/
I am getting a slight line or border around my background image. I am dynamically changing the height of the parent div via javascript so that the inner div (which has the background image set) will "stick" to the bottom of the window.
No line appears on the desktop browsers, but on the mobile browser after the script runs, there is usually a thin border around it:
The border is on the left and the way it should be is on the right. Any suggestions?
This is the script:
<script type="text/javascript">
function layoutHandler(){
if(window.innerHeight > 1061){
var newsize = 150 + (window.innerHeight - 1061);
document.getElementById("footerwrapper").style.height = newsize+'px';
}
else {
document.getElementById("footerwrapper").style.height = '150px';
}
}
window.onload = layoutHandler;
window.onresize = layoutHandler;
layoutHandler();
</script>
And then the inner div is setup like so:
#inner {
background-color: #FFF;
padding: 0px;
height: 150px;
bottom: 0px;
width: 100%;
position: absolute;
background-image: url(Images/grad.png);
background-repeat: repeat-x;
}
Edit:
Okay, after testing this a bit more I narrowed down when it happens. (This might get frustratingly specific) It happens most noticeably on the iPad in portrait mode. I turned off the "repeat-x" and it goes away completely. That led me to try a much wider background image which would not be repeating within the width of the iPad and it took away this issue. Any ideas why the heck this is happening?
I had the same problem and removing repeat-x solved it. I think it is bug of phone browsers.