diff --git a/render/index.html b/render/index.html
index 8ede8db..cdfbf99 100644
--- a/render/index.html
+++ b/render/index.html
@@ -1,124 +1,15 @@
- Terminalizer
+ Renderer
-
-
-
+
+
-
-
-
-
-
-
-
-
-
-
-
diff --git a/render/index.js b/render/index.js
index 064d443..c040a13 100644
--- a/render/index.js
+++ b/render/index.js
@@ -11,9 +11,19 @@ var path = require('path'),
ipcMain = require('electron').ipcMain,
os = require('os');
-// Set as global to be read by the web page
+/**
+ * The step option
+ * To reduce the number of rendered frames (step > 1)
+ * @type {Number}
+ */
global.step = process.argv[2] || 1;
+/**
+ * The temporary rendering directory's path
+ * @type {String}
+ */
+global.renderDir = path.join(__dirname, 'frames');
+
// Set the display scale factor to 1
app.commandLine.appendSwitch('force-device-scale-factor', 1);
@@ -55,10 +65,11 @@ ipcMain.on('captured', function(event, recordIndex) {
* A callback function for the event:
* When something unexpected happened
*
- * @param {String} errorMsg
+ * @param {Object} event
+ * @param {String} error
*/
-ipcMain.on('error', function(errorMsg) {
+ipcMain.on('error', function(event, error) {
- console.error(errorMsg);
+ process.stderr.write(error);
});
diff --git a/render/src/css/app.css b/render/src/css/app.css
new file mode 100644
index 0000000..008248b
--- /dev/null
+++ b/render/src/css/app.css
@@ -0,0 +1,15 @@
+/**
+ * Terminalizer
+ *
+ * @author Mohammad Fares
+ */
+
+body {
+ background-color: white;
+ margin: 0;
+}
+
+#terminal {
+ display: inline-block;
+ font-size: 0px;
+}
diff --git a/render/src/js/app.js b/render/src/js/app.js
new file mode 100644
index 0000000..82ce993
--- /dev/null
+++ b/render/src/js/app.js
@@ -0,0 +1,127 @@
+/**
+ * Terminalizer
+ *
+ * @author Mohammad Fares
+ */
+
+var fs = require('fs'),
+ path = require('path'),
+ async = require('async'),
+ remote = require('electron').remote,
+ ipcRenderer = require('electron').ipcRenderer,
+ terminalizerPlayer = require('terminalizer-player');
+var currentWindow = remote.getCurrentWindow(),
+ capturePage = currentWindow.webContents.capturePage,
+ step = remote.getGlobal('step'),
+ renderDir = remote.getGlobal('renderDir');
+
+// Styles
+import '../css/app.css';
+import 'terminalizer-player/dist/css/terminalizer.min.css';
+import 'xterm/dist/xterm.css';
+
+/**
+ * Used for the step option
+ * @type {Number}
+ */
+var stepsCounter = 0;
+
+/**
+ * A callback function for the event:
+ * When the document is loaded
+ */
+$(document).ready(function() {
+
+ // Initialize the terminalizer plugin
+ $('#terminal').terminalizer({
+ recordingFile: 'data.json',
+ autoplay: true,
+ controls: false,
+ });
+
+ /**
+ * A callback function for the event:
+ * When the terminal playing is started
+ */
+ $('#terminal').on('playingStarted', function() {
+
+ var terminalizer = $('#terminal').data('terminalizer');
+ var framesCount = terminalizer.getFramesCount();
+ var tasks = [];
+
+ terminalizer.pause();
+
+ for (var i = 0; i < framesCount; i++) {
+
+ (function(frameIndex) {
+
+ tasks.push(function(callback) {
+
+ terminalizer._applySnapshot(terminalizer._snapshots[frameIndex]);
+
+ // A workaround delay to allow rendering
+ setTimeout(function() {
+ capture(frameIndex, callback);
+ }, 20);
+
+ });
+
+ }(i));
+
+ }
+
+ async.series(tasks, function(error, result) {
+
+ if (error) {
+ throw new Error(error);
+ }
+
+ currentWindow.close();
+
+ });
+
+ });
+
+});
+
+/**
+ * Capture the current frame
+ *
+ * @param {Number} frameIndex
+ * @param {Function} callback
+ */
+function capture(frameIndex, callback) {
+
+ var width = $('#terminal').width();
+ var height = $('#terminal').height();
+ var captureRect = {x: 0, y: 0, width: width, height: height};
+
+ if (stepsCounter != 0) {
+ stepsCounter = (stepsCounter + 1) % step;
+ return callback();
+ }
+
+ stepsCounter = (stepsCounter + 1) % step;
+
+ capturePage(captureRect, function(img) {
+
+ var outputPath = path.join(renderDir, frameIndex + '.png');
+
+ fs.writeFileSync(outputPath, img.toPNG());
+ ipcRenderer.send('captured', frameIndex);
+ callback();
+
+ });
+
+}
+
+/**
+ * Catch all unhandled errors
+ *
+ * @param {String} error
+ */
+window.onerror = function(error) {
+
+ ipcRenderer.send('error', error);
+
+};