diff --git a/audio/applause.mp3 b/audio/applause.mp3 new file mode 100644 index 0000000..3f04bd5 Binary files /dev/null and b/audio/applause.mp3 differ diff --git a/audio/button_down.mp3 b/audio/button_down.mp3 new file mode 100644 index 0000000..1102d7f Binary files /dev/null and b/audio/button_down.mp3 differ diff --git a/audio/button_up.mp3 b/audio/button_up.mp3 new file mode 100644 index 0000000..6d8339d Binary files /dev/null and b/audio/button_up.mp3 differ diff --git a/audio/ding.mp3 b/audio/ding.mp3 new file mode 100644 index 0000000..a70e888 Binary files /dev/null and b/audio/ding.mp3 differ diff --git a/audio/flip_down.mp3 b/audio/flip_down.mp3 new file mode 100644 index 0000000..7c1f2eb Binary files /dev/null and b/audio/flip_down.mp3 differ diff --git a/audio/flip_up.mp3 b/audio/flip_up.mp3 new file mode 100644 index 0000000..67e84bc Binary files /dev/null and b/audio/flip_up.mp3 differ diff --git a/audio/reset.mp3 b/audio/reset.mp3 new file mode 100644 index 0000000..5d01d2d Binary files /dev/null and b/audio/reset.mp3 differ diff --git a/audio/slider_down.mp3 b/audio/slider_down.mp3 new file mode 100644 index 0000000..7549f1a Binary files /dev/null and b/audio/slider_down.mp3 differ diff --git a/audio/slider_up.mp3 b/audio/slider_up.mp3 new file mode 100644 index 0000000..2594e43 Binary files /dev/null and b/audio/slider_up.mp3 differ diff --git a/audio/type1.mp3 b/audio/type1.mp3 new file mode 100644 index 0000000..5d42295 Binary files /dev/null and b/audio/type1.mp3 differ diff --git a/audio/type2.mp3 b/audio/type2.mp3 new file mode 100644 index 0000000..56f3cd3 Binary files /dev/null and b/audio/type2.mp3 differ diff --git a/audio/type3.mp3 b/audio/type3.mp3 new file mode 100644 index 0000000..668f65a Binary files /dev/null and b/audio/type3.mp3 differ diff --git a/audio/type4.mp3 b/audio/type4.mp3 new file mode 100644 index 0000000..1e3fcf1 Binary files /dev/null and b/audio/type4.mp3 differ diff --git a/audio/type5.mp3 b/audio/type5.mp3 new file mode 100644 index 0000000..349347d Binary files /dev/null and b/audio/type5.mp3 differ diff --git a/audio/win.mp3 b/audio/win.mp3 new file mode 100644 index 0000000..bb35673 Binary files /dev/null and b/audio/win.mp3 differ diff --git a/audio/win_final.mp3 b/audio/win_final.mp3 new file mode 100644 index 0000000..32ec617 Binary files /dev/null and b/audio/win_final.mp3 differ diff --git a/ch1.html b/ch1.html index 5b3fa95..cf2f6c7 100644 --- a/ch1.html +++ b/ch1.html @@ -174,7 +174,7 @@ You need desirable difficulty: the sweet spot of just-hard-enough. Same simulation as before, but now it shows the sweet spot – where you’ve forgotten just a little bit. - Put the recall in the middle of the sweet spot. What happens? + Put the recall in the middle of the sweet spot. What happens? @@ -186,8 +186,8 @@ You need desirable difficulty: the sweet spot of just-hard-enough. - See? If you time a single recall so that it's in the sweet spot, - you can slow down the decay! + See? If you time a recall so that it's right in the sweet spot, + you can slow the decay by a lot! Now, what about multiple recalls? @@ -232,14 +232,14 @@ then when you’re ready, flip the card over ↓ Which is very counter-intuitive! You can prove to yourself this is true, by playing with the sim below. - Get all recalls into the middle of the sweet spot. + Get all recalls into the middle of the sweet spot. What spacing do you get? - - + + @@ -254,8 +254,8 @@ then when you’re ready, flip the card over ↓ - - + + @@ -459,5 +459,6 @@ Early feedback helps me a lot. Many thanks in advance! + diff --git a/ch2.html b/ch2.html index 8de650b..afc6b4b 100644 --- a/ch2.html +++ b/ch2.html @@ -912,5 +912,6 @@ Early feedback helps me a lot. Many thanks in advance! + diff --git a/ch3.html b/ch3.html index d83bd71..29a1af8 100644 --- a/ch3.html +++ b/ch3.html @@ -127,12 +127,11 @@ So, here's the front of our first flashcard, our question: - + @@ -164,19 +163,19 @@ So, here's the front of our first flashcard, our question: concrete examples of a why behind a what: - WHAT: a new language + WHAT: a new language
- WHY: to speak to friends, family, lovers in their native tongue + WHY: to speak to friends, family, lovers in their native tongue
- WHAT: computer programming + WHAT: computer programming
- WHY: to make money so you can eat + WHY: to make money so you can eat
- WHAT: anything interesting + WHAT: anything interesting
- WHY: curiosity, for its own sake! + WHY: curiosity, for its own sake!
So... what's your why? @@ -804,5 +803,6 @@ Before sleeping, coz otherwise you'd just stress-binge on twitter + diff --git a/intro.html b/intro.html index fb05acf..bc424c8 100644 --- a/intro.html +++ b/intro.html @@ -297,5 +297,6 @@ Like so: + diff --git a/js/comic.js b/js/comic.js index 39d4d98..935f878 100644 --- a/js/comic.js +++ b/js/comic.js @@ -236,3 +236,41 @@ if(linx){ }); } + +////////////////////// +// SOUNDS //////////// +////////////////////// + +var SOUNDS_TO_LOAD = [ + ["applause",1], + ["ding",1], + ["button_down",1], + ["button_up",1], + ["flip_down",1], + ["flip_up",1], + ["reset",1], + ["slider_down",0.25], + ["slider_up",0.25], + ["type1",1], + ["type2",1], + ["type3",1], + ["type4",1], + ["type5",1], + ["win",1], + ["win_final",1], +]; +var SOUNDS = {}; +SOUNDS_TO_LOAD.forEach(function(config){ + + var name = config[0]; + var vol = config[1]; + + SOUNDS[name] = new Howl({ + src: ["audio/"+name+".mp3"], + volume: vol + }); + +}); +window.playSound = function(name){ + SOUNDS[name].play(); +}; diff --git a/js/howler.core.min.js b/js/howler.core.min.js new file mode 100644 index 0000000..9c5fa5e --- /dev/null +++ b/js/howler.core.min.js @@ -0,0 +1,2 @@ +/*! howler.js v2.0.15 | (c) 2013-2018, James Simpson of GoldFire Studios | MIT License | howlerjs.com */ +!function(){"use strict";var e=function(){this.init()};e.prototype={init:function(){var e=this||n;return e._counter=1e3,e._codecs={},e._howls=[],e._muted=!1,e._volume=1,e._canPlayEvent="canplaythrough",e._navigator="undefined"!=typeof window&&window.navigator?window.navigator:null,e.masterGain=null,e.noAudio=!1,e.usingWebAudio=!0,e.autoSuspend=!0,e.ctx=null,e.mobileAutoEnable=!0,e._setup(),e},volume:function(e){var o=this||n;if(e=parseFloat(e),o.ctx||_(),void 0!==e&&e>=0&&e<=1){if(o._volume=e,o._muted)return o;o.usingWebAudio&&o.masterGain.gain.setValueAtTime(e,n.ctx.currentTime);for(var t=0;t=0;o--)e._howls[o].unload();return e.usingWebAudio&&e.ctx&&void 0!==e.ctx.close&&(e.ctx.close(),e.ctx=null,_()),e},codecs:function(e){return(this||n)._codecs[e.replace(/^x-/,"")]},_setup:function(){var e=this||n;if(e.state=e.ctx?e.ctx.state||"running":"running",e._autoSuspend(),!e.usingWebAudio)if("undefined"!=typeof Audio)try{var o=new Audio;void 0===o.oncanplaythrough&&(e._canPlayEvent="canplay")}catch(n){e.noAudio=!0}else e.noAudio=!0;try{var o=new Audio;o.muted&&(e.noAudio=!0)}catch(e){}return e.noAudio||e._setupCodecs(),e},_setupCodecs:function(){var e=this||n,o=null;try{o="undefined"!=typeof Audio?new Audio:null}catch(n){return e}if(!o||"function"!=typeof o.canPlayType)return e;var t=o.canPlayType("audio/mpeg;").replace(/^no$/,""),r=e._navigator&&e._navigator.userAgent.match(/OPR\/([0-6].)/g),a=r&&parseInt(r[0].split("/")[1],10)<33;return e._codecs={mp3:!(a||!t&&!o.canPlayType("audio/mp3;").replace(/^no$/,"")),mpeg:!!t,opus:!!o.canPlayType('audio/ogg; codecs="opus"').replace(/^no$/,""),ogg:!!o.canPlayType('audio/ogg; codecs="vorbis"').replace(/^no$/,""),oga:!!o.canPlayType('audio/ogg; codecs="vorbis"').replace(/^no$/,""),wav:!!o.canPlayType('audio/wav; codecs="1"').replace(/^no$/,""),aac:!!o.canPlayType("audio/aac;").replace(/^no$/,""),caf:!!o.canPlayType("audio/x-caf;").replace(/^no$/,""),m4a:!!(o.canPlayType("audio/x-m4a;")||o.canPlayType("audio/m4a;")||o.canPlayType("audio/aac;")).replace(/^no$/,""),mp4:!!(o.canPlayType("audio/x-mp4;")||o.canPlayType("audio/mp4;")||o.canPlayType("audio/aac;")).replace(/^no$/,""),weba:!!o.canPlayType('audio/webm; codecs="vorbis"').replace(/^no$/,""),webm:!!o.canPlayType('audio/webm; codecs="vorbis"').replace(/^no$/,""),dolby:!!o.canPlayType('audio/mp4; codecs="ec-3"').replace(/^no$/,""),flac:!!(o.canPlayType("audio/x-flac;")||o.canPlayType("audio/flac;")).replace(/^no$/,"")},e},_enableMobileAudio:function(){var e=this||n,o=/iPhone|iPad|iPod|Android|BlackBerry|BB10|Silk|Mobi|Chrome/i.test(e._navigator&&e._navigator.userAgent);if(!e._mobileEnabled&&e.ctx&&o){e._mobileEnabled=!1,e.mobileAutoEnable=!1,e._mobileUnloaded||44100===e.ctx.sampleRate||(e._mobileUnloaded=!0,e.unload()),e._scratchBuffer=e.ctx.createBuffer(1,1,22050);var t=function(o){n._autoResume();var r=e.ctx.createBufferSource();r.buffer=e._scratchBuffer,r.connect(e.ctx.destination),void 0===r.start?r.noteOn(0):r.start(0),"function"==typeof e.ctx.resume&&e.ctx.resume(),r.onended=function(){r.disconnect(0),e._mobileEnabled=!0,document.removeEventListener("touchstart",t,!0),document.removeEventListener("touchend",t,!0),document.removeEventListener("click",t,!0);for(var n=0;n0?i._seek:t._sprite[e][0]/1e3),s=Math.max(0,(t._sprite[e][0]+t._sprite[e][1])/1e3-_),l=1e3*s/Math.abs(i._rate);if(i._paused=!1,i._ended=!1,i._sprite=e,i._seek=_,i._start=t._sprite[e][0]/1e3,i._stop=(t._sprite[e][0]+t._sprite[e][1])/1e3,i._loop=!(!i._loop&&!t._sprite[e][2]),i._seek>=i._stop)return void t._ended(i);var c=i._node;if(t._webAudio){var f=function(){t._refreshBuffer(i);var e=i._muted||t._muted?0:i._volume;c.gain.setValueAtTime(e,n.ctx.currentTime),i._playStart=n.ctx.currentTime,void 0===c.bufferSource.start?i._loop?c.bufferSource.noteGrainOn(0,_,86400):c.bufferSource.noteGrainOn(0,_,s):i._loop?c.bufferSource.start(0,_,86400):c.bufferSource.start(0,_,s),l!==1/0&&(t._endTimers[i._id]=setTimeout(t._ended.bind(t,i),l)),o||setTimeout(function(){t._emit("play",i._id)},0)};"running"===n.state?f():(t.once("resume",f),t._clearTimer(i._id))}else{var p=function(){c.currentTime=_,c.muted=i._muted||t._muted||n._muted||c.muted,c.volume=i._volume*n.volume(),c.playbackRate=i._rate;try{var r=c.play();if(r&&"undefined"!=typeof Promise&&(r instanceof Promise||"function"==typeof r.then)?(t._playLock=!0,r.then(function(){t._playLock=!1,o||t._emit("play",i._id)}).catch(function(){t._playLock=!1,t._emit("playerror",i._id,"Playback was unable to start. This is most commonly an issue on mobile devices and Chrome where playback was not within a user interaction.")})):o||t._emit("play",i._id),c.playbackRate=i._rate,c.paused)return void t._emit("playerror",i._id,"Playback was unable to start. This is most commonly an issue on mobile devices and Chrome where playback was not within a user interaction.");"__default"!==e||i._loop?t._endTimers[i._id]=setTimeout(t._ended.bind(t,i),l):(t._endTimers[i._id]=function(){t._ended(i),c.removeEventListener("ended",t._endTimers[i._id],!1)},c.addEventListener("ended",t._endTimers[i._id],!1))}catch(e){t._emit("playerror",i._id,e)}},m=window&&window.ejecta||!c.readyState&&n._navigator.isCocoonJS;if(c.readyState>=3||m)p();else{var v=function(){p(),c.removeEventListener(n._canPlayEvent,v,!1)};c.addEventListener(n._canPlayEvent,v,!1),t._clearTimer(i._id)}}return i._id},pause:function(e){var n=this;if("loaded"!==n._state||n._playLock)return n._queue.push({event:"pause",action:function(){n.pause(e)}}),n;for(var o=n._getSoundIds(e),t=0;t=0?o=parseInt(r[0],10):e=parseFloat(r[0])}else r.length>=2&&(e=parseFloat(r[0]),o=parseInt(r[1],10));var a;if(!(void 0!==e&&e>=0&&e<=1))return a=o?t._soundById(o):t._sounds[0],a?a._volume:0;if("loaded"!==t._state||t._playLock)return t._queue.push({event:"volume",action:function(){t.volume.apply(t,r)}}),t;void 0===o&&(t._volume=e),o=t._getSoundIds(o);for(var u=0;u0?t/_:t),l=Date.now();e._fadeTo=o,e._interval=setInterval(function(){var r=(Date.now()-l)/t;l=Date.now(),i+=d*r,i=Math.max(0,i),i=Math.min(1,i),i=Math.round(100*i)/100,u._webAudio?e._volume=i:u.volume(i,e._id,!0),a&&(u._volume=i),(on&&i>=o)&&(clearInterval(e._interval),e._interval=null,e._fadeTo=null,u.volume(o,e._id),u._emit("fade",e._id))},s)},_stopFade:function(e){var o=this,t=o._soundById(e);return t&&t._interval&&(o._webAudio&&t._node.gain.cancelScheduledValues(n.ctx.currentTime),clearInterval(t._interval),t._interval=null,o.volume(t._fadeTo,e),t._fadeTo=null,o._emit("fade",e)),o},loop:function(){var e,n,o,t=this,r=arguments;if(0===r.length)return t._loop;if(1===r.length){if("boolean"!=typeof r[0])return!!(o=t._soundById(parseInt(r[0],10)))&&o._loop;e=r[0],t._loop=e}else 2===r.length&&(e=r[0],n=parseInt(r[1],10));for(var a=t._getSoundIds(n),u=0;u=0?o=parseInt(r[0],10):e=parseFloat(r[0])}else 2===r.length&&(e=parseFloat(r[0]),o=parseInt(r[1],10));var i;if("number"!=typeof e)return i=t._soundById(o),i?i._rate:t._rate;if("loaded"!==t._state||t._playLock)return t._queue.push({event:"rate",action:function(){t.rate.apply(t,r)}}),t;void 0===o&&(t._rate=e),o=t._getSoundIds(o);for(var d=0;d=0?o=parseInt(r[0],10):t._sounds.length&&(o=t._sounds[0]._id,e=parseFloat(r[0]))}else 2===r.length&&(e=parseFloat(r[0]),o=parseInt(r[1],10));if(void 0===o)return t;if("loaded"!==t._state||t._playLock)return t._queue.push({event:"seek",action:function(){t.seek.apply(t,r)}}),t;var i=t._soundById(o);if(i){if(!("number"==typeof e&&e>=0)){if(t._webAudio){var d=t.playing(o)?n.ctx.currentTime-i._playStart:0,_=i._rateSeek?i._rateSeek-i._seek:0;return i._seek+(_+d*Math.abs(i._rate))}return i._node.currentTime}var s=t.playing(o);s&&t.pause(o,!0),i._seek=e,i._ended=!1,t._clearTimer(o),!t._webAudio&&i._node&&(i._node.currentTime=e);var l=function(){t._emit("seek",o),s&&t.play(o,!0)};if(s&&!t._webAudio){var c=function(){t._playLock?setTimeout(c,0):l()};setTimeout(c,0)}else l()}return t},playing:function(e){var n=this;if("number"==typeof e){var o=n._soundById(e);return!!o&&!o._paused}for(var t=0;t=0&&n._howls.splice(a,1);var u=!0;for(t=0;t=0;a--)r[a].id&&r[a].id!==n&&"load"!==e||(setTimeout(function(e){e.call(this,n,o)}.bind(t,r[a].fn),0),r[a].once&&t.off(e,r[a].fn,r[a].id));return t._loadQueue(e),t},_loadQueue:function(e){var n=this;if(n._queue.length>0){var o=n._queue[0];o.event===e&&(n._queue.shift(),n._loadQueue()),e||o.action()}return n},_ended:function(e){var o=this,t=e._sprite;if(!o._webAudio&&e._node&&!e._node.paused&&!e._node.ended&&e._node.currentTime=0;t--){if(o<=n)return;e._sounds[t]._ended&&(e._webAudio&&e._sounds[t]._node&&e._sounds[t]._node.disconnect(0),e._sounds.splice(t,1),o--)}}},_getSoundIds:function(e){var n=this;if(void 0===e){for(var o=[],t=0;t0?(r[o._src]=e,d(o,e)):t()};"undefined"!=typeof Promise&&1===n.ctx.decodeAudioData.length?n.ctx.decodeAudioData(e).then(a).catch(t):n.ctx.decodeAudioData(e,a,t)},d=function(e,n){n&&!e._duration&&(e._duration=n.duration),0===Object.keys(e._sprite).length&&(e._sprite={__default:[0,1e3*e._duration]}),"loaded"!==e._state&&(e._state="loaded",e._emit("load"),e._loadQueue())},_=function(){try{"undefined"!=typeof AudioContext?n.ctx=new AudioContext:"undefined"!=typeof webkitAudioContext?n.ctx=new webkitAudioContext:n.usingWebAudio=!1}catch(e){n.usingWebAudio=!1}var e=/iP(hone|od|ad)/.test(n._navigator&&n._navigator.platform),o=n._navigator&&n._navigator.appVersion.match(/OS (\d+)_(\d+)_?(\d+)?/),t=o?parseInt(o[1],10):null;if(e&&t&&t<9){var r=/safari/.test(n._navigator&&n._navigator.userAgent.toLowerCase());(n._navigator&&n._navigator.standalone&&!r||n._navigator&&!n._navigator.standalone&&!r)&&(n.usingWebAudio=!1)}n.usingWebAudio&&(n.masterGain=void 0===n.ctx.createGain?n.ctx.createGainNode():n.ctx.createGain(),n.masterGain.gain.setValueAtTime(n._muted?0:1,n.ctx.currentTime),n.masterGain.connect(n.ctx.destination)),n._setup()};"function"==typeof define&&define.amd&&define([],function(){return{Howler:n,Howl:o}}),"undefined"!=typeof exports&&(exports.Howler=n,exports.Howl=o),"undefined"!=typeof window?(window.HowlerGlobal=e,window.Howler=n,window.Howl=o,window.Sound=t):"undefined"!=typeof global&&(global.HowlerGlobal=e,global.Howler=n,global.Howl=o,global.Sound=t)}(); \ No newline at end of file diff --git a/sims/calendar/calendar.js b/sims/calendar/calendar.js index b9e580e..2049d30 100644 --- a/sims/calendar/calendar.js +++ b/sims/calendar/calendar.js @@ -50,6 +50,14 @@ daySlider.oninput = function(){ } +// Slider has SOUNDS +daySlider.onmousedown = daySlider.ontouchstart = function(){ + playSound("slider_down"); +}; +daySlider.onmouseup = daySlider.ontouchend = function(){ + playSound("slider_up"); +}; + window.REDRAW = 0; function update(){ diff --git a/sims/ebbinghaus/ebbinghaus.css b/sims/ebbinghaus/ebbinghaus.css index 0fb875d..2becc31 100644 --- a/sims/ebbinghaus/ebbinghaus.css +++ b/sims/ebbinghaus/ebbinghaus.css @@ -76,6 +76,9 @@ input[fullw]{ background: #d3d3d3; outline: none; } +.timing_slider{ + margin-bottom: 20px; +} .timing_slider::-webkit-slider-thumb{ @@ -132,3 +135,9 @@ input[fullw]{ cursor: pointer; } +.auto_optimize{ + background: #e6e6e6; + padding: 0 5px; + border-radius: 10px; + cursor: pointer; +} \ No newline at end of file diff --git a/sims/ebbinghaus/ebbinghaus.js b/sims/ebbinghaus/ebbinghaus.js index b280af1..1d16a4f 100644 --- a/sims/ebbinghaus/ebbinghaus.js +++ b/sims/ebbinghaus/ebbinghaus.js @@ -129,7 +129,7 @@ var _addSlideyUI = function(x,y){ window.pointy = null; var _addPointyUI = function(x,y){ - window.slidey = new createAnimatedUIHelper({ + window.pointy = new createAnimatedUIHelper({ x: x, y: y, width: 70, @@ -243,6 +243,7 @@ var _appendCheckbox = function(name, onActivate, onDeactivate){ var label = _getLabel(name); var labelDOM = document.createElement("label"); + labelDOM.className = "auto_optimize"; var labelTextNode = document.createTextNode(label); var input = document.createElement("input"); @@ -251,8 +252,10 @@ var _appendCheckbox = function(name, onActivate, onDeactivate){ input.onclick = function(){ if(input.checked){ onActivate(); + playSound("ding"); }else{ onDeactivate(); + playSound("button_up"); } } @@ -288,8 +291,19 @@ var _createParamSlider = function(config){ slider.oninput = _onSliderUpdate; _onSliderUpdate(); + // Slider has SOUNDS + slider.onmousedown = slider.ontouchstart = function(){ + playSound("slider_down"); + }; + slider.onmouseup = slider.ontouchend = function(){ + playSound("slider_up"); + }; + }; +// HACK - for sounds... +var recallIsOptimal = [false,false,false,false]; + // Update var MAGIC_CONSTANT = 0.013815; // Through pure brute force, don't care. @@ -470,6 +484,20 @@ function update(){ ctx.lineTo(p.x,p.y); imCut = true; theCircles.push(theLastPoint); + + // HACK: OPTIMAL?? + var d = theLastPoint.distance; + if(d