From 27c1ba250a7db26cf24dd456d20af9ff1649e638 Mon Sep 17 00:00:00 2001 From: hwc487 Date: Mon, 23 Apr 2012 17:04:48 -0700 Subject: canvas interaction --- js/document/html-document.js | 2 +- js/helper-classes/3D/snap-manager.js | 274 ++++++++++++++--------------------- js/lib/drawing/world.js | 9 +- js/lib/geom/circle.js | 8 +- js/lib/geom/rectangle.js | 39 +++-- js/tools/OvalTool.js | 2 +- js/tools/ShapeTool.js | 22 +-- 7 files changed, 161 insertions(+), 195 deletions(-) diff --git a/js/document/html-document.js b/js/document/html-document.js index 2531465d..cce88747 100755 --- a/js/document/html-document.js +++ b/js/document/html-document.js @@ -228,7 +228,7 @@ exports.HTMLDocument = Montage.create(TextDocument, { { // JSON format. pull off the importStr = importStr.substr( index+1 ); - jObj = jObj = JSON.parse( importStr ); + jObj = JSON.parse( importStr ); id = jObj.id; } else diff --git a/js/helper-classes/3D/snap-manager.js b/js/helper-classes/3D/snap-manager.js index cd8cc102..2c975985 100755 --- a/js/helper-classes/3D/snap-manager.js +++ b/js/helper-classes/3D/snap-manager.js @@ -1077,7 +1077,7 @@ var SnapManager = exports.SnapManager = Montage.create(Component, { var hitRec = this.snapToScreenBounds( elt, globalScrPt, bounds, bounds3D ); // see if we can snap to a contained geometry object - if (hitRec && this.getGLWorld(elt) && !this.isARectangle(elt)) + if (hitRec && this.getGLWorld(elt)) // && !this.isARectangle(elt)) { var localPt = hitRec.calculateElementWorldPoint(); if (hitRec.getType() != hitRec.SNAP_TYPE_ELEMENT) @@ -1320,193 +1320,135 @@ var SnapManager = exports.SnapManager = Montage.create(Component, { } }, - snapToContainedElement : + doSnapToContainedElement: { value: function( eyePt, dir, glObj, hitRec, targetScrPt ) { var rtnVal = false; - var elt = hitRec.getElement(); + var elt = hitRec.getElt(); var world = glObj.getWorld(); - switch (glObj.geomType()) + + var nearVrt = glObj.getNearVertex( eyePt, dir ); + if (nearVrt) { - case glObj.GEOM_TYPE_RECTANGLE: - break; + var viewPt = this.GLToView(nearVrt, world ); + var mat = viewUtils.getMatrixFromElement( elt ); + var worldPt = MathUtils.transformPoint( viewPt, mat ); - case glObj.GEOM_TYPE_CIRCLE: + viewUtils.pushViewportObj( elt ); + var scrPt = viewUtils.viewToScreen( worldPt ); + var offset = viewUtils.getElementOffset( elt ); + MathUtils.makeDimension3( offset ); + var parentPt = vecUtils.vecAdd(3, scrPt, offset ); + var globalPt = viewUtils.localToGlobal( parentPt, elt.offsetParent ); + + var dist = vecUtils.vecDist(2, globalPt, targetScrPt ); + if (dist < this.ELEMENT_VERTEX_HIT_RAD) + { + console.log( "hit a vertex" ); + + // check if the distance is less than + // the distance on the current hit record + if (dist <= vecUtils.vecDist(2, targetScrPt, hitRec.getScreenPoint() )) { - var nearVrt = glObj.getNearVertex( eyePt, dir ); - if (nearVrt) - { - var viewPt = this.GLToView(nearVrt, world ); - var mat = viewUtils.getMatrixFromElement( elt ); - var worldPt = MathUtils.transformPoint( viewPt, mat ); - - viewUtils.pushViewportObj( elt ); - var scrPt = viewUtils.viewToScreen( worldPt ); - var offset = viewUtils.getElementOffset( elt ); - MathUtils.makeDimension3( offset ); - var parentPt = vecUtils.vecAdd(3, scrPt, offset ); - var globalPt = viewUtils.localToGlobal( parentPt, elt.offsetParent ); - - var dist = vecUtils.vecDist(2, globalPt, targetScrPt ); - if (dist < this.ELEMENT_VERTEX_HIT_RAD) - { - // check if the distance is less than - // the distance on the current hit record - if (dist <= vecUtils.vecDist(2, targetScrPt, hitRec.getScreenPoint() )) - { - hitRec.setScreenPoint( globalPt ); - //var localMatInv = hitRec.getPlaneMatrix().inverse(); - var localMatInv = glmat4.inverse( hitRec.getPlaneMatrix(), []); - viewUtils.pushViewportObj( hitRec.getElement() ); - var localPt = viewUtils.screenToView( scrPt[0], scrPt[1], scrPt[2] ); - viewUtils.popViewportObj(); - localPt = MathUtils.transformPoint( localPt, localMatInv ); - hitRec.setLocalPoint( localPt ); - hitRec.setType( hitRec.SNAP_TYPE_CONTAINED_ELEMENT ); - - rtnVal = true; - } - } - } // if (nearVrt) + console.log( "rejected - further than existing snap" ); + + hitRec.setScreenPoint( globalPt ); + //var localMatInv = hitRec.getPlaneMatrix().inverse(); + var localMatInv = glmat4.inverse( hitRec.getPlaneMatrix(), []); + viewUtils.pushViewportObj( hitRec.getElement() ); + var localPt = viewUtils.screenToView( scrPt[0], scrPt[1], scrPt[2] ); + viewUtils.popViewportObj(); + localPt = MathUtils.transformPoint( localPt, localMatInv ); + hitRec.setLocalPoint( localPt ); + hitRec.setType( hitRec.SNAP_TYPE_CONTAINED_ELEMENT ); - if (!rtnVal) - { - var nearPt = glObj.getNearPoint( eyePt, dir ); - if (nearPt) - { - var viewPt = this.GLToView(nearPt, world ); - var mat = viewUtils.getMatrixFromElement( elt ); - var worldPt = MathUtils.transformPoint( viewPt, mat ); - - viewUtils.pushViewportObj( elt ); - var scrPt = viewUtils.viewToScreen( worldPt ); - var offset = viewUtils.getElementOffset( elt ); - MathUtils.makeDimension3( offset ); - var parentPt = vecUtils.vecAdd(3, scrPt, offset ); - var globalPt = viewUtils.localToGlobal( parentPt, elt.offsetParent ); - - var dist = vecUtils.vecDist(2, globalPt, targetScrPt ); - if (dist < this.ELEMENT_EDGE_HIT_RAD) - { - // check if the distance is less than - // the distance on the current hit record - //var dist2 = vecUtils.vecDist(2, targetScrPt, hitRec.getScreenPoint() ); - //if (dist <= dist2+1 ) - { - hitRec.setScreenPoint( globalPt ); - //var localMatInv = hitRec.getPlaneMatrix().inverse(); - var localMatInv = glmat4.inverse( hitRec.getPlaneMatrix(), []); - viewUtils.pushViewportObj( hitRec.getElement() ); - var localPt = viewUtils.screenToView( scrPt[0], scrPt[1], scrPt[2] ); - viewUtils.popViewportObj(); - localPt = MathUtils.transformPoint( localPt, localMatInv ); - hitRec.setLocalPoint( localPt ); - hitRec.setType( hitRec.SNAP_TYPE_CONTAINED_ELEMENT ); - - rtnVal = true; - } - } - } - } // if (!rtnVal) + rtnVal = true; + } + } + } - if (!rtnVal && glObj.containsPoint( eyePt, dir )) + if (!rtnVal) + { + var nearPt = glObj.getNearPoint( eyePt, dir ); + if (nearPt) + { + var viewPt = this.GLToView(nearPt, world ); + var mat = viewUtils.getMatrixFromElement( elt ); + var worldPt = MathUtils.transformPoint( viewPt, mat ); + + viewUtils.pushViewportObj( elt ); + var scrPt = viewUtils.viewToScreen( worldPt ); + var offset = viewUtils.getElementOffset( elt ); + MathUtils.makeDimension3( offset ); + var parentPt = vecUtils.vecAdd(3, scrPt, offset ); + var globalPt = viewUtils.localToGlobal( parentPt, elt.offsetParent ); + + var dist = vecUtils.vecDist(2, globalPt, targetScrPt ); + if (dist < this.ELEMENT_EDGE_HIT_RAD) + { + console.log( "hit an edge" ); + + // check if the distance is less than + // the distance on the current hit record + //var dist2 = vecUtils.vecDist(2, targetScrPt, hitRec.getScreenPoint() ); + //if (dist <= dist2+1 ) { + hitRec.setScreenPoint( globalPt ); + //var localMatInv = hitRec.getPlaneMatrix().inverse(); + var localMatInv = glmat4.inverse( hitRec.getPlaneMatrix(), []); + viewUtils.pushViewportObj( hitRec.getElement() ); + var localPt = viewUtils.screenToView( scrPt[0], scrPt[1], scrPt[2] ); + viewUtils.popViewportObj(); + localPt = MathUtils.transformPoint( localPt, localMatInv ); + hitRec.setLocalPoint( localPt ); + hitRec.setType( hitRec.SNAP_TYPE_CONTAINED_ELEMENT ); + rtnVal = true; } } + } + } // if (!rtnVal) + + if (!rtnVal && glObj.containsPoint( eyePt, dir )) + { + rtnVal = true; + } + + return rtnVal; + } + }, + + snapToContainedElement : + { + value: function( eyePt, dir, glObj, hitRec, targetScrPt ) + { + var rtnVal = false; + var elt = hitRec.getElement(); + + var world = glObj.getWorld(); + switch (glObj.geomType()) + { + case glObj.GEOM_TYPE_RECTANGLE: + if ((glObj.getWidth() != world.getViewportWidth()) || (glObj.getHeight() != world.getViewportHeight())) + rtnVal = this.doSnapToContainedElement( eyePt, dir, glObj, hitRec, targetScrPt ); + break; + + case glObj.GEOM_TYPE_CIRCLE: + rtnVal = this.doSnapToContainedElement( eyePt, dir, glObj, hitRec, targetScrPt ); break; case glObj.GEOM_TYPE_LINE: case glObj.GEOM_TYPE_PATH: // Snapping not implemented for these type, but don't throw an error... break; - case glObj.GEOM_TYPE_BRUSH_STROKE: + + case glObj.GEOM_TYPE_BRUSH_STROKE: break; //don't throw error because snapping not yet implemented - case glObj.GEOM_TYPE_CUBIC_BEZIER: - { - var nearVrt = glObj.getNearVertex( eyePt, dir ); - if (nearVrt) - { - var viewPt = this.GLToView(nearVrt, world ); - var mat = viewUtils.getMatrixFromElement( elt ); - var worldPt = MathUtils.transformPoint( viewPt, mat ); - - viewUtils.pushViewportObj( elt ); - var scrPt = viewUtils.viewToScreen( worldPt ); - var offset = viewUtils.getElementOffset( elt ); - MathUtils.makeDimension3( offset ); - var parentPt = vecUtils.vecAdd(3, scrPt, offset ); - var globalPt = viewUtils.localToGlobal( parentPt, elt.offsetParent ); - - var dist = vecUtils.vecDist(2, globalPt, targetScrPt ); - if (dist < this.ELEMENT_VERTEX_HIT_RAD) - { - // check if the distance is less than - // the distance on the current hit record - if (dist <= vecUtils.vecDist(2, targetScrPt, hitRec.getScreenPoint() )) - { - hitRec.setScreenPoint( globalPt ); - //var localMatInv = hitRec.getPlaneMatrix().inverse(); - var localMatInv = glmat4.inverse( hitRec.getPlaneMatrix(), []); - viewUtils.pushViewportObj( hitRec.getElement() ); - var localPt = viewUtils.screenToView( scrPt[0], scrPt[1], scrPt[2] ); - viewUtils.popViewportObj(); - localPt = MathUtils.transformPoint( localPt, localMatInv ); - hitRec.setLocalPoint( localPt ); - hitRec.setType( hitRec.SNAP_TYPE_CONTAINED_ELEMENT ); - - rtnVal = true; - } - } - } // if (nearVrt) - - if (!rtnVal) - { - var nearPt = glObj.getNearPoint( eyePt, dir ); - if (nearPt) - { - var viewPt = this.GLToView(nearPt, world ); - var mat = viewUtils.getMatrixFromElement( elt ); - var worldPt = MathUtils.transformPoint( viewPt, mat ); - - viewUtils.pushViewportObj( elt ); - var scrPt = viewUtils.viewToScreen( worldPt ); - var offset = viewUtils.getElementOffset( elt ); - MathUtils.makeDimension3( offset ); - var parentPt = vecUtils.vecAdd(3, scrPt, offset ); - var globalPt = viewUtils.localToGlobal( parentPt, elt.offsetParent ); - - var dist = vecUtils.vecDist(2, globalPt, targetScrPt ); - if (dist < this.ELEMENT_EDGE_HIT_RAD) - { - // check if the distance is less than - // the distance on the current hit record - //var dist2 = vecUtils.vecDist(2, targetScrPt, hitRec.getScreenPoint() ); - //if (dist <= dist2+1 ) - { - hitRec.setScreenPoint( globalPt ); - //var localMatInv = hitRec.getPlaneMatrix().inverse(); - var localMatInv = glmat4.inverse( hitRec.getPlaneMatrix(), []); - viewUtils.pushViewportObj( hitRec.getElement() ); - var localPt = viewUtils.screenToView( scrPt[0], scrPt[1], scrPt[2] ); - viewUtils.popViewportObj(); - localPt = MathUtils.transformPoint( localPt, localMatInv ); - hitRec.setLocalPoint( localPt ); - hitRec.setType( hitRec.SNAP_TYPE_CONTAINED_ELEMENT ); - - rtnVal = true; - } - } - } - } // if (!rtnVal) - - if (!rtnVal && glObj.containsPoint( eyePt, dir )) - { - rtnVal = true; - } - } + + case glObj.GEOM_TYPE_CUBIC_BEZIER: + rtnVal = this.doSnapToContainedElement( eyePt, dir, glObj, hitRec, targetScrPt ); break; default: throw new Error( "invalid GL geometry type: " + glObj.geomType() ); diff --git a/js/lib/drawing/world.js b/js/lib/drawing/world.js index 945c9883..8ad4c6f5 100755 --- a/js/lib/drawing/world.js +++ b/js/lib/drawing/world.js @@ -362,9 +362,9 @@ var World = function GLWorld( canvas, use3D, preserveDrawingBuffer ) { // start RDGE passing your runtime object, and false to indicate we don't need a an initialization state // in the case of a procedurally built scene an init state is not needed for loading data + this._canvas.rdgeid = this._canvas.getAttribute( "data-RDGE-id" ); if (this._useWebGL) { rdgeStarted = true; - this._canvas.rdgeid = this._canvas.getAttribute( "data-RDGE-id" ); RDGE.globals.engine.unregisterCanvas( this._canvas ); RDGE.globals.engine.registerCanvas(this._canvas, this); RDGE.RDGEStart( this._canvas ); @@ -835,8 +835,11 @@ World.prototype.importJSON = function (jObj) { // import the objects // there should be exactly one child of the parent object - if (jObj.children && (jObj.children.length === 1)) - this.importObjectsJSON( jObj.children[0] ); + if (jObj.children) + { + for (var i=0; i 0) { - ctx.quadraticCurveTo( inset, height-inset, inset+rad, height-inset ); + ctx.quadraticCurveTo( inset+xOff, height-inset+yOff, inset+rad+xOff, height-inset+yOff ); } // do the bottom of the rectangle @@ -392,11 +407,11 @@ var Rectangle = function GLRectangle() { rad = brRad - inset; if (rad < 0) rad = 0; pt[0] -= rad; - ctx.lineTo( pt[0], pt[1] ); + ctx.lineTo( pt[0]+xOff, pt[1]+yOff ); // get the bottom right arc if (MathUtils.fpSign(rad) > 0) { - ctx.quadraticCurveTo( width-inset, height-inset, width-inset, height-inset-rad ); + ctx.quadraticCurveTo( width-inset+xOff, height-inset+yOff, width-inset+xOff, height-inset-rad+yOff ); } // get the right of the rectangle @@ -404,11 +419,11 @@ var Rectangle = function GLRectangle() { rad = trRad - inset; if (rad < 0) rad = 0; pt[1] += rad; - ctx.lineTo( pt[0], pt[1] ); + ctx.lineTo( pt[0]+xOff, pt[1]+yOff ); // do the top right corner if (MathUtils.fpSign(rad) > 0) { - ctx.quadraticCurveTo( width-inset, inset, width-inset-rad, inset ); + ctx.quadraticCurveTo( width-inset+xOff, inset+yOff, width-inset-rad+xOff, inset+yOff ); } // do the top of the rectangle @@ -416,13 +431,13 @@ var Rectangle = function GLRectangle() { rad = tlRad - inset; if (rad < 0) rad = 0; pt[0] += rad; - ctx.lineTo( pt[0], pt[1] ); + ctx.lineTo( pt[0]+xOff, pt[1]+yOff ); // do the top left corner if (MathUtils.fpSign(rad) > 0) { - ctx.quadraticCurveTo( inset, inset, inset, inset+rad ); + ctx.quadraticCurveTo( inset+xOff, inset+yOff, inset+xOff, inset+rad+yOff ); } else { - ctx.lineTo( inset, 2*inset ); + ctx.lineTo( inset+xOff, 2*inset+yOff ); } } }; @@ -430,7 +445,7 @@ var Rectangle = function GLRectangle() { this.render = function() { // get the world var world = this.getWorld(); - if (!world) throw( "null world in rectangle render" ); + if (!world) throw( "null world in rectangle render" ); // get the context var ctx = world.get2DContext(); diff --git a/js/tools/OvalTool.js b/js/tools/OvalTool.js index e8e88d1d..6edec811 100755 --- a/js/tools/OvalTool.js +++ b/js/tools/OvalTool.js @@ -66,7 +66,7 @@ exports.OvalTool = Montage.create(ShapeTool, { var world = this.getGLWorld(canvas, this.options.use3D); var xOffset = ((left - canvas.offsetLeft + w/2) - canvas.width/2); - var yOffset = (canvas.height/2 - (top - canvas.offsetTop + h/2)); + var yOffset = -(canvas.height/2 - (top - canvas.offsetTop + h/2)); var oval = new Circle(); //GLCircle(); oval.init(world, xOffset, yOffset, w, h, strokeSize, strokeColor, fillColor, innerRadius, strokeMaterial, fillMaterial, strokeStyle); diff --git a/js/tools/ShapeTool.js b/js/tools/ShapeTool.js index f3b5e92d..b2948fe7 100755 --- a/js/tools/ShapeTool.js +++ b/js/tools/ShapeTool.js @@ -54,9 +54,9 @@ exports.ShapeTool = Montage.create(DrawingTool, { }, HandleLeftButtonUp: - { - value: function (event) - { + { + value: function (event) + { var drawData; drawData = this.getDrawingData(); @@ -69,24 +69,26 @@ exports.ShapeTool = Montage.create(DrawingTool, { drawData.planeMat, drawData.midPt, canvas, true); canvas.elementModel.isShape = true; - this.application.ninja.elementMediator.addElements(canvas, elementModel.data); } else { canvas = this._targetedElement; + if (!canvas.getAttribute( "data-RDGE-id" )) + canvas.setAttribute( "data-RDGE-id", NJUtils.generateRandom() ); canvas.elementModel.controller = ShapesController; if(!canvas.elementModel.shapeModel) { canvas.elementModel.shapeModel = Montage.create(ShapeModel); } } + this.application.ninja.elementMediator.addElements(canvas, canvas.elementModel.data); } - this.endDraw(event); + this.endDraw(event); - this._isDrawing = false; - this._hasDraw=false; + this._isDrawing = false; + this._hasDraw=false; - this.DrawHandles(); - } - }, + this.DrawHandles(); + } + }, onAddElements: { value: function(el) { -- cgit v1.2.3