added working prev/next/save functionality

This commit is contained in:
Rick Companje 2013-10-29 23:26:09 +01:00
parent 8745e037a4
commit 0b5cf1a5f4
5 changed files with 331 additions and 19 deletions

View File

@ -32,7 +32,8 @@ module.exports = function(grunt) {
'js_src/utils.js',
'js_src/sidebar.js',
'js_src/Message.js',
'js_src/main.js'
'js_src/main.js',
'js_src/sketches.js'
],
dest: 'www/js/<%= pkg.name %>.js'
}

View File

@ -45,6 +45,10 @@ function initButtonBehavior() {
btnNew.on('touchstart mousedown', clearDoodle);
btnPrint.on('touchstart mousedown', print);
getSavedSketchStatus();
setSketchModified(false);
//updatePrevNextButtonStateOnClear();
// btnClear.click(function(e) {
// e.preventDefault();
// // console.log("clear");
@ -191,13 +195,13 @@ function stopPrint() {
}
function prevDoodle(e) {
console.log("f:prevDoodle()");
console.log("f:prevDoodle()");
}
function nextDoodle(e) {
console.log("f:nextDoodle()");
}
// function prevDoodle(e) {
// console.log("f:prevDoodle()");
// console.log("f:prevDoodle()");
// }
// function nextDoodle(e) {
// console.log("f:nextDoodle()");
// }
function print(e) {
console.log("f:print() >> sendPrintCommands = " + sendPrintCommands);
@ -285,6 +289,8 @@ function previewUp(redrawLess) {
if (numLayers < maxNumLayers) {
numLayers++;
}
setSketchModified(true);
// redrawPreview(redrawLess);
redrawRenderedPreview(redrawLess);
}
@ -293,6 +299,7 @@ function previewDown(redrawLess) {
if (numLayers > minNumLayers) {
numLayers--;
}
setSketchModified(true);
// redrawPreview(redrawLess);
redrawRenderedPreview(redrawLess);
}
@ -302,12 +309,14 @@ function previewTwistLeft(redrawLess) {
if (rStep > -previewRotationLimit) rStep -= twistIncrement;
// redrawPreview(redrawLess);
redrawRenderedPreview(redrawLess);
setSketchModified(true);
}
function previewTwistRight(redrawLess) {
// console.log("f:previewTwistRight()");
if (rStep < previewRotationLimit) rStep += twistIncrement;
// redrawPreview(redrawLess);
redrawRenderedPreview(redrawLess);
setSketchModified(true);
}
@ -390,20 +399,14 @@ function setState(newState,newHasControl) {
/* save, next and prev buttons */
switch(newState) {
/*case Printer.WIFIBOX_DISCONNECTED_STATE:
case Printer.WIFIBOX_DISCONNECTED_STATE:
disableButton(btnPrevious);
disableButton(btnNext);
disableButton(btnSave);
break;
default:
enableButton(btnPrevious, null);
enableButton(btnNext, null);
enableButton(btnSave, null);
break;*/
default:
disableButton(btnPrevious);
disableButton(btnNext);
disableButton(btnSave);
updatePrevNextButtonState();
if (isModified) enableButton(btnSave, saveSketch);
break;
}

View File

@ -29,6 +29,8 @@ var movementCounter = 0;
var drawVariableLineWeight = false; // set to true to have the momentum of the mouse/touch movement result in larger/smaller strokes
var lineweight = 2;
var isModified = false;
/* * * * * * * * * *
*
* INIT
@ -146,6 +148,8 @@ function draw(_x, _y, _width) {
function clearDoodle() {
console.log("f:clearDoodle");
updatePrevNextButtonStateOnClear();
_points = [];
prevX = 0;
@ -162,6 +166,8 @@ function clearDoodle() {
clearMainView();
resetPreview();
resetVerticalShapes();
setSketchModified(false);
}
function redrawDoodle(recalcBoundsAndTransforms) {
@ -258,6 +264,8 @@ function adjustPreviewTransformation() {
*
* * * * * * * * * */
function onCanvasMouseDown(e) {
setSketchModified(true);
// console.log("f:onCanvasMouseDown()");
// console.log("onCanvasMouseDown >> e.offsetX,e.offsetY = " + e.offsetX+","+e.offsetY);
// console.log("onCanvasMouseDown >> e.layerX,e.layerY= " + e.layerX+","+e.layerY);
@ -285,8 +293,12 @@ function onCanvasMouseDown(e) {
var prevPoint = {x:-1, y:-1};
function onCanvasMouseMove(e) {
// console.log("f:onCanvasMouseMove()");
if (!dragging) return;
setSketchModified(true);
// console.log("onmousemove");
var x, y;
@ -360,6 +372,8 @@ function onCanvasMouseUp(e) {
}
function onCanvasTouchDown(e) {
setSketchModified(true);
e.preventDefault();
console.log("f:onCanvasTouchDown >> e: " , e);
// var x = e.touches[0].pageX - e.touches[0].target.offsetLeft;
@ -382,6 +396,8 @@ function onCanvasTouchDown(e) {
}
function onCanvasTouchMove(e) {
setSketchModified(true);
e.preventDefault();
// var x = e.touches[0].pageX - e.touches[0].target.offsetLeft;
// var y = e.touches[0].pageY - e.touches[0].target.offsetTop;
@ -458,4 +474,139 @@ function onCanvasTouchEnd(e) {
function prevent(e) {
e.preventDefault();
}
}
//SVG validator: http://validator.w3.org/
//SVG viewer: http://svg-edit.googlecode.com/svn/branches/2.6/editor/svg-editor.html
function saveToSvg() {
var lastX = 0, lastY = 0, lastIsMove;
var svg = '';
var boundsWidth = doodleBounds[2] - doodleBounds[0];
var boundsHeight = doodleBounds[3] - doodleBounds[1];
svg += '<?xml version="1.0" standalone="no"?>\n';
svg += '<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">\n';
svg += '<svg width="' + boundsWidth + '" height="' + boundsHeight + '" version="1.1" xmlns="http://www.w3.org/2000/svg">\n';
svg += '\t<desc>Doodle 3D sketch</desc>\n';
var data = '';
for (var i = 0; i < _points.length; ++i) {
var x = _points[i][0], y = _points[i][1], isMove = _points[i][2];
var dx = x - lastX, dy = y - lastY;
if (i == 0)
data += 'M'; //emit absolute move on first pair of coordinates
else if (isMove != lastIsMove)
data += isMove ? 'm' : 'l';
data += dx + ',' + dy + ' ';
lastX = x;
lastY = y;
lastIsMove = isMove;
}
svg += '\t<path transform="translate(' + -doodleBounds[0] + ',' + -doodleBounds[1] + ')" d="' + data + '" fill="none" stroke="black" stroke-width="2" />\n';
var fields = JSON.stringify({'height': numLayers, 'outlineShape': VERTICALSHAPE, 'twist': rStep});
svg += '\t<!--<![CDATA[d3d-keys ' + fields + ']]>-->\n';
svg += '</svg>\n';
return svg;
}
//TODO: use local variables instead of _points,numLayers,VERTICALSHAPE and rStep so we can leave a current doodle in tact if an error occurs while parsing
function loadFromSvg(svgData) {
var mode = '', x = 0, y = 0;
console.log("loading " + svgData.length + " bytes of data...");
clearDoodle();
var p = svgData.indexOf("<path");
if (p == -1) { console.log("loadFromSvg: could not find parsing start point"); return false; }
p = svgData.indexOf('d="', p);
if (p == -1) { console.log("loadFromSvg: could not find parsing start point"); return false; }
p += 3; //skip 'd="'
var skipSpace = function() { while (svgData.charAt(p) == ' ') p++; }
var parseCommand = function() {
while (true) {
skipSpace();
var c = svgData.charAt(p);
if (c == 'M' || c == 'm' || 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);
if (numberEnd == -1) { console.log("could not find comma in coordinate pair"); return false; }
len = numberEnd - p;
tx = parseInt(svgData.substr(p, len));
p += len + 1;
skipSpace();
numberEnd = svgData.indexOf(' ', p);
if (numberEnd == -1) { console.log("could not find space after coordinate pair"); return false; }
len = numberEnd - p;
ty = parseInt(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("loadFromSvg: found coordinate pair but mode was never set");
return false;
}
var isMove = mode == 'm' || mode == 'M';
//TODO: create script-wide function for adding points?
//console.log("inserting "+x+","+y+" ",isMove);
updatePrevX = x;
updatePrevY = y;
_points.push([x, y, isMove]);
adjustBounds(x, y);
adjustPreviewTransformation();
if (isMove) draw(x, y, .5);
else draw(x, y);
}
p++;
}
return true;
};
parseCommand(); //depends on value of p, so don't move this without taking that into consideration
const fieldDefMarker = "<!--<![CDATA[d3d-keys";
p = svgData.indexOf(fieldDefMarker);
if (p == -1) { console.log("loadFromSvg: could not find metadata marker"); return false; }
p += fieldDefMarker.length;
skipSpace();
var endP = svgData.indexOf("]]>-->", p);
if (endP == -1) { console.log("loadFromSvg: could not find metadata end-marker"); return false; }
var metaFields = JSON.parse(svgData.substr(p, endP - p));
//TODO: log error and return false if parsing failed
for (var k in metaFields) {
var v = metaFields[k];
switch (k) {
case "height": numLayers = v; break;
case "outlineShape": VERTICALSHAPE = v; break;
case "twist": rStep = v; break;
}
}
renderToImageDataPreview();
return true;
}

156
js_src/sketches.js Normal file
View File

@ -0,0 +1,156 @@
var currentSketchId = 0;
var numSavedSketches = 0;
function getSavedSketchStatus() {
$.ajax({
url: wifiboxURL + "/sketch/status",
dataType: 'json',
type: 'GET',
//timeout: this.timeoutTime,
success: function(response) {
if (response.status == 'error' || response.status == 'fail') {
console.log("getSavedSketchStatus fail/error: " + response.msg + " -- ", response);
} else {
console.log("getSavedSketchStatus success: num. saved: " + response.data.number_of_sketches + ", space available: " + response.data.available);
numSavedSketches = response.data.number_of_sketches;
updatePrevNextButtonStateOnClear();
}
}
}).fail(function() {
console.log("getSavedSketchStatus failed: ", response);
});
}
function setSketchModified(_isModified, doNotClearCurrent) {
isModified = _isModified;
// alert("isModified: " + isModified);
//console.log("setModified: " + isModified + (typeof(doNotClearCurrent) !== 'undefined' ? " (doNotClearCurrent: "+doNotClearCurrent+")" : "")); //TEMP
if (isModified) enableButton(btnSave, saveSketch);
else disableButton(btnSave);
//if (typeof(doNotClearCurrent) !== 'undefined' && !doNotClearCurrent) setCurrentSketchId(-1);
//sketchModified = isModified; /// ERROR?
}
function setCurrentSketchId(sId) {
console.log("setCurrentSketchId: " + sId + " / " + numSavedSketches);
// var enablePrev = false;
// var enableNext = false;
currentSketchId = sId;
//clamp
if (currentSketchId > numSavedSketches) currentSketchId = numSavedSketches;
if (currentSketchId < 1) currentSketchId = 1;
//update textbox
//$("#txtSketch").val(currentSketchId);
updatePrevNextButtonState();
}
function updatePrevNextButtonStateOnClear() {
enableButton(btnPrevious, prevDoodle);
disableButton(btnNext);
currentSketchId = numSavedSketches+1; //after the end of the list
disableButton(btnSave);
}
function updatePrevNextButtonState() {
//btnPrevious state
if (numSavedSketches==0 || currentSketchId < 2) {
disableButton(btnPrevious);
} else {
enableButton(btnPrevious, prevDoodle);
}
//btnNext state
if (numSavedSketches==0 || currentSketchId >= numSavedSketches) {
disableButton(btnNext);
} else {
enableButton(btnNext, nextDoodle);
}
}
function loadSketch(sketchId) {
$.ajax({
url: wifiboxURL + "/sketch/" + sketchId,
dataType: 'json',
type: 'GET',
// timeout: this.timeoutTime,
success: function(response) {
if (response.status == 'error' || response.status == 'fail') {
console.log("loadSketch fail/error: " + response.msg + " -- ", response);
} else {
console.log("loadSketch success: loaded id #" + response.data.id, response);
//console.log("sketch content:\n" + response.data.data);
if (loadFromSvg(response.data.data)) {
setSketchModified(false, true);
setCurrentSketchId(response.data.id);
}
}
}
}).fail(function() {
console.log("loadSketch failed: ", response);
});
}
//btnSave.mouseup(saveSketch);
function saveSketch() {
svg = saveToSvg();
console.log("generated SVG [" + _points.length + " points, " + svg.length + " bytes]:\n" + svg);
$.ajax({
url: wifiboxURL + "/sketch",
dataType: 'json',
type: 'POST',
data: { data: svg },
//timeout: this.timeoutTime,
success: function(response) {
if (response.status == 'error' || response.status == 'fail') {
console.log("saveSketch fail/error: " + response.msg + " -- ", response);
} else {
console.log("saveSketch success: saved with id #" + response.data.id, response);
setSketchModified(false, true);
numSavedSketches = response.data.id;
setCurrentSketchId(response.data.id);
}
}
}).fail(function() {
console.log("saveSketch failed: ", response);
});
}
function prevDoodle(e) {
console.log("f:prevDoodle(): " + currentSketchId + " / " + numSavedSketches);
//alert('prev ' + numSavedSketches);
//return;
//TODO: if (enabled) {
var sketchId = (currentSketchId > 0) ? currentSketchId : numSavedSketches;
if (sketchId > 1) sketchId--;
//alert(sketchId);
loadSketch(sketchId);
//}
}
function nextDoodle(e) {
console.log("f:nextDoodle()");
//alert('next ' + numSavedSketches);
//return;
//TODO: if (enabled) {
var sketchId = (currentSketchId > 0) ? currentSketchId : numSavedSketches;
if (sketchId < numSavedSketches) sketchId++;
loadSketch(sketchId);
//}
}

View File

@ -31,9 +31,10 @@
<div class="leftpanel shadowright">
<div class='sidebutton shadowright'></div>
<img class="btnNew btn" src="img/buttons/btnNew.png" /><br/>
<div class="btnsPrevNext">
<div class="btnsPrevNext" style="text-align:center">
<img class="btnPrevious btn" src="img/buttons/btnLeft.png">
<img class="btnNext btn" src="img/buttons/btnRight.png">
<!-- <div id="txtSketch"></div> -->
</div>
<img class="btnSave btn" src="img/buttons/btnSave.png" /><br/>
<img class="btnOops btn" src="img/buttons/btnOops.png" /><br/>