Created
October 25, 2016 15:41
-
-
Save JoeAlamo/e3c1718cd0440c309e4de62c7fbd1966 to your computer and use it in GitHub Desktop.
Demo of interactive visio topology
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html lang="en"> | |
<head> | |
<meta charset="UTF-8"> | |
<title>Ocucon Camera Topology Demo</title> | |
<style> | |
#topology-container { | |
width: 700px; | |
height: 495px; | |
margin-bottom: 40px; | |
} | |
rect:hover { | |
cursor: pointer; | |
} | |
</style> | |
<!-- Latest compiled and minified CSS --> | |
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous"> | |
<!-- Optional theme --> | |
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap-theme.min.css" integrity="sha384-rHyoN1iRsVXV4nD0JutlnGaslCJuC7uwjduW9SVrLvRYooPp2bWYgmgJQIXwl/Sp" crossorigin="anonymous"> | |
</head> | |
<body> | |
<div class="container"> | |
<div class="row"> | |
<div class="col-xs-8 col-xs-offset-2"> | |
<header> | |
<h2 id="mode-title">View Mode</h2> | |
<div class="row"> | |
<button id="mode-edit" class="btn btn-primary">Edit</button> | |
<button class="btn btn-default pull-right edit-mode-controls" data-toggle="modal" data-target="#add-camera-modal">Add Camera</button> | |
</div> | |
</header> | |
<div id="topology-container"> | |
<svg id="visio-svg" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 700 495" > | |
<image width="700" height="495" xlink:href="visio.png"> | |
</image> | |
</svg> | |
</div> | |
<div class="edit-mode-controls"> | |
<div class="row"> | |
<div class="col-xs-6"> | |
<button id="edit-cancel" class="btn btn-danger pull-left">Cancel</button> | |
</div> | |
<div class="col-xs-6"> | |
<button id="edit-save" class="btn btn-success pull-right">Save</button> | |
</div> | |
</div> | |
</div> | |
<p>Double click on a created camera to either edit or view it.</p> | |
</div> | |
</div> | |
<div class="modal fade" id="add-camera-modal" tabindex="-1" role="dialog" aria-labelledby="add-camera-modal-label"> | |
<div class="modal-dialog" role="document"> | |
<div class="modal-content"> | |
<div class="modal-header"> | |
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button> | |
<h4 class="modal-title" id="add-camera-modal-label">Select a camera</h4> | |
</div> | |
<div class="modal-body"> | |
<label for="add-camera-select">Select which camera you would like to add</label> | |
<select id="add-camera-select" name="add-camera-select"> | |
<option value="1" selected>1</option> | |
<option value="2">2</option> | |
<option value="3">3</option> | |
<option value="4">4</option> | |
<option value="5">5</option> | |
</select> | |
<p><i>Show most recent footage here for selected camera</i></p> | |
<p>Once you have added the camera, drag it to its location in the store.</p> | |
<p>Double click a camera to edit it.</p> | |
</div> | |
<div class="modal-footer"> | |
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button> | |
<button type="button" id="add-camera" class="btn btn-primary">Add camera</button> | |
</div> | |
</div> | |
</div> | |
</div> | |
<div class="modal fade" id="edit-camera-modal" tabindex="-1" role="dialog" aria-labelledby="edit-camera-modal-label"> | |
<div class="modal-dialog" role="document"> | |
<div class="modal-content"> | |
<div class="modal-header"> | |
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button> | |
<h4 class="modal-title" id="edit-camera-modal-label">Edit camera</h4> | |
</div> | |
<div class="modal-body"> | |
<input type="hidden" id="local-camera-id"> | |
<label for="edit-camera-select">Change the camera</label> | |
<select id="edit-camera-select" name="edit-camera-select"> | |
<option value="1">1</option> | |
<option value="2">2</option> | |
<option value="3">3</option> | |
<option value="4">4</option> | |
<option value="5">5</option> | |
</select> | |
<p>Show most recent footage here for selected camera</p> | |
</div> | |
<div class="modal-footer"> | |
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button> | |
<button type="button" id="edit-camera" class="btn btn-primary">Edit camera</button> | |
</div> | |
</div> | |
</div> | |
</div> | |
<div class="modal fade" id="view-camera-modal" tabindex="-1" role="dialog" aria-labelledby="view-camera-modal-label"> | |
<div class="modal-dialog" role="document"> | |
<div class="modal-content"> | |
<div class="modal-header"> | |
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button> | |
<h4 class="modal-title" id="view-camera-modal-label"></h4> | |
</div> | |
<div class="modal-body"> | |
<h3></h3> | |
<p>Show most recent footage here for selected camera</p> | |
</div> | |
<div class="modal-footer"> | |
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button> | |
</div> | |
</div> | |
</div> | |
</div> | |
</div><!-- CONTAINER --> | |
<script src="https://code.jquery.com/jquery-3.1.1.js" integrity="sha256-16cdPddA6VdVInumRGo6IbivbERE8p7CQR3HzTBuELA=" crossorigin="anonymous"></script> | |
<!-- Latest compiled and minified JavaScript --> | |
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/snap.svg/0.4.1/snap.svg.js"></script> | |
<script> | |
$(document).ready(function(e) { | |
if (typeof(Storage) === 'undefined') { | |
alert("HTML5 storage is required for this little demo :)"); | |
return false; | |
} | |
var EDIT_MODE = false; | |
var snap = Snap('#visio-svg'), | |
cameraTotal = 0; | |
var init = function () { | |
// Load previously saved cameras | |
if (localStorage.cameras !== undefined) { | |
initCameras(); | |
} | |
EDIT_MODE ? initEditMode() : initViewMode(); | |
}; | |
var initViewMode = function() { | |
EDIT_MODE = false; | |
$('#mode-title').text('View mode'); | |
$('#mode-edit').show(); | |
$('.edit-mode-controls').hide(); | |
$('rect[data-camera-id]').tooltip(); | |
}; | |
var initEditMode = function() { | |
EDIT_MODE = true; | |
$('#mode-title').text('Edit mode'); | |
$('#mode-edit').hide(); | |
$('.edit-mode-controls').show(); | |
$('rect[data-camera-id]').tooltip('destroy'); | |
}; | |
var initCameras = function() { | |
try { | |
var cameras = JSON.parse(localStorage.cameras); | |
$.each(cameras, function(key, camera) { | |
var rect = snap.rect(camera.x, camera.y, camera.width, camera.height); | |
rect.attr({ | |
'fill': '#000', | |
'fill-opacity': 0.4, | |
'stroke': 'black', | |
'transform': camera.transform, | |
'data-camera-id': camera.id, | |
'data-id': (++cameraTotal), | |
'data-toggle': 'tooltip', | |
'data-title': 'Camera ' + camera.id, | |
'data-container': 'body' | |
}); | |
rect.addClass('svg-camera'); | |
rect.drag(move, start); | |
rect.dblclick(click); | |
}) | |
} catch (e) { | |
console.log('Failed to parse local stored cameras'); | |
} | |
}; | |
$('#mode-edit').on('click', initEditMode); | |
$('#edit-cancel').on('click', initViewMode); | |
$('#edit-save').on('click', function () { | |
saveCameras(); | |
initViewMode(); | |
}); | |
$('#add-camera').on('click', function(e) { | |
var cameraId = $('#add-camera-select').val(); | |
var rect = snap.rect(25, 25, 20, 10); | |
rect.attr({ | |
'fill': '#000', | |
'fill-opacity': 0.4, | |
'stroke': 'black', | |
'data-camera-id': cameraId, | |
'data-id': (++cameraTotal), | |
'data-toggle': 'tooltip', | |
'data-title': 'Camera ' + cameraId, | |
'data-container': 'body' | |
}); | |
rect.addClass('svg-camera'); | |
rect.drag(move, start); | |
rect.dblclick(click); | |
$('#add-camera-modal').modal('hide'); | |
}); | |
var move = function(dx,dy) { | |
if (!EDIT_MODE) { | |
return; | |
} | |
this.attr({ | |
transform: this.data('origTransform') + (this.data('origTransform') ? "T" : "t") + [dx, dy] | |
}); | |
}; | |
var start = function() { | |
if (!EDIT_MODE) { | |
return; | |
} | |
this.data('origTransform', this.transform().local ); | |
}; | |
var click = function(e) { | |
EDIT_MODE ? showEditModal(e) : showViewModal(e); | |
}; | |
var saveCameras = function() { | |
// Iterate through rect objects in svg canvas | |
var cameraRects = $('#visio-svg>rect.svg-camera'), | |
cameras = []; | |
// Save data-camera-id and x,y,transform | |
cameraRects.each(function (index, element) { | |
var el = $(element); | |
cameras.push({ | |
'id': el.attr('data-camera-id'), | |
'x': el.attr('x'), | |
'y': el.attr('y'), | |
'width': el.attr('width'), | |
'height': el.attr('height'), | |
'transform': el.attr('transform') | |
}) | |
}); | |
// Save to local storage | |
localStorage.cameras = JSON.stringify(cameras); | |
}; | |
var showEditModal = function (e) { | |
var editModal = $('#edit-camera-modal'), | |
cameraId = $(e.target).attr('data-camera-id'), | |
localCameraId = $(e.target).attr('data-id'), | |
cameraSelect = editModal.find('#edit-camera-select'); | |
cameraSelect.val(cameraId); | |
editModal.find('#local-camera-id').val(localCameraId); | |
editModal.modal('show'); | |
}; | |
var showViewModal = function (e) { | |
var viewModal = $('#view-camera-modal'), | |
cameraId = $(e.target).attr('data-camera-id'); | |
viewModal.find('#view-camera-modal-label').text('Camera ' + cameraId); | |
viewModal.find('.modal-body>h3').text('Viewing camera ' + cameraId); | |
viewModal.modal('show'); | |
}; | |
$('#edit-camera-modal #edit-camera').on('click', function () { | |
var localId = $('#edit-camera-modal').find('#local-camera-id').val(); | |
var cameraId = $('#edit-camera-modal').find('#edit-camera-select').val(); | |
$('#visio-svg').find('rect[data-id="' + localId + '"]').attr({ | |
'data-camera-id': cameraId, | |
'data-original-title': 'Camera ' + cameraId | |
}); | |
$('#edit-camera-modal').modal('hide'); | |
}); | |
init(); | |
}); | |
</script> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment