Changes to how we draw to the canvas and how the preview is rendered. This has massive speedup results for tablets and phones.

This commit is contained in:
Adriaan Wormgoor 2013-08-16 22:27:26 +02:00
parent aa82d6daa8
commit ed8ceb7879
3 changed files with 228 additions and 139 deletions

View File

@ -118,16 +118,17 @@ function initButtonBehavior() {
function startMoveUp(e) { function startMoveUp(e) {
e.preventDefault(); e.preventDefault();
// console.log("btnMoveUp mouse down"); // console.log("btnMoveUp mouse down");
previewUp(); previewUp(true);
clearInterval(btnMoveUpInterval); clearInterval(btnMoveUpInterval);
btnMoveUpInterval = setInterval( function() { btnMoveUpInterval = setInterval( function() {
previewUp(); previewUp(true);
}, 1000/30); }, 1000/30);
} }
function stopMoveUp(e) { function stopMoveUp(e) {
e.preventDefault(); e.preventDefault();
console.log("btnMoveUp mouse up"); console.log("btnMoveUp mouse up");
clearInterval(btnMoveUpInterval); clearInterval(btnMoveUpInterval);
previewUp();
} }
btnMoveUp.mousedown(function(e) { startMoveUp(e) }); btnMoveUp.mousedown(function(e) { startMoveUp(e) });
btnMoveUp.mouseup(function(e) { stopMoveUp(e) }); btnMoveUp.mouseup(function(e) { stopMoveUp(e) });
@ -137,16 +138,17 @@ function initButtonBehavior() {
function startMoveDown(e) { function startMoveDown(e) {
e.preventDefault(); e.preventDefault();
// console.log("btnMoveDown mouse down"); // console.log("btnMoveDown mouse down");
previewDown(); previewDown(true);
clearInterval(btnMoveDownInterval); clearInterval(btnMoveDownInterval);
btnMoveDownInterval = setInterval( function() { btnMoveDownInterval = setInterval( function() {
previewDown(); previewDown(true);
}, 1000/30); }, 1000/30);
} }
function stopMoveDown(e) { function stopMoveDown(e) {
e.preventDefault(); e.preventDefault();
console.log("btnMoveDown mouse up"); console.log("btnMoveDown mouse up");
clearInterval(btnMoveDownInterval); clearInterval(btnMoveDownInterval);
previewDown();
} }
btnMoveDown.mousedown(function(e) { startMoveDown(e) }); btnMoveDown.mousedown(function(e) { startMoveDown(e) });
btnMoveDown.mouseup(function(e) { stopMoveDown(e) }); btnMoveDown.mouseup(function(e) { stopMoveDown(e) });
@ -156,16 +158,17 @@ function initButtonBehavior() {
function startTwistLeft(e) { function startTwistLeft(e) {
e.preventDefault(); e.preventDefault();
// console.log("btnTwistLeft mouse down"); // console.log("btnTwistLeft mouse down");
previewTwistLeft(); previewTwistLeft(true);
clearInterval(btnTwistLeftInterval); clearInterval(btnTwistLeftInterval);
btnTwistLeftInterval = setInterval( function() { btnTwistLeftInterval = setInterval( function() {
previewTwistLeft(); previewTwistLeft(true);
}, 1000/30); }, 1000/30);
} }
function stopTwistLeft(e) { function stopTwistLeft(e) {
e.preventDefault(); e.preventDefault();
// console.log("btnTwistLeft mouse up"); // console.log("btnTwistLeft mouse up");
clearInterval(btnTwistLeftInterval); clearInterval(btnTwistLeftInterval);
previewTwistLeft();
} }
btnTwistLeft.mousedown(function(e) { startTwistLeft(e) }); btnTwistLeft.mousedown(function(e) { startTwistLeft(e) });
btnTwistLeft.mouseup(function(e) { stopTwistLeft(e) }); btnTwistLeft.mouseup(function(e) { stopTwistLeft(e) });
@ -175,16 +178,17 @@ function initButtonBehavior() {
function startTwistRight(e) { function startTwistRight(e) {
e.preventDefault(); e.preventDefault();
// console.log("btnTwistRight mouse down"); // console.log("btnTwistRight mouse down");
previewTwistRight(); previewTwistRight(true);
clearInterval(btnTwistRightInterval); clearInterval(btnTwistRightInterval);
btnTwistRightInterval = setInterval( function() { btnTwistRightInterval = setInterval( function() {
previewTwistRight(); previewTwistRight(true);
}, 1000/30); }, 1000/30);
} }
function stopTwistRight(e) { function stopTwistRight(e) {
e.preventDefault(); e.preventDefault();
// console.log("btnTwistRight mouse up"); // console.log("btnTwistRight mouse up");
clearInterval(btnTwistRightInterval); clearInterval(btnTwistRightInterval);
previewTwistLeft();
} }
btnTwistRight.mousedown(function(e) { startTwistRight(e) }); btnTwistRight.mousedown(function(e) { startTwistRight(e) });
btnTwistRight.mouseup(function(e) { stopTwistRight(e) }); btnTwistRight.mouseup(function(e) { stopTwistRight(e) });
@ -223,49 +227,56 @@ function initButtonBehavior() {
btnStop.bind('touchstart mousedown',stopPrint); btnStop.bind('touchstart mousedown',stopPrint);
} }
function stopPrint() { function stopPrint() {
printer.stop(); console.log("f:stopPrint() >> sendPrintCommands = " + sendPrintCommands);
if (sendPrintCommands) printer.stop();
} }
function prevDoodle(e) { function prevDoodle(e) {
console.log("f:prevDoodle()"); console.log("f:prevDoodle()");
console.log("f:prevDoodle()");
} }
function nextDoodle(e) { function nextDoodle(e) {
console.log("f:nextDoodle()"); console.log("f:nextDoodle()");
} }
function print(e) { function print(e) {
console.log("f:print()"); console.log("f:print() >> sendPrintCommands = " + sendPrintCommands);
$("#textdump").text(""); if (sendPrintCommands) {
if (_points.length > 2) { $("#textdump").text("");
if (_points.length > 2) {
setState(PRINTING_STATE); setState(PRINTING_STATE);
var gcode = generate_gcode(); var gcode = generate_gcode();
//startPrint(gencode); //startPrint(gencode);
printer.print(gcode); printer.print(gcode);
// console.log(""); // console.log("");
// console.log(""); // console.log("");
// console.log("-------------------------------------------------"); // console.log("-------------------------------------------------");
// console.log("generated gcode:"); // console.log("generated gcode:");
// console.log(gencode); // console.log(gencode);
// console.log("-------------------------------------------------"); // console.log("-------------------------------------------------");
// console.log(""); // console.log("");
// console.log(""); // console.log("");
// console.log(""); // console.log("");
$("#textdump").text(gcode.join("\n")); if (debugMode) $("#textdump").text(gcode.join("\n"));
// copyToClipboard(gencode);
//*/ // copyToClipboard(gencode);
} else { //*/
console.log("f:print >> not enough points!"); } else {
} console.log("f:print >> not enough points!");
}
// $.post("/doodle3d.of", { data:output }, function(data) { // $.post("/doodle3d.of", { data:output }, function(data) {
// btnPrint.disabled = false; // btnPrint.disabled = false;
// }); // });
} else {
console.log("sendPrintCommands is false: not sending print command to 3dprinter");
}
} }
@ -288,33 +299,34 @@ function oopsUndo() {
redrawDoodle(); redrawDoodle();
redrawPreview(); redrawPreview();
} }
function previewUp() { function previewUp(redrawLess) {
// console.log("f:previewUp()"); // console.log("f:previewUp()");
if (numLayers < 100) { if (numLayers < 100) {
numLayers++; numLayers++;
} }
redrawPreview(); redrawPreview(redrawLess);
} }
function previewDown() { function previewDown(redrawLess) {
// console.log("f:previewDown()"); // console.log("f:previewDown()");
if (numLayers > 2) { if (numLayers > 2) {
numLayers--; numLayers--;
} }
redrawPreview(); redrawPreview(redrawLess);
} }
function previewTwistLeft() { function previewTwistLeft(redrawLess) {
if (redrawLess == undefined) redrawLess = false;
// console.log("f:previewTwistLeft()"); // console.log("f:previewTwistLeft()");
// if (rStep < Math.PI) { // if (rStep < Math.PI) {
rStep -= twistIncrement; rStep -= twistIncrement;
// } // }
redrawPreview(); redrawPreview(redrawLess);
} }
function previewTwistRight() { function previewTwistRight(redrawLess) {
// console.log("f:previewTwistRight()"); // console.log("f:previewTwistRight()");
// if (rStep < Math.PI) { // if (rStep < Math.PI) {
rStep += twistIncrement; rStep += twistIncrement;
// } // }
redrawPreview(); redrawPreview(redrawLess);
} }

View File

@ -139,6 +139,9 @@ function clearDoodle() {
prevX = 0; prevX = 0;
prevY = 0; prevY = 0;
updatePrevX = -1;
updatePrevY = -1;
doodleBounds = [-1, -1, -1, -1]; // left, top, right, bottom doodleBounds = [-1, -1, -1, -1]; // left, top, right, bottom
doodleTransform = [0, 0, 1.0, 1.0]; // [ x, y, scaleX, scaleY ] doodleTransform = [0, 0, 1.0, 1.0]; // [ x, y, scaleX, scaleY ]
@ -165,6 +168,7 @@ function redrawDoodle() {
} }
function adjustBounds(x, y) { function adjustBounds(x, y) {
var newPointsOutsideOfCurrentBounds = false;
// console.log("f:adjustBounds("+x+","+y+")"); // console.log("f:adjustBounds("+x+","+y+")");
if (doodleBounds[0] == -1) { if (doodleBounds[0] == -1) {
@ -177,11 +181,27 @@ function redrawDoodle() {
return; return;
} }
doodleBounds[0] = Math.min(doodleBounds[0], x); // left if (x < doodleBounds[0]) {
doodleBounds[2] = Math.max(doodleBounds[2], x); // right doodleBounds[0] = x;
newPointsOutsideOfCurrentBounds = true;
doodleBounds[1] = Math.min(doodleBounds[1], y); // top }
doodleBounds[3] = Math.max(doodleBounds[3], y); // bottom if (x > doodleBounds[2]) {
doodleBounds[2] = x;
newPointsOutsideOfCurrentBounds = true;
}
if (y < doodleBounds[1]) {
doodleBounds[1] = y;
newPointsOutsideOfCurrentBounds = true;
}
if (y > doodleBounds[3]) {
doodleBounds[3] = y;
newPointsOutsideOfCurrentBounds = true;
}
// doodleBounds[0] = Math.min(doodleBounds[0], x); // left
// doodleBounds[2] = Math.max(doodleBounds[2], x); // right
//
// doodleBounds[1] = Math.min(doodleBounds[1], y); // top
// doodleBounds[3] = Math.max(doodleBounds[3], y); // bottom
// draw the bounding rect (DEBUG) // draw the bounding rect (DEBUG)
/* /*
@ -195,6 +215,7 @@ function redrawDoodle() {
// console.log(" new bounds: " + doodleBounds); // console.log(" new bounds: " + doodleBounds);
return newPointsOutsideOfCurrentBounds;
} }
// does what exactly? // does what exactly?
@ -264,15 +285,11 @@ function onCanvasMouseDown(e) {
draw(x, y, 0.5); draw(x, y, 0.5);
} }
var prevPoint = {x:-1, y:-1};
function onCanvasMouseMove(e) { function onCanvasMouseMove(e) {
if (!dragging) return; if (!dragging) return;
// console.log("onmousemove"); // console.log("onmousemove");
// _points.push([e.clientX - canvas.offsetLeft, e.clientY - canvas.offsetTop, false]);
// adjustBounds(e.clientX - canvas.offsetLeft, e.clientY - canvas.offsetTop);
// adjustPreviewTransformation();
// draw(e.clientX - canvas.offsetLeft, e.clientY - canvas.offsetTop);
var x, y; var x, y;
if (e.offsetX != undefined) { if (e.offsetX != undefined) {
x = e.offsetX; x = e.offsetX;
@ -282,21 +299,24 @@ function onCanvasMouseMove(e) {
y = e.layerY; y = e.layerY;
} }
_points.push([x, y, false]); if (prevPoint.x != -1 || prevPoint.y != -1) {
adjustBounds(x, y); var dist = Math.sqrt(Math.pow((prevPoint.x - x), 2) + Math.pow((prevPoint.y - y), 2));
adjustPreviewTransformation(); if (dist > 5) {
draw(x, y); _points.push([x, y, false]);
adjustBounds(x, y)
// update counter -> this was for getting a handle on how often the Canvas fires a move-event adjustPreviewTransformation();
/* draw(x, y);
movementCounter++; prevPoint.x = x;
if (new Date().getTime() - prevCountingTime > 1000) { prevPoint.y = y;
// console.log("number of moves in 1sec: " + movementCounter) }
prevCountingTime= new Date().getTime(); } else {
$("#numtimes").text(movementCounter + " times"); _points.push([x, y, false]);
movementCounter = 0; adjustBounds(x, y)
adjustPreviewTransformation();
draw(x, y);
prevPoint.x = x;
prevPoint.y = y;
} }
//*/
// DEBUG // DEBUG
// $("#textdump").text(""); // $("#textdump").text("");
@ -304,7 +324,12 @@ function onCanvasMouseMove(e) {
// $("#textdump").append("doodletransform:" + doodleTransform + "\n"); // $("#textdump").append("doodletransform:" + doodleTransform + "\n");
if (new Date().getTime() - prevRedrawTime > redrawInterval) { if (new Date().getTime() - prevRedrawTime > redrawInterval) {
redrawPreview(); // redrawing the whole preview the first X points ensures that the doodleBounds is set well
if (_points.length < 50) {
redrawPreview();
} else {
updatePreview(x, y, true);
}
prevRedrawTime = new Date().getTime(); prevRedrawTime = new Date().getTime();
} }
} }
@ -351,11 +376,24 @@ function onCanvasTouchMove(e) {
var x = e.touches[0].pageX - drawCanvasTopLeftCoords[0]; var x = e.touches[0].pageX - drawCanvasTopLeftCoords[0];
var y = e.touches[0].pageY - drawCanvasTopLeftCoords[1]; var y = e.touches[0].pageY - drawCanvasTopLeftCoords[1];
_points.push([x, y, false]); if (prevPoint.x != -1 || prevPoint.y != -1) {
adjustBounds(x, y); var dist = Math.sqrt(Math.pow((prevPoint.x - x), 2) + Math.pow((prevPoint.y - y), 2));
adjustPreviewTransformation(); if (dist > 5) {
draw(x, y); _points.push([x, y, false]);
adjustBounds(x, y)
adjustPreviewTransformation();
draw(x, y);
prevPoint.x = x;
prevPoint.y = y;
}
} else {
_points.push([x, y, false]);
adjustBounds(x, y)
adjustPreviewTransformation();
draw(x, y);
prevPoint.x = x;
prevPoint.y = y;
}
// update counter -> this was for getting a handle on how often the Canvas fires a move-event // update counter -> this was for getting a handle on how often the Canvas fires a move-event
/* /*
@ -369,36 +407,27 @@ function onCanvasTouchMove(e) {
//*/ //*/
if (new Date().getTime() - prevRedrawTime > redrawInterval) { if (new Date().getTime() - prevRedrawTime > redrawInterval) {
redrawPreview(); // redrawing the whole preview the first X points ensures that the doodleBounds is set well
if (_points.length < 50) {
redrawPreview();
} else {
updatePreview(x, y, true);
}
prevRedrawTime = new Date().getTime(); prevRedrawTime = new Date().getTime();
} }
} }
function onCanvasTouchEnd(e) { function onCanvasTouchEnd(e) {
// console.log("ontouchend"); // console.log("ontouchend");
console.log("doodleBounds: " + doodleBounds);
console.log("doodleTransform: " + doodleTransform);
// ctx.stroke();
console.log("_points.length :" + _points.length);
redrawPreview(); redrawPreview();
} }
function prevent(e) { function prevent(e) {
e.preventDefault(); e.preventDefault();
} }
/*
function print(e) {
output = path.attributes.d.nodeValue;
console.log(output);
output = output.split("M").join("\n");
output = output.split(" L").join("_");
output = output.split(" ").join(",");
output = output.split("_").join(" ");
output = "\nBEGIN\n" + output + "\n\nEND\n";
$.post("/doodle3d.of", { data:output }, function(data) {
btnPrint.disabled = false;
});
}
//*/

View File

@ -11,7 +11,7 @@ var svgPathRegExp = /[LM]\d* \d*/ig;
var svgPathParamsRegExp = /([LM])(\d*) (\d*)/; var svgPathParamsRegExp = /([LM])(\d*) (\d*)/;
var prevRedrawTime = new Date().getTime(); var prevRedrawTime = new Date().getTime();
var redrawInterval = 1000 / 20; // ms var redrawInterval = 1000 / 30; // ms
function initPreviewRendering() { function initPreviewRendering() {
console.log("f:initPreviewRendering()"); console.log("f:initPreviewRendering()");
@ -44,7 +44,9 @@ var prevY = 0;
var highlight = true; //highlight bottom, middle and top layers var highlight = true; //highlight bottom, middle and top layers
var linesRaw = ""; var linesRaw = "";
function redrawPreview() { var debug_redrawSimplification = 6;
function redrawPreview(redrawLess) {
if (redrawLess == undefined) redrawLess = false;
//*/ //*/
//TODO //TODO
/* /*
@ -53,6 +55,26 @@ function redrawPreview() {
niet? niet?
*/ */
if (!redrawLess) {
//debug_redrawSimplification = Math.round(_points.length / 65);
//*
if (_points.length < 100) {
debug_redrawSimplification = 6;
} else if (_points.length < 250) {
debug_redrawSimplification = 7;
} else if (_points.length < 400) {
debug_redrawSimplification = 8;
} else if (_points.length < 550) {
debug_redrawSimplification = 9;
} else if (_points.length < 700) {
debug_redrawSimplification = 10;
} else {
debug_redrawSimplification = 11;
}
//*/
// console.log("debug_redrawSimplification: " + debug_redrawSimplification);
}
if (_points.length < 2) return; if (_points.length < 2) return;
var y = 0; var y = 0;
@ -65,12 +87,19 @@ function redrawPreview() {
for(var i = 0; i < numLayers; i++) { for(var i = 0; i < numLayers; i++) {
if(i == 0 || i == Math.floor(numLayers/2) || i == numLayers-1){
if(i == 0 || i == Math.floor(numLayers/2) || i == numLayers-1) {
previewCtx.globalAlpha = 1; previewCtx.globalAlpha = 1;
} else { } else {
previewCtx.globalAlpha = globalAlpha; previewCtx.globalAlpha = globalAlpha;
} }
if (redrawLess && i%debug_redrawSimplification != 0 && !(i == 0 || i == Math.floor(numLayers/2) || i == numLayers-1) ) {
y -= yStep;
r += rStep;
continue;
}
previewCtx.save(); previewCtx.save();
previewCtx.translate(layerCX, layerOffsetY + layerCY + y); previewCtx.translate(layerCX, layerOffsetY + layerCY + y);
@ -89,6 +118,9 @@ function redrawPreview() {
previewCtx.moveTo(adjustedDoodlePoint.x, adjustedDoodlePoint.y); previewCtx.moveTo(adjustedDoodlePoint.x, adjustedDoodlePoint.y);
for(var j = 1; j < _points.length; j++) { for(var j = 1; j < _points.length; j++) {
adjustedDoodlePoint = centeredAndScaledDoodlePoint(_points[j]) adjustedDoodlePoint = centeredAndScaledDoodlePoint(_points[j])
// if (redrawLess && Math.floor(j/debug_redrawSimplification)%2 == 0 ) continue;
// if (redrawLess && Math.floor(j/debug_redrawSimplification)%2 == 0 ) continue;
if (redrawLess && j%debug_redrawSimplification != 0 ) continue;
previewCtx.lineTo(adjustedDoodlePoint.x, adjustedDoodlePoint.y); previewCtx.lineTo(adjustedDoodlePoint.x, adjustedDoodlePoint.y);
} }
previewCtx.stroke(); previewCtx.stroke();
@ -113,49 +145,65 @@ function centeredAndScaledDoodlePoint(p) {
return obj; return obj;
} }
/* //*
function updatePreview(x, y, move) { var updatePrevX = -1;
x *= globalScale; var updatePrevY = -1;
y *= globalScale; function updatePreview(_x, _y, redrawLess) {
if (redrawLess == undefined) redrawLess = false;
redrawLess = false;
if(!move) { if (_points.length < 2) return;
var tY = 0; if (updatePrevX == -1 || updatePrevY == -1) {
var r = 0; updatePrevX = _x;
updatePrevY = _y;
if(!highlight) { return;
previewCtx.globalAlpha = globalAlpha;
previewCtx.beginPath();
}
for(var i=0;i<numLayers;i++) {
if(highlight && (i == 0 || i == numLayers/2 || i == numLayers-1)){
previewCtx.stroke();
previewCtx.globalAlpha = 1;
previewCtx.beginPath();
}
previewCtx.save();
previewCtx.translate(layerCX,layerOffsetY+layerCY+tY);
previewCtx.scale(1, scaleY)
previewCtx.rotate(r);
previewCtx.translate(-layerCX,-layerCY);
previewCtx.moveTo(prevX,prevY);
previewCtx.lineTo(x,y);
tY -= yStep;
r += rStep;
previewCtx.restore();
if(highlight && (i == 0 || i == numLayers/2 || i == numLayers-1)){
previewCtx.stroke();
previewCtx.globalAlpha = globalAlpha;
previewCtx.beginPath();
}
}
} }
previewCtx.stroke();
prevX = x; // if (_points.length < 16 && Math.sqrt(Math.pow((updatePrevX - _x), 2) + Math.pow((updatePrevY - _y), 2)) < 8) return;
prevY = y;
var y = 0;
var r = 0;
previewCtx.lineWidth = strokeWidth;
previewCtx.strokeStyle = '#f00'; //"rgba(255,255,0,0)";
for(var i = 0; i < numLayers; i++) {
if(i == 0 || i == Math.floor(numLayers/2) || i == numLayers-1) {
previewCtx.globalAlpha = 1;
} else {
previewCtx.globalAlpha = globalAlpha;
}
if (redrawLess && i%debug_redrawSimplification != 0 && !(i == 0 || i == Math.floor(numLayers/2) || i == numLayers-1) ) {
y -= yStep;
r += rStep;
continue;
}
previewCtx.save();
previewCtx.translate(layerCX, layerOffsetY + layerCY + y);
previewCtx.scale(viewerScale, scaleY * viewerScale);
previewCtx.rotate(r);
previewCtx.translate((-doodleTransform[0]) * (globalScale * doodleTransform[2]), (-doodleTransform[1]) * (globalScale * doodleTransform[3]));
previewCtx.beginPath();
var prevPoint = centeredAndScaledDoodlePoint([updatePrevX, updatePrevY]);
previewCtx.moveTo(prevPoint.x, prevPoint.y);
var adjustedDoodlePoint = centeredAndScaledDoodlePoint([_x, _y]);
previewCtx.lineTo(adjustedDoodlePoint.x, adjustedDoodlePoint.y);
previewCtx.stroke();
y -= yStep;
r += rStep;
previewCtx.restore();
}
previewCtx.globalAlpha = globalAlpha;
updatePrevX = _x;
updatePrevY = _y;
} }
//*/ //*/