Starbeamrainbowlabs

Stardust
Blog


Archive

Mailing List Articles Atom Feed Comments Atom Feed Twitter

Tag Cloud

3d account algorithms announcement archives arduino artificial intelligence assembly async audio bash batch blog bookmarklet booting c sharp c++ challenge chrome os code codepen coding conundrums coding conundrums evolved command line compiling css dailyprogrammer debugging demystification distributed computing downtime embedded systems encryption es6 features event experiment external first impressions future game github github gist graphics hardware hardware meetup holiday html html5 html5 canvas interfaces internet io.js jabber javascript js bin labs learning library linux low level lua maintenance network networking node.js operating systems performance photos php pixelbot portable privacy programming problems project projects prolog protocol pseudo 3d python reddit reference release releases resource review rust secrets security series list server servers software sorting source code control statistics svg technical terminal textures three thing game three.js tool tutorial twitter ubuntu university update updates upgrade version control visual web website windows windows 10 xmpp

Terminal Reference Sheet

While browsing my stackedit markdown documents, I found a reference sheet for the linux terminal. While originally posted on novitiate, I thought that it might be of use to someone on this website too. The reference sheet was originally designed for the raspberry pi, but it works for other bash like shells too :)

You can find it below.

Basic Linux Terminal Reference Sheet

Command Function
ls List the contents of the current directory
cd orange Change the current directory to the sub-folder orange
cd .. Change the current directory to the parent folder
cd ~ Change the current directory to your home folder
rm banana.txt Delete the file banana.txt
rmdir pineapple Delete the directory pineapple, but only if it is empty
rm -rf mango Delete the directory mango, even if it has files and folders inside it
mkdir cheese Create a new folder called cheese
mv kiwi.py cake.py Rename kiwi.py to cake.py
cp bread.7z cherry.7z Copy bread.7z to cherry.7z
mv cabbage oranges/tangerines Move the folder cabbage to the folder tangerines inside the folder oranges
sudo command Execute command as the root (administrator) user
sudo apt-get update Update the package list
sudo apt-get upgrade Update the currently installed packages
sudo apt-get install foo Install the package foo
rpi-update Update the Raspberry Pi's firmware1
raspi-config Start the Raspberry Pi configuration utility
nano apple.txt Edit the file apple.txt in the nano command line text editor
exit Exit the terminal
sudo shutdown -h now Shutdown
sudo reboot Restart
top View a list of processes using your CPU most intensively
CTRL + C Keyboard shortcut to exit most programs
CTRL + Z Keyboard shortcut to suspend the currently active process and return focus to the terminal
fg Resume the currently suspended process
jobs Display a list of jobs attached to the current terminal
bg 2 Put the job with the id 2 into the background2
disown 2 Disown the job with the id 2 so that it will not be terminated when the terminal is terminated2
help | less Pipe the output of the command help into the command less, which lets you scroll through large amounts of output with the arrow keys (press q to quit).
cat cakes.log View the contents of cakes.log. Tip: add | lessto pipe it into less so that you can browse the file with the arrow keys.
man less Display the manual page about the command less
help less Display some basic help about the command less
ssh pi@192.168.0.3 Connect to the device at the IP 192.168.0.3 with the username pi and start a remote terminal session

Links to other useful lists

If you have any other commands or links to useful lists / references, please leave a comment below.

Have you found a cool bash reference? Post a comment below and I will consider adding it to the list.


  1. This needs installing first. See this page: https://github.com/Hexxeh/rpi-update 

  2. Note that to specify job #1, you type the command on it's own without the job id.  

Behind the Parallax Stars

Unfortunately I have been busy, so I have been unable to write this post up until now. Anyway, welcome to the second technical post on this blog. This time, we will be looking behind the Parallax Stars.

The FPS and rendering time graphs are drawn by a slightly modified version of stats.js, by mrdoob. It's original github repository can be found here, and the slightly modified version can be found here. The modifications I made allow both the FPS graph and the rendering time graphs to be displayed at once.

The interesting code that makes the stars work is found in stars.js. The function is a constructor that returns an containing everything needed to make the stars appear and animate.

