summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--public/assets/javascripts/rectangles/engine/map/tools/eraser.js27
-rw-r--r--public/assets/javascripts/rectangles/engine/shapes/polyline.js147
-rw-r--r--public/assets/javascripts/rectangles/engine/shapes/shapelist.js61
-rw-r--r--public/assets/test/ortho3.html243
4 files changed, 238 insertions, 240 deletions
diff --git a/public/assets/javascripts/rectangles/engine/map/tools/eraser.js b/public/assets/javascripts/rectangles/engine/map/tools/eraser.js
new file mode 100644
index 0000000..648cd11
--- /dev/null
+++ b/public/assets/javascripts/rectangles/engine/map/tools/eraser.js
@@ -0,0 +1,27 @@
+var EraserTool = MapTool.extend(function(base){
+ var exports = {}
+ exports.down = function(e, cursor){
+ last_point.a = cursor.x.a
+ last_point.b = cursor.y.a
+ var segment = shapes.findClosestSegment(last_point)
+ if (segment) {
+ shapes.removeSegment(segment)
+ }
+ }
+ exports.move = function(e, cursor){
+ last_point.a = cursor.x.a
+ last_point.b = cursor.y.a
+ var segment = shapes.findClosestSegment(last_point)
+ if (segment) {
+ document.body.style.cursor = "pointer"
+ last_point.a = segment.x
+ last_point.b = segment.y
+ cursor.x.a = cursor.x.b = last_point.a
+ cursor.y.a = cursor.y.b = last_point.b
+ }
+ else {
+ document.body.style.cursor = "crosshair"
+ }
+ }
+ return exports
+})
diff --git a/public/assets/javascripts/rectangles/engine/shapes/polyline.js b/public/assets/javascripts/rectangles/engine/shapes/polyline.js
new file mode 100644
index 0000000..7e3c04c
--- /dev/null
+++ b/public/assets/javascripts/rectangles/engine/shapes/polyline.js
@@ -0,0 +1,147 @@
+var Polyline = Fiber.extend(function(base){
+ var exports = {}
+ exports.init = function(){
+ this.points = []
+ this.mx_points = []
+ this.closed = false
+ }
+ exports.add = function(p){
+ this.points.push( p )
+ this.mx_points.push( new MX.Point(p) )
+ }
+ exports.firstPoint = function(){
+ return this.points[0]
+ }
+ exports.lastPoint = function(){
+ return this.points[this.points.length-1]
+ }
+ exports.canCloseWith = function(p){
+ return (this.points.length > 2 && this.points[0].distanceTo( p ) < 10/map.zoom)
+ }
+ exports.getHeadAtIndex = function(index){
+ if (index == 0) { return null }
+ if (index == this.points.length-1) { return this.clone() }
+ var head = new Polyline()
+ head.points = this.points.slice(0, index+1)
+ return head
+ }
+ exports.getTailAtIndex = function(index){
+ if (index == this.points.length-1) { return null }
+ if (index == 0) { return this.clone() }
+ var tail = new Polyline()
+ tail.points = this.points.slice(index, this.points.length)
+ return tail
+ }
+ exports.clone = function(){
+ var clone = new Polyline()
+ clone.points = this.points.concat()
+ }
+ exports.hasPointNear = function(p){
+ var point
+ for (var i = 0; i < this.points.length; i++){
+ point = this.points[i]
+ if (point.distanceTo( p ) < 10/map.zoom) {
+ return point
+ }
+ }
+ return null
+ }
+ exports.hasEndPointNear = function(p){
+ if (this.closed) return null
+ if (this.firstPoint().distanceTo( p ) < 10/map.zoom) {
+ return this.firstPoint()
+ }
+ if (this.lastPoint().distanceTo( p ) < 10/map.zoom) {
+ return this.lastPoint()
+ }
+ return null
+ }
+ exports.hasSegmentNear = function(p, min_dist){
+ var p1, p2, d1, d2, sum, rat
+ var dx, dy, new_x, new_y, x, y, closest_distance = min_dist || Infinity
+ var closest_i = -1
+ var points = this.points
+ var p1, p2 = points[0]
+ for (var i = 1; i < points.length; i++) {
+ p1 = p2
+ p2 = points[i]
+ d1 = p2.a - p1.a
+ d2 = p2.b - p1.b
+ sum = d1*d1 + d2*d2
+ rat = ((p.a - p1.a) * d1 + (p.b - p1.b) * d2) / sum
+ rat = rat < 0 ? 0 : rat < 1 ? rat : 1
+ new_x = p1.a + rat * d1
+ new_y = p1.b + rat * d2
+ dx = new_x - p.a
+ dy = new_y - p.b
+ sum2 = sqrt(dx*dx+dy*dy)
+ if (sum2 < closest_distance) {
+ x = new_x
+ y = new_y
+ closest_distance = sum2
+ closest_i = i
+ }
+ }
+ if (closest_i == -1) return null
+ return {
+ x: x,
+ y: y,
+ distance: closest_distance,
+ head: closest_i-1,
+ tail: closest_i,
+ }
+ }
+ exports.draw = function(ctx){
+ var points = this.points
+ if (! points.length) return
+ if (points.length == 1) {
+ ctx.fillStyle = "#f80"
+ map.draw.dot_at(this.points[0].a, points[0].b, 5)
+ }
+ if (points.length > 1) {
+ ctx.fillStyle = "rgba(255,255,0,0.1)"
+ ctx.strokeStyle = "#f80"
+ ctx.lineWidth = 2 / map.zoom
+ ctx.beginPath()
+ ctx.moveTo(points[0].a, points[0].b)
+ points.forEach(function(point, i){
+ i && ctx.lineTo(point.a, point.b)
+ })
+ ctx.stroke()
+ if (! map.ui.placing || this.closed) {
+ ctx.fill()
+ }
+ }
+ }
+ exports.draw_line = function (ctx, p){
+ var last = this.points[this.points.length-1]
+ ctx.strokeStyle = "#f80"
+ ctx.lineWidth = 2 / map.zoom
+ ctx.beginPath()
+ ctx.moveTo(last.a, last.b)
+ ctx.lineTo(p.a, p.b)
+ ctx.stroke()
+ }
+ exports.close = function(){
+ this.points[this.points.length] = this.points[0]
+ this.closed = true
+ }
+ exports.build = function(){
+ this.mx_points && this.mx_points.forEach(function(mx){ scene.remove(mx) })
+ this.mx = new MX.Polyline(this)
+ shapes.add(this)
+ }
+ exports.rebuild = function(){
+ this.mx.rebuild()
+ }
+ exports.reset = function(){
+ this.mx_points.forEach(function(mx){ scene.remove(mx) })
+ this.mx_points.length = 0
+ this.points.length = 0
+ }
+ exports.destroy = function(){
+ this.reset()
+ this.mx && this.mx.destroy()
+ }
+ return exports
+})
diff --git a/public/assets/javascripts/rectangles/engine/shapes/shapelist.js b/public/assets/javascripts/rectangles/engine/shapes/shapelist.js
new file mode 100644
index 0000000..00e1a4e
--- /dev/null
+++ b/public/assets/javascripts/rectangles/engine/shapes/shapelist.js
@@ -0,0 +1,61 @@
+var ShapeList = Fiber.extend(function(base){
+ var exports = {}
+ exports.init = function(){
+ this.shapes = []
+ }
+ exports.add = function(shape){
+ this.shapes.push(shape)
+ }
+ exports.remove = function(shape){
+ var index = this.shapes.indexOf(shape)
+ if (index !== -1) {
+ this.shapes.splice(index, 1)
+ }
+ }
+ exports.removeSegment = function (segment){
+ var shape = segment.shape
+ var head = shape.getHeadAtIndex(segment.head)
+ var tail = shape.getTailAtIndex(segment.tail)
+ this.remove(shape)
+ shape.destroy()
+ if (head) {
+ this.add(head)
+ head.build()
+ }
+ if (tail) {
+ this.add(tail)
+ tail.build()
+ }
+ }
+ exports.findClosestPoint = function (p){
+ var point
+ for (var i = 0; i < this.shapes.length; i++) {
+ point = this.shapes[i].hasPointNear(p)
+ if (point) return { point: point, shape: this.shapes[i] }
+ }
+ return null
+ }
+ exports.findClosestEndPoint = function (p){
+ var point
+ for (var i = 0; i < this.shapes.length; i++) {
+ point = this.shapes[i].hasEndPointNear(p)
+ if (point) return { point: point, shape: this.shapes[i] }
+ }
+ return null
+ }
+ exports.findClosestSegment = function (p){
+ var segment = null, closest_segment = null
+ for (var i = 0; i < this.shapes.length; i++) {
+ segment = this.shapes[i].hasSegmentNear(p, 10)
+ if (segment && (! closest_segment || segment.distance < closest_segment.distance)) {
+ closest_segment = segment
+ closest_segment.shape = this.shapes[i]
+ }
+ }
+ return closest_segment
+ }
+ exports.forEach = function(fn){
+ this.shapes.forEach(fn)
+ }
+ return exports
+}) \ No newline at end of file
diff --git a/public/assets/test/ortho3.html b/public/assets/test/ortho3.html
index f56c73f..ef5732c 100644
--- a/public/assets/test/ortho3.html
+++ b/public/assets/test/ortho3.html
@@ -74,9 +74,12 @@ body {
<script src="/assets/javascripts/rectangles/engine/map/ui/ortho.js"></script>
<script src="/assets/javascripts/rectangles/engine/map/tools/_base.js"></script>
<script src="/assets/javascripts/rectangles/engine/map/tools/arrow.js"></script>
+<script src="/assets/javascripts/rectangles/engine/map/tools/eraser.js"></script>
<script src="/assets/javascripts/rectangles/engine/map/tools/ortho.js"></script>
<script src="/assets/javascripts/rectangles/engine/map/tools/polyline.js"></script>
<script src="/assets/javascripts/rectangles/engine/map/tools/position.js"></script>
+<script src="/assets/javascripts/rectangles/engine/shapes/shapelist.js"></script>
+<script src="/assets/javascripts/rectangles/engine/shapes/polyline.js"></script>
<script>
var app = window.app || {}
@@ -84,246 +87,6 @@ app.tube = new Tube ()
app.on = function(){ app.tube.on.apply(app.tube, arguments) }
app.off = function(){ app.tube.off.apply(app.tube, arguments) }
-var EraserTool = MapTool.extend(function(base){
- var exports = {}
- exports.down = function(e, cursor){
- last_point.a = cursor.x.a
- last_point.b = cursor.y.a
- var segment = shapes.findClosestSegment(last_point)
- if (segment) {
- shapes.removeSegment(segment)
- }
- }
- exports.move = function(e, cursor){
- last_point.a = cursor.x.a
- last_point.b = cursor.y.a
- var segment = shapes.findClosestSegment(last_point)
- if (segment) {
- document.body.style.cursor = "pointer"
- last_point.a = segment.x
- last_point.b = segment.y
- cursor.x.a = cursor.x.b = last_point.a
- cursor.y.a = cursor.y.b = last_point.b
- }
- else {
- document.body.style.cursor = "crosshair"
- }
- }
- return exports
-})
-
-var ShapeList = Fiber.extend(function(base){
- var exports = {}
- exports.init = function(){
- this.shapes = []
- }
- exports.add = function(shape){
- this.shapes.push(shape)
- }
- exports.remove = function(shape){
- var index = this.shapes.indexOf(shape)
- if (index !== -1) {
- this.shapes.splice(index, 1)
- }
- }
- exports.removeSegment = function (segment){
- var shape = segment.shape
- var head = shape.getHeadAtIndex(segment.head)
- var tail = shape.getTailAtIndex(segment.tail)
- this.remove(shape)
- shape.destroy()
- if (head) {
- this.add(head)
- head.build()
- }
- if (tail) {
- this.add(tail)
- tail.build()
- }
- }
- exports.findClosestPoint = function (p){
- var point
- for (var i = 0; i < this.shapes.length; i++) {
- point = this.shapes[i].hasPointNear(p)
- if (point) return { point: point, shape: this.shapes[i] }
- }
- return null
- }
- exports.findClosestEndPoint = function (p){
- var point
- for (var i = 0; i < this.shapes.length; i++) {
- point = this.shapes[i].hasEndPointNear(p)
- if (point) return { point: point, shape: this.shapes[i] }
- }
- return null
- }
- exports.findClosestSegment = function (p){
- var segment = null, closest_segment = null
- for (var i = 0; i < this.shapes.length; i++) {
- segment = this.shapes[i].hasSegmentNear(p, 10)
- if (segment && (! closest_segment || segment.distance < closest_segment.distance)) {
- closest_segment = segment
- closest_segment.shape = this.shapes[i]
- }
- }
- return closest_segment
- }
- exports.forEach = function(fn){
- this.shapes.forEach(fn)
- }
- return exports
-})
-
-var Polyline = Fiber.extend(function(base){
- var exports = {}
- exports.init = function(){
- this.points = []
- this.mx_points = []
- this.closed = false
- }
- exports.add = function(p){
- this.points.push( p )
- this.mx_points.push( new MX.Point(p) )
- }
- exports.firstPoint = function(){
- return this.points[0]
- }
- exports.lastPoint = function(){
- return this.points[this.points.length-1]
- }
- exports.canCloseWith = function(p){
- return (this.points.length > 2 && this.points[0].distanceTo( p ) < 10/map.zoom)
- }
- exports.getHeadAtIndex = function(index){
- if (index == 0) { return null }
- if (index == this.points.length-1) { return this.clone() }
- var head = new Polyline()
- head.points = this.points.slice(0, index+1)
- return head
- }
- exports.getTailAtIndex = function(index){
- if (index == this.points.length-1) { return null }
- if (index == 0) { return this.clone() }
- var tail = new Polyline()
- tail.points = this.points.slice(index, this.points.length)
- return tail
- }
- exports.clone = function(){
- var clone = new Polyline()
- clone.points = this.points.concat()
- }
- exports.hasPointNear = function(p){
- var point
- for (var i = 0; i < this.points.length; i++){
- point = this.points[i]
- if (point.distanceTo( p ) < 10/map.zoom) {
- return point
- }
- }
- return null
- }
- exports.hasEndPointNear = function(p){
- if (this.closed) return null
- if (this.firstPoint().distanceTo( p ) < 10/map.zoom) {
- return this.firstPoint()
- }
- if (this.lastPoint().distanceTo( p ) < 10/map.zoom) {
- return this.lastPoint()
- }
- return null
- }
- exports.hasSegmentNear = function(p, min_dist){
- var p1, p2, d1, d2, sum, rat
- var dx, dy, new_x, new_y, x, y, closest_distance = min_dist || Infinity
- var closest_i = -1
- var points = this.points
- var p1, p2 = points[0]
- for (var i = 1; i < points.length; i++) {
- p1 = p2
- p2 = points[i]
- d1 = p2.a - p1.a
- d2 = p2.b - p1.b
- sum = d1*d1 + d2*d2
- rat = ((p.a - p1.a) * d1 + (p.b - p1.b) * d2) / sum
- rat = rat < 0 ? 0 : rat < 1 ? rat : 1
- new_x = p1.a + rat * d1
- new_y = p1.b + rat * d2
- dx = new_x - p.a
- dy = new_y - p.b
- sum2 = sqrt(dx*dx+dy*dy)
- if (sum2 < closest_distance) {
- x = new_x
- y = new_y
- closest_distance = sum2
- closest_i = i
- }
- }
- if (closest_i == -1) return null
- return {
- x: x,
- y: y,
- distance: closest_distance,
- head: closest_i-1,
- tail: closest_i,
- }
- }
- exports.draw = function(ctx){
- var points = this.points
- if (! points.length) return
- if (points.length == 1) {
- ctx.fillStyle = "#f80"
- map.draw.dot_at(this.points[0].a, points[0].b, 5)
- }
- if (points.length > 1) {
- ctx.fillStyle = "rgba(255,255,0,0.1)"
- ctx.strokeStyle = "#f80"
- ctx.lineWidth = 2 / map.zoom
- ctx.beginPath()
- ctx.moveTo(points[0].a, points[0].b)
- points.forEach(function(point, i){
- i && ctx.lineTo(point.a, point.b)
- })
- ctx.stroke()
- if (! map.ui.placing || this.closed) {
- ctx.fill()
- }
- }
- }
- exports.draw_line = function (ctx, p){
- var last = this.points[this.points.length-1]
- ctx.strokeStyle = "#f80"
- ctx.lineWidth = 2 / map.zoom
- ctx.beginPath()
- ctx.moveTo(last.a, last.b)
- ctx.lineTo(p.a, p.b)
- ctx.stroke()
- }
- exports.close = function(){
- this.points[this.points.length] = this.points[0]
- this.closed = true
- }
- exports.build = function(){
- this.mx_points && this.mx_points.forEach(function(mx){ scene.remove(mx) })
- this.mx = new MX.Polyline(this)
- shapes.add(this)
- }
- exports.rebuild = function(){
- this.mx.rebuild()
- }
- exports.reset = function(){
- this.mx_points.forEach(function(mx){ scene.remove(mx) })
- this.mx_points.length = 0
- this.points.length = 0
- }
- exports.destroy = function(){
- this.reset()
- this.mx && this.mx.destroy()
- }
- return exports
-})
-
-
-
var scene, map, controls
map = new Map ({