working on printmanager + api improvements
This commit is contained in:
parent
1aa0417c33
commit
0c2f774376
11
Gruntfile.js
11
Gruntfile.js
|
@ -16,7 +16,7 @@ module.exports = function(grunt) {
|
|||
},
|
||||
js: {
|
||||
src: [
|
||||
'js/api/*.js',
|
||||
//'js/api/*.js',
|
||||
'js/settings/FormPanel.js',
|
||||
'js/settings/*.js',
|
||||
'js/*.js',
|
||||
|
@ -24,6 +24,10 @@ module.exports = function(grunt) {
|
|||
'!js/main.js',
|
||||
'js/main.js', ],
|
||||
dest: 'www/js/<%= pkg.name %>.js'
|
||||
},
|
||||
api: {
|
||||
src: [ 'js/api/*.js'],
|
||||
dest: 'www/js/doodle3d-api.js'
|
||||
}
|
||||
},
|
||||
uglify: {
|
||||
|
@ -37,7 +41,8 @@ module.exports = function(grunt) {
|
|||
},
|
||||
js: {
|
||||
files: {
|
||||
'www/js/<%= pkg.name %>.min.js' : ['www/js/<%= pkg.name %>.js']
|
||||
'www/js/<%= pkg.name %>.min.js' : ['www/js/<%= pkg.name %>.js'],
|
||||
'www/js/doodle3d-api.min.js' : ['www/js/doodle3d-api.js']
|
||||
}
|
||||
},
|
||||
jslibs: {
|
||||
|
@ -91,7 +96,7 @@ module.exports = function(grunt) {
|
|||
watch: {
|
||||
javascript: {
|
||||
files: ["js/**", '!www/js/<%= pkg.name %>.min.js', '!www/js/<%= pkg.name %>.js'],
|
||||
tasks: ["concat:js", "uglify:js"]
|
||||
tasks: ["concat:api", "concat:js", "uglify:js"],
|
||||
// tasks: ["jshint", "concat", "uglify"]
|
||||
},
|
||||
javascriptLibs: {
|
||||
|
|
|
@ -0,0 +1,64 @@
|
|||
/*
|
||||
* This file is part of the Doodle3D project (http://doodle3d.com).
|
||||
*
|
||||
* Copyright (c) 2013, Doodle3D
|
||||
* This software is licensed under the terms of the GNU GPL v2 or later.
|
||||
* See file LICENSE.txt or visit http://www.gnu.org/licenses/gpl.html for full license details.
|
||||
*/
|
||||
|
||||
var API = function() {
|
||||
|
||||
var _wifiboxURL = 'http://192.168.5.1/d3dapi/';
|
||||
var _wifiboxCGIBinURL = 'http://192.168.5.1/cgi-bin/d3dapi/';
|
||||
var _timeoutTime = 10000;
|
||||
|
||||
function post(cmd,data,success,fail) {
|
||||
$.ajax({
|
||||
url: _wifiboxURL + cmd,
|
||||
type: "POST",
|
||||
data: data,
|
||||
dataType: 'json',
|
||||
timeout: _timeoutTime,
|
||||
success: function(response){
|
||||
if(response.status == "error" || response.status == "fail") {
|
||||
console.log('API.post fail',cmd)
|
||||
if (fail) fail(response);
|
||||
} else {
|
||||
if (success) success(response.data);
|
||||
else console.log('API.post:',cmd,'success cb undefined')
|
||||
}
|
||||
}
|
||||
}).fail(function(jqXHR, textStatus) {
|
||||
console.log('API.post fail',cmd,jqXHR,textStatus);
|
||||
if (fail) fail(jqXHR,textStatus);
|
||||
});
|
||||
}
|
||||
|
||||
function get(cmd,success,fail) {
|
||||
$.ajax({
|
||||
url: _wifiboxURL + cmd,
|
||||
type: "GET",
|
||||
dataType: 'json',
|
||||
timeout: _timeoutTime,
|
||||
success: function(response){
|
||||
if (response.status == "error" || response.status == "fail") {
|
||||
console.log('API.get fail',cmd,response);
|
||||
if (fail) fail(response);
|
||||
} else {
|
||||
if (success) success(response.data);
|
||||
else console.log('API.get:',cmd,'success cb undefined')
|
||||
}
|
||||
}
|
||||
}).fail(function() {
|
||||
console.log('API.get fail',cmd);
|
||||
if (fail) fail();
|
||||
});
|
||||
}
|
||||
|
||||
return {
|
||||
get: get,
|
||||
post: post
|
||||
}
|
||||
|
||||
}();
|
||||
|
|
@ -8,92 +8,77 @@
|
|||
|
||||
function ConfigAPI() {
|
||||
|
||||
var _wifiboxURL;
|
||||
var _wifiboxCGIBinURL;
|
||||
var _timeoutTime = 3000;
|
||||
var _saveSettingsTimeoutTime = 8000;
|
||||
function loadAll(success,fail) {
|
||||
API.get('config/all',success,fail);
|
||||
};
|
||||
|
||||
var _self = this;
|
||||
function load(key,success,fail) {
|
||||
API.get('config/?'+key+'=',success,fail)
|
||||
};
|
||||
|
||||
this.init = function(wifiboxURL,wifiboxCGIBinURL) {
|
||||
//console.log("ConfigAPI:init");
|
||||
function save(newSettings,success,fail) {
|
||||
API.post('config',{data:newSettings},success,fail);
|
||||
};
|
||||
|
||||
_wifiboxURL = wifiboxURL;
|
||||
_wifiboxCGIBinURL = wifiboxCGIBinURL;
|
||||
}
|
||||
this.loadAll = function(completeHandler,failedHandler) {
|
||||
//console.log("ConfigAPI:loadAll");
|
||||
$.ajax({
|
||||
url: _wifiboxURL + "/config/all",
|
||||
type: "GET",
|
||||
dataType: 'json',
|
||||
timeout: _timeoutTime,
|
||||
success: function(response){
|
||||
if(response.status == "error" || response.status == "fail") {
|
||||
if(failedHandler) failedHandler(response);
|
||||
} else {
|
||||
completeHandler(response.data);
|
||||
}
|
||||
}
|
||||
}).fail(function() {
|
||||
if(failedHandler) failedHandler();
|
||||
});
|
||||
function resetAll(success,fail) {
|
||||
API.post('config/resetall',{},success,fail)
|
||||
};
|
||||
this.load = function(targetSettings,completeHandler,failedHandler) {
|
||||
//console.log("ConfigAPI:load");
|
||||
$.ajax({
|
||||
url: _wifiboxURL + "/config/",
|
||||
type: "GET",
|
||||
dataType: 'json',
|
||||
data: targetSettings,
|
||||
timeout: _timeoutTime,
|
||||
success: function(response){
|
||||
if(response.status == "error" || response.status == "fail") {
|
||||
if(failedHandler) failedHandler(response);
|
||||
} else {
|
||||
completeHandler(response.data);
|
||||
|
||||
function getSetting(key,success,fail) {
|
||||
API.get('config/?'+key+'=',function(response) {
|
||||
if (success) success(response[key]);
|
||||
},fail);
|
||||
}
|
||||
|
||||
function getStartCode(success,fail) {
|
||||
loadAll(function(data) {
|
||||
var startcode = subsituteVariables(data['printer.startcode'],data);
|
||||
if (success) success(startcode);
|
||||
},fail);
|
||||
}
|
||||
}).fail(function() {
|
||||
if(failedHandler) failedHandler();
|
||||
});
|
||||
};
|
||||
this.save = function(newSettings,completeHandler,failedHandler) {
|
||||
//console.log("ConfigAPI:save");
|
||||
$.ajax({
|
||||
url: _wifiboxCGIBinURL + "/config",
|
||||
type: "POST",
|
||||
data: newSettings,
|
||||
dataType: 'json',
|
||||
timeout: _saveSettingsTimeoutTime,
|
||||
success: function(response){
|
||||
//console.log("ConfigAPI:save response: ",response);
|
||||
if(response.status == "error" || response.status == "fail") {
|
||||
if(failedHandler) failedHandler(response);
|
||||
} else {
|
||||
completeHandler(response.data);
|
||||
|
||||
function getEndCode(success,fail) {
|
||||
loadAll(function(data) {
|
||||
var endcode = subsituteVariables(data['printer.endcode'],data);
|
||||
if (success) success(endcode);
|
||||
},fail);
|
||||
}
|
||||
|
||||
function subsituteVariables(gcode,settings) {
|
||||
//,temperature,bedTemperature,preheatTemperature,preheatBedTemperature
|
||||
var temperature = settings["printer.temperature"];
|
||||
var bedTemperature = settings["printer.bed.temperature"];
|
||||
var preheatTemperature = settings["printer.heatup.temperature"];
|
||||
var preheatBedTemperature = settings["printer.heatup.bed.temperature"];
|
||||
var printerType = settings["printer.type"];
|
||||
var heatedbed = settings["printer.heatedbed"];
|
||||
|
||||
switch (printerType) {
|
||||
case "makerbot_replicator2": printerType = "r2"; break;
|
||||
case "makerbot_replicator2x": printerType = "r2x"; break;
|
||||
case "makerbot_thingomatic": printerType = "t6"; break;
|
||||
case "makerbot_generic": printerType = "r2"; break;
|
||||
case "_3Dison_plus": printerType = "r2"; break;
|
||||
}
|
||||
}).fail(function() {
|
||||
if(failedHandler) failedHandler();
|
||||
});
|
||||
};
|
||||
this.resetAll = function(completeHandler,failedHandler) {
|
||||
//console.log("ConfigAPI:resetAll");
|
||||
$.ajax({
|
||||
url: _wifiboxCGIBinURL + "/config/resetall",
|
||||
type: "POST",
|
||||
dataType: 'json',
|
||||
timeout: _timeoutTime,
|
||||
success: function(response){
|
||||
if(response.status == "error" || response.status == "fail") {
|
||||
if(failedHandler) failedHandler(response);
|
||||
} else {
|
||||
completeHandler(response.data);
|
||||
var heatedBedReplacement = (heatedbed)? "" : ";";
|
||||
|
||||
gcode = gcode.replace(/{printingTemp}/gi ,temperature);
|
||||
gcode = gcode.replace(/{printingBedTemp}/gi ,bedTemperature);
|
||||
gcode = gcode.replace(/{preheatTemp}/gi ,preheatTemperature);
|
||||
gcode = gcode.replace(/{preheatBedTemp}/gi ,preheatBedTemperature);
|
||||
gcode = gcode.replace(/{printerType}/gi ,printerType);
|
||||
gcode = gcode.replace(/{if heatedBed}/gi ,heatedBedReplacement);
|
||||
|
||||
return gcode;
|
||||
}
|
||||
|
||||
return {
|
||||
loadAll: loadAll,
|
||||
load: load,
|
||||
save: save,
|
||||
resetAll: resetAll,
|
||||
getSetting: getSetting,
|
||||
getStartCode: getStartCode,
|
||||
getEndCode: getEndCode,
|
||||
}
|
||||
}).fail(function() {
|
||||
if(failedHandler) failedHandler();
|
||||
});
|
||||
};
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
/*
|
||||
* This file is part of the Doodle3D project (http://doodle3d.com).
|
||||
*
|
||||
* Copyright (c) 2013, Doodle3D
|
||||
* This software is licensed under the terms of the GNU GPL v2 or later.
|
||||
* See file LICENSE.txt or visit http://www.gnu.org/licenses/gpl.html for full license details.
|
||||
*/
|
||||
function InfoAPI() {
|
||||
|
||||
this.status = function(success,fail) {
|
||||
API.get('info/status',success,fail);
|
||||
};
|
||||
|
||||
}
|
|
@ -5,42 +5,84 @@
|
|||
* This software is licensed under the terms of the GNU GPL v2 or later.
|
||||
* See file LICENSE.txt or visit http://www.gnu.org/licenses/gpl.html for full license details.
|
||||
*/
|
||||
|
||||
function PrinterAPI() {
|
||||
|
||||
var _wifiboxURL;
|
||||
var _wifiboxCGIBinURL;
|
||||
var _timeoutTime = 3000;
|
||||
this.remainingLines = [];
|
||||
this.totalLinesAtStart = 0;
|
||||
|
||||
var _self = this;
|
||||
this.state = function(success,fail) {
|
||||
API.get('printer/state',success,fail);
|
||||
};
|
||||
|
||||
this.init = function(wifiboxURL,wifiboxCGIBinURL) {
|
||||
//console.log("PrinterAPI:init");
|
||||
//console.log(" wifiboxURL: ",wifiboxURL);
|
||||
//console.log(" wifiboxCGIBinURL: ",wifiboxCGIBinURL);
|
||||
_wifiboxURL = wifiboxURL;
|
||||
_wifiboxCGIBinURL = wifiboxCGIBinURL;
|
||||
this.listAll = function(success,fail) {
|
||||
API.get('printer/listall',success,fail);
|
||||
};
|
||||
|
||||
this.temperature = function(success,fail) {
|
||||
API.get('printer/temperature',success,fail);
|
||||
};
|
||||
|
||||
this.progress = function(success,fail) {
|
||||
API.get('printer/progress',success,fail);
|
||||
}
|
||||
|
||||
this.listAll = function(completeHandler,failedHandler) {
|
||||
//console.log("PrinterAPI:listAll");
|
||||
//console.log(" _wifiboxURL: ",_wifiboxURL);
|
||||
$.ajax({
|
||||
url: _wifiboxURL + "/printer/listall",
|
||||
type: "GET",
|
||||
dataType: 'json',
|
||||
timeout: _timeoutTime,
|
||||
success: function(response){
|
||||
//console.log("PrinterAPI response: ",response);
|
||||
if(response.status == "error" || response.status == "fail") {
|
||||
//console.log("PrinterAPI:listAll failed: ",response);
|
||||
if(failedHandler) failedHandler(response);
|
||||
function _printPartPost(lines,data,cb) {
|
||||
|
||||
API.post('printer/print',data,function(response) {
|
||||
console.log('print part success',response);
|
||||
setTimeout(function() {
|
||||
_printPart(lines,false,false,cb);
|
||||
},10);
|
||||
|
||||
},function(jqXHR,textStatus) {
|
||||
console.log('print fail jqHXR:',jqXHR,"textStatus:",textStatus);
|
||||
if (textStatus=="timeout") {
|
||||
console.log('TIMEOUT, waiting to try again');
|
||||
setTimeout(function() {
|
||||
console.log('now try again');
|
||||
_printPartPost(lines,data,cb);
|
||||
},5000);
|
||||
} else {
|
||||
completeHandler(response.data);
|
||||
console.log("_printPartPost FATAL error:",textStatus);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function _printPart(lines,first,start,cb) {
|
||||
var chunk = lines.splice(0,500);
|
||||
console.log('printPart',chunk.length,lines.length);
|
||||
|
||||
if (chunk.length>0) {
|
||||
var data = {gcode: chunk.join("\n"), first: first, start: start};
|
||||
|
||||
_printPartPost(lines,data,function() {
|
||||
console.log('_printPartPost cb');
|
||||
cb(); //??? needed
|
||||
});
|
||||
|
||||
} else {
|
||||
console.log('no more print parts');
|
||||
cb(); //finished
|
||||
}
|
||||
}
|
||||
}).fail(function() {
|
||||
//console.log("PrinterAPI:listAll failed");
|
||||
if(failedHandler) failedHandler();
|
||||
|
||||
this.print = function(gcode,start,first,success,fail) {
|
||||
//need a check here for state??
|
||||
this.remainingLines = gcode.split("\n");
|
||||
this.totalLinesAtStart = this.remainingLines.length;
|
||||
// console.log('remainingLines.length',this.remainingLines.length);
|
||||
_printPart(this.remainingLines,true,true,function() {
|
||||
console.log('done sending');
|
||||
});
|
||||
};
|
||||
|
||||
this.stop = function(endcode,success,fail) {
|
||||
//need a check here for state??
|
||||
// console.log('remainingLines',this.remainingLines.length);
|
||||
this.remainingLines.length = 0; //clear array
|
||||
totalLinesAtStart = 0;
|
||||
API.post('printer/stop',{gcode:endcode},success,fail);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
/*
|
||||
* This file is part of the Doodle3D project (http://doodle3d.com).
|
||||
*
|
||||
* Copyright (c) 2013, Doodle3D
|
||||
* This software is licensed under the terms of the GNU GPL v2 or later.
|
||||
* See file LICENSE.txt or visit http://www.gnu.org/licenses/gpl.html for full license details.
|
||||
*/
|
||||
|
||||
function SketchAPI() {
|
||||
|
||||
this.load = function(id,success,fail) {
|
||||
API.get('sketch/?id='+id,success,fail);
|
||||
}
|
||||
|
||||
}
|
|
@ -310,7 +310,6 @@ function oopsUndo() {
|
|||
}
|
||||
|
||||
function previewUp(redrawLess) {
|
||||
// console.log("f:previewUp()");
|
||||
if (numLayers < maxNumLayers) {
|
||||
numLayers++;
|
||||
}
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
body {
|
||||
font-family: Helvetica, Abel, Arial;
|
||||
font-size: 1em;
|
||||
|
||||
-webkit-user-select: none; /* webkit (safari, chrome) browsers */
|
||||
-moz-user-select: none; /* mozilla browsers */
|
||||
-khtml-user-select: none; /* webkit (konqueror) browsers */
|
||||
|
@ -12,7 +11,7 @@ button {
|
|||
font-size: 1em;
|
||||
}
|
||||
|
||||
div.item {
|
||||
.item {
|
||||
width:150px;
|
||||
height:130px;
|
||||
border:1px solid black;
|
||||
|
@ -22,14 +21,10 @@ div.item {
|
|||
margin-right: 5px;
|
||||
}
|
||||
|
||||
div.item.selected {
|
||||
.item.selected {
|
||||
background-color: #7cf;
|
||||
}
|
||||
|
||||
div.item input[type='checkbox'] {
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
#frmUpload {
|
||||
display: inline;
|
||||
}
|
||||
|
@ -41,9 +36,11 @@ input[type='file'] {
|
|||
|
||||
#txtInfo {
|
||||
float: right;
|
||||
margin-top: 5px;
|
||||
/*display: inline-block;*/
|
||||
}
|
||||
|
||||
img#logo {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
|
|
|
@ -6,25 +6,22 @@
|
|||
</head>
|
||||
<body>
|
||||
|
||||
<span id="txtInfo"></span>
|
||||
<img id="logo" src="../img/logo/doodle3d.png" height="25">
|
||||
<hr>
|
||||
<button id="btnSelectAll">Select all</button>
|
||||
<button id="btnDeselectAll">Deselect all</button>
|
||||
<button id="btnDelete">Delete</button>
|
||||
<button id="btnDownload">Download</button> <!-- <a id="link" href="#">Download</a> -->
|
||||
|
||||
<button id="btnPrint">Print...</button>
|
||||
<button id="btnRefresh">Refresh</button>
|
||||
<form id="frmUpload"><button id="btnUpload">Upload</button><input id="uploads" type="file" accept="image/svg+xml" multiple/></form>
|
||||
|
||||
<span id="txtInfo"></span>
|
||||
|
||||
<hr>
|
||||
<form>
|
||||
<div id="svgContainer"></div>
|
||||
</form>
|
||||
|
||||
<script src="../js/libs/jquery-1-9-1.min.js"></script>
|
||||
<script src="js/main.js"></script>
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -24,6 +24,8 @@ $("#btnSelectAll").click(selectAll);
|
|||
$("#btnDeselectAll").click(deselectAll);
|
||||
$("#uploads").change(upload);
|
||||
$("#btnDownload").click(download);
|
||||
$("#btnRefresh").click(refresh);
|
||||
$("#btnPrint").click(print);
|
||||
|
||||
$("#btnUpload").click(function(e) {
|
||||
e.preventDefault();
|
||||
|
@ -60,6 +62,7 @@ $.get(api+'list', function(data) { //?id=00003
|
|||
console.log(status);
|
||||
});
|
||||
|
||||
|
||||
function onLogoClick() {
|
||||
location.href='/'+location.search;
|
||||
}
|
||||
|
@ -93,15 +96,14 @@ function addItem(id,svgData,doPrepend) {
|
|||
else if (svgData.indexOf("CDATA")==-1) path = "";
|
||||
else path = svgData.split('d="')[1].split('"')[0];
|
||||
|
||||
var item = $('<div class="item" data="'+id+'" title="'+id+'">');
|
||||
var item = $('<li class="item ui-widget-content" data="'+id+'" title="'+id+'"></li>');
|
||||
var svg = '<svg xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0 0 640 540"><path fill="none" stroke="black" stroke-width="2" d="'+path+'"></path></svg>';
|
||||
|
||||
item.append(svg);
|
||||
item.click(function() {
|
||||
$(this).toggleClass('selected');
|
||||
console.log($(this).attr("data"));
|
||||
updateButtonStates();
|
||||
})
|
||||
item.append(svg);
|
||||
|
||||
if (doPrepend) $('#svgContainer').prepend(item);
|
||||
else $('#svgContainer').append(item);
|
||||
|
@ -173,8 +175,10 @@ function updateButtonStates() {
|
|||
$("#btnDeselectAll").attr("disabled",isBusy || noSelection);
|
||||
$("#btnSelectAll").attr("disabled",isBusy || numItems==0);
|
||||
$("#btnUpload").attr("disabled",isBusy || !noSelection);
|
||||
$("#btnDelete").text("Delete" + (noSelection ? "" : " ("+numSelected+")"));
|
||||
$("#btnDownload").text("Download" + (noSelection ? "" : " ("+numSelected+")"));
|
||||
$("#btnPrint").attr("disabled",isBusy || noSelection);
|
||||
// $("#btnDelete").text("Delete" + (noSelection ? "" : " ("+numSelected+")"));
|
||||
// $("#btnDownload").text("Download" + (noSelection ? "" : " ("+numSelected+")"));
|
||||
// $("#btnPrint").text("Print" + (noSelection ? "..." : " ("+numSelected+")..."));
|
||||
}
|
||||
|
||||
function uploadFile(files, index, next) {
|
||||
|
@ -265,3 +269,15 @@ function download() {
|
|||
});
|
||||
}
|
||||
|
||||
function refresh() {
|
||||
location.reload();
|
||||
}
|
||||
|
||||
function print() {
|
||||
var ids = [];
|
||||
$('.item.selected').each(function() {
|
||||
ids.push($(this).attr('data'));
|
||||
});
|
||||
location.href = '/printmanager/' + location.search + "&ids=" + ids.join();
|
||||
}
|
||||
|
||||
|
|
|
@ -182,6 +182,7 @@
|
|||
<script src="js/libs/jquery-coolfieldset.min.js"></script>
|
||||
<script src="js/libs/FileSaver.min.js"></script>
|
||||
<script src="js/libs/jquery-fastclick.min.js"></script>
|
||||
<script src="js/doodle3d-api.min.js"></script>
|
||||
<script src="js/doodle3d-client.min.js"></script>
|
||||
|
||||
</body>
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -0,0 +1,90 @@
|
|||
body {
|
||||
font-family: Helvetica, Abel, Arial;
|
||||
font-size: 1em;
|
||||
|
||||
-webkit-user-select: none; /* webkit (safari, chrome) browsers */
|
||||
-moz-user-select: none; /* mozilla browsers */
|
||||
-khtml-user-select: none; /* webkit (konqueror) browsers */
|
||||
-ms-user-select: none; /* IE10+ */
|
||||
}
|
||||
|
||||
button {
|
||||
font-size: 1em;
|
||||
}
|
||||
|
||||
#svgContainer {
|
||||
width: 540px;
|
||||
height: 540px;
|
||||
border: 1px solid black;
|
||||
margin: 0 auto;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
display: inline-block;
|
||||
}
|
||||
#svgContainer svg {
|
||||
border: 1px solid lightgrey;
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
#printPreview {
|
||||
width: 540px;
|
||||
height: 540px;
|
||||
border: 1px solid black;
|
||||
margin: 0 auto;
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
/*#svgContainer {
|
||||
width: 640px;
|
||||
height: 640px;
|
||||
border: 1px solid black;
|
||||
display: inline-block;
|
||||
}*/
|
||||
|
||||
/*.item {
|
||||
padding: 0.5em;
|
||||
display: inline-block;
|
||||
position: absolute;
|
||||
margin-right: 5px;
|
||||
margin-bottom: 5px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.item.selected {
|
||||
background-color: rgba(102, 206, 255, 0.4);
|
||||
}
|
||||
|
||||
.item.crosshair {
|
||||
cursor: crosshair;
|
||||
}*/
|
||||
|
||||
#frmUpload {
|
||||
display: inline;
|
||||
}
|
||||
|
||||
#txtInfo {
|
||||
float: right;
|
||||
}
|
||||
|
||||
img#logo {
|
||||
cursor: pointer;
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
#buttonsPanel {
|
||||
float: right;
|
||||
}
|
||||
|
||||
span.statusvar {
|
||||
background-color: #7cf;
|
||||
margin: 2px 2px 2px 2px;
|
||||
padding: 5px 5px 2px 5px;
|
||||
}
|
||||
|
||||
#preview {
|
||||
display: inline-block;
|
||||
border: 1px solid black;
|
||||
width: 640px;
|
||||
height: 540px;
|
||||
}
|
|
@ -0,0 +1,48 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Doodle3D</title>
|
||||
<link href="css/style.css" rel="stylesheet" media="screen">
|
||||
|
||||
<link href="//cdnjs.cloudflare.com/ajax/libs/jqueryui/1.10.3/css/base/jquery.ui.all.css" rel="stylesheet">
|
||||
<link href="//cdnjs.cloudflare.com/ajax/libs/jqueryui/1.10.2/css/lightness/jquery-ui-1.10.2.custom.min.css" rel="stylesheet">
|
||||
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
|
||||
<script src="//cdnjs.cloudflare.com/ajax/libs/jqueryui/1.10.3/jquery-ui.min.js"></script>
|
||||
<script src="//cdnjs.cloudflare.com/ajax/libs/jqueryui-touch-punch/0.2.2/jquery.ui.touch-punch.min.js"></script>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<img id="logo" src="../img/logo/doodle3d.png" height="25" alt="Doodle3D">PrintManager
|
||||
<button id="btnRefresh">Refresh</button>
|
||||
<!-- <button id="btnPlus">+</button>
|
||||
<button id="btnMin">-</button> -->
|
||||
<button id="btnPrepare">Prepare</button>
|
||||
<button id="btnPrint">Print</button>
|
||||
<button id="btnStop">Stop</button>
|
||||
<input type="file" name="file"/>
|
||||
<span class="statusvar" id="lblState"></span>
|
||||
<span class="statusvar" id="lblNozzle"></span>
|
||||
<span class="statusvar" id="lblBed"></span>
|
||||
<span class="statusvar" id="txtInfo"></span>
|
||||
<span class="statusvar" id="lblBufferProgress"></span>
|
||||
<span class="statusvar" id="lblPrintProgress"></span>
|
||||
<hr>
|
||||
|
||||
<div id="svgContainer"></div>
|
||||
<div id="printPreview"></div>
|
||||
|
||||
<script src="../js/doodle3d-api.js"></script>
|
||||
<script src="js/touchSwipe.min.js"></script>
|
||||
<script src="js/Point.js"></script>
|
||||
<script src="js/Rectangle.js"></script>
|
||||
<script src="js/Polyline.js"></script>
|
||||
<script src="js/Path.js"></script>
|
||||
<script src="js/Svg.js"></script>
|
||||
<script src="js/Doodle.js"></script>
|
||||
<script src="js/Viewer.js"></script>
|
||||
<script src="js/Doodle2gcode.js"></script>
|
||||
<script src="js/main.js"></script>
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,177 @@
|
|||
var Doodle = function(svgData,settings) {
|
||||
|
||||
var path = new Path();
|
||||
var height = 50; //in mm
|
||||
var offset = new Point(0,0);
|
||||
var scale = 1;
|
||||
var rotation = 0;
|
||||
var twist = 0;
|
||||
|
||||
if (svgData!==undefined) {
|
||||
setFromSvgPathDescription(svgData);
|
||||
removeShortPaths(); //move this to main.js?
|
||||
|
||||
//TODO: determine current offset from boundingbox and store in 'offset' variable
|
||||
path.alignCorner(); //set left-top corner of path boundingbox to 0,0
|
||||
}
|
||||
|
||||
if (settings!==undefined) {
|
||||
if (settings.height!==undefined) height = settings.height;
|
||||
if (settings.twist!==undefined) twist = settings.twist;
|
||||
}
|
||||
|
||||
function setFromSvgPathDescription(svgData) {
|
||||
// if (!svgData) svgData = "";
|
||||
// else if (typeof(svgData)!='string') svgData = "";
|
||||
// // else if (svgData.indexOf("CDATA")==-1) svgData = "";
|
||||
// else svgData = svgData.split('d="')[1].split('"')[0];
|
||||
|
||||
console.log('svgData',svgData);
|
||||
|
||||
svgData+=' '; //add a trailing space
|
||||
|
||||
//Parse Path Description
|
||||
var mode = '', x=0, y=0, p=0;
|
||||
var path = new Path();
|
||||
|
||||
var skipSpace = function() {
|
||||
while (svgData.charAt(p) == ' ') p++;
|
||||
}
|
||||
|
||||
var parser = function() {
|
||||
while (true) {
|
||||
skipSpace();
|
||||
|
||||
if (p==svgData.length) {
|
||||
return true;
|
||||
}
|
||||
|
||||
var c = svgData.charAt(p);
|
||||
if (c == 'M' || c == 'm' || c == 'L' || c == 'l') { //new command letter
|
||||
mode = c;
|
||||
} else if (c == '"') { //end of command chain
|
||||
return true;
|
||||
} else { //something else, must be a pair of coordinates...
|
||||
var tx = 0, ty = 0, numberEnd = 0, len = 0;
|
||||
numberEnd = svgData.indexOf(',', p);
|
||||
|
||||
////// RC: if instead of a comma a space is used between a pair use that as a separator
|
||||
//var firstSpace = svgData.indexOf(' ', p);
|
||||
//if (firstSpace<numberEnd) numberEnd=firstSpace;
|
||||
if (numberEnd == -1) { console.log("parsePathDescription:could not find *COMMA* in coordinate pair pos:",p,'of',svgData.length,svgData.substr(p)); return false; }
|
||||
len = numberEnd - p;
|
||||
tx = parseFloat(svgData.substr(p, len));
|
||||
p += len + 1;
|
||||
skipSpace();
|
||||
numberEnd = svgData.indexOf(' ', p);
|
||||
if (numberEnd == -1) { console.log("parsePathDescription:could not find *SPACE* after coordinate pair",p,'of',svgData.length); return false; }
|
||||
len = numberEnd - p;
|
||||
ty = parseFloat(svgData.substr(p, len));
|
||||
p += len;
|
||||
|
||||
if (mode == 'M' || mode == 'L') {
|
||||
x = tx; y = ty;
|
||||
} else if (mode == 'm' || mode == 'l') {
|
||||
x += tx; y += ty;
|
||||
} else {
|
||||
console.log("parsePathDescription: found coordinate pair but mode was never set");
|
||||
return false;
|
||||
}
|
||||
|
||||
var isMove = mode == 'm' || mode == 'M';
|
||||
|
||||
if (isMove) path.moveTo(x,y);
|
||||
else path.lineTo(x,y);
|
||||
}
|
||||
p++;
|
||||
}
|
||||
}
|
||||
parser();
|
||||
setPath(path);
|
||||
}
|
||||
|
||||
function getSvgPathDescription() {
|
||||
var d = "";
|
||||
var polylines = path.getPolylines();
|
||||
for (var i=0; i<polylines.length; i++) {
|
||||
var points = polylines[i].getPoints();
|
||||
for (var j=0; j<points.length; j++) {
|
||||
d += (j==0 ? "M" : "L");
|
||||
d += Math.round(points[j].x) + "," + Math.round(points[j].y) + " ";
|
||||
}
|
||||
}
|
||||
return d;
|
||||
// return '<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="640" height="540"><path xmlns="http://www.w3.org/2000/svg" fill="none" stroke="black" stroke-width="2" d="'+d+'"></path></svg>';
|
||||
}
|
||||
|
||||
function removeShortPaths(minLength,minPoints) {
|
||||
if (!minLength) minLength = 10;
|
||||
if (!minPoints) minPoints = 1;
|
||||
|
||||
path.setPolylines(path.getPolylines().filter(function(polyline) {
|
||||
return polyline.getPoints().length>minPoints && polyline.getPerimeter()>minLength;
|
||||
}));
|
||||
}
|
||||
|
||||
function getPath() {
|
||||
return path;
|
||||
}
|
||||
|
||||
function setPath(newPath) {
|
||||
path = newPath
|
||||
}
|
||||
|
||||
function getSettings() {
|
||||
return settings;
|
||||
}
|
||||
|
||||
function getHeight() {
|
||||
return height;
|
||||
}
|
||||
|
||||
function getTwist() {
|
||||
return twist;
|
||||
}
|
||||
|
||||
function getScale() {
|
||||
return scale;
|
||||
}
|
||||
|
||||
function setScale(_scale) {
|
||||
scale = _scale;
|
||||
}
|
||||
|
||||
function getOffset() {
|
||||
return offset;
|
||||
}
|
||||
|
||||
function setOffset(_offset) {
|
||||
offset = _offset;
|
||||
}
|
||||
|
||||
function getRotation() {
|
||||
return rotation;
|
||||
}
|
||||
|
||||
function getScaleFunction(f) {
|
||||
return 1; //Math.sin(f*2*Math.PI)/4+1;
|
||||
}
|
||||
|
||||
return {
|
||||
getPath: getPath,
|
||||
setPath: setPath,
|
||||
getSettings: getSettings,
|
||||
setFromSvgPathDescription: setFromSvgPathDescription,
|
||||
getSvgPathDescription: getSvgPathDescription,
|
||||
getHeight: getHeight,
|
||||
getRotation: getRotation,
|
||||
getTwist: getTwist,
|
||||
getScaleFunction: getScaleFunction,
|
||||
getScale: getScale,
|
||||
setScale: setScale,
|
||||
getOffset: getOffset,
|
||||
setOffset: setOffset,
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,109 @@
|
|||
var Doodle2gcode = function() {
|
||||
var className = "Doodle2gcode";
|
||||
|
||||
var speed = 50;
|
||||
var layerHeight = .2;
|
||||
var filamentDiameter = 2.89;
|
||||
var nozzleDiameter = .4;
|
||||
var dimensions = {x:200,y:200,z:200};
|
||||
var px2mm = .3;
|
||||
|
||||
var nozzleFilamentRatio = nozzleDiameter / filamentDiameter;
|
||||
var layerNozzleRatio = layerHeight / nozzleDiameter;
|
||||
var extrudeFactor = nozzleFilamentRatio * layerNozzleRatio;
|
||||
var flowRatio = 1;
|
||||
|
||||
var extruder = 0;
|
||||
|
||||
function generate(doodles) {
|
||||
var gcode = "";
|
||||
extruder = 0;
|
||||
for (var z=0,layer=0; z<dimensions.z; z+=layerHeight,layer++) {
|
||||
for (var i=0; i<doodles.length; i++) {
|
||||
|
||||
var path = getDoodlePathAtHeight(doodles[i],z);
|
||||
|
||||
// var path = new Path();
|
||||
// path.moveTo(0,0);
|
||||
// path.lineTo(100,0);
|
||||
// path.lineTo(100,100);
|
||||
// path.lineTo(0,100);
|
||||
// path.lineTo(0,0);
|
||||
|
||||
gcode += path2gcode(path,z);
|
||||
}
|
||||
}
|
||||
return gcode;
|
||||
}
|
||||
|
||||
function getDoodlePathAtHeight(doodle,z) {
|
||||
if (z>doodle.getHeight()) return new Path(); //return empty path, doodle not visible in this slice
|
||||
var zz = z/doodle.getHeight(); //0..1
|
||||
var rotation = doodle.getRotation();
|
||||
var twist = zz * doodle.getTwist();
|
||||
var offset = doodle.getOffset();
|
||||
var scale = doodle.getScale();
|
||||
var scaler = doodle.getScaleFunction(zz);
|
||||
var path = doodle.getPath().clone();
|
||||
|
||||
// var org = path.getOffset();
|
||||
var box = path.getBoundingBox();
|
||||
|
||||
// console.log(box.toString());
|
||||
|
||||
path.translate(-box.getX(),-box.getY());
|
||||
path.translate(-box.getWidth()/2,-box.getHeight()/2);
|
||||
|
||||
// path.alignCenter();
|
||||
path.scale(scale);
|
||||
path.scale(scaler);
|
||||
|
||||
path.translate(box.getX(),box.getY());
|
||||
path.translate(box.getWidth()/2,box.getHeight()/2);
|
||||
|
||||
// path.rotate(rotation);
|
||||
path.rotate(twist,box.getCenter());
|
||||
// path.alignCorner();
|
||||
path.translate(offset.x,offset.y);
|
||||
|
||||
return path;
|
||||
}
|
||||
|
||||
function path2gcode(path,z) {
|
||||
var gcode = '';
|
||||
var polylines = path.getPolylines();
|
||||
|
||||
path.scale(px2mm);
|
||||
path.translate(0,-dimensions.y);
|
||||
|
||||
for (var i=0; i<polylines.length; i++) {
|
||||
var points = polylines[i].getPoints();
|
||||
for (var j=0; j<points.length; j++) {
|
||||
var x = points[j].x;
|
||||
var y = -points[j].y;
|
||||
|
||||
gcode += (j==0 ? 'G0' : 'G1');
|
||||
gcode += ' ';
|
||||
gcode += 'X' + x.toFixed(2);
|
||||
gcode += ' ';
|
||||
gcode += 'Y' + y.toFixed(2);
|
||||
gcode += ' ';
|
||||
gcode += 'Z' + z.toFixed(2);
|
||||
gcode += ' ';
|
||||
|
||||
if (j>0) {
|
||||
var dist = points[j-1].distance(points[j]) * px2mm;
|
||||
extruder += dist * extrudeFactor * flowRatio;
|
||||
gcode += 'E' + extruder.toFixed(4);
|
||||
}
|
||||
|
||||
gcode += '\n';
|
||||
}
|
||||
}
|
||||
return gcode;
|
||||
}
|
||||
|
||||
return {
|
||||
generate: generate,
|
||||
}
|
||||
}
|
|
@ -0,0 +1,104 @@
|
|||
var Path = function() {
|
||||
var className = "Path";
|
||||
var polylines = [];
|
||||
|
||||
function translate(x,y) {
|
||||
for (var i = 0; i < polylines.length; i++) {
|
||||
polylines[i].translate(x,y);
|
||||
}
|
||||
}
|
||||
|
||||
function rotate(radians,pivot) {
|
||||
for (var i = 0; i < polylines.length; i++) {
|
||||
var points = polylines[i].getPoints();
|
||||
for (var j = 0; j < points.length; j++) {
|
||||
points[j].rotate(radians,pivot)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function scale(scale) {
|
||||
for (var i = 0; i < polylines.length; i++) {
|
||||
// console.log(className,'scale',scale);
|
||||
polylines[i].scale(scale);
|
||||
}
|
||||
}
|
||||
|
||||
function moveTo(x,y) {
|
||||
polylines.push(new Polyline(x,y));
|
||||
}
|
||||
|
||||
function lineTo(x,y) {
|
||||
if (polylines.length==0) moveTo(x,y);
|
||||
else polylines[polylines.length-1].addVertex(x,y);
|
||||
}
|
||||
|
||||
function getBoundingBox() {
|
||||
var box = new Rectangle(0,0,0,0);
|
||||
for (var i = 0; i < polylines.length; i++) {
|
||||
if (i==0) box = polylines[i].getBoundingBox();
|
||||
else box.growToIncludeRectangle(polylines[i].getBoundingBox());
|
||||
}
|
||||
return box;
|
||||
}
|
||||
|
||||
function getWidth() {
|
||||
return this.getBoundingBox().getWidth();
|
||||
}
|
||||
|
||||
function getHeight() {
|
||||
return this.getBoundingBox().getHeight();
|
||||
}
|
||||
|
||||
function getPolylines() {
|
||||
return polylines;
|
||||
}
|
||||
|
||||
function setPolylines(_polylines) {
|
||||
polylines = _polylines;
|
||||
}
|
||||
|
||||
function clone() {
|
||||
var p = new Path();
|
||||
for (var i=0; i<polylines.length; i++) {
|
||||
// console.log(className,'clone poly#',i,"/",polylines.length,polylines[i].toString(),"||||",polylines[i].clone().toString());
|
||||
p.getPolylines().push(polylines[i].clone());
|
||||
}
|
||||
// console.log(className,'p.toString()',p.toString());
|
||||
return p;
|
||||
}
|
||||
|
||||
function alignCorner() {
|
||||
var box = getBoundingBox();
|
||||
translate(-box.getX(),-box.getY());
|
||||
}
|
||||
|
||||
function alignCenter() {
|
||||
var box = getBoundingBox();
|
||||
// console.log(className,'alignCenter',box.toString());
|
||||
translate(-box.getX(),-box.getY());
|
||||
translate(-box.getWidth()/2,-box.getHeight()/2);
|
||||
}
|
||||
|
||||
function toString() {
|
||||
return polylines.join(" --- ");
|
||||
}
|
||||
|
||||
return {
|
||||
translate: translate,
|
||||
rotate: rotate,
|
||||
scale: scale,
|
||||
moveTo: moveTo,
|
||||
lineTo: lineTo,
|
||||
getBoundingBox: getBoundingBox,
|
||||
getWidth: getWidth,
|
||||
getHeight: getHeight,
|
||||
getPolylines: getPolylines,
|
||||
setPolylines: setPolylines,
|
||||
clone: clone,
|
||||
alignCenter: alignCenter,
|
||||
alignCorner: alignCorner,
|
||||
toString: toString
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
var Point = function(x,y) {
|
||||
if (x===undefined) x = 0;
|
||||
if (y===undefined) y = 0;
|
||||
|
||||
if (isNaN(x) || isNaN(y)) {
|
||||
console.warning("Point x or y isNaN: ",x,y);
|
||||
}
|
||||
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
}
|
||||
|
||||
// Point.prototype.clone = function() { //not used since it easy to clone a point using 'new Point(org.x,org.y)'
|
||||
// return new Point(this.x, this.y);
|
||||
// }
|
||||
|
||||
Point.prototype.distance = function(p) {
|
||||
var x1 = this.x;
|
||||
var y1 = this.y;
|
||||
var x2 = p.x;
|
||||
var y2 = p.y;
|
||||
return Math.sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
|
||||
}
|
||||
|
||||
Point.prototype.rotate = function(radians,pivot) {
|
||||
if (pivot===undefined) pivot = new Point(0,0);
|
||||
var x = this.x;
|
||||
var y = this.y;
|
||||
var xrot = ((x-pivot.x)*Math.cos(radians) - (y-pivot.y)*Math.sin(radians)) + pivot.x;
|
||||
this.y = ((x-pivot.x)*Math.sin(radians) + (y-pivot.y)*Math.cos(radians)) + pivot.y;
|
||||
this.x = xrot;
|
||||
}
|
||||
|
||||
|
||||
Point.prototype.toString = function(p) {
|
||||
return this.x.toFixed(2) + "," + this.y.toFixed(2);
|
||||
}
|
|
@ -0,0 +1,84 @@
|
|||
var Polyline = function(x,y) {
|
||||
var className = "Polyline";
|
||||
var points = [new Point(x,y)];
|
||||
|
||||
function translate(x,y) {
|
||||
for (var i = 0; i < points.length; i++) {
|
||||
points[i].x += x;
|
||||
points[i].y += y;
|
||||
}
|
||||
}
|
||||
|
||||
function rotate(degrees) {
|
||||
console.log('rotate: to be implemented')
|
||||
}
|
||||
|
||||
function scale(scale) {
|
||||
for (var i = 0; i < points.length; i++) {
|
||||
points[i].x *= scale;
|
||||
points[i].y *= scale;
|
||||
}
|
||||
}
|
||||
|
||||
function addVertex(x,y) {
|
||||
var p = new Point(x,y);
|
||||
points.push(p);
|
||||
}
|
||||
|
||||
function getBoundingBox() {
|
||||
var box = new Rectangle(0,0,0,0);
|
||||
for (var i=0; i<points.length; i++) {
|
||||
if (i==0) box.set(points[i].x,points[i].y,0,0);
|
||||
else box.growToIncludePoint(points[i]);
|
||||
}
|
||||
return box;
|
||||
}
|
||||
|
||||
function getWidth() {
|
||||
return getBoundingBox().getWidth();
|
||||
}
|
||||
|
||||
function getHeight() {
|
||||
return getBoundingBox().getHeight();
|
||||
}
|
||||
|
||||
function getPoints() {
|
||||
return points;
|
||||
}
|
||||
|
||||
function getPerimeter() {
|
||||
var len = 0;
|
||||
for (var i = 1; i < points.length; i++) {
|
||||
len += points[i-1].distance(points[i]);
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
function clone() {
|
||||
var p = new Polyline(points[0].x,points[0].y);
|
||||
for (var i=1; i<points.length; i++) {
|
||||
p.getPoints().push(new Point(points[i].x, points[i].y));
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
function toString() {
|
||||
return points.join(", ");
|
||||
}
|
||||
|
||||
|
||||
return {
|
||||
translate: translate,
|
||||
rotate: rotate,
|
||||
scale: scale,
|
||||
addVertex: addVertex,
|
||||
getBoundingBox: getBoundingBox,
|
||||
getPerimeter: getPerimeter,
|
||||
getWidth: getWidth,
|
||||
getHeight: getHeight,
|
||||
getPoints: getPoints,
|
||||
clone: clone,
|
||||
toString: toString,
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,64 @@
|
|||
var Rectangle = function(_x,_y,_w,_h) {
|
||||
|
||||
var x,y,w,h;
|
||||
|
||||
set(_x,_y,_w,_h);
|
||||
|
||||
function set(_x,_y,_w,_h) {
|
||||
x = _x;
|
||||
y = _y;
|
||||
w = _w;
|
||||
h = _h;
|
||||
}
|
||||
|
||||
function growToIncludeRectangle(rect) {
|
||||
growToIncludePoint(new Point(rect.getMinX(),rect.getMinY()));
|
||||
growToIncludePoint(new Point(rect.getMaxX(),rect.getMaxY()));
|
||||
}
|
||||
|
||||
function growToIncludePoint(p) {
|
||||
var x0 = Math.min(getMinX(),p.x);
|
||||
var x1 = Math.max(getMaxX(),p.x);
|
||||
var y0 = Math.min(getMinY(),p.y);
|
||||
var y1 = Math.max(getMaxY(),p.y);
|
||||
var w = x1 - x0;
|
||||
var h = y1 - y0;
|
||||
set(x0,y0,w,h);
|
||||
}
|
||||
|
||||
function getCenter() {
|
||||
var cx = (getMaxX()-getMinX()) / 2;
|
||||
var cy = (getMaxY()-getMinY()) / 2;
|
||||
return new Point(cx,cy);
|
||||
}
|
||||
|
||||
function getX() { return x; }
|
||||
function getY() { return y; }
|
||||
function getWidth() { return w; }
|
||||
function getHeight() { return h; }
|
||||
function getMinX() { return Math.min(x, x + w); }
|
||||
function getMaxX() { return Math.max(x, x + w); }
|
||||
function getMinY() { return Math.min(y, y + h); }
|
||||
function getMaxY() { return Math.max(y, y + h); }
|
||||
|
||||
function toString() {
|
||||
return 'x:' + x + ", y:" + y + ", w:" + w + ", h:" + h;
|
||||
}
|
||||
|
||||
return {
|
||||
getMinX: getMinX,
|
||||
getMaxX: getMaxX,
|
||||
getMinY: getMinY,
|
||||
getMaxY: getMaxY,
|
||||
getWidth: getWidth,
|
||||
getHeight: getHeight,
|
||||
set: set,
|
||||
growToIncludeRectangle: growToIncludeRectangle,
|
||||
growToIncludePoint: growToIncludePoint,
|
||||
toString: toString,
|
||||
getX: getX,
|
||||
getY: getY,
|
||||
getCenter: getCenter,
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,149 @@
|
|||
// var Svg = function() {
|
||||
|
||||
// // var pathElement;
|
||||
// var svgElement;
|
||||
// var path;
|
||||
|
||||
// this.load = function(svgData) {
|
||||
|
||||
// if (!svgData) svgData = "";
|
||||
// else if (typeof(svgData)!='string') svgData = "";
|
||||
// // else if (svgData.indexOf("CDATA")==-1) svgData = "";
|
||||
// else svgData = svgData.split('d="')[1].split('"')[0];
|
||||
|
||||
// svgElement = $('<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="640" height="540"><path xmlns="http://www.w3.org/2000/svg" fill="none" stroke="black" stroke-width="2" d="'+svgData+'"></path></svg>');
|
||||
|
||||
// var pathElement = $(svgElement).find('path');
|
||||
// var pathDescription = pathElement.attr('d');
|
||||
// var path = parsePathDescription(pathDescription);
|
||||
// var box = path.getBoundingBox();
|
||||
|
||||
// console.log(box.toString());
|
||||
|
||||
// var polylines = path.getPolylines();
|
||||
// for (var i=0; i<polylines.length; i++) {
|
||||
|
||||
// var len = polylines[i].getPerimeter();
|
||||
// // console.log(i,len,);
|
||||
// if (len<10 || polylines[i].getPoints().length<6) {
|
||||
// console.log('removing polyline ',i);
|
||||
// polylines.splice(i,1);
|
||||
// }
|
||||
// }
|
||||
|
||||
// var box = path.getBoundingBox();
|
||||
|
||||
// path.translate(-box.getX()+1,-box.getY()+1);
|
||||
|
||||
// svgElement.attr('width',box.getWidth()+2);
|
||||
// svgElement.attr('height',box.getHeight()+2);
|
||||
|
||||
|
||||
// // var indices = path.getPointIndicesByDistance(367,433,50);
|
||||
// // console.log('indices',indices);
|
||||
|
||||
// // svgElement.append('<circle xmlns="http://www.w3.org/2000/svg" version="1.1" cx="60" cy="60" r="50"/>');
|
||||
|
||||
// // var points = path.getPoints();
|
||||
// // for (var i=0; i<points.length; i++) {
|
||||
// // path.removePoint(i);
|
||||
// // if (i>400) break;
|
||||
// // }
|
||||
|
||||
// // console.log(points.length);
|
||||
|
||||
// // console.log(path.getPoints().length);
|
||||
|
||||
|
||||
// // path.removePoint(502);
|
||||
// // path.removePoint(503);
|
||||
// var d = getPathDescription(path);
|
||||
// pathElement.attr('d',d); //update
|
||||
// }
|
||||
|
||||
// function getPathDescription(path) {
|
||||
// var d = "";
|
||||
// var polylines = path.getPolylines();
|
||||
// for (var i=0; i<polylines.length; i++) {
|
||||
// var points = polylines[i].getPoints();
|
||||
// for (var j=0; j<points.length; j++) {
|
||||
// // console.log(i,points.length);
|
||||
// d += (j==0 ? "M" : "L");
|
||||
// d += Math.round(points[j].x) + "," + Math.round(points[j].y) + " ";
|
||||
// }
|
||||
// }
|
||||
// return d;
|
||||
// }
|
||||
|
||||
// function parsePathDescription(svgData) {
|
||||
// var mode = '', x=0, y=0, p=0;
|
||||
// var path = new Path();
|
||||
|
||||
// var skipSpace = function() {
|
||||
// while (svgData.charAt(p) == ' ') p++;
|
||||
// }
|
||||
|
||||
// var parser = function() {
|
||||
// while (true) {
|
||||
// skipSpace();
|
||||
|
||||
// if (p==svgData.length) {
|
||||
// return true;
|
||||
// }
|
||||
|
||||
// var c = svgData.charAt(p);
|
||||
// if (c == 'M' || c == 'm' || c == 'L' || c == 'l') { //new command letter
|
||||
// mode = c;
|
||||
// } else if (c == '"') { //end of command chain
|
||||
// return true;
|
||||
// } else { //something else, must be a pair of coordinates...
|
||||
// var tx = 0, ty = 0, numberEnd = 0, len = 0;
|
||||
// numberEnd = svgData.indexOf(',', p);
|
||||
|
||||
// ////// RC: if instead of a comma a space is used between a pair use that as a separator
|
||||
// var firstSpace = svgData.indexOf(' ', p);
|
||||
// if (firstSpace<numberEnd) numberEnd=firstSpace;
|
||||
// if (numberEnd == -1) { console.log("parsePathDescription:could not find *COMMA* in coordinate pair"); return false; }
|
||||
// len = numberEnd - p;
|
||||
// tx = parseFloat(svgData.substr(p, len));
|
||||
// p += len + 1;
|
||||
// skipSpace();
|
||||
// numberEnd = svgData.indexOf(' ', p);
|
||||
// if (numberEnd == -1) { console.log("parsePathDescription:could not find *SPACE* after coordinate pair"); return false; }
|
||||
// len = numberEnd - p;
|
||||
// ty = parseFloat(svgData.substr(p, len));
|
||||
// p += len;
|
||||
|
||||
// if (mode == 'M' || mode == 'L') {
|
||||
// x = tx; y = ty;
|
||||
// } else if (mode == 'm' || mode == 'l') {
|
||||
// x += tx; y += ty;
|
||||
// } else {
|
||||
// console.log("parsePathDescription: found coordinate pair but mode was never set");
|
||||
// return false;
|
||||
// }
|
||||
|
||||
// var isMove = mode == 'm' || mode == 'M';
|
||||
|
||||
// if (isMove) path.moveTo(x,y);
|
||||
// else path.lineTo(x,y);
|
||||
// }
|
||||
// p++;
|
||||
// }
|
||||
// }
|
||||
|
||||
// parser();
|
||||
|
||||
// return path;
|
||||
// }
|
||||
|
||||
|
||||
// this.getElement = function() {
|
||||
// return svgElement;
|
||||
// }
|
||||
|
||||
// this.getPath = function() {
|
||||
|
||||
// }
|
||||
|
||||
// }
|
|
@ -0,0 +1,180 @@
|
|||
var Viewer = function(viewer) {
|
||||
var className = "Viewer";
|
||||
var doodles = [];
|
||||
|
||||
//Object houd data bij van svg transformaties
|
||||
//(alle svg's worden automatisch hier in gezet, positie is relatief aan zijn html parent)
|
||||
// x -> x positie
|
||||
// y -> y positie
|
||||
// scale -> scale
|
||||
// svg -> svg object
|
||||
var svgsData = [];
|
||||
|
||||
console.log(className,viewer);
|
||||
|
||||
function setDoodles(_doodles) {
|
||||
doodles = _doodles;
|
||||
console.log(className,'items',doodles);
|
||||
|
||||
for (var i=0; i<doodles.length; i++) {
|
||||
var doodle = doodles[i];
|
||||
var path = doodle.getPath();
|
||||
var svgData = doodle.getSvgPathDescription();
|
||||
var box = path.getBoundingBox();
|
||||
|
||||
var svg = $('<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="640" height="540"><path xmlns="http://www.w3.org/2000/svg" fill="none" stroke="black" stroke-width="2" d="'+svgData+'"></path></svg>');
|
||||
viewer.append(svg);
|
||||
|
||||
var box = path.getBoundingBox();
|
||||
var viewbox = box.getX() + " " + box.getY() + " " + box.getWidth() + " " + box.getHeight();
|
||||
svg[0].setAttribute("viewBox", viewbox); //changig the viewBox with jQuery doesn't work (may be because of capital B)
|
||||
svg.attr('width',box.getWidth()+2);
|
||||
svg.attr('height',box.getHeight()+2);
|
||||
|
||||
initTouch(svg,doodle)
|
||||
}
|
||||
}
|
||||
|
||||
function initTouch(svg,doodle) {
|
||||
// $("svg").each(function () {
|
||||
// var svg = $(this);
|
||||
// var data = {
|
||||
// x: 0,
|
||||
// y: 0,
|
||||
// scale: 1,
|
||||
// };
|
||||
// svgsData.push(data);
|
||||
|
||||
var startX;
|
||||
var startY;
|
||||
var touchX;
|
||||
var touchY;
|
||||
var offsetX = 0;
|
||||
var offsetY = 0;
|
||||
var handleGesture = false;
|
||||
|
||||
var offsetZoom = 1;
|
||||
var zoom = 1;
|
||||
|
||||
var mouseDown = false;
|
||||
|
||||
svg.on("mousedown", function (e) {
|
||||
var event = e.originalEvent;
|
||||
mouseDown = true;
|
||||
|
||||
touchX = startX = event.pageX;
|
||||
touchY = startY = event.pageY;
|
||||
});
|
||||
|
||||
$(document).on("mousemove", function (e) {
|
||||
if (mouseDown) {
|
||||
var event = e.originalEvent;
|
||||
|
||||
touchX = event.pageX;
|
||||
touchY = event.pageY;
|
||||
|
||||
var dX = touchX - startX;
|
||||
var dY = touchY - startY;
|
||||
|
||||
svg.css({
|
||||
left: offsetX + dX,
|
||||
top: offsetY + dY
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
svg.on("mouseup", function (e) {
|
||||
var event = e.originalEvent;
|
||||
mouseDown = false;
|
||||
|
||||
offsetX = offsetX + touchX - startX;
|
||||
offsetY = offsetY + touchY - startY;
|
||||
|
||||
setData();
|
||||
});
|
||||
|
||||
svg.on("touchstart", function (e) {
|
||||
var event = e.originalEvent;
|
||||
event.preventDefault();
|
||||
|
||||
if (event.touches.length === 1) {
|
||||
var touch = event.touches[0];
|
||||
|
||||
touchX = startX = touch.pageX;
|
||||
touchY = startY = touch.pageY;
|
||||
}
|
||||
else {
|
||||
handleGesture = true;
|
||||
}
|
||||
});
|
||||
|
||||
svg.on("touchmove", function (e) {
|
||||
var event = e.originalEvent;
|
||||
event.preventDefault();
|
||||
|
||||
if (event.touches.length === 1 && !handleGesture) {
|
||||
var touch = event.touches[0];
|
||||
touchX = touch.pageX;
|
||||
touchY = touch.pageY;
|
||||
|
||||
var dX = touchX - startX;
|
||||
var dY = touchY - startY;
|
||||
|
||||
svg.css({
|
||||
left: offsetX + dX,
|
||||
top: offsetY + dY
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
svg.on("touchend", function (e) {
|
||||
var event = e.originalEvent;
|
||||
|
||||
if (event.touches.length === 0) {
|
||||
if (handleGesture) {
|
||||
handleGesture = false;
|
||||
}
|
||||
else {
|
||||
offsetX = offsetX + touchX - startX;
|
||||
offsetY = offsetY + touchY - startY;
|
||||
|
||||
setData();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
svg.swipe({
|
||||
pinchStatus: function (event, phase, direction, distance , duration , fingerCount, pinchZoom) {
|
||||
if (phase === "cancel" || phase === "end") {
|
||||
offsetZoom = offsetZoom*zoom;
|
||||
|
||||
setData();
|
||||
}
|
||||
else {
|
||||
zoom = pinchZoom;
|
||||
|
||||
svg.css({transform: "scale(" + offsetZoom*zoom + ")"});
|
||||
}
|
||||
},
|
||||
fingers: 2,
|
||||
pinchThreshold: 0
|
||||
});
|
||||
|
||||
function setData () {
|
||||
var offset = {
|
||||
x: offsetX - svg.width()*offsetZoom/2 + svg.width()/2,
|
||||
y: offsetY - svg.height()*offsetZoom/2 + svg.height()/2
|
||||
}
|
||||
doodle.setScale(offsetZoom);
|
||||
doodle.setOffset(offset);
|
||||
// data.scale = offsetZoom;
|
||||
// data.x = offsetX - svg.width()*offsetZoom/2 + svg.width()/2;
|
||||
// data.y = offsetY - svg.height()*offsetZoom/2 + svg.height()/2;
|
||||
// console.log(data);
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
setDoodles: setDoodles,
|
||||
}
|
||||
}
|
File diff suppressed because one or more lines are too long
|
@ -0,0 +1,11 @@
|
|||
/*!
|
||||
* jQuery UI Touch Punch 0.2.3
|
||||
*
|
||||
* Copyright 2011–2014, Dave Furfero
|
||||
* Dual licensed under the MIT or GPL Version 2 licenses.
|
||||
*
|
||||
* Depends:
|
||||
* jquery.ui.widget.js
|
||||
* jquery.ui.mouse.js
|
||||
*/
|
||||
!function(a){function f(a,b){if(!(a.originalEvent.touches.length>1)){a.preventDefault();var c=a.originalEvent.changedTouches[0],d=document.createEvent("MouseEvents");d.initMouseEvent(b,!0,!0,window,1,c.screenX,c.screenY,c.clientX,c.clientY,!1,!1,!1,!1,0,null),a.target.dispatchEvent(d)}}if(a.support.touch="ontouchend"in document,a.support.touch){var e,b=a.ui.mouse.prototype,c=b._mouseInit,d=b._mouseDestroy;b._touchStart=function(a){var b=this;!e&&b._mouseCapture(a.originalEvent.changedTouches[0])&&(e=!0,b._touchMoved=!1,f(a,"mouseover"),f(a,"mousemove"),f(a,"mousedown"))},b._touchMove=function(a){e&&(this._touchMoved=!0,f(a,"mousemove"))},b._touchEnd=function(a){e&&(f(a,"mouseup"),f(a,"mouseout"),this._touchMoved||f(a,"click"),e=!1)},b._mouseInit=function(){var b=this;b.element.bind({touchstart:a.proxy(b,"_touchStart"),touchmove:a.proxy(b,"_touchMove"),touchend:a.proxy(b,"_touchEnd")}),c.call(b)},b._mouseDestroy=function(){var b=this;b.element.unbind({touchstart:a.proxy(b,"_touchStart"),touchmove:a.proxy(b,"_touchMove"),touchend:a.proxy(b,"_touchEnd")}),d.call(b)}}}(jQuery);
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue