diff --git a/example/exampleMedium/buttons.js b/example/exampleMedium/buttons.js new file mode 100644 index 0000000..5ff4db4 --- /dev/null +++ b/example/exampleMedium/buttons.js @@ -0,0 +1,78 @@ +!function(){ + /*I will use this variable for storing frames + for button clicks below*/ + var resetFrame; + function makeButtons(exports){ + /*create an 2 element array of arrays, + I will chain forEach to generate buttons + using the button function*/ + [ + [ + "Stop", + function(event){ + /*either resume or pause taskq, changing the button + text accordingly*/ + this.textContent = this.textContent === "Stop" + ? (taskq.pause,exports.message("paused!;"),"Resume") + : (taskq.resume,exports.message("resumed!;"),"Stop"); + } + ], + [ + "Restart", + function(event){ + /*clear all the points, and reset the counter*/ + var row = document.getElementsByClassName("row")[0]; + while(row.hasChildNodes()){ + row.removeChild(row.lastChild); + }; + exports.counter = 0; + /*if the main thread has ended, we have to restart. But here is + the catch: taskq.running is set by 2 threads when they shift() their tasks + at start, the main and the immediate thread. They both operate under + Promises and requestAnimationFrame. So in a single frame of ~17ms, + taskq.running might return false before it is true again the next frame. + When you are checking taskq.running, it good to check it next frame as well + to make sure the threads are done. Below is normally not necessary unless + someone spams the buttons faster than ~17ms.*/ + if(!taskq.running){ + window.cancelAnimationFrame(resetFrame); + resetFrame = window.requestAnimationFrame(function(){ + /*taskq was infact running, return*/ + if(taskq.running){ + return; + } + /*push a function to main thread and call perform to start. + This was automatically done for you at the load event.*/ + taskq + .push(function(){ + /*exports are flushed from taskq at the end of main thread. + Luckily its kept in memory here, so we can re-export it.*/ + taskq.export(exports,"exports"); + taskq.load("./draw.js") + .then(function(res){ + res.init; + setTimeout(function(){ + res(true); + },500); + }); + }).perform(); + }); + } + } + ] + ].forEach(function(d,i){ + button.apply(null,d); + }); + /*create a button generator that takes + as arguments a text to display and a function + to fire on click event.*/ + function button(text,f){ + var div = document.createElement("div"); + div.addEventListener("click",f,false); + button.div = button.div || document.getElementsByClassName("buttons")[0]; + button.div.appendChild(div); + div.textContent = encodeURI(text).replace(/(?:%20)/gi," "); + }; + }; + taskq.push(makeButtons); +}(); \ No newline at end of file diff --git a/example/exampleMedium/draw.js b/example/exampleMedium/draw.js new file mode 100644 index 0000000..f34da46 --- /dev/null +++ b/example/exampleMedium/draw.js @@ -0,0 +1,43 @@ +!function(){ + function draw(exports){ + /*instead of recreating similar divs, + I will make one template div, store it + in exports and then clone it each time.*/ + if(!exports.point) { + var div = document.createElement("div"); + div.className = "point"; + exports.point = div; + } + /*Store the main div, so we dont have to + grab it each time*/ + if(!exports.row){ + exports.row = document.getElementsByClassName("row")[0]; + } + div = exports.point.cloneNode(); + div.style.top = (50 - Math.sin(exports.counter * exports.step) * 50) + "%"; + div.style.left = exports.counter + "%"; + exports.row.appendChild(div); + /*introduce a small delay which allows the + css styles to kick in.*/ + window.requestAnimationFrame(function(){ + div.style.boxShadow = "0px 0px 0px 0px Orange"; + }); + /*if we reach 101, we are done*/ + exports.counter = ++exports.counter % 101; + /*if we did not reach 101, load draw.js again, + updating the immediate thread*/ + if (exports.counter) { + taskq.load("./draw.js") + .then(function(res){ + res.init; + setTimeout(function(){ + res(true); + },500); + }); + } else { + /*otherwise report*/ + exports.message("routine ended!;"); + } + }; + taskq.push(draw); +}(); \ No newline at end of file diff --git a/example/exampleMedium/githubButtons.js b/example/exampleMedium/githubButtons.js new file mode 100644 index 0000000..d7fa48c --- /dev/null +++ b/example/exampleMedium/githubButtons.js @@ -0,0 +1,9 @@ +!function(){ + function githubButtons(exports){ + exports.message("Let's add some github corner!;"); + var anchor = document.querySelector("a.github-corner"); + anchor.innerHTML = ''; + anchor.href = "https://github.com/IbrahimTanyalcin/taskq"; + }; + taskq.push(githubButtons); +}(); \ No newline at end of file diff --git a/example/exampleMedium/index.html b/example/exampleMedium/index.html new file mode 100644 index 0000000..ac3f8d1 --- /dev/null +++ b/example/exampleMedium/index.html @@ -0,0 +1,18 @@ + + + + + + + + +
+
+
+
+
+
+ + + + \ No newline at end of file diff --git a/example/exampleMedium/index.js b/example/exampleMedium/index.js new file mode 100644 index 0000000..2c69297 --- /dev/null +++ b/example/exampleMedium/index.js @@ -0,0 +1,93 @@ +!function(){ + /*in our main thread there is only index function + so there is no need to use _taskqId or _taskqWaitFor. + We define the function and directly do taskq.push + to start the main thread.*/ + function index(exports){ + /*start by loading the message generator + then wait 3 seconds before proceeding next*/ + taskq.load("./message.js") + .then(function(){ + exports.message("message generator added!;"); + }) + .then(function(res){ + res.init; + exports.message("Waiting 3 seconds..."); + setTimeout(function(){ + res(true); + },3000); + }); + /*load the styles, wait for 3 seconds, + then export some variables that we will + need later*/ + taskq.load("./loadStyles.js") + .then(function(){ + exports.message("styleSheets loaded!;"); + }) + .then(function(res){ + res.init; + exports.message("Waiting 3 seconds..."); + setTimeout(function(){ + res(true); + },3000); + }) + .then(function(){ + /*To draw sin(x), everytime draw.js is loaded, it will + increment the counter. We will finish the graph in + 100 steps. Since the period is 2PI, we divide it by 100*/ + exports.counter = 0; + exports.step = Math.PI*2/100; + exports.message("Variables set!;"); + }); + /*Let's add a github button, then wait for 3 seconds*/ + taskq.load("./githubButtons.js") + .then(function(res){ + res.init; + setTimeout(function(){ + exports.message("Added github corner!;"); + res(true); + },3000); + }) + .then(function(res){ + res.init; + setTimeout(function(){ + exports.message("Let's add some buttons!;"); + res(true); + },3000); + }); + /*Add buttons to resume or pause, + wait for another 3 seconds twice*/ + taskq.load("./buttons.js") + .then(function(res){ + res.init; + setTimeout(function(){ + exports.message("Buttons made!;"); + res(true); + },3000); + }) + .then(function(res){ + res.init; + exports.message("Starting to draw in 3 seconds..."); + setTimeout(function(){ + res(true); + },3000); + }); + /*recursively load draw function, + this will not blow the stack. + Wait for 500 milliseconds before + proceeding reload*/ + taskq.load("./draw.js") + .then(function(res){ + res.init; + setTimeout(function(){ + res(true); + },500); + }); + }; + /*since iief executes immediately + we can export a variable to be available + for the pushed functions*/ + taskq.export({},"exports"); + /*start the main thread*/ + taskq.push(index); +}(); \ No newline at end of file diff --git a/example/exampleMedium/loadStyles.js b/example/exampleMedium/loadStyles.js new file mode 100644 index 0000000..fdf1c02 --- /dev/null +++ b/example/exampleMedium/loadStyles.js @@ -0,0 +1,10 @@ +!function(){ + function loadStyles(){ + var link = document.createElement("link"); + link.href = "./styles.css"; + link.type = "text/css"; + link.rel = "stylesheet"; + document.head.appendChild(link); + }; + taskq.push(loadStyles); +}(); \ No newline at end of file diff --git a/example/exampleMedium/message.js b/example/exampleMedium/message.js new file mode 100644 index 0000000..44f7a81 --- /dev/null +++ b/example/exampleMedium/message.js @@ -0,0 +1,15 @@ +!function(){ + function messenger(exports){ + /*export the message so it is visible for other functions*/ + exports.message = message; + /*function for message generator*/ + function message(text){ + var div = document.createElement("div"); + message.count = message.count || 0; + message.div = message.div || document.getElementsByClassName("sideCar")[0]; + message.div.appendChild(div); + div.textContent = ++message.count + ") " + encodeURI(text).replace(/(?:%20)/gi," "); + }; + }; + taskq.push(messenger); +}(); \ No newline at end of file diff --git a/example/exampleMedium/styles.css b/example/exampleMedium/styles.css new file mode 100644 index 0000000..1efd1e6 --- /dev/null +++ b/example/exampleMedium/styles.css @@ -0,0 +1,93 @@ +html { + font-size:16px; + font-family:Helvetica, Arial, "sans-serif"; + color:DimGray; + cursor:pointer; +} +html * { + box-sizing:border-box; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} +div.row { + position:absolute; + width:50%; + height:50%; + top:0; + left:0; + bottom:0; + right:0; + margin:auto; + text-align:center; + font-size:1rem; + line-height:200%; + border: 20px solid DimGray; + background-color:DimGray; + border-radius:10px; +} +div.sideCar { + font-size:0.75rem; + padding: 20px; + position:absolute; + top:0; + left:0; + width:20%; + height:100%; + overflow-y:auto; +} +div.sideCar > div { + margin-bottom:20px; +} +div.buttons { + padding: 20px; + position:absolute; + top:80%; + left:30%; + width:40%; + height:20%; + text-align:center; +} +div.buttons > div { + margin:0px 20px 0px 20px; + background-color: Orange; + border: 0px solid transparent; + border-radius:5px; + min-width:35%; + display:inline-block; + padding:10px; + transition: background-color 1s ease; +} +div.buttons > div:hover { + background-color: OrangeRed; +} +div.point { + position:absolute; + width:6px; + height:6px; + border-radius:100%; + transform:translate(-50%,-50%); + background-color: Orange; + box-shadow:0px 0px 30px 30px Orange; + transition: box-shadow 1.5s ease; +} +.github-corner:hover .octo-arm{ + animation:octocat-wave 560ms ease-in-out +} +@keyframes octocat-wave{ + 0%,100% { + transform:rotate(0) + } + 20%,60% { + transform:rotate(-25deg) + } + 40%,80% { + transform:rotate(10deg) + } +} +@media (max-width:500px){ + .github-corner:hover .octo-arm{animation:none}.github-corner .octo-arm{ + animation:octocat-wave 560ms ease-in-out + } +} \ No newline at end of file