2013-07-26 22:39:28 +02:00
/ * * * * * * * * * *
*
* VARS
*
* * * * * * * * * * /
var preview ;
var previewCtx ;
var svgPathRegExp = /[LM]\d* \d*/ig ;
var svgPathParamsRegExp = /([LM])(\d*) (\d*)/ ;
var dragging = false ;
2013-10-11 11:42:27 +02:00
var $canvas , canvas , ctx ;
var canvasWidth , canvasHeight ;
2013-07-26 22:39:28 +02:00
var drawCanvas ;
var drawCanvasTopLeftCoords = [ 0 , 0 ] ;
var doodleBounds = [ - 1 , - 1 , - 1 , - 1 ] ; // left, top, right, bottom
// var doodleScaleVals = [[0, 0], [1.0, 1.0]]; // [ [x, y], [scaleX, scaleY] ]
var doodleTransform = [ 0 , 0 , 1.0 , 1.0 ] ; // [ x, y, scaleX, scaleY ]
var _points = [ ] ;
var prevCountingTime = 0 ;
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 ;
2013-10-29 23:26:09 +01:00
var isModified = false ;
2013-07-26 22:39:28 +02:00
/ * * * * * * * * * *
*
* INIT
*
* * * * * * * * * * /
function initDoodleDrawing ( ) {
console . log ( "f:initDoodleDrawing()" ) ;
2013-10-11 11:42:27 +02:00
$canvas = $ ( "#mycanvas" ) ;
canvas = $canvas [ 0 ] ;
ctx = canvas . getContext ( '2d' ) ;
canvasWidth = canvas . width ;
canvasHeight = canvas . height ;
2013-09-18 19:08:58 +02:00
//*
2013-09-18 10:46:36 +02:00
//TODO make these jquery eventhandlers (works for all)
2013-07-26 22:39:28 +02:00
if ( ! canvas . addEventListener ) {
canvas . attachEvent ( 'onmousedown' , onCanvasMouseDown ) ;
canvas . attachEvent ( 'onmousemove' , onCanvasMouseMove ) ;
canvas . attachEvent ( 'onmouseup' , onCanvasMouseUp ) ;
canvas . attachEvent ( 'ontouchstart' , onCanvasTouchDown ) ;
canvas . attachEvent ( 'ontouchmove' , onCanvasTouchMove ) ;
canvas . attachEvent ( 'ontouchend' , onCanvasTouchEnd ) ;
document . body . attachEvent ( 'ontouchmove' , prevent ) ;
} else {
canvas . addEventListener ( 'mousedown' , onCanvasMouseDown , false ) ;
canvas . addEventListener ( 'mousemove' , onCanvasMouseMove , false ) ;
canvas . addEventListener ( 'mouseup' , onCanvasMouseUp , false ) ;
canvas . addEventListener ( 'touchstart' , onCanvasTouchDown , false ) ;
canvas . addEventListener ( 'touchmove' , onCanvasTouchMove , false ) ;
canvas . addEventListener ( 'touchend' , onCanvasTouchEnd , false ) ;
2013-10-12 15:34:57 +02:00
if ( ! debugMode ) document . body . addEventListener ( 'touchmove' , prevent , false ) ;
2013-07-26 22:39:28 +02:00
}
2013-09-18 19:08:58 +02:00
//*/
2013-07-26 22:39:28 +02:00
2013-10-11 11:42:27 +02:00
// drawCanvas = $(".drawareacontainer");
drawCanvas = $ ( "#mycanvasContainer" ) ; // $("#drawAreaContainer")
2013-07-26 22:39:28 +02:00
console . log ( "drawCanvasTopLeftCoords: " + drawCanvasTopLeftCoords ) ;
2013-09-18 19:08:58 +02:00
// drawCanvasTopLeftCoords[0] = drawCanvas.css("left").match(/[0-9]/g).join("");
// drawCanvasTopLeftCoords[1] = drawCanvas.css("top").match(/[0-9]/g).join("");
drawCanvasTopLeftCoords [ 0 ] = drawCanvas . offset ( ) . left ;
drawCanvasTopLeftCoords [ 1 ] = drawCanvas . offset ( ) . top ;
// drawCanvasTopLeftCoords[0] = drawCanvas[0].offsetParent.offsetLeft;
// drawCanvasTopLeftCoords[1] = drawCanvas[0].offsetParent.offsetTop;
2013-07-26 22:39:28 +02:00
console . log ( "f:initDoodleDrawing() >> canvasWidth: " + canvasWidth ) ;
console . log ( "f:initDoodleDrawing() >> canvasHeight: " + canvasHeight ) ;
}
/ * * * * * * * * * *
*
* CANVAS DRAWING FUNCTION
*
* * * * * * * * * * /
function draw ( _x , _y , _width ) {
// console.log("f:draw() >> _width: " + _width);
if ( prevX == 0 && prevY == 0 ) {
prevX = _x ;
prevY = _y ;
}
ctx . beginPath ( ) ;
ctx . moveTo ( prevX , prevY ) ;
ctx . lineTo ( _x , _y ) ;
if ( _width != undefined ) {
ctx . lineWidth = _width ;
} else {
if ( drawVariableLineWeight ) {
var dist = Math . sqrt ( Math . pow ( ( prevX - _x ) , 2 ) + Math . pow ( ( prevY - _y ) , 2 ) ) ;
if ( dist < 10 ) {
lineweight += . 25 ;
} else if ( dist < 20 ) {
lineweight += . 5 ;
} else if ( dist < 30 ) {
lineweight += . 75 ;
} else if ( dist < 50 ) {
lineweight += 1 ;
} else if ( dist < 80 ) {
lineweight += 1.5 ;
} else if ( dist < 120 ) {
lineweight += 2.25 ;
} else if ( dist < 170 ) {
lineweight += 3.5 ;
} else {
lineweight += 2 ;
}
lineweight = Math . min ( lineweight , 30 ) ;
lineweight *= 0.90 ;
lineweight = Math . max ( lineweight , 1.0 ) ;
} else {
lineweight = 2 ;
}
ctx . lineWidth = lineweight ;
}
ctx . lineCap = 'round' ;
ctx . stroke ( ) ;
prevX = _x ;
prevY = _y ;
}
/ * * * * * * * * * *
*
* SUPPORTING FUNCTIONS
*
* * * * * * * * * * /
function clearDoodle ( ) {
console . log ( "f:clearDoodle" ) ;
2013-10-29 23:26:09 +01:00
updatePrevNextButtonStateOnClear ( ) ;
2013-07-26 22:39:28 +02:00
_points = [ ] ;
prevX = 0 ;
prevY = 0 ;
2013-08-16 22:27:26 +02:00
updatePrevX = - 1 ;
updatePrevY = - 1 ;
2013-07-26 22:39:28 +02:00
doodleBounds = [ - 1 , - 1 , - 1 , - 1 ] ; // left, top, right, bottom
doodleTransform = [ 0 , 0 , 1.0 , 1.0 ] ; // [ x, y, scaleX, scaleY ]
2013-09-18 19:08:58 +02:00
dragging = false ;
2013-07-26 22:39:28 +02:00
clearMainView ( ) ;
2013-09-17 13:12:51 +02:00
resetPreview ( ) ;
2013-09-18 22:35:38 +02:00
resetVerticalShapes ( ) ;
2013-10-29 23:26:09 +01:00
setSketchModified ( false ) ;
2013-07-26 22:39:28 +02:00
}
2013-10-28 19:37:33 +01:00
function redrawDoodle ( recalcBoundsAndTransforms ) {
if ( recalcBoundsAndTransforms == undefined ) recalcBoundsAndTransforms = false ;
2013-10-29 21:27:17 +01:00
// console.log("f:redrawDoodle() >> recalcBoundsAndTransforms = " + recalcBoundsAndTransforms);
2013-10-28 19:37:33 +01:00
if ( recalcBoundsAndTransforms == true ) {
doodleBounds = [ - 1 , - 1 , - 1 , - 1 ] ; // left, top, right, bottom
doodleTransform = [ 0 , 0 , 1.0 , 1.0 ] ; // [ x, y, scaleX, scaleY ]
for ( var i = 0 ; i < _points . length ; i ++ ) {
adjustBounds ( _points [ i ] [ 0 ] , _points [ i ] [ 1 ] ) ;
adjustPreviewTransformation ( ) ;
}
}
2013-07-27 18:19:50 +02:00
clearMainView ( ) ;
prevX = 0 ;
prevY = 0 ;
for ( var i = 0 ; i < _points . length ; i ++ ) {
// console.log(" drawing points " + _points[i]);
if ( _points [ i ] [ 2 ] == true ) {
draw ( _points [ i ] [ 0 ] , _points [ i ] [ 1 ] , 0.5 ) ;
} else {
draw ( _points [ i ] [ 0 ] , _points [ i ] [ 1 ] ) ;
}
}
}
2013-07-26 22:39:28 +02:00
function adjustBounds ( x , y ) {
2013-08-16 22:27:26 +02:00
var newPointsOutsideOfCurrentBounds = false ;
2013-10-28 19:37:33 +01:00
// console.log("f:adjustBounds("+x+","+y+")");
2013-07-26 22:39:28 +02:00
if ( doodleBounds [ 0 ] == - 1 ) {
// if doodleBounds[0] is -1 then it isn't initted yet, so x and y are both the min and max vals
doodleBounds [ 0 ] = x ;
doodleBounds [ 1 ] = y ;
doodleBounds [ 2 ] = x ;
doodleBounds [ 3 ] = y ;
return ;
}
2013-08-16 22:27:26 +02:00
if ( x < doodleBounds [ 0 ] ) {
doodleBounds [ 0 ] = x ;
newPointsOutsideOfCurrentBounds = true ;
}
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 ;
}
2013-07-26 22:39:28 +02:00
2013-10-28 19:37:33 +01:00
return newPointsOutsideOfCurrentBounds ;
2013-07-26 22:39:28 +02:00
}
// does what exactly?
function adjustPreviewTransformation ( ) {
// console.log("f:adjustPreviewTransformation()");
doodleTransform [ 0 ] = doodleBounds [ 0 ] ;
doodleTransform [ 1 ] = doodleBounds [ 1 ] ;
var sclX , sclY , finalScl ;
if ( _points . length < 2 ) {
2013-07-28 02:46:32 +02:00
// console.log(_points);
2013-07-26 22:39:28 +02:00
sclX = 1.0 ;
sclY = 1.0 ;
finalScl = Math . min ( sclX , sclY ) ;
} else {
sclX = canvasWidth / ( doodleBounds [ 2 ] - doodleBounds [ 0 ] ) ;
sclY = canvasHeight / ( doodleBounds [ 3 ] - doodleBounds [ 1 ] ) ;
// TODO this shouldn't be a matter if choosing the smallest but should probably involve maintaining aspect ratio??
finalScl = Math . min ( sclX , sclY ) ;
}
doodleTransform [ 2 ] = finalScl ;
doodleTransform [ 3 ] = finalScl ;
}
/ * * * * * * * * * *
*
* MOUSE / TOUCH EVENTHANDLERS
*
* * * * * * * * * * /
function onCanvasMouseDown ( e ) {
2013-10-29 23:26:09 +01:00
setSketchModified ( true ) ;
2013-09-18 19:08:58 +02:00
// console.log("f:onCanvasMouseDown()");
2013-10-28 19:37:33 +01:00
// console.log("onCanvasMouseDown >> e.offsetX,e.offsetY = " + e.offsetX+","+e.offsetY);
// console.log("onCanvasMouseDown >> e.layerX,e.layerY= " + e.layerX+","+e.layerY);
// console.log("onCanvasMouseDown >> e: " , e);
2013-07-26 22:39:28 +02:00
dragging = true ;
prevCountingTime = new Date ( ) . getTime ( ) ;
movementCounter = 0
2013-07-28 02:46:32 +02:00
var x , y ;
if ( e . offsetX != undefined ) {
x = e . offsetX ;
y = e . offsetY ;
} else {
x = e . layerX ;
y = e . layerY ;
}
// console.log(" x: " + x + ", y: " + y);
_points . push ( [ x , y , true ] ) ;
adjustBounds ( x , y ) ;
2013-07-26 22:39:28 +02:00
adjustPreviewTransformation ( ) ;
2013-07-28 02:46:32 +02:00
draw ( x , y , 0.5 ) ;
2013-07-26 22:39:28 +02:00
}
2013-08-16 22:27:26 +02:00
var prevPoint = { x : - 1 , y : - 1 } ;
2013-07-26 22:39:28 +02:00
function onCanvasMouseMove ( e ) {
2013-10-29 23:26:09 +01:00
2013-09-18 19:08:58 +02:00
// console.log("f:onCanvasMouseMove()");
2013-07-26 22:39:28 +02:00
if ( ! dragging ) return ;
2013-10-29 23:26:09 +01:00
setSketchModified ( true ) ;
2013-07-26 22:39:28 +02:00
// console.log("onmousemove");
2013-07-28 02:46:32 +02:00
var x , y ;
if ( e . offsetX != undefined ) {
x = e . offsetX ;
y = e . offsetY ;
} else {
x = e . layerX ;
y = e . layerY ;
}
2013-08-16 22:27:26 +02:00
if ( prevPoint . x != - 1 || prevPoint . y != - 1 ) {
2013-10-28 19:37:33 +01:00
var dist = Math . sqrt ( ( ( prevPoint . x - x ) * ( prevPoint . x - x ) ) + ( ( prevPoint . y - y ) * ( prevPoint . y - y ) ) ) ;
2013-08-28 18:33:25 +02:00
if ( dist > 5 ) { // replace by setting: doodle3d.simplify.minDistance
2013-08-16 22:27:26 +02:00
_points . push ( [ x , y , false ] ) ;
2013-10-28 19:37:33 +01:00
adjustBounds ( x , y ) ;
2013-08-16 22:27:26 +02:00
adjustPreviewTransformation ( ) ;
draw ( x , y ) ;
prevPoint . x = x ;
prevPoint . y = y ;
}
} else {
2013-10-28 19:37:33 +01:00
// this is called once, every time you start to draw a line
2013-08-16 22:27:26 +02:00
_points . push ( [ x , y , false ] ) ;
2013-10-28 19:37:33 +01:00
adjustBounds ( x , y ) ;
2013-08-16 22:27:26 +02:00
adjustPreviewTransformation ( ) ;
draw ( x , y ) ;
prevPoint . x = x ;
prevPoint . y = y ;
2013-07-26 22:39:28 +02:00
}
// DEBUG
// $("#textdump").text("");
// $("#textdump").append("doodlebounds:" + doodleBounds + "\n");
// $("#textdump").append("doodletransform:" + doodleTransform + "\n");
if ( new Date ( ) . getTime ( ) - prevRedrawTime > redrawInterval ) {
2013-08-16 22:27:26 +02:00
// redrawing the whole preview the first X points ensures that the doodleBounds is set well
2013-08-21 18:08:32 +02:00
prevRedrawTime = new Date ( ) . getTime ( ) ;
2013-10-28 19:37:33 +01:00
// Keep fully updating the preview if device is not a smartphone.
// (An assumption is made here that anything greater than a smartphone will have sufficient
// performance to always redraw the preview.)
if ( _points . length < 50 || ! clientInfo . isSmartphone ) {
2013-08-16 22:27:26 +02:00
redrawPreview ( ) ;
} else {
updatePreview ( x , y , true ) ;
}
2013-07-26 22:39:28 +02:00
}
}
2013-08-21 18:08:32 +02:00
prevUpdateFullPreview = 0 ; // 0 is not a timeframe but refers to the _points array
prevUpdateFullPreviewInterval = 25 ; // refers to number of points, not a timeframe
2013-07-26 22:39:28 +02:00
function onCanvasMouseUp ( e ) {
2013-09-18 19:08:58 +02:00
// console.log("f:onCanvasMouseUp()");
2013-07-26 22:39:28 +02:00
// console.log("onmouseup");
dragging = false ;
console . log ( "doodleBounds: " + doodleBounds ) ;
console . log ( "doodleTransform: " + doodleTransform ) ;
// ctx.stroke();
console . log ( "_points.length :" + _points . length ) ;
// console.log(_points);
// DEBUG
// $("#textdump").text("");
// $("#textdump").append("doodlebounds:" + doodleBounds + "\n");
// $("#textdump").append("doodletransform:" + doodleTransform + "\n");
2013-08-21 17:37:20 +02:00
// redrawPreview();
renderToImageDataPreview ( ) ;
2013-07-26 22:39:28 +02:00
}
function onCanvasTouchDown ( e ) {
2013-10-29 23:26:09 +01:00
setSketchModified ( true ) ;
2013-07-26 22:39:28 +02:00
e . preventDefault ( ) ;
2013-09-18 19:08:58 +02:00
console . log ( "f:onCanvasTouchDown >> e: " , e ) ;
2013-07-26 22:39:28 +02:00
// var x = e.touches[0].pageX - e.touches[0].target.offsetLeft;
// var y = e.touches[0].pageY - e.touches[0].target.offsetTop;
2013-10-11 18:40:03 +02:00
var x = e . touches [ 0 ] . pageX - drawCanvasTopLeftCoords [ 0 ] ;
var y = e . touches [ 0 ] . pageY - drawCanvasTopLeftCoords [ 1 ] ;
// var x = e.touches[0].pageX;
// var y = e.touches[0].pageY;
// var x = e.touches[0].layerX;
// var y = e.touches[0].layerY;
2013-07-26 22:39:28 +02:00
_points . push ( [ x , y , true ] ) ;
adjustBounds ( x , y ) ;
adjustPreviewTransformation ( ) ;
draw ( x , y , . 5 ) ;
movementCounter = 0 ;
prevRedrawTime = new Date ( ) . getTime ( ) ;
}
function onCanvasTouchMove ( e ) {
2013-10-29 23:26:09 +01:00
setSketchModified ( true ) ;
2013-07-26 22:39:28 +02:00
e . preventDefault ( ) ;
// var x = e.touches[0].pageX - e.touches[0].target.offsetLeft;
// var y = e.touches[0].pageY - e.touches[0].target.offsetTop;
var x = e . touches [ 0 ] . pageX - drawCanvasTopLeftCoords [ 0 ] ;
var y = e . touches [ 0 ] . pageY - drawCanvasTopLeftCoords [ 1 ] ;
2013-10-11 18:40:03 +02:00
// var x = e.touches[0].layerX;
// var y = e.touches[0].layerY;
2013-09-18 19:08:58 +02:00
// var x = e.touches[0].layerX;
// var y = e.touches[0].layerY;
2013-07-26 22:39:28 +02:00
2013-10-11 18:40:03 +02:00
console . log ( "f:onCanvasTouchMove >> x,y = " + x + "," + y + " , e: " , e ) ;
2013-08-16 22:27:26 +02:00
if ( prevPoint . x != - 1 || prevPoint . y != - 1 ) {
var dist = Math . sqrt ( Math . pow ( ( prevPoint . x - x ) , 2 ) + Math . pow ( ( prevPoint . y - y ) , 2 ) ) ;
if ( dist > 5 ) {
_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 ;
}
2013-07-26 22:39:28 +02:00
// update counter -> this was for getting a handle on how often the Canvas fires a move-event
/ *
movementCounter ++ ;
if ( new Date ( ) . getTime ( ) - prevCountingTime > 1000 ) {
// console.log("number of moves in 1sec: " + movementCounter)
prevCountingTime = new Date ( ) . getTime ( ) ;
$ ( "#numtimes" ) . text ( movementCounter + " times" ) ;
movementCounter = 0 ;
}
//*/
if ( new Date ( ) . getTime ( ) - prevRedrawTime > redrawInterval ) {
2013-08-16 22:27:26 +02:00
// 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 ) ;
2013-08-21 18:08:32 +02:00
/ *
if ( _points . length - prevUpdateFullPreview > prevUpdateFullPreviewInterval ) {
console . log ( "f:onTouchMove >> passed prevUpdateFullPreviewInterval, updating full preview" ) ;
redrawPreview ( ) ;
prevUpdateFullPreview = _points . length ;
} else {
updatePreview ( x , y , true ) ;
}
//*/
2013-08-16 22:27:26 +02:00
}
2013-07-26 22:39:28 +02:00
prevRedrawTime = new Date ( ) . getTime ( ) ;
}
}
function onCanvasTouchEnd ( e ) {
2013-08-21 18:08:32 +02:00
console . log ( "f:onCanvasTouchEnd()" ) ;
2013-08-16 22:27:26 +02:00
console . log ( "doodleBounds: " + doodleBounds ) ;
console . log ( "doodleTransform: " + doodleTransform ) ;
// ctx.stroke();
console . log ( "_points.length :" + _points . length ) ;
2013-08-21 17:37:20 +02:00
// redrawPreview();
renderToImageDataPreview ( ) ;
2013-07-26 22:39:28 +02:00
}
function prevent ( e ) {
e . preventDefault ( ) ;
2013-10-29 23:26:09 +01:00
}
//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 ;
}