fixing the drawing tool
authorHarris Baptiste <harris.baptiste@iri.centrepompidou.fr>
Wed, 15 Jun 2016 18:34:15 +0200
changeset 17 ad201ca2f0e8
parent 15 63b29f1370c1
child 18 71cc29b47aba
fixing the drawing tool
src/iconolab/static/iconolab/css/iconolab.css
src/iconolab/static/iconolab/js/components/cutout/index.js
src/iconolab/static/iconolab/js/dist/bundle.js
src/iconolab/templates/iconolab/fragment_draw.html
src/iconolab/templates/iconolab_base.html
--- a/src/iconolab/static/iconolab/css/iconolab.css	Mon Jun 13 17:33:11 2016 +0200
+++ b/src/iconolab/static/iconolab/css/iconolab.css	Wed Jun 15 18:34:15 2016 +0200
@@ -4,4 +4,5 @@
 
 .form-drawing {border-bottom: 1px solid #C3C3C3; }
 
-.form-drawing-wrapper .selected {border: 1px solid orange; color: white; background-color: orange}
\ No newline at end of file
+.form-drawing-wrapper .selected {border: 1px solid orange; color: white; background-color: orange}
+.showPointer {cursor: pointer;}
\ No newline at end of file
--- a/src/iconolab/static/iconolab/js/components/cutout/index.js	Mon Jun 13 17:33:11 2016 +0200
+++ b/src/iconolab/static/iconolab/js/components/cutout/index.js	Wed Jun 15 18:34:15 2016 +0200
@@ -15,7 +15,9 @@
 });
 
 var paper = null;
+var mainImage = null;
 var pointData = [];
+var viewBoxBounds = {X: 100, Y:100};
 var config = null;
 var readOnly = false;
 var startPoint = null;
@@ -264,6 +266,7 @@
 	/* add resizer */
 
 	paper.mousedown(function (e) {
+
 		if (drawingMode === FREE_MODE || pathIsClosed) { return; }
 		startPosition.x = e.offsetX;
 		startPosition.y = e.offsetY;
@@ -271,6 +274,7 @@
 	});
 
 	paper.mousemove(function (e) {
+		console.log("icic. ... ");
 		if (drawingMode === FREE_MODE) { return; }
 		if (!canDraw) { return; }
 		var x, y;
@@ -360,6 +364,11 @@
 		}
 	},
 
+	transform: function () {
+
+	},
+
+
 	setDrawingMode: function (mode) {
 		if (availableModes.indexOf(mode) !== -1) {
 			drawingMode = mode;
@@ -379,7 +388,6 @@
 		 if (drawing_path) {
 
 		 	console.log(drawingMode);
-		 	alert("rads");
 		 	if (drawingMode === RECT_MODE) {
 		 		alert("radical ... ");
 		 		console.log("radical ... ");
@@ -412,21 +420,17 @@
 				path = drawing_path.attr('d');
 			}
 		}
-		/* save path should be normalized */
-		//taille/10
-		var xRatio = 1/7;
-		var yRatio = 1/4.3;
-		var transformMatrix = Snap.matrix(xRatio.toFixed(2), 0, 0, yRatio.toFixed(2), 0, 0);
-		console.log(transformMatrix);
-		console.log(path);
-		newPath = Snap.path.map(path,transformMatrix).toString();
-		console.log(newPath);
-		test = paper.path(newPath);
-		console.log(test);
-		//should be normalize
 
-		//[sx 0 0 sy 0 0]. One unit in the X and Y directions in the new coordinate system equals sx and sy units in the previous coordinate system, respectively.
+		var xRatio = viewBoxBounds.X / paper.node.clientWidth;
+		var yRatio = viewBoxBounds.Y / paper.node.clientHeight;
+		
+		if(isNaN(xRatio) || isNaN(yRatio)) {
+			new Error('Ratio should be a number.');
+		}
 
+		var normalizeMatrix = Snap.matrix(xRatio, 0, 0, yRatio, 0, 0);
+		path = Snap.path.map(path, normalizeMatrix).toString();
+		path += ";" + drawingMode;
 		return path;
 	}
 };
@@ -445,7 +449,6 @@
 		
 		if (!cutCanvas.length) {
 			var cutCanvas = jQuery('<svg version="1.1"></svg>').addClass('cut-canvas');
-			cutCanvas.css({border: "1px solid red"});
 			jQuery(config.wrapperId).append(cutCanvas);
 		}
 
