window.ctx = window.w = window.h = null; var clipper = new function(){ var base = this var canvas = document.createElement("canvas") var ctx = window.ctx = canvas.getContext("2d") var w = window.w = canvas.width = 500 var h = window.h = canvas.height = 500 var regions = [] document.querySelector("#map").appendChild(canvas) var rooms = base.rooms = [] base.creating = false base.dragging = false var modified = true base.mouse = new rect(0,0,0,0) base.init = function (){ base.bind() } base.animate = function(){ clear_canvas() if (modified) { solve_rects() builder.tube("clipper:update") } draw_ruler() draw_regions(base.regions) draw_mouse(base.mouse) modified = z = false } base.add_room = function(r){ rooms.push( new room({ id: base.rooms.length, rect: r, }) ) } base.bind = function(){ canvas.addEventListener("mousedown", function(e){ e.stopPropagation() var x = e.pageX, y = e.pageY base.mouse = new rect (x,y) if (e.shiftKey) { base.mouse.quantize(10) } var intersects = rooms.filter(function(r){ return r.focused = r.rect.contains(x,y) }) if (intersects.length){ clipper.dragging = intersects[0] } else { clipper.creating = true } if (e.shiftKey && clipper.dragging) { clipper.dragging.rect.quantize(10) } }) canvas.addEventListener("mousemove", function(e){ e.stopPropagation() var x, y if (e.shiftKey) { x = quantize( e.pageX, 10 ) y = quantize( e.pageY, 10 ) } else { x = e.pageX y = e.pageY } base.mouse.x.b = x base.mouse.y.b = y if (clipper.dragging) { clipper.dragging.rect.translation.a = base.mouse.x.magnitude() clipper.dragging.rect.translation.b = base.mouse.y.magnitude() } else if (clipper.creating) { base.mouse.x.b = x base.mouse.y.b = y } else { base.mouse.x.a = base.mouse.x.b base.mouse.y.a = base.mouse.y.b } }) document.addEventListener("mouseup", function(e){ e.stopPropagation() if (clipper.creating) { if (base.mouse.height() != 0 && base.mouse.width() != 0) { base.add_room( base.mouse.translate() ) } } if (clipper.dragging) { clipper.dragging.rect.translate() } base.mouse = new rect(e.pageX, e.pageY) clipper.creating = clipper.dragging = false modified = true }) } function solve_rects(){ for (var i = 0; i < base.rooms.length; i++) { base.rooms[i].id = i base.rooms[i].reset() } var rooms = sort_rooms_by_position( base.rooms ) var regions = [] var left, right for (var i = 0; i < rooms.length; i++) { left = rooms[i] for (var j = i+1; j < rooms.length; j++) { right = rooms[j] if (left.rect.intersects(right.rect)) { left.clipTo(right.rect) right.clipTo(left.rect) } if (left.rect.x.b < right.rect.x.a) { break } } } for (var i = 0; i < rooms.length; i++) { rooms[i].regions = rooms[i].regions.filter(function(r){ return !!r }) regions = regions.concat(rooms[i].regions) } regions = sort_rects_by_area( regions ) var ty = new tree (regions[0].y.a, [regions[0]]) var tx = new tree (regions[0].x.a, ty) var ttx, tty for (var i = 1; i < regions.length; i++) { ttx = tx.add (regions[i].x.a, null) if (ttx.data) { tty = ttx.data.add (regions[i].y.a, null) // duplicate polygon? if (tty.data) { tty.data.forEach(function(yy, ii){ if (yy.intersects(regions[i])) { if (yy.area() > regions[i].area()) { regions[i].dupe = true } else { yy.dupe = true tty.data[ii] = regions[i] } } }) } else { tty.data = [regions[i]] } } else { ttx.data = new tree (regions[i].y.a, [regions[i]]) } } base.regions = sort_rects_by_position(regions) } // generate floor and ceiling for some regions // generate walls from surviving regions // generate ceiling-walls where ceiling has discontinuity return base }