diff --git a/public/javascripts/spacedeck_board_artifacts.js b/public/javascripts/spacedeck_board_artifacts.js index ce44a424..29e33004 100644 --- a/public/javascripts/spacedeck_board_artifacts.js +++ b/public/javascripts/spacedeck_board_artifacts.js @@ -137,6 +137,11 @@ var SpacedeckBoardArtifacts = { if (a.border_radius) { styles.push("border-radius:"+a.border_radius+"px"); } + } else { + // Prevents any click events from occuring on the svg area. + // It is now possible to click artifacts in the area around the 'invisible' + // svg box that was preventing the click event to pass through. + styles.push("pointer-events:none;") } if (a.fill_color && !svg_style) { @@ -293,7 +298,8 @@ var SpacedeckBoardArtifacts = { if (mtype != "vector" && mtype != "shape") return ""; var shape = a.shape || ""; - var padding = 32 + a.stroke*2; + // Increased padding handles the case of the arrow curve going outside the drawing border + var padding = 32 + a.stroke * (shape=='arrow' ? 10 : 2) var path_svg; var fill = ""; diff --git a/public/javascripts/spacedeck_sections.js b/public/javascripts/spacedeck_sections.js index 959e734d..f15cefed 100644 --- a/public/javascripts/spacedeck_sections.js +++ b/public/javascripts/spacedeck_sections.js @@ -35,6 +35,10 @@ var SpacedeckSections = { selected_artifacts_dict: {}, in_memory_clipboard: {}, first_selected_artifact: null, + arrow_options: { + vector_point_adjustment_dx: 0, + vector_point_adjustment_dy: 0, + }, selection_metrics: { contains_text: false, contains_images: false, @@ -1009,10 +1013,74 @@ var SpacedeckSections = { return this.enclosing_rect(this.selected_artifacts()); }, + // This function exists so the selection box includes the arrow-head. + // This is achieved by calculating the arrow point, and adjusting both the selection box and the arrow's control points. + // Arrow_option also stores the adjustment values so they can be used in Space.vue + calculateArrowPositions: function(a) { + // Control points by their position in the array [start,end,middle] + var start = a.control_points[0] + var end = a.control_points[1] + + var arrowLeft = end.dx < start.dx + var arrowUp = end.dy < start.dy + var startX; + var endX; + var startY; + var endY; + if(arrowLeft) { + startX = a.x + a.w + endX = a.x + } else { + startX = a.x + endX = a.x + a.w + } + + if(arrowUp) { + startY = a.y + a.h + endY = a.y + } else { + startY = a.y + endY = a.y + a.h + } + // Calculate the angle of the arrow in radian + var rad = Math.atan2(endY - startY, endX - startX); + + // Calculate the rayon (the length of the arrow) + // Note: Your arrow size depends on the the 'strokeWidth' attribute of your line + // 3 is the constant taken from vector-render.js + var r = 3 * a.stroke; + var xAdjust = r * Math.cos(rad) + var yAdjust = r * Math.sin(rad) + + // Adjusting vector points for arrow handles + // Arrow options are consumed inside space.vue component + arrowUp && (this.arrow_options.vector_point_adjustment_dy = - yAdjust) + arrowLeft && (this.arrow_options.vector_point_adjustment_dx = - xAdjust) + + var result = { + x1: a.x + (arrowLeft ? xAdjust : 0), + y1: a.y + (arrowUp ? yAdjust : 0), + x2: a.x + a.w + (!arrowLeft ? xAdjust : 0), + y2: a.y + a.h + (!arrowUp ? yAdjust : 0) + } + return result + }, + enclosing_rect: function(arts) { if (arts.length==0) return null; arts = _.filter(arts); // remove any nulls + if(arts.length==1) { + var artifact = arts[0] + if(artifact.shape=='arrow') { + return this.calculateArrowPositions(artifact) + } else { + // reset arrow_options on each update if the artifact is not an arrow + this.arrow_options.vector_point_adjustment_dx = 0 + this.arrow_options.vector_point_adjustment_dy = 0 + } + } + return { x1: parseInt(_.min(arts.map(function(a){return ((!a || !a.x)?0:a.x)}))), y1: parseInt(_.min(arts.map(function(a){return ((!a || !a.y)?0:a.y)}))), diff --git a/views/alfaview/Space.vue b/views/alfaview/Space.vue index f2ec550f..d9f3a03b 100644 --- a/views/alfaview/Space.vue +++ b/views/alfaview/Space.vue @@ -478,7 +478,10 @@ > @@ -513,6 +516,9 @@ export default { }; }, computed: { + arrowOptions() { + return this.$root.arrow_options; + }, userCursors() { return this.$root.user_cursors; },