--- a/src/iconolab/static/iconolab/js/dist/bundle.js	Mon Jun 13 17:33:11 2016 +0200
+++ b/src/iconolab/static/iconolab/js/dist/bundle.js	Wed Jun 15 18:34:15 2016 +0200
@@ -85,13 +85,19 @@
 	});
 
 	var paper = null;
+	var mainImage = null;
 	var pointData = [];
+	var viewBoxBounds = {X: 100, Y:100};
 	var config = null;
+	var readOnly = false;
 	var startPoint = null;
 	var drawing_path = null;
 	var canDraw = false;
 	var rectZone = null;
 	var PATH_COLOR = "#ff00ff";
+	var READ_ONLY_STOKE = "";
+	var READ_ONLY_FILL = "";
+
 	var SELECTED_COLOR = "#ffff00";
 	var FIRST_NODE_COLOR = "#FF0000";
 	var HANDLE_SIZE = 6;
@@ -102,6 +108,7 @@
 	var RECT_MODE ='RECT';
 	var drawingMode = RECT_MODE; //free
 	var FREE_MODE = 'FREE';
+	var availableModes = [RECT_MODE, FREE_MODE];
 
 	var getId = (function () {
 			var cpt = 0;
@@ -113,10 +120,56 @@
 			}
 		}());
 
+
+
 	var pathToPoint = function (path) {
-		if (typeof path === "string") { return false; }
+
+	};
+
+	var handleRectPath = function (path) {
+		if (readOnly) {
+			paper.path(path).attr({ stroke:'red', opacity: 0.6});
+			return;
+		}
+
+		var pathInfos = Snap.parsePathString(path);
+		drawing_path = paper.path(path);
+		drawing_path.attr({stroke:'white', opacity: 0.4});
+		handlePathClosed();
 	};
 
+	var handlePathClosed = function () {
+		if (drawing_path) {
+			drawing_path.drag();
+		}
+	}
+
+	var handleFreePath = function (path) {
+
+		if (readOnly) {
+			
+			paper.path(path).attr({
+				stoke: 'orange',
+				fill: 'orange',
+				opacity: 0.5,
+			});
+
+			return; 
+		}
+
+		var pathInfos = Snap.parsePathString(path);
+		pathInfos.map(function (pathData) {
+			if(pathData[0] !== 'Z') {
+				createPoint(paper, pathData[1], pathData[2], pointData);
+			} else {
+				pathIsClosed = true;
+				updatePath(paper, onClosePath);
+			}
+		});
+
+		/* replay the path here */
+
+	}; 
 	//transform point to path
 	var updatePath = function (paper, updateCallback) {
 		var path = "M";
@@ -125,10 +178,6 @@
 			return;
 		}
 
