commit
4670ff8e93
Binary file not shown.
@ -0,0 +1,95 @@
|
||||
/* FONT FACE */
|
||||
@font-face {
|
||||
font-family: "PatrickHand";
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
src: url(PatrickHand-Regular.ttf) format('truetype');
|
||||
}
|
||||
|
||||
/* HTML & BODY */
|
||||
html, body{
|
||||
width:100%;
|
||||
height:100%;
|
||||
}
|
||||
body{
|
||||
background: #eeeeee;
|
||||
margin:0;
|
||||
font-family: "PatrickHand", Helvetica, Arial;
|
||||
font-size: 25px;
|
||||
line-height: 1.2em;
|
||||
}
|
||||
/* fake bold */
|
||||
b, strong{
|
||||
font-weight: normal;
|
||||
text-shadow:1px 0 0 currentColor;
|
||||
letter-spacing: 1px;
|
||||
}
|
||||
|
||||
/*********/
|
||||
/* COMIC */
|
||||
/*********/
|
||||
|
||||
#comic{
|
||||
overflow:hidden;
|
||||
width:610px;
|
||||
margin: 50px auto;
|
||||
text-align: center;
|
||||
}
|
||||
#comic panel{
|
||||
display: inline-block;
|
||||
width: 250px;
|
||||
height: 250px;
|
||||
/*border: 2px solid #ccc;*/
|
||||
margin: 5px;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
transition: opacity 0.5s ease-in-out;
|
||||
}
|
||||
#comic panel[fadeInOn]{
|
||||
opacity: 0;
|
||||
}
|
||||
#comic panel pic{
|
||||
display: block;
|
||||
position: absolute;
|
||||
top:0;
|
||||
left:0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
/*background: #bada55;*/
|
||||
background: #ccc;
|
||||
}
|
||||
#comic panel words{
|
||||
display: block;
|
||||
position: absolute;
|
||||
top:0;
|
||||
left:0;
|
||||
background: #fff;
|
||||
/*text-align: left;*/
|
||||
padding: 15px;
|
||||
}
|
||||
#comic panel words[no-bg]{
|
||||
background: none;
|
||||
}
|
||||
#comic panel sim{
|
||||
display: block;
|
||||
position: absolute;
|
||||
}
|
||||
#comic panel sim > iframe{
|
||||
border: none;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
position: absolute;
|
||||
top:0; left:0;
|
||||
}
|
||||
#comic panel sim > label{
|
||||
display:none;
|
||||
}
|
||||
|
||||
/**********/
|
||||
/* LABELS */
|
||||
/**********/
|
||||
|
||||
#labels{
|
||||
display: none;
|
||||
}
|
||||
|
@ -0,0 +1,92 @@
|
||||
|
||||
// The poor man's jQuery
|
||||
function $(query){
|
||||
return document.querySelector(query);
|
||||
}
|
||||
function $all(query){
|
||||
return [].slice.call(document.querySelectorAll(query));
|
||||
}
|
||||
|
||||
window.onload = function(){
|
||||
|
||||
var panels = $all("panel");
|
||||
var pics = $all("pic");
|
||||
var sims = $all("sim");
|
||||
var words = $all("words");
|
||||
|
||||
// Adjust positions & dimensions of all the things
|
||||
var boxes = panels.concat(pics).concat(words).concat(sims);
|
||||
boxes.forEach(function(b){
|
||||
|
||||
var s = b.style;
|
||||
var val;
|
||||
if(val = b.getAttribute("x")) s.left = val+"px";
|
||||
if(val = b.getAttribute("y")) s.top = val+"px";
|
||||
if(val = b.getAttribute("w")) s.width = val+"px";
|
||||
if(val = b.getAttribute("h")) s.height = val+"px";
|
||||
|
||||
});
|
||||
|
||||
// Pics have image (and maybe crop it?)
|
||||
pics.forEach(function(p){
|
||||
|
||||
var s = p.style;
|
||||
var val;
|
||||
if(val = p.getAttribute("src")){
|
||||
s.backgroundImage = "url("+val+")";
|
||||
var x = p.getAttribute("sx") || 0;
|
||||
var y = p.getAttribute("sy") || 0;
|
||||
s.backgroundPosition = (-x)+"px "+(-y)+"px";
|
||||
var w = p.getBoundingClientRect().width;
|
||||
s.backgroundSize = Math.round((3000/w)*50)+"%";
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
// Sims have iframes in them. (Pass in the labels!)
|
||||
sims.forEach(function(sim){
|
||||
|
||||
// Create & append iframe
|
||||
var iframe = document.createElement("iframe");
|
||||
iframe.src = sim.getAttribute("src");
|
||||
iframe.scrolling = "no";
|
||||
sim.appendChild(iframe);
|
||||
|
||||
});
|
||||
|
||||
// Words... no bg? And, fontsize?
|
||||
words.forEach(function(word){
|
||||
var s = word.style;
|
||||
var val;
|
||||
if(val = word.getAttribute("bg")) s.background = val;
|
||||
if(val = word.getAttribute("fontsize")) s.fontSize = s.lineHeight = val+"px";
|
||||
});
|
||||
|
||||
// Panels... Any MESSAGES?
|
||||
panels.forEach(function(panel){
|
||||
|
||||
var msg;
|
||||
|
||||
// Fade in!
|
||||
if(msg = panel.getAttribute("fadeInOn")){
|
||||
subscribe(msg, function(){
|
||||
panel.style.opacity = 1;
|
||||
});
|
||||
}
|
||||
|
||||
// BG?
|
||||
var s = panel.style;
|
||||
var val;
|
||||
if(val = panel.getAttribute("bg")) s.background = val;
|
||||
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
window.getLabel = function(name){
|
||||
return $("#"+name).innerHTML;
|
||||
}
|
||||
|
||||
window.broadcastMessage = function(message){
|
||||
publish(message);
|
||||
};
|
@ -0,0 +1,96 @@
|
||||
/*!
|
||||
* MinPubSub
|
||||
* Copyright(c) 2011 Daniel Lamb <daniellmb.com>
|
||||
* MIT Licensed
|
||||
*/
|
||||
window.c_ = {}; // NICKY - UNIT TESTING
|
||||
(function (context) {
|
||||
var MinPubSub = {};
|
||||
|
||||
// the topic/subscription hash
|
||||
var cache = context.c_ || {}; //check for 'c_' cache for unit testing
|
||||
|
||||
MinPubSub.publish = function ( /* String */ topic, /* Array? */ args) {
|
||||
// summary:
|
||||
// Publish some data on a named topic.
|
||||
// topic: String
|
||||
// The channel to publish on
|
||||
// args: Array?
|
||||
// The data to publish. Each array item is converted into an ordered
|
||||
// arguments on the subscribed functions.
|
||||
//
|
||||
// example:
|
||||
// Publish stuff on '/some/topic'. Anything subscribed will be called
|
||||
// with a function signature like: function(a,b,c){ ... }
|
||||
//
|
||||
// publish('/some/topic', ['a','b','c']);
|
||||
|
||||
var subs = cache[topic],
|
||||
len = subs ? subs.length : 0;
|
||||
|
||||
//can change loop or reverse array if the order matters
|
||||
while (len--) {
|
||||
subs[len].apply(context, args || []);
|
||||
}
|
||||
};
|
||||
|
||||
MinPubSub.subscribe = function ( /* String */ topic, /* Function */ callback) {
|
||||
// summary:
|
||||
// Register a callback on a named topic.
|
||||
// topic: String
|
||||
// The channel to subscribe to
|
||||
// callback: Function
|
||||
// The handler event. Anytime something is publish'ed on a
|
||||
// subscribed channel, the callback will be called with the
|
||||
// published array as ordered arguments.
|
||||
//
|
||||
// returns: Array
|
||||
// A handle which can be used to unsubscribe this particular subscription.
|
||||
//
|
||||
// example:
|
||||
// subscribe('/some/topic', function(a, b, c){ /* handle data */ });
|
||||
|
||||
if (!cache[topic]) {
|
||||
cache[topic] = [];
|
||||
}
|
||||
cache[topic].push(callback);
|
||||
return [topic, callback]; // Array
|
||||
};
|
||||
|
||||
MinPubSub.unsubscribe = function ( /* Array */ handle, /* Function? */ callback) {
|
||||
// summary:
|
||||
// Disconnect a subscribed function for a topic.
|
||||
// handle: Array
|
||||
// The return value from a subscribe call.
|
||||
// example:
|
||||
// var handle = subscribe('/some/topic', function(){});
|
||||
// unsubscribe(handle);
|
||||
|
||||
var subs = cache[callback ? handle : handle[0]],
|
||||
callback = callback || handle[1],
|
||||
len = subs ? subs.length : 0;
|
||||
|
||||
while (len--) {
|
||||
if (subs[len] === callback) {
|
||||
subs.splice(len, 1);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// UMD definition to allow for CommonJS, AMD and legacy window
|
||||
if (typeof module === 'object' && module.exports) {
|
||||
// CommonJS, just export
|
||||
module.exports = exports = MinPubSub;
|
||||
} else if (typeof define === 'function' && define.amd) {
|
||||
// AMD support
|
||||
define(function () {
|
||||
return MinPubSub;
|
||||
});
|
||||
} else if (typeof context === 'object') {
|
||||
// If no AMD and we are in the browser, attach to window
|
||||
context.publish = MinPubSub.publish;
|
||||
context.subscribe = MinPubSub.subscribe;
|
||||
context.unsubscribe = MinPubSub.unsubscribe;
|
||||
}
|
||||
|
||||
})(this.window);
|
After Width: | Height: | Size: 1.9 MiB |
After Width: | Height: | Size: 141 KiB |
After Width: | Height: | Size: 362 KiB |
After Width: | Height: | Size: 196 KiB |
After Width: | Height: | Size: 309 KiB |
@ -0,0 +1,67 @@
|
||||
/* FONT FACE */
|
||||
@font-face {
|
||||
font-family: "PatrickHand";
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
src: url(../../css/PatrickHand-Regular.ttf) format('truetype');
|
||||
}
|
||||
|
||||
body{
|
||||
margin: 0;
|
||||
font-family: "PatrickHand", Helvetica, Arial;
|
||||
color: #000;
|
||||
padding: 0 10px;
|
||||
background: #fff;
|
||||
letter-spacing: 1px;
|
||||
}
|
||||
|
||||
#content{
|
||||
background: #fff;
|
||||
width: 600px;
|
||||
overflow: hidden;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
}
|
||||
#container{
|
||||
width: 500px;
|
||||
margin: 30px auto;
|
||||
}
|
||||
|
||||
|
||||
#graph{
|
||||
border-left: 2px solid black;
|
||||
border-bottom: 2px solid black;
|
||||
}
|
||||
#y_axis, #x_axis{
|
||||
font-size: 18px;
|
||||
position: absolute;
|
||||
color: #000;
|
||||
}
|
||||
#y_axis{
|
||||
position: absolute;
|
||||
transform: rotate(-90deg);
|
||||
left: -67px;
|
||||
top: 114px;
|
||||
text-align: right;
|
||||
width: 200px;
|
||||
}
|
||||
#x_axis{
|
||||
width: 200px;
|
||||
left: 358px;
|
||||
top: 282px;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
#ui{
|
||||
margin-top: 25px;
|
||||
font-size: 25px;
|
||||
line-height: 1em;
|
||||
}
|
||||
input[fullw]{
|
||||
width:100%;
|
||||
}
|
||||
|
||||
#default_labels{
|
||||
display:none;
|
||||
}
|
@ -0,0 +1,398 @@
|
||||
window.MODE = -1;
|
||||
window.onload = function(){
|
||||
|
||||
// Get Mode
|
||||
window.MODE = parseInt( _getQueryVariable("mode") );
|
||||
|
||||
// Init labels
|
||||
$("#y_axis").innerHTML = _getLabel("ebbinghaus_y_axis");
|
||||
$("#x_axis").innerHTML = _getLabel("ebbinghaus_x_axis");
|
||||
|
||||
// Initialize all the things!
|
||||
switch(MODE){
|
||||
// Just decay
|
||||
case 0:
|
||||
sim_params.push(_sliders.d);
|
||||
break;
|
||||
// ONE retrieval
|
||||
case 1:
|
||||
recall_params.push(_sliders.r1);
|
||||
break;
|
||||
// ONE retrieval, with optimal learning
|
||||
case 2:
|
||||
PARAMS.optimal = 0.75;
|
||||
recall_params.push(_sliders.r1);
|
||||
break;
|
||||
// MULTI retrievals, with optimal learning
|
||||
case 3:
|
||||
PARAMS.optimal = 0.75;
|
||||
recall_params.push(_sliders.r1);
|
||||
recall_params.push(_sliders.r2);
|
||||
recall_params.push(_sliders.r3);
|
||||
recall_params.push(_sliders.r4);
|
||||
break;
|
||||
// FULL SANDBOX
|
||||
case 4:
|
||||
|
||||
sim_params.push(_sliders.d);
|
||||
sim_params.push(_sliders.o);
|
||||
|
||||
recall_params.push(_sliders.r1);
|
||||
recall_params.push(_sliders.r2);
|
||||
recall_params.push(_sliders.r3);
|
||||
recall_params.push(_sliders.r4);
|
||||
|
||||
break;
|
||||
}
|
||||
sim_params.concat(recall_params).forEach(_createParamSlider);
|
||||
|
||||
// Add UI
|
||||
switch(MODE){
|
||||
// Just decay
|
||||
case 0:
|
||||
_appendSpan("ebbinghaus_decay");
|
||||
_appendSlider("init_decay");
|
||||
break;
|
||||
// ONE retrieval
|
||||
case 1:
|
||||
_appendSpan("ebbinghaus_recalls");
|
||||
_appendSlider("recall_1");
|
||||
break;
|
||||
// ONE retrieval, with optimal learning
|
||||
case 2:
|
||||
_appendSpan("ebbinghaus_recalls");
|
||||
_appendSlider("recall_1");
|
||||
break;
|
||||
// MULTI retrievals, with optimal learning
|
||||
case 3:
|
||||
_appendSpan("ebbinghaus_recalls");
|
||||
_appendSlider("recall_1");
|
||||
_appendSlider("recall_2");
|
||||
_appendSlider("recall_3");
|
||||
_appendSlider("recall_4");
|
||||
break;
|
||||
// FULL SANDBOX
|
||||
case 4:
|
||||
|
||||
_appendSpan("ebbinghaus_decay");
|
||||
_appendSlider("init_decay");
|
||||
|
||||
_appendSpan("ebbinghaus_forgetting");
|
||||
_appendSlider("optimal");
|
||||
|
||||
_appendBr();
|
||||
_appendBr();
|
||||
|
||||
_appendSpan("ebbinghaus_recalls");
|
||||
_appendButton("ebbinghaus_auto",_AUTO_OPTIMIZE);
|
||||
_appendSlider("recall_1");
|
||||
_appendSlider("recall_2");
|
||||
_appendSlider("recall_3");
|
||||
_appendSlider("recall_4");
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
// Update
|
||||
window.PARAMS_CHANGED = true;
|
||||
update();
|
||||
|
||||
};
|
||||
|
||||
////////////////////////////////////////
|
||||
////////////////////////////////////////
|
||||
////////////////////////////////////////
|
||||
|
||||
// The most fudge-y function in existence
|
||||
var _AUTO_OPTIMIZE = function(){
|
||||
|
||||
// When t hits the sweet spot (k)...
|
||||
// k = A*e^(-Bt)
|
||||
// Therefore:
|
||||
// t = (ln(A) - ln(k))/B
|
||||
// Dunno what A & B are. Fudge it.
|
||||
|
||||
var A = 1; // coz, at 0, it's 1. Duh.
|
||||
var k = PARAMS.optimal;
|
||||
var B = 102 * PARAMS.init_decay * MAGIC_CONSTANT; // FUDGE IT.
|
||||
var timing = (Math.log(A) - Math.log(k))/B;
|
||||
|
||||
// Set first one!
|
||||
_sliderUI.recall_1.value = timing;
|
||||
_sliderUI.recall_1.oninput();
|
||||
|
||||
// Multiply by fudged values for the rest.
|
||||
timing *= 2.92;
|
||||
_sliderUI.recall_2.value = timing;
|
||||
_sliderUI.recall_2.oninput();
|
||||
timing *= 2.23;
|
||||
_sliderUI.recall_3.value = timing;
|
||||
_sliderUI.recall_3.oninput();
|
||||
timing *= 2.01;
|
||||
_sliderUI.recall_4.value = timing;
|
||||
_sliderUI.recall_4.oninput();
|
||||
|
||||
};
|
||||
|
||||
////////////////////////////////////////
|
||||
////////////////////////////////////////
|
||||
////////////////////////////////////////
|
||||
|
||||
var canvas = document.getElementById("graph");
|
||||
var ctx = canvas.getContext('2d');
|
||||
|
||||
// Params & their sliders
|
||||
var PARAMS = {};
|
||||