this.build = function() {
    this.data = [];

    for (var i = 0; i < this.number; i++)
    {
        this.data[i] = new star();
    }

    if(this.depthsort == true)
    {
        this.data.sort(depthsort);
    }
};
function star()
{
    this.z = Math.random()*(0.7) + 0.3;

    this.x  = rand(canvas.width);
    this.y  = rand(canvas.height);
    this.radius = Math.floor(this.z * 7);

    var r, g;
    r = rand(200, 255);
    g = rand(200, g - 20);

    this.colour = "rgb(" + r + ", " + g + ", " + 0 + ");"

    this.speed = this.z * 3;
}

The build() function contains some setup code that populates an array with stars, which are constructed by a different function, star(). Each star is assigned an x, y, and z co-ordinate. The x and y co-ordinates determine it's position on the screen. and the z co-ordinate determines it's size and speed. The stars are also given a colour too. The function rand() is a small utility function I sometimes use for generating random numbers:

// EXAMPLES:
// rand(256) returns a whole number between or equal to 0 and 255
// rand(100,201) returns a whole number between or equal to 100 and 200
// rand() returns a decimal between or equal to 0 and less than 1
function rand()
{
    // takes 0-2 arguments (numbers)
    var args = arguments, num;
    if (args[0] && !args[1]) { 
        num = Math.floor(Math.random()*(args[0]));
    } else if (args[0] && args[1]) {
        num = Math.floor(Math.random()*(args[1]-args[0])) + args[0];
    } else {
        num = Math.random();
    }
    return num;
}

The array that hold all the stars is also depth sorted before we start and on each frame to keep the stars in order since stars are leaving the screen and new one coming onto the screen on every frame. The standard array .sort() function is used, along with a custom sort function:

function depthsort(a,b) {
    if(a.z < b.z)
        return -1;
    if(a.z > b.z)
        return 1;
    else
        return 0;
}

The updates that happen every frame are split into two different functions. step() deals with incrementing co-ordinates and keeping the depth sorting up to date, and render() takes the current state and renders it on the canvas.

this.step = function() {
    for (var i = 0; i < this.data.length - 1; i ++)
    {
        this.data[i].x += this.data[i].speed;

        if(this.data[i].x > canvas.width + this.data[i].radius + 1)
        {
            this.data[i].x = new star();
            this.data[i].x = -this.data[i].radius - 1;

            if(this.depthsort == true)
            {
                this.data.sort(depthsort);
            }
        }
    }
}

The this.data array holds all of the stars. For each star, it's x value is incremented by it's speed. If this moves the star off the screen, we replace it with a new star that starts off at the left hand side. The stars are then depth sorted again to keep all the further away stars behind the stars that are (supposed to be) closer to the front.

this.render = function() {
    context.clearRect(0, 0, canvas.width, canvas.height);

    for (var i = 0; i < this.data.length - 1; i ++)
    {
        context.globalAlpha = 1;
        context.globalCompositeOperation = "destination-out";

        context.beginPath();
        context.arc(this.data[i].x, this.data[i].y, this.data[i].radius, 0, Math.PI*2, true);
        context.closePath();
        context.fill();

        context.globalAlpha = this.data[i].z;
        context.globalCompositeOperation = "source-over";

        context.fillStyle = this.data[i].colour;

        context.beginPath();
        context.arc(this.data[i].x, this.data[i].y, this.data[i].radius, 0, Math.PI*2, true);
        context.closePath();
        context.fill();
    }
}

To start off the rendering, the canvas is cleared. After that, For each star, a hole in the canvas is cleared with the destination-out drawing mode. The reason for this is that the z co-ordinate is also used as an alpha value for each star to make it dimmer the further away it is. This gives a slightly more realistic 3d appearance. After clearing a hole, the drawing mode is rest to the default (source-over), and the alpha and fill colours are set up according to the star's current z co-ordinates and colour respectively. Then the star is drawn. Since when this script was written we did not have a canvas drawing function to draw an ellpise, the context.arc(this.data[i].x, this.data[i].y, this.data[i].radius, 0, Math.PI*2, true); code is used to draw circles via context.beginPath() and context.fill().

Finally, One nice neat update() function is provided that calls render() and step() in sequence:

this.update = function() {
    this.render();
    this.step();
}

That concludes this technical post! If you have any questions, please post them below and I will try my best to answer them.

Website Updates

