Lajittelualgoritmi:

var canvas = document.getElementsByClassName("canvas")[0];
var ctx = canvas.getContext("2d");

function set_canvas() {
	canvas.width = canvas.getBoundingClientRect().width;
	canvas.height = canvas.getBoundingClientRect().height;
}
window.addEventListener("resize", set_canvas, false);
set_canvas();



function get_rand_number(min, max) {
	return Math.round(Math.random() * (max - min) + min);
}



var audio_ctx = null;
var counter = 0;
var blue_list = [];
var cursor_position = 0;
var play_index = true;

var test_run = true;
var hits = 0;
var all_done = false;



function play_sound(audio_array) {
    var buf = new Float32Array(audio_array.length);
    for (var i = 0; i < audio_array.length; i++) buf[i] = audio_array[i];

    var buffer = audio_ctx.createBuffer(1, buf.length, audio_ctx.sampleRate);
    buffer.copyToChannel(buf, 0);

    var source = audio_ctx.createBufferSource();
    source.buffer = buffer;
    source.connect(audio_ctx.destination);
    source.start(0);
}



window.AudioContext = window.AudioContext || window.webkitAudioContext;
audio_ctx = new AudioContext();
start_button_clicked = true;

var list_length = 20;
for (var i = 0; i < list_length; i++) {
	var sinewave = [];
	var target_volume = 0.02;
	var volume = 0;
	var seconds = 1.0/30;
	var tone = 120+(50*i);
	
	for (var u = 0; u < audio_ctx.sampleRate * seconds; u++) {
		var sample_freq = audio_ctx.sampleRate / tone;
		
		// Poistaa siniaallon napsahdukset. fade-in alkuun ja fade-out loppuun.
		if (u >= (audio_ctx.sampleRate * seconds)-list_length) {
			volume -= target_volume/list_length;
		} else if (u <= list_length) {
			volume += target_volume/list_length;
		}
		sinewave[u] = Math.sin(u/(sample_freq/(Math.PI*2))) * volume;
	}
	
	blue_list.push({index:i,audio:sinewave});
}

for (var i = 0; i < blue_list.length; i++) {
	do {
		var rand_number = get_rand_number(0, blue_list.length-1);
	} while (rand_number == i);
	
	var t = blue_list[i];
	var y = blue_list[rand_number];
	
	blue_list[i] = y;
	blue_list[rand_number] = t;
}



function funny123() {
	if (cursor_position+1 == blue_list.length) {
    	return;
    }

	var this1 = blue_list[cursor_position];
	var next1 = blue_list[cursor_position+1];

	if (this1.index > next1.index) {
		if (test_run) {
			cursor_position++;
			hits++;
			return;
		}
	
		blue_list[cursor_position] = next1;
		blue_list[cursor_position+1] = this1;
		cursor_position--;
		if (cursor_position < 0) {
			cursor_position = 0;
		}
		return;
	}

	cursor_position++;
}



setInterval(function () {
    ctx.beginPath();
    ctx.fillStyle = "#000";
    ctx.fillRect(0, 0, canvas.width, canvas.height);
    ctx.closePath();
    
    // Piirretään sininen lista.
    for (var i = 0; i < blue_list.length; i++) {
        ctx.beginPath();
    	ctx.fillStyle = "blue";
    	ctx.fillRect(
			Math.floor((canvas.width/list_length)*i),
			Math.floor(canvas.height-((canvas.height/list_length)*blue_list[i].index)),
			Math.floor((canvas.width/list_length)-2),
			Math.floor((canvas.height/list_length)*blue_list[i].index)
		);
    	ctx.closePath();
    }
    
    // Piirretään kursori kohta.
    ctx.beginPath();
    ctx.fillStyle = (test_run)?"rgba(255,0,0,.5)":"rgba(255,255,255,.5)";
    ctx.fillRect(
		Math.floor((canvas.width/list_length)*cursor_position),
		0,
		Math.floor(canvas.width/list_length),
		canvas.height
	);
    ctx.closePath();
    if (play_index) {
    	play_sound(blue_list[cursor_position].audio);
        play_index = false;
    }

	// Tehdään juttuja.
	if (cursor_position != blue_list.length-1) {
    	if (counter >= 0) {
        	funny123();
            counter = 0;
            play_index = true;
    	}
        counter++;
    } else {
    	if (test_run) {
        	if (hits > 0) {
        		test_run = false;
            	cursor_position = 0;
        	} else {
            	test_run = false;
                all_done = true;
            }
        } else if (!all_done) {
        	test_run = true;
            hits = 0;
            cursor_position = 0;
        }
    }
}, 1000 / 30);
00004643