59 lines
2.4 KiB
JavaScript
59 lines
2.4 KiB
JavaScript
/* custom pixel cursor — appears only once we know the real pointer position,
|
|
so it never flashes at a stale spot on page changes. native cursor is hidden
|
|
via CSS (*{cursor:none}). */
|
|
(function () {
|
|
if (!window.matchMedia("(pointer: fine)").matches) return;
|
|
|
|
var c = document.createElement("canvas");
|
|
c.style.cssText =
|
|
"position:fixed;left:0;top:0;pointer-events:none;z-index:9999;" +
|
|
"image-rendering:pixelated;will-change:transform;opacity:0;" +
|
|
"transform:translate3d(-200px,-200px,0);";
|
|
document.body.appendChild(c);
|
|
|
|
var ctx = c.getContext("2d");
|
|
var px = 2;
|
|
var art = [
|
|
"_BB_______", "BRRB______", "BRRRB_____", "BRRRRB____", "BRRRRRB___",
|
|
"BRRRRRRB__", "BRRRRRRB__", "BRRRRSB___", "BRRSRRB___", "_BBBRRB___", "____BBB___"
|
|
];
|
|
var rows = art.length;
|
|
var cols = Math.max.apply(null, art.map(function (r) { return r.length; }));
|
|
c.width = cols * px; c.height = rows * px;
|
|
c.style.width = cols * px + "px"; c.style.height = rows * px + "px";
|
|
art.forEach(function (line, y) {
|
|
for (var x = 0; x < line.length; x++) {
|
|
var ch = line[x];
|
|
if (ch === "B") ctx.fillStyle = "#1a1a1a";
|
|
else if (ch === "R") ctx.fillStyle = "#ffffff";
|
|
else if (ch === "S") ctx.fillStyle = "#b0b0b0";
|
|
else continue;
|
|
ctx.fillRect(x * px, y * px, px, px);
|
|
}
|
|
});
|
|
|
|
var mx = -200, my = -200, raf = 0, shown = false;
|
|
function place() {
|
|
raf = 0;
|
|
c.style.transform = "translate3d(" + mx + "px," + my + "px,0)";
|
|
if (!shown) { shown = true; c.style.opacity = "1"; }
|
|
}
|
|
function move(e) {
|
|
mx = e.clientX; my = e.clientY;
|
|
if (!raf) raf = requestAnimationFrame(place);
|
|
}
|
|
function hide() { shown = false; c.style.opacity = "0"; }
|
|
|
|
document.addEventListener("mousemove", move, { passive: true });
|
|
document.addEventListener("mouseenter", function (e) { mx = e.clientX; my = e.clientY; place(); }, { passive: true });
|
|
// hide when the pointer leaves the window or the page is navigating away
|
|
document.addEventListener("mouseleave", hide, { passive: true });
|
|
window.addEventListener("blur", hide);
|
|
window.addEventListener("pagehide", hide);
|
|
// over a cross-origin iframe (vimeo, doom) we get no mousemove, so hide ours
|
|
// instead of leaving it frozen at the edge; it returns on the next move out
|
|
document.addEventListener("mouseover", function (e) {
|
|
if (e.target && e.target.tagName === "IFRAME") hide();
|
|
}, true);
|
|
})();
|