8

I've really enjoyed the April Fool's theme this year, most of all the cursor decoration. Could someone create a user script for me that activates the decoration everywhere on the network (chat can be excluded) rather than only on question pages?

1 Answer 1

8

Yep!

// ==UserScript==
// @name         Decorated Cursor
// @version      2
// @description  Get the fancy mouse found in the 2019 April Fools theme network-wide!
// @author       a stone arachnid
// @include      https://*stackoverflow.com/*
// @include      https://*superuser.com/*
// @include      https://*serverfault.com/*
// @include      https://*stackapps.com/*
// @include      https://*askubuntu.com/*
// @include      https://*mathoverflow.net/*
// @include      https://*stackexchange.com/*
// @exclude      http*://chat.*/
// @grant        none
// ==/UserScript==
(function($,se){
    "use strict";
    const style = `
.js-cursor-container{
    font: 25px "Times New Roman", Times, serif;
}
`;
    $("<style>").text(style).appendTo("head");
se.ready(()=>{
    if(document.querySelector(".js-cursor-container") == null)
    {
        $("<span>").addClass("js-cursor-container").prependTo("#content > div:first-of-type");
    }
/*!
 * Fairy Dust Cursor.js
 * - 90's cursors collection
 * -- https://github.com/tholman/90s-cursor-effects
 * -- https://codepen.io/tholman/full/jWmZxZ/
 */
    (function fairyDustCursor() {

        var possibleColors = ["#D61C59", "#E7D84B", "#1B8798"]
        var width = window.innerWidth;
        var height = window.innerHeight;
        var cursor = {x: width/2, y: width/2};
        var particles = [];

        function init() {
            bindEvents();
            loop();
        }

        // Bind events that are needed
        function bindEvents() {
            document.addEventListener('mousemove', onMouseMove);
            window.addEventListener('resize', onWindowResize);
        }

        function onWindowResize(e) {
            width = window.innerWidth;
            height = window.innerHeight;
        }

        function onMouseMove(e) {
            cursor.x = e.clientX;
            cursor.y = e.clientY;

            addParticle( cursor.x, cursor.y, possibleColors[Math.floor(Math.random()*possibleColors.length)]);
        }

        function addParticle(x, y, color) {
            var particle = new Particle();
            particle.init(x, y, color);
            particles.push(particle);
        }

        function updateParticles() {

            // Updated
            for( var i = 0; i < particles.length; i++ ) {
                particles[i].update();
            }

            // Remove dead particles
            for( var j = particles.length -1; j >= 0; j-- ) {
                if( particles[j].lifeSpan < 0 ) {
                    particles[j].die();
                    particles.splice(j, 1);
                }
            }

        }

        function loop(){
            setInterval(function(){
                updateParticles()
            }, 1000/60);
        }

        // Particles!

        function Particle() {
            this.character = "*";
            this.lifeSpan = 120; //ms
            this.initialStyles ={
                "position": "fixed",
                "display": "inline-block",
                "top": "0px",
                "left": "0px",
                "pointerEvents": "none",
                "touch-action": "none",
                "z-index": "10000000",
                "fontSize": "25px",
                "will-change": "transform"
            };

            // Init, and set properties
            this.init = function(x, y, color) {

                this.velocity = {
                    x:  (Math.random() < 0.5 ? -1 : 1) * (Math.random() / 2),
                    y: 1
                };

                this.position = {x: x + 10, y: y + 10};
                this.initialStyles.color = color;

                this.element = document.createElement('span');
                this.element.innerHTML = this.character;
                applyProperties(this.element, this.initialStyles);
                this.update();

                document.querySelector('.js-cursor-container').appendChild(this.element);
            };

            this.update = function() {
                this.position.x += this.velocity.x;
                this.position.y += this.velocity.y;
                this.lifeSpan--;

                this.element.style.transform = "translate3d(" + this.position.x + "px," + this.position.y + "px, 0) scale(" + (this.lifeSpan / 120) + ")";
            }

            this.die = function () {
                this.element.parentNode.removeChild(this.element);
            }

        }
        // Applies css `properties` to an element.
        function applyProperties( target, properties ) {
            for( var key in properties ) {
                target.style[ key ] = properties[ key ];
            }
        }

        if (!('ontouchstart' in window || navigator.msMaxTouchPoints)) init();
    })();
});
})(window.jQuery,window.StackExchange);

Direct install from GitHub

As @rob mentioned, Stack Exchange used the cursor sprinkle code that comes from here: https://github.com/tholman/cursor-effects

8
  • 2
    Oooh, does the possibleColors section mean that I can customize the colors myself if I want to by replacing/augmenting that list? Commented Apr 1, 2019 at 22:00
  • @Catija it should Commented Apr 1, 2019 at 22:03
  • 2
    Oh, wow, it totally does and it's magical. <3 Thanks! Commented Apr 1, 2019 at 22:06
  • How do you use this? Commented Apr 2, 2019 at 16:11
  • 1
    @DCOPTimDowd see here Commented Apr 2, 2019 at 16:41
  • I'm not sure what changed but this freezes in Chrome (OSX) after a few seconds... but I'm also not sure if anyone else is having the issue. Commented May 15, 2019 at 4:56
  • @Catija Does the updated part work? Commented Jun 6, 2019 at 16:09
  • Oooh! Seems to! Thanks so much! I'll let you know if it goes wonky again! It's working longer than the other one was. <3 Commented Jun 6, 2019 at 16:12

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.