var toolInited = false; var polyId = 1000; (function($) { $.fn.extend({ canvasAreaDraw: function(options) { this.each(function(index, element) { init.apply(element, [index, element, options]); }); } }); var init = function(index, input, options) { var historyKey = 0; var restorePoints = []; var points, activePoint, settings; var $reset, $canvas, ctx, tmp_ctx, image; var draw, mousedown, mouseup, move, resize, reset, rightclick, record; var auxline = true; points = []; settings = $.extend({ width: $(this).width(), height: $(this).height(), imageid: $(this).attr('id'), id: 'div' + $(this).attr('id') }, options); // IMAGE REPLACE ###################################################################### if ($("#div" + settings.imageid).length > 0) { $("#div" + settings.imageid).before($("#image")); $("#div" + settings.imageid).remove(); $("#" + settings.imageid).removeClass("maphilighted"); $("#" + settings.imageid).removeAttr("style"); } wrap = $('
').css({ display: 'block', background: 'url("' + $(this).attr('src') + '")', position: 'relative', padding: 0, width: $(this).width(), height: $(this).height() }); if ($('#div' + settings.imageid).length == 0) { $(this).before(wrap).css('opacity', 0).remove(); if (has_VML) { $(this).css('filter', 'Alpha(opacity=0)'); } wrap.append($(this)); } // ------------------------------------------------------------------ $canvas = $(''); var ctx = $canvas[0].getContext('2d'); $tmp_canvas = $(''); resetDivImage = function() { }; resize = function() { $canvas.attr('height', settings.height).attr('width', settings.width); $tmp_canvas.attr('height', settings.height).attr('width', settings.width); }; $canvas.addClass('canvas'); $tmp_canvas.addClass('tmp_canvas'); // DELETE POINT ############################################################# rightclick = function(e) { e.preventDefault(); if (!e.offsetX) { e.offsetX = (e.pageX - $(e.target).offset().left); e.offsetY = (e.pageY - $(e.target).offset().top); } var x = e.offsetX, y = e.offsetY; for (var i = 0; i < points.length; i += 2) { dis = Math.sqrt(Math.pow(x - points[i], 2) + Math.pow(y - points[i + 1], 2)); if (dis < 6) { points.splice(i, 2); draw(); record(); return false; } } return false; }; // UPDATE MAP ##################################################### updateMap = function() { if (points.length > 0) { var tmpID; if (editingID > -1) tmpID = editingID; else tmpID = ++polyId; //alert(getData().title); $('#map').append($('') .attr('shape', 'poly') .attr('id', 'poly_' + tmpID) .attr('href', 'javascript:editAreaAxis(' + tmpID + ');') .attr('coords', points.join(',')) .attr('title', getData().title)//selectedFloorName) .attr('floorid', selectedFloorID) .attr('data-description', getData().description)); var values = {}; values = { 'title': '', 'description': '', 'coords': '', 'floorid': '' }; updateData(values); } editingID = -1; unbindDraw(); reset() }; // SAVE ####################################################################### save = function(change_state) { updateMap(); setToolState('select'); }; // SET TOOL STATE setToolState = function(options) { if (!options.polyid) options.polyid = -1; if (!options.state) options.state = 'select'; settings.state = options.state; updateMap(); switch (options.state) { default: case 'select': if ($("#div" + settings.imageid).length > 0) { $("#div" + settings.imageid).before($("#image")); $("#div" + settings.imageid).remove(); $("#" + settings.imageid).removeClass("maphilighted"); $("#" + settings.imageid).removeAttr("style"); $('.tool').removeClass('selected'); $('#select').addClass('selected'); $('#image').maphilight({ alwaysOn: true }); } break; case 'draw': $('.tool').removeClass('selected'); $('#draw').addClass('selected'); $('#image').canvasAreaDraw(options); break; case 'edit': $('.tool').removeClass('selected'); $('#draw').addClass('selected'); break; } } // DRAW UNBIND ############################################################### unbindDraw = function() { $('canvas.canvas').remove(); $('canvas.tmp_canvas').remove(); }; // RESET ####################################################################### reset = function() { points = []; draw(); }; // MOUSEDOWN ####################################################################### mousedown = function(e) { var x, y, dis, lineDis, insertAt = points.length; if (e.which === 3) { return false; } e.preventDefault(); if (!e.offsetX) { e.offsetX = (e.pageX - $(e.target).offset().left); e.offsetY = (e.pageY - $(e.target).offset().top); } x = e.offsetX; y = e.offsetY; for (var i = 0; i < points.length; i += 2) { dis = Math.sqrt(Math.pow(x - points[i], 2) + Math.pow(y - points[i + 1], 2)); if (dis < 6) { activePoint = i; $(this).bind('mousemove', move); return false; } } for (var i = 0; i < points.length; i += 2) { if (i > 1) { lineDis = dotLineLength( x, y, points[i], points[i + 1], points[i - 2], points[i - 1], true ); if (lineDis < 6) { insertAt = i; } } } points.splice(insertAt, 0, Math.round(x), Math.round(y)); activePoint = insertAt; draw(); record(); return false; }; // MOUSE MOVE ####################################################################### move = function(e) { if (!e.offsetX) { e.offsetX = (e.pageX - $(e.target).offset().left); e.offsetY = (e.pageY - $(e.target).offset().top); } points[activePoint] = Math.round(e.offsetX); points[activePoint + 1] = Math.round(e.offsetY); draw(); }; // MOUSE UP ####################################################################### mouseup = function(e) { $(this).unbind('mousemove'); record(); saveRestorePoint(); if (settings.state == 'draw') { $(this).bind('mousemove', auxline); } activePoint = null; }; // NORMAL DRAW ####################################################################### draw = function() { ctx.canvas.width = ctx.canvas.width; if (points.length < 2) { return false; } ctx.globalCompositeOperation = 'destination-over'; ctx.fillStyle = 'rgb(255,255,255)' ctx.strokeStyle = 'rgb(255,20,20)'; ctx.lineWidth = 1; ctx.beginPath(); ctx.moveTo(points[0], points[1]); for (var i = 0; i < points.length; i += 2) { ctx.fillRect(points[i] - 2, points[i + 1] - 2, 4, 4); ctx.strokeRect(points[i] - 2, points[i + 1] - 2, 4, 4); if (points.length > 2 && i > 1) { ctx.lineTo(points[i], points[i + 1]); } } ctx.closePath(); ctx.fillStyle = 'rgba(255,0,0,0.3)'; ctx.fill(); ctx.stroke(); record(); }; // DASHED LINE UNBIND ####################################################################### auxlineUnbind = function() { auxline = false; tmp_ctx = $tmp_canvas[0].getContext('2d'); tmp_ctx.canvas.width = tmp_ctx.canvas.width; }; // DASHED LINE BIND ####################################################################### auxline = function(e) { if (auxline == false) return false; tmp_ctx = $tmp_canvas[0].getContext('2d'); tmp_ctx.canvas.width = tmp_ctx.canvas.width; for (var i = 0; i < points.length; i += 2) { fromX = points[i]; fromY = points[i + 1]; } toX = (e.pageX - $(e.target).offset().left); toY = (e.pageY - $(e.target).offset().top); dashPattern = [5, 10]; tmp_ctx.beginPath(); var dx = toX - fromX; var dy = toY - fromY; var angle = Math.atan2(dy, dx); var x = fromX; var y = fromY; tmp_ctx.moveTo(fromX, fromY); var idx = 0; var draw = true; while (!((dx < 0 ? x <= toX : x >= toX) && (dy < 0 ? y <= toY : y >= toY))) { var dashLength = dashPattern[idx++ % dashPattern.length]; var nx = x + (Math.cos(angle) * dashLength); x = dx < 0 ? Math.max(toX, nx) : Math.min(toX, nx); var ny = y + (Math.sin(angle) * dashLength); y = dy < 0 ? Math.max(toY, ny) : Math.min(toY, ny); if (draw) { tmp_ctx.lineTo(x, y); } else { tmp_ctx.moveTo(x, y); } draw = !draw; } tmp_ctx.closePath(); tmp_ctx.stroke(); }; // SAVE RESTORE POINT ####################################################################### saveRestorePoint = function() { restorePoints[historyKey] = []; $.map(points, function(val, i) { restorePoints[historyKey][i] = val; }); console.log('RESTORE POINT SAVE:'); console.log(restorePoints); historyKey++; }; // UNDO ####################################################################### undoDrawOnCanvas = function() { if (points.length > 3 && restorePoints.length > 1) { restorePoints.pop(); points = []; $.map(restorePoints[restorePoints.length - 1], function(val, i) { points[i] = val; }); console.log(restorePoints); draw(); record(); auxlineUnbind(); historyKey--; } }; // RECORD POINTS ####################################################################### record = function() { var values = {}; values.coords = points.join(','); values.title = getData().title; values.description = getData().description; values.floorid = getData().floorid; //alert("3543535____" + getData().title); updateData(values); }; /** * Polygons initalize */ initPolygons = function() { poly = []; $('#map area').each(function(index, el) { var _polyrow = {}; map_points = $(el).attr('coords').split(',').map(function(point) { return parseInt(point, 10); }); if ('poly_' + settings.polyid == $(el).attr('id')) { points = map_points; $(this).remove(); var values = { 'title': $(el).attr('title'), 'description': $(el).data('description'), 'coords': $(el).attr('coords'), 'floorid': $(el).attr('floorid') }; //alert($(el).attr('title')); updateData(values); draw(); } else { _polyrow = { 'id': $(el).attr('id'), 'Building': buildingID, 'title': $(el).attr('title'), 'description': $(el).data('description'), 'coords': $(el).attr('coords'), 'floorid': $(el).attr('floorid') }; poly.push(_polyrow); } $('#image').maphilight({ alwaysOn: true }); console.log(poly); }); }; /** * Drawing initialize */ initDraw = function() { unbindDraw(); $('#' + settings.id).before($canvas); $('#' + settings.id).before($tmp_canvas); resize(); initPolygons(); $canvas.bind('mousedown', mousedown); $canvas.bind('mouseup', mouseup); $canvas.bind('contextmenu', rightclick); // $(document).keyup(function(e) { // if (e.keyCode == 13) { save(); } // enter // if (e.keyCode == 27) { save(); } // esc // }); $(document).unbind('keypress').keypress("z", function(e) { if (e.ctrlKey) { console.log('control + z'); undoDrawOnCanvas(); } }); } initTools = function() { var options = {}; if (toolInited == true) return true; $(".tool").click(function() { options.state = $(this).attr('id'); setToolState(options); }); options.state = $(".tool.selected").attr('id'); //alert($(".tool.selected").attr('id')); setToolState(options); toolInited = true; } /** onDOMReady ***/ $(document).ready(function() { initTools(); initDraw(); }); }; // VML: more complex var has_VML = function() { var a = document.createElement('div'); a.innerHTML = ''; var b = a.firstChild; b.style.behavior = "url(#default#VML)"; return b ? typeof b.adj == "object" : true; }; var dotLineLength = function(x, y, x0, y0, x1, y1, o) { function lineLength(x, y, x0, y0) { return Math.sqrt((x -= x0) * x + (y -= y0) * y); } if (o && !(o = function(x, y, x0, y0, x1, y1) { if (!(x1 - x0)) return { x: x0, y: y }; else if (!(y1 - y0)) return { x: x, y: y0 }; var left, tg = -1 / ((y1 - y0) / (x1 - x0)); return { x: left = (x1 * (x * tg - y + y0) + x0 * (x * -tg + y - y1)) / (tg * (x1 - x0) + y0 - y1), y: tg * left - tg * x + y }; } (x, y, x0, y0, x1, y1), o.x >= Math.min(x0, x1) && o.x <= Math.max(x0, x1) && o.y >= Math.min(y0, y1) && o.y <= Math.max(y0, y1))) { var l1 = lineLength(x, y, x0, y0), l2 = lineLength(x, y, x1, y1); return l1 > l2 ? l2 : l1; } else { var a = y0 - y1, b = x1 - x0, c = x0 * y1 - y0 * x1; return Math.abs(a * x + b * y + c) / Math.sqrt(a * a + b * b); } }; })(jQuery);