Snowflake effect for your Nextcloud (2022, NC24/NC25)

Hey there!

Christmas is not far away and winter already started. Here in Germany we already got some snow and more is probably comming soon.

You want to let your Nextcloud instance snowing? Maybe because you love snow or just can’t get snow in real? No problem, follow this steps here!

I’ve found a very simple and lightwell script, prepaired it to get it working within Nextcloud, added a bit more configuration possibility, and here we go.

Installation

  1. Goto into your Nextcloud to the App Store and install “JSLoader”.
    It’s probably outdated for your instance, so you need to force install it, as it’s not officially compatible and updated for NC22+.
    Is it safe? Well, probably. For me it works on NC24 and NC25 in productive use. I also read some other people that it’s working for them too.
  2. Goto Administrative Settings within your Nextcloud and navigate to “JSLoader”.
  3. Place here the following code and press “Save”. All done!
    Maybe you want to adjust a few configuration values for your personal wish.
/*!
// Snow.js - v0.0.4
// Version <=0.0.3 by kurisubrooks.com
// Version 0.0.4 by pilzinsel64.de
*/

// Amount of Snowflakes
// Recommended: 35
var snowMax = 35;

// Snowflake Colours
var snowColor = ["#DDD", "#EEE"];

// Snow Entity
var snowEntity = "&#x2022;";

// Falling Velocity
// Recommended: 0.75
var snowSpeed = 0.75;

// Minimum Flake Size
// Recommended: 8
var snowMinSize = 5;

// Maximum Flake Size
// Recommended: 24
var snowMaxSize = 20;

// Refresh Rate (in milliseconds)
// Recommended: 50
var snowRefresh = 15;

// Additional Styles
var snowStyles = "cursor: default; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; -o-user-select: none; user-select: none;";

/*
// Experimental Configuration
// ----------------------------------------
// Do only modify this, if you know what you do. Otherwise keep in mind, that it can break the functionallity.
*/

// The Z-Index where the snowflakes are leveled. Higher values is more in the front.
// Increase this value if your snowflakes are not (or only partly) visible.
// Recommended: 1000
var snowZIndex = 100100;

// How much the snowflakes should move to left and back to right.
// Higher Value = More
// Recommended: 15
var snowLeftRightMultiplicator = 10;

// How fast the snowflakes should move to left and back to right.
// Higher Value = Slower
// Recommended: 10
var snowLeftRightSpeedDivider = 20;

// The tolerance where the showflakes get despawned.
// Recommended: 2
var marginBottmTolerance = 5;

/*
// End of Configuration
// ----------------------------------------
// Do not modify the code below this line
*/

var snow = [],
	pos = [],
	coords = [],
	lefr = [],
	marginBottom,
	marginRight;

function randomise(range) {
	rand = Math.floor(range * Math.random());
	return rand;
}

function initSnow() {
	var snowSize = snowMaxSize - snowMinSize;
	resize();

	for (i = 0; i <= snowMax; i++) {
		coords[i] = 0;
		lefr[i] = Math.random() * snowLeftRightMultiplicator;
		pos[i] = 0.03 + Math.random() / snowLeftRightSpeedDivider;
		snow[i] = document.getElementById("flake" + i);
		snow[i].style.fontFamily = "inherit";
		snow[i].size = randomise(snowSize) + snowMinSize;
		snow[i].style.fontSize = snow[i].size + "px";
		snow[i].style.color = snowColor[randomise(snowColor.length)];
		snow[i].style.zIndex = snowZIndex;
		snow[i].sink = snowSpeed * snow[i].size / 5;
		snow[i].posX = randomise(marginRight - snow[i].size);
		snow[i].posY = randomise(2 * marginBottom - marginBottom - 2 * snow[i].size);
		snow[i].style.left = snow[i].posX + "px";
		snow[i].style.top = snow[i].posY + "px";
	}

	moveSnow();
}

function resize() {
	marginBottom = document.body.scrollHeight - 5;
	marginRight = document.body.clientWidth - 15;
}

function moveSnow() {
	for (i = 0; i <= snowMax; i++) {
		coords[i] += pos[i];
		snow[i].posY += snow[i].sink;
		snow[i].style.left = snow[i].posX + lefr[i] * Math.sin(coords[i]) + "px";
		snow[i].style.top = snow[i].posY + "px";

		if (snow[i].posY >= marginBottom - marginBottmTolerance * snow[i].size || parseInt(snow[i].style.left) > (marginRight - 3 * lefr[i])) {
			snow[i].posX = randomise(marginRight - snow[i].size);
			snow[i].posY = 0;
		}
	}

	window.setTimeout(moveSnow, snowRefresh);
}

for (i = 0; i <= snowMax; i++) {
	var element = document.createElement("span");
	element.id = "flake" + i;
	element.style = snowStyles + "position:absolute;top:-" + snowMaxSize;
	element.innerHTML = snowEntity;
	document.body.insertBefore(element, document.body.firstChild);
}

