summaryrefslogtreecommitdiff
path: root/public/assets/javascripts/rectangles/engine/shapes/shapelist.js
blob: 21beb76071af39a30b76bad02f8a449bbed34c39 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
// The ShapeList manages the list of polylines which form a V2 layout.

if (! ('window' in this) ) {
  var Fiber = require("../../../vendor/bower_components/fiber/src/fiber.js")
  var Polyline = require("./polyline.js")
  var OrthoPolyline = require("./ortho.js")
}

var ShapeList = Fiber.extend(function(base){
  var exports = {}
  exports.init = function(){
    this.shapes = []
    this.workline = null
  }
  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.destroy = function(){
    this.shapes.forEach(function(shape){
      shape.destroy()
    })
    this.shapes = []
  }
  exports.count = function(){
    return this.shapes.length
  }
  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)
  }
  exports.getAllShapeSegments = function(){
    return this.shapes.map(function(shape){ return shape.getSegments() })
  }
  exports.getAllSegments = function(){
    var segments = []
    this.shapes.forEach(function(shape){
      segments = segments.concat( shape.getSegments() )
    })
    return segments
  }
  exports.draw = function(ctx, fillStyle, strokeStyle) {
    this.shapes.forEach(function(shape){
      shape.draw(ctx, fillStyle, strokeStyle)
    })
  }
  exports.serialize = function(){
    return this.shapes.map(function(shape){
      return shape.serialize()
    })
  }
  exports.deserialize = function(data){
    data && data.forEach(function(shape_data){
      var line
      switch (shape_data.type) {
        case 'ortho':
          line = new OrthoPolyline()
          break
        default:
          line = new Polyline()
          break
      }
      line.deserialize(shape_data)
      shapes.add(line)
    }.bind(this))
  }
  exports.build = function(){
    this.shapes.forEach(function(shape){
      shape.build()
    })
  }
  return exports
})

if (! ('window' in this) ) {
  shapes = new ShapeList
  module.exports = shapes
}