-		/*if (pathIsClosed) {
-			pointData.pop(); 
-		}*/
-
 		path += pointData[0].x + ',' + pointData[0].y;
 
 		for (var i=0; i < pointData.length; i++) {
@@ -280,11 +329,14 @@
 
 
 	var attachRectEvents = function (paper) {
+		if (readOnly) { return false; }
+
 		var startPosition = {};
 		var currentPosition = {};
 		/* add resizer */
 
 		paper.mousedown(function (e) {
+
 			if (drawingMode === FREE_MODE || pathIsClosed) { return; }
 			startPosition.x = e.offsetX;
 			startPosition.y = e.offsetY;
@@ -292,6 +344,7 @@
 		});
 
 		paper.mousemove(function (e) {
+			console.log("icic. ... ");
 			if (drawingMode === FREE_MODE) { return; }
 			if (!canDraw) { return; }
 			var x, y;
@@ -337,13 +390,14 @@
 		paper.mouseup(function () {
 			if ((drawingMode === FREE_MODE) || pathIsClosed || !rectZone) { return false; }
 			rectZone.drag();
+			drawing_path = rectZone;
 			canDraw = false;
 			pathIsClosed = true;
 		});
 	};
 
 	var attachPointEvents = function (paper) {
-
+		if (readOnly) { return; }
 		paper.click( function(e) {
 			if (drawingMode === RECT_MODE) {
 				return true;
@@ -356,10 +410,37 @@
 
 	var API = {
 		
-		setMode: function (mode) {
-			var availableMode = ['RECT', 'FREE'];
-			console.log("undefined", mode);
-			if (availableMode.indexOf(mode) !== -1) {
+		setPath: function (pathString) {
+			/* redraw the path */
+			var pathInfos = pathString.split(';');
+			if( availableModes.indexOf(pathInfos[1]) === -1) {
+				new Error("drawing mode: [" + pathInfos[1] + "] is not available");
+			}
+
+			this.setDrawingMode(pathInfos[1]);
+			if (pathInfos.length === 1) {
+				new Error("A drawing mode must be provided");
+			}
+
+			if (pathInfos.length >= 2) {
+				var path = pathInfos[0];
+				if (pathInfos[1] === RECT_MODE) {
+					handleRectPath(path);
+				}
+				
+				if (pathInfos[1] === FREE_MODE) {
+					handleFreePath(path);
+				}
+			}
+		},
+
+		transform: function () {
+
+		},
+
+
+		setDrawingMode: function (mode) {
+			if (availableModes.indexOf(mode) !== -1) {
 				drawingMode = mode;
 			}
 			this.clear();
@@ -375,12 +456,18 @@
 
 			/*clear path is exists*/
 			 if (drawing_path) {
+
+			 	console.log(drawingMode);
+			 	if (drawingMode === RECT_MODE) {
+			 		alert("radical ... ");
+			 		console.log("radical ... ");
+			 		console.log(drawing_path.getBBox().path.toString());
+			 	}
+			 	//drawing_path.getBBox().path.toString()
 			 	drawing_path.remove();
-			 }
-
-			 if (rectZone) {
-			 	rectZone.remove();
-			 }
+			 }		
+			 
+
 
 			pointData = [];
 			startPoint = null;
@@ -389,13 +476,32 @@
 			enablePoint = true;
 			pathIsClosed = false;
 			ENABLE_NEW_NODE = true;
-			/* clear path */
-
 		},
 
 		getPath: function () {
 			/* retourne le chemin */
-			console.log();
+			/* send path and BBox | implement edit and load path */
+			var path = "";
+			if (drawing_path) {
+				if (drawingMode === RECT_MODE) {
+					path = Snap.path.toAbsolute(drawing_path.getBBox().path).toString();
+				}
+				else {
+					path = drawing_path.attr('d');
+				}
+			}
+
+			var xRatio = viewBoxBounds.X / paper.node.clientWidth;
+			var yRatio = viewBoxBounds.Y / paper.node.clientHeight;
+			
+			if(isNaN(xRatio) || isNaN(yRatio)) {
+				new Error('Ratio should be a number.');
+			}
+
+			var normalizeMatrix = Snap.matrix(xRatio, 0, 0, yRatio, 0, 0);
+			path = Snap.path.map(path, normalizeMatrix).toString();
+			path += ";" + drawingMode;
+			return path;
 		}
 	};
 
@@ -413,13 +519,13 @@
 			
 			if (!cutCanvas.length) {
 				var cutCanvas = jQuery('<svg version="1.1"></svg>').addClass('cut-canvas');
-				cutCanvas.css({border: "1px solid red"});
 				jQuery(config.wrapperId).append(cutCanvas);
 			}
 
 			if (!mainImage) {
 				new Error(config.wrapperId + "Can't be found ...");
 			}
+
 			cutCanvas.css({
 				position: 'absolute', 
 				top: '0px', 
@@ -427,9 +533,14 @@
 				marginLeft: 'auto',
 				marginRight: 'auto',
 				width: mainImage.width(),
-				height: mainImage.height()
+				height: mainImage.height(),
+				viewBox: '0 0 100 100'
 			});
 
+			if (typeof config.readOnly === 'boolean' && config.readOnly === true) {
+				readOnly = true;
+			}
+
 			paper = new Snap(cutCanvas.get(0));
 
 			/* handle drawin here */
@@ -444,7 +555,7 @@
 /* 2 */
 /***/ function(module, exports, __webpack_require__) {
 
-	var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_LOCAL_MODULE_0__;/*** IMPORTS FROM imports-loader ***/
+	var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_LOCAL_MODULE_0__;var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/*** IMPORTS FROM imports-loader ***/
 	(function() {
 	var fix = module.exports=0;
 
@@ -28498,6 +28609,11 @@
 	// shim for using process in browser
 
 	var process = module.exports = {};
+
+	// cached from whatever global is present so that test runners that stub it don't break things.
+	var cachedSetTimeout = setTimeout;
+	var cachedClearTimeout = clearTimeout;
+
 	var queue = [];
 	var draining = false;
 	var currentQueue;
@@ -28522,7 +28638,7 @@
 	    if (draining) {
 	        return;
 	    }
-	    var timeout = setTimeout(cleanUpNextTick);
+	    var timeout = cachedSetTimeout(cleanUpNextTick);
 	    draining = true;
 
 	    var len = queue.length;
@@ -28539,7 +28655,7 @@
 	    }
 	    currentQueue = null;
 	    draining = false;
-	    clearTimeout(timeout);
+	    cachedClearTimeout(timeout);
 	}
 
 	process.nextTick = function (fun) {
@@ -28551,7 +28667,7 @@
 	    }
 	    queue.push(new Item(fun, args));
 	    if (queue.length === 1 && !draining) {
-	        setTimeout(drainQueue, 0);
+	        cachedSetTimeout(drainQueue, 0);
 	    }
 	};
 
--- a/src/iconolab/templates/iconolab/fragment_draw.html	Mon Jun 13 17:33:11 2016 +0200
+++ b/src/iconolab/templates/iconolab/fragment_draw.html	Wed Jun 15 18:34:15 2016 +0200
@@ -4,84 +4,99 @@
 
 {% load thumbnail %}
 
-
-{% block page_js %}
-	<script src="{% static 'iconolab/js/dist/bundle.js' %}" type="text/javascript"></script>
-{% endblock%}
-
 {% block content %}
-	<div id="drawing-zone" style="padding-top: 10px">
-
-		<p class="pullright"><a href='javascript:;'>Retour</a></p>
-		<div class='col-md-2'>
-			<ul class='form-drawing-wrapper list-inline'>
-				<p class='form-drawing pullright'><strong>Type de sélection</strong></p>
-				<li @click="setRectangleMode" v-bind:class="{ 'selected': isRect }" class='pull-md-left drawingModeBtn'>Rect.</li>
-				<li @click="setFreeMode" v-bind:class="{ 'selected': !isRect }" class='pull-md-left drawingModeBtn'>Libre</li>
-			</ul>
-
-			<ul class='form-drawing-wrapper list-inline'>
-				<p class='form-drawing pullright'><strong>Actions</strong></p>
-				
-				<li @click="clear" class='pull-md-left drawingModeBtn'><i class='fa fa-trash'></i> Effacer</li>
-
-				<li @click="save" class='pull-md-left drawingModeBtn'><i class='fa fa-plus'></i> Créer une annotation</li>
-				<li @click="showPreview" class='pull-md-left drawingModeBtn'><i class='fa fa-eye'></i> Prévisualiser</li>
-			</ul>
+	<div id="drawing-zone" class="row" style="padding-top: 10px; border:1px solid red">
+		
+		<div v-show='!formView' class="editor-wrapper col-md-12">
+			<div class='col-md-2'>
+				<ul class="form-drawing-wrapper list-inline">
+					<p class='form-drawing pullright'><strong>Type de dessin</strong></p>
+					<li @click="setRectangleMode" v-bind:class="{ 'selected': isRect }" class='pull-md-left drawingModeBtn'>Rect.</li>
+					<li @click="setFreeMode" v-bind:class="{ 'selected': !isRect }" class='pull-md-left drawingModeBtn'>Libre</li>
+				</ul>
 
-			<form v-el:form-fragment id='fragment-form' method='GET' target="{% url 'annotation_create' %}">
-				{% csrf_token %}
-				<input name="fragmentPath" type="hidden" v-model="normalizePath"></input>
-			</form>
-
-		</div>
-			
-		<div class="col-md-8">
+				<ul class='form-drawing-wrapper list-inline'>
+					<p class='form-drawing pullright'><strong>Actions</strong></p>
+					
+					<li @click="clear" class='pull-md-left drawingModeBtn'><i class='fa fa-trash'></i> Effacer</li>
 
-			<div id="iconolab-image-wrapper">
-				{% thumbnail annotation.image.media "x800" crop="center" as im %}
-    				<img src="{{ im.url }}" width="{{ im.width }}" height="{{ im.height }}">
-				{% endthumbnail %}
+					<li @click="save" class='pull-md-left drawingModeBtn'><i class='fa fa-plus'></i> Créer le fragment</li>
+				</ul>
 			</div>
-
-			<div class='row' style='padding-top:10px'>
-
-				<div class='image-item col-xs-4'>
-				{% thumbnail annotation.image.media "x100" crop="center" as im %}
-    				<img src="{{ im.url }}" width="{{ im.width }}" height="{{ im.height }}">
-				{% endthumbnail %}
-				</div>
-				
-				<div class='image-item col-xs-4'>
-					{% thumbnail annotation.image.media "x150" crop="center" as im %}
-    					<img src="{{ im.url }}" width="{{ im.width }}" height="{{ im.height }}">
+			
+			<div class="col-md-8">
+				<div v-el:image id="iconolab-image-wrapper">
+					{% thumbnail annotation.image.media "x800" crop="center" as im %}
+	    				<img src="{{ im.url }}" width="{{ im.width }}" height="{{ im.height }}">
 					{% endthumbnail %}
 				</div>
-									
-				<div class='image-item col-xs-4'>
-					{% thumbnail annotation.image.media "x200" crop="center" as im %}
-    					<img src="{{ im.url }}" width="{{ im.width }}" height="{{ im.height }}">
-					{% endthumbnail %}
-				</div>
-
-				<div class='image-item col-xs-4'>
-					{% thumbnail annotation.image.media "x250" crop="center" as im %}
-    					<img src="{{ im.url }}" width="{{ im.width }}" height="{{ im.height }}">
-					{% endthumbnail %}
-				</div>
-
 			</div>
 
 		</div>
 
-		<div class='col-md-2'>
-			<div id='action-wrapper' style='display: none'>
-				<a class='btn btn-link create'>> Créer le fragment</a>
-				<a class='btn btn-link delete'>> Effacer la zone</a>
+		<div v-show="formView" class="col-md-12">
+			
+			<div class="col-xs-6">
+				<div class="small-image-wrapper" style="position: relative">
+					{% thumbnail annotation.image.media "x300" crop="center" as im %}
+						<img v-el:small-image @click="showEditor" src="{{ im.url }}" width="{{ im.width }}" height="{{ im.height }}">
+
+						<svg width="{{ im.width }}" height="{{ im.height }}" version="1.1" style="position:absolute; top:0px; left: 0px">
+							
+							<defs>
+								<mask xmlns="http://www.w3.org/2000/svg" id="smallImage">
+									<rect x="0" y="0" width="{{ im.width }}", height="{{ im.height }}" fill="white"/>
+									<g v-bind:transform="transformMatrix">
+										<path v-bind:d="fragmentPath"></path>
+									</g>
+								</mask>	
+							</defs>
+
+							<g v-show="!displayMask" v-bind:transform="transformMatrix">
+								<path v-bind:d="fragmentPath" opacity="0.7" fill="orange"></path>
+							</g>
+
+							<rect v-show="displayMask" v-el:small-mask x="0" y="0" mask="url(#smallImage)" opacity="0.7" fill="white" width="{{ im.width }}" height="{{ im.height }}"></rect>
+						</svg>
+						
+					{% endthumbnail %}
+				</div>
+				<ul class="inline">
+				<a @click="showEditor" class="showPointer"> <i class='fa fa-edit'></i> Editer le fragment</a>
+				<a v-show="!displayMask" @click="highLightZone" class="showPointer"> <i class='fa fa-eye-slash'></i>Masquer l'image</a>
+				<a v-show="displayMask" @click="highLightZone(1)" class="showPointer"> <i class='fa fa-eye-slash'></i>Afficher la zone</a>
+
+				</ul>
+			</div>
+
+			<div class='col-xs-6' style="">
+				<form>
+				  
+				  <fieldset class="form-group">
+				    <label for="formGroupExampleInput">Titre</label>
+				    <input type="text" class="form-control" id="formGroupExampleInput" placeholder="Titre">
+				  </fieldset>
+				  
+				  <fieldset class="form-group">
+				    <label for="formGroupExampleInput2">Description</label>
+				    <textarea></textarea>
+				  </fieldset>
+
+				  <fieldset class="form-group">
+				    <label for="formGroupExampleInput2">Tags</label>
+				  </fieldset>
+
+				    <div class="form-group pull-right">
+				    	<button type="submit" class="btn btn-default">Envoyer</button>
+				    	<button type="submit" class="btn btn-default">Annuler</button>
+				    </div>
+
+				</form>
+
 			</div>
 		</div>
+	</div>
 
-	</div>
 {% endblock %}
 
 {% block footer_js %}
@@ -95,24 +110,23 @@
 				mode:"",
 				isRect: true,
 				normalizePath: "",
-				readOnly: false
+				readOnly: false,
+				formView: false,
+				useClipPath: false,
+				transformMatrix: "",
+				fragmentPath: "",
+				displayMask: false
+
 			},
 
 			init: function () {
 				//this.mode = this.$options.MODE_RECT;
-				this.drawingComponent = iconolab.initCutoutComponent({ 
+				var self = this;
+				self.drawingComponent = iconolab.initCutoutComponent({ 
 					wrapperId: '#iconolab-image-wrapper',
- 					actionWrapper: '#action-wrapper',
- 					readOnly: false 
-				}); 
-
-				this.drawingComponent.setDrawingMode(this.mode);
-				//var rectPath = "M173,101L319,101L319,224L173,224Z;RECT";
-				//var relPath = 'M137,62 L155,67 L163,77 L166,99 L161,113 L142,119 L129,114 L120,95 L116,79 L120,64 Z;FREE';
-				//var zonePath = "M236,111 L268,112 L293,146 L293,182 L280,215 L254,220 L229,212 L205,198 L210,175 L207,143 L215,123 Z;FREE";
-				//var transformMatrix = [];//en fonction de l'échelle
-
-				//this.drawingComponent.setPath(relPath);
+						actionWrapper: '#action-wrapper',
+						readOnly: false
+				}); 	
 			},
 
 			methods: {
@@ -121,9 +135,21 @@
 					this.mode = this.$options.MODE_RECT;
 					this.isRect = true;
 				},
-				
-				showPreview: function () {
-					
+
+				showEditor: function () {
+					this.formView = false;
+					console.log(this.$els.smallImage);
+				},
+
+				highLightZone: function () {
+					if (!this.displayMask) {
+						this.displayMask = true;
+					}
+					else {
+						this.displayMask = false;
+					}
+					//this.maskFill = "orange";
+					//this.fragmentFill = "none";
 				},
 
 				setFreeMode:  function () {
@@ -131,12 +157,24 @@
 					this.isRect = false;
 					this.drawingComponent.setDrawingMode(this.mode);
 				},
+				
+				displayEditedPath: function () {
+					/* path to save */
+					var normalizePath = this.drawingComponent.getPath();
+				},
 
 				save: function () {
-					console.log('drawingPath', this.drawingComponent.getPath());
 					this.normalizePath = this.drawingComponent.getPath();
-					console.log(this.normalizePath)
-					//this.$els.formFragment.submit();
+					var smallImage = this.$els.smallImage;
+					this.formView = true;
+					/* 100x = smallImageHeight && 100x=smallImageWidth | 100 = ViewBoxBound */
+					var xRatio = smallImage.width / 100;
+					var yRatio = smallImage.height / 100;
+					var transformMatrix = [xRatio, 0, 0, yRatio, 0, 0].join(',');
+					this.transformMatrix ="matrix(" + transformMatrix + ")";
+					this.fragmentPath = this.normalizePath.split(';')[0];
+					console.log(this.fragmentPath);
+					console.log(this.transformMatrix);
 				},
 
 				clear: function () {
--- a/src/iconolab/templates/iconolab_base.html	Mon Jun 13 17:33:11 2016 +0200
+++ b/src/iconolab/templates/iconolab_base.html	Wed Jun 15 18:34:15 2016 +0200
@@ -6,14 +6,15 @@
 	<head>
 		<title>{% block title %} {% endblock %}</title>
 		
-		{% block js %} {% endblock %}
-
+		{% block main_js %}
+			<script src="{% static 'iconolab/js/dist/bundle.js' %}" type="text/javascript"></script>
+		{% endblock %}
 		{% block page_js %} {% endblock %}
 
 		{% block main_css %}		
-		<link rel="stylesheet" href="{% static 'iconolab/js/node_modules/bootstrap/dist/css/bootstrap.min.css' %}">
-		<link rel="stylesheet" href="{% static 'iconolab/css/iconolab.css' %}">
-
+			<link rel="stylesheet" href="{% static 'iconolab/js/node_modules/bootstrap/dist/css/bootstrap.min.css' %}">
+			<link rel="stylesheet" href="{% static 'iconolab/js/node_modules/font-awesome/css/font-awesome.min.css' %}">
+			<link rel="stylesheet" href="{% static 'iconolab/css/iconolab.css' %}">
 		{% endblock %}
 		
 		{% block page_css %} {% endblock %}
@@ -24,7 +25,7 @@
 	<body>
 		<!-- navigation -->
 	    <div class="container">
-	    	{% include "partials/header.html" with person="Jane" greeting="Hello" %}
+	    	{% include "partials/header.html"%}
 			{% block content %} {% endblock %}
 	    </div>
 	    {% block footer_js %} {% endblock %}