initSnow();
// window.addEventListener('load', initSnow);
window.addEventListener('resize', resize);

Wish you all a good christmas time and a good start to the new year! :tada: And thank you all devs and maintainers for all your hard work! :heart:

4 Likes

Not sure if this is the right channel to use btw. It’s more a How To but not sure if I should post anything in the How To category and as it is more “hacking” I posted in Development.
Feel free to correct me or change it, if you want to.

1 Like

As always, be careful when copy pasting a blob of code from the internet and putting it into production if you don’t understand it.

1 Like

maybe you could even make this into an app? :wink:

1 Like

@marcelklehr

and maybe that’s a bit OT - following @Daphne 's idea to make that skript an app is someone/something keeping track upon apps not supplying evil code, in general?

(I am not saying that the listed script from above is evil or not - I simply haven’t looked through it)

@Pilzinsel64 would you be okay of this script was published in an app as @Daphne suggested? There is no license information attached… :wink:.

1 Like

Sure, packing this into an app and maybe add more configuration options via an admin GUI later would be a nice idea. But not sure if I have the time for this and the whole maintenance and possible optimization. So yes, if anyone want to take the script and write an app, sure feel free!

3 Likes

Ok, i just created an app stub for that effect. See GitHub - christianlupus-nextcloud/snowflakestheme: A minimalistic snowing effect for the web frontend. I still have to fix some issues like wrong URLs etc and register a new app on the store. I will try to push that out ASAP.

One thing i am a bit concerned is the license of the provided js file of @Pilzinsel64. Is AGPL a valid license for your work (and the original author)? Who should I put as the original author in the repo? This should be cleared before the first release.

5 Likes

Uh, looks great!

The license is MIT, you can find the original script published here: Minimalist Falling Snow Effect with Pure JavaScript - Snow.js | CSS Script

2 Likes

Cyrrently, the app does show the “snow” but no configuration or such nice things are present. I just pushed out a request for an app certificate for publishing on the store. I will postpone documentation and automation until everything runs smoothly. As winter/Christmas is on the doorstep, I consider this optional, at the moment. I just wanted to keep you posted.

4 Likes

thanks a lot for the continued efforts :smiley: I can’t wait to put snow theme on my Nextcloud ❅

3 Likes

I agree with this. Some features are more important than others.

I just pushed out a hasty version to have it running at least before Christmas. It is marked to be compatible with NC25. I have not checked earlier versions of NC. Most probably they will work but as I have not tested them, I did not mark them as compatible. Feel free to ask comments here or open issues there.

4 Likes

I can verify that the app works in NC24 too :smiley: Nice job @christianlupus! Maybe you can push a new version which has 24 as the minimum NC version requirement?

Meanwhile, to install it simply download the latest snowflakestheme-appstore.tar.gz from Releases · christianlupus-nextcloud/snowflakestheme · GitHub , unpack it such that you have a directory named snowflakestheme in your custom_apps directory in your Nextcloud installation (or the equivalent directory if you have changed the name of it), then edit the appinfo/info.xml file such that <nextcloud min-version="25" max-version="25"/> instead reads <nextcloud min-version="24" max-version="25"/>. After this, you can simply go to the Apps view in your NC and click Enable for the app, and it should work!

PS: If doing the manual install described above, make sure that the directory and files are owned by the correct user (the same as the other apps).

2 Likes

I just learnt that this app is deprecated :frowning: Spoke with someone else and they told me this:

We had an internal project for a domain management app, our customer (aka boss/owner of company) mentioned Unicorns, so we built in a Unicorn Mode, transforming the cursor into a unicorn and making sparkles everywhere while moving.

This is clearly superior to snowflakes :confused:

:joy: this made me laugh. That should be an app too :unicorn:

2 Likes

You mean the js loader app? Because i am not aware that i deprecated the snowflake theme app :wink:.

If you want to have unicorns, we have to check if there is a unicorn in a gibt available. :wink:

Thanks for testing. I tested on a old 23 installation of mine as well. So, v0.0.2 is compatible with NC 23 to 25. Just pushed out.

2 Likes

Very nice! Although you didn’t up the version in the app, but it doesn’t matter in practice for those that couldn’t install it earlier as it is now available to them the first time :slight_smile: Thanks!

EDIT: Hm, looking in the app store it is indeed 0.0.2 instead of as previous 0.0.1, but in my NC it still turns turned up as 0.0.1 in the apps list. Quite odd, because when I look in the info.xml file it does say 0.0.2. Works now though. Whatever :smiley:

1 Like

I thought this was one of the dumbest apps on Nextcloud, but it’s actually great. With all the browser tabs I have, I know when I see snow I am inside MY cloud. It’s the same reason I have different backgrounds for each virtual machine I run. Easy to identify what machine I am using.

That said, would be amazing to have different objects. Like sparkling stars, smoke, lightning. Man, thinking about it, it would be GREAT because I run multiple clouds :stuck_out_tongue: