#MonthOfCode - Day 25: cursor

My entry for the 25th day of the month of code. The theme for today is: cursor.

You can’t use an animated gif as a custom CSS cursor and you can’t use CSS animations either. So, let’s create a canvas cursor! Move your mouse over the red <div> to see it.

Code after the break.

cursor.cssview raw
1
2
3
4
5
6
7
#moc-25 {
margin: 20px 0;
width: 100%;
height: 200px;
outline: 1px solid red;
cursor: none;
}

cursor.jsview raw
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
document.addEventListener('DOMContentLoaded', function() {

var requestAnimFrame = (function(){
return window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
function (callback) {
window.setTimeout(callback, 1000/60);
};
})();

$('#moc-25').on('mouseenter', function () {
$canvas.show();
startAnimation();
}).on('mouseleave', function () {
$canvas.hide();
stopAnimation();
}).on('mousemove', function (ev) {
move(ev.pageX, ev.pageY);
});

var $canvas = $('<canvas>');
$canvas.css({
'position': 'absolute',
'z-index': 100,
'pointer-events': 'none'
});
$canvas.attr({
width: 32,
height: 32
});
var ctx = $canvas[0].getContext('2d');

$canvas.appendTo(document.body);

function rand(min, max) {
if (max == null) {
max = min;
min = 0;
}
return min + Math.floor(Math.random() * (max - min));
}

function move(x, y) {
$canvas.css({
top: y,
left: x
});
}

var i = 0;
function draw() {
ctx.clearRect(0, 0, 32, 32);

ctx.lineWidth = 1.5;
// change color every 20 frames
if (++i === 20) {
i = 0;
ctx.fillStyle = 'rgb(' + [rand(255), rand(255), rand(255)].join(',') + ')';
ctx.strokeStyle = 'rgb(' + [rand(255), rand(255), rand(255)].join(',') + ')';
}
ctx.beginPath();
ctx.moveTo(2, 2);
ctx.lineTo(2, 18);
ctx.lineTo(6.5, 13);
ctx.lineTo(13.3, 13.3);
ctx.closePath();

ctx.fill();
ctx.stroke();
}

var run = false;
function stopAnimation() {
run = false;
}
function startAnimation() {
run = true;
loop();
}
function loop() {
draw();
if (run) {
requestAnimFrame(loop);
}

}
});