Yesterday I tweaked and updated the website. Here are the thing that I changed:

  • Finished adding the jigsaw puzzle pieces to the homepage
  • Added navigation aid to the top left of website on widescreens
  • Added footer to blog index page
  • Moved prism to the new /libraries/ folder
  • Added a smooth scrolling script to the navlist in the top left
  • Updated the todo list
  • Removed spam from blog
  • Added extra antispam measure: Not allowing email field to be filled in since it is not currently used yet anyway
  • Changed the highlighted selection colour to rgba(54, 0, 255, 0.21)

If you discover any issues while using the website, please leave a comment below. Antispam measures for this blog in particular seem to cause issues - in which case you can send bug reports to bugs at starbeamrainbowlabs dot com.

More changes will be coming in the near future, such as an Atom feed for comments and an email notification system for replies to your comments.

Update: The Atom feed for comments has been created! You can find it over at feed.comments.php.

An Animated GIF Renderer

The online tool I am releasing today is another one of the projects I did a while ago (December 2013 in this case). The difference here is that someone asked me to build it for them. The tool allows you to stich a number of still images into an animated gif.

Having an online version of the tool on a server that I own seems like a good idea (so I can keep it up to date) - so I am releasing it on this site for you to use.

It uses a javascript library called gif.js to render the still images as an animated gif. Please bear in mind that all the rendering is done on your computer! Nothing is uploaded to the server at all. If you refresh the page, everything will be reset.

A description of the options and known issues can be found below. If you just want to skip all that and play around with it for yourself, please follow this link:

Animated GIF Renderer

Options

A description of all the options available can be found below:

Option Description
Repeats The number of repeats. -1 = no repeat, 0 = repeat forever.
Default Delay The default delay each still image should be given when first dragged into the tool. Remember to set this before you drag all your images in to save time!
Frames per second An alternative method of setting the default delay. Simply enter the number of frame you want to show per second.
Workers* The number of threads to use to render the animated gif. For optimum performace enter the number of cpu cores you have. This will speed up the rendering process for large gifs.
Quality* The quality of the resultant gif. In the code this is referred to as the pixel sample interval. I don't really understand this setting myself - if you do, please leave a comment below and I will update both this post and the tool itself.

A '*' indicates an advanced setting.

Known issues

  • The 'x' button to remove an image is buggy. - Fixed! A new image removal system has been implemented to fix this bug.
  • The size of the rendered gif i snot updated when images are removed - Fixed! The maximum image dimensions are now recalculated when an image is removed.
  • Found another bug? Report it below.

Parallax Stars

Since I forgot to post last wednesday, I will post twice this week :)

A while ago I played around with creating a parallax effect with stars on an HTML5 Canvas. After tiding up the original code I wrote a little bit, I have decided to release it in this website. It will not, however do well as a screensaver due to the high CPU / GPU usage it induces because of the inefficiencies in the code.

It can be found here: parallax scrolling stars

I will (hopefully) write a technical post in the near future that will explain how it works, including an explanation behind the high CPU / GPU usage.

A Simpler Way to Generate XML in PHP

In an effort to make XML generation simpler in PHP, I have written another PHP class, called simpexmlwriter.

Much like atom.gen.php, everything you need is all packaged up into one file - simply download and require simplexmlwriter.php and you are ready to start. Links can be found near the bottom of this post.

The same system is in place for contributions and feature requests: post a comment below to either request a feature or link to a modified version of the code and I will consider either merging your changes or adding the feature that you request.

It also has a 'reference' - just like atom.gen.php. A link can be found near the bottom of this post.

If you are still reading this and you are not interested in code, there will be a few things that you may be interesting in appearing on this website soon.

simplexmlwriter.php

simplexmlwriter.php reference

Generating Atom Feeds

This week I am releasing atom.gen.php, the PHP script that powers this blog's Atom feed (which you can find here!).

This PHP class has been designed to be simple and easy to use (apart from the addentry() function which needs tidying up :D), and quick to get started with. I have also created a basic example showing you how to use it and a 'reference' that covers all of the functions and properties that are available for use. Links to both the script and the 'reference' can be found at the bottom of this post.

Although I have tested it, it is entirely possible that you will come across a bug. If you do, please post about in the comments below.

You may also find that atom.gen.php does not do everything that you want it to. In this case, you have two options: either post a comment down below and I will consider adding the feature you request, or adding the feature yourself. If you add the feature or fix a bug yourself, please post a comment down below along with a link to the modified code and I will merge your changes and give you full credit for all the work you have done.

atom.gen.php

atom.gen.php reference

Saving and Restoring <inputs />

I have made a pair of Javascript bookmarklets that allow you to save and load the contents of input boxes and textareas on any webpage.

To use them, simply drag the 2 links below to your bookmarks (bar), and click "Save Inputs" when you wish to save the contents of all the inputs, and click "Restore Inputs" and paste in the code you received from the "Save Inputs" bookmarklet to restore the contents of the input boxes on any given page.

Save Inputs

Restore Inputs

Source Code

The (pretty printed and decoded) source code for the two bookmarklets can be found below:

Save Inputs

(function () {
	var inputs = document.querySelectorAll("input, textarea"),
	savedata = [];
	
	for (var i = 0; i < inputs.length; i++)
	{
		savedata.push(inputs[i].value);
	}
	console.log(savedata);
	prompt("< input /  > and < textarea > savedata :", JSON.stringify(savedata));
})();

Restore Inputs

(function () {
	var savedata = JSON.parse(prompt("Savedata: ", "")),
	inputs = document.querySelectorAll("input, textarea");
	for (var i = 0; i < savedata.length; i++)
	{
		inputs[i].value = savedata[i];
	}
})();

Known Limitations

  • The savedata code that the "Save Inputs" bookmarlet produces is not copied to the clipboard
  • Strange things happen if you try to restore the contents of a set of input boxes from a savedata code from another page
  • The script breaks if the input boxes on a page get changed

If you have a better version of these bookmarklets, please leave a comment below.

Found a spelling mistake? Got suggestion? Leave a comment below. Suggestions for improvement are always appreciated.

An (Almost) Pure CSS Spotlight

I made a spotlight demonstration using (almost) pure CSS!

A little bit of javascript is used to make the spotlight follow the mouse. You can also click through the layer in from of everything that makes the spotlight work because of the pointer-events: none; CSS styling rule.

It can be found below.

The (editable!) source code can be found here. A full screen version of the demo above can be found here.

Lightsout and Syntax Highlighting

Hello!

I am releasing a javascript bookmarklet that allows you to select an element of any web page and put the rest of the page behind a screen.

To use it, simply drag the link below to your bookmarks bar and then click the bookmark when you want to use it. After it loads, you can then select the element of the page you want to focus, indicated by the blue border. You can also press 'A' to attempt to autoselect a flash object, while avoiding ads.

Lightsout

If you can't get the bookmarklet to load by dragging the link above to your bookmarks, copy and paste the following code into a new bookmark:

javascript: (function () { var lightsoutloading = document.createElement('div');lightsoutloading.id='SBRLlightsoutloadingmessagecontainer'; lightsoutloading.innerHTML = '<div id=\'SBRLlightsoutloadingmessage\' style=\'width:300px;height:auto;position:fixed;top:0;left:0;background:rgba(200, 200, 200, 0.8);border-radius:5px;z-index:2147483647;transition:all 0.5s;margin:10px;padding:10px;border:none;opacity:1.0;text-transform:none;min-height:0;min-width:0;font-faamily:sans-serif;bottom:auto;right:auto;font-size:12px;text-indent:0;line-height:normal;color: black;text-decoration:none;clip:auto;font-style:normal;font-variant:normal;font-weight:normal;max-height:none;max-width:none;direction:ltr;word-spacing:normal;visibility:visible;text-shadow:none;\'>Loading lightsout...</div>'; document.body.appendChild(lightsoutloading); var jsCode = document.createElement('script');jsCode.setAttribute('src', 'https://starbeamrainbowlabs.com/bookmarklets/lightsout/lightsout.js');document.body.appendChild(jsCode);}()););

Since this is a javascript bookmarklet, there are probably websites that this doesn't work with. If you stumble across one of these websites, leave a comment below and I will look into it.

I am also trialing a new syntax highlighter along with this post! It is possible that the site may not work as expected during this trial period.

Edit: Testing complete! This blog now has code syntax highlighting enabled thanks to PrismJS.

Art by Mythdael