76489

Arrow is not drawn correctly on fabricJS canvas

Question:

I'm working on a project in which several shapes (rectangle, triangle, ellipse, ..) can be drawn on a fabricJS canvas. Now I'm implementing the functionality to draw an arrow. This arrow consists out of two shapes, a line and a triangle (arrow head). They are added to the canvas as a group object but the problem is that the arrow is not drawn correctly on the canvas. (see <a href="https://i.stack.imgur.com/nyvAV.png" rel="nofollow">this picture</a> ).

Below is my code to draw the arrow:

drawShape: function(canvas, shape) { let selectedShape; let pointer, startX, startY, origX, origY; let rect, ellipse, line, triangle, arrow; let stroke = 'black'; let fill = 'transparent'; canvas.on('mouse:down', function(option) { if(option.target != null) { return; } else { switch(shape) { case 'arrow' : pointer = canvas.getPointer(option.e); let arrowLinePoints = [pointer.x, pointer.y, pointer.x, pointer.y]; startX = pointer.x; startY = pointer.y; line = new fabric.Line(arrowLinePoints, { top: startY, left: startX, fill: fill, stroke: stroke, }); // reference points for arrowhead origX = line.x2; origY = line.y2; let dx = line.x2 - line.x1, dy = line.y2 - line.y1; /* calculate angle of arrow */ let angle = Math.atan2(dy, dx); angle *= 180 / Math.PI; angle += 90; arrow = new fabric.Triangle({ angle: angle, fill: 'black', top: line.y2, left: line.x2, width: 1, height: 1, originX: 'center', originY: 'center', stroke: stroke }); let grp = new fabric.Group([line, arrow], { top: startY, left: startX, width: 1, height: 1, hasBorders: true, hasControls: true, }); selectedShape = grp; break; } canvas.add(selectedShape); canvas.on("mouse:move", function(option) { switch(shape) { case 'arrow' : pointer = canvas.getPointer(option.e); selectedShape.set({ width: Math.abs(startX -pointer.x), height: Math.abs(startY - pointer.y) }); selectedShape.setCoords(); line = selectedShape.item(0); line.set({ x2: pointer.x, y2: pointer.y, left: selectedShape.left, top: selectedShape.top }); line.setCoords(); let dx = line.x2 - line.x1, dy = line.y2 - line.y1; let angle = Math.atan2(dy, dx); angle *= 180 / Math.PI; angle += 90; arrow = selectedShape.item(1); arrow.set({ top: line.y2, left: line.x2, angle: angle, width: 15, height: 15 }); arrow.setCoords(); canvas.renderAll(); break; } }); canvas.on('mouse:up', function() { canvas.off('mouse:move'); });

JSFiddle: <a href="https://jsfiddle.net/9408k1gb/" rel="nofollow">https://jsfiddle.net/9408k1gb/</a>

Is there a way to fix this? Thanks in advance!

Kind regards,

Sven

Answer1:

I think that adding the line and arrow to the group and then moving them around was causing some problems. I shifted the code around so that the arrow and line are only joined into a group once the drawing is done and that seemed to fix the issue. The basics of what I did was wait until the mouse:up event and then take care of the group like so:

canvas.deactivateAll(); canvas.remove(line); canvas.remove(arrow); selectedShape = new fabric.Group([line, arrow], { hasBorders: true, hasControls: true, }); canvas.add(selectedShape);

<a href="https://jsfiddle.net/9408k1gb/1/" rel="nofollow">https://jsfiddle.net/9408k1gb/1/</a>

Recommend

  • how to make android sweeping second hand on analog clock?
  • Why do I get “Can't locate loadable object for module” even after installing the module?
  • Google fonts in React Native
  • take a screenshot of the current activity the user is on using a floating bubble running as a backgr
  • having a condition to fragment adding
  • Double data-confirm prompt observed on rails with framework7
  • Generate Quartz Cron Expression Every 2nd monday/friday
  • NServiceBus How To Publish Message From 2 Physical Locations Of 1 Logical Service
  • problems using replaceText for special characters: [ ]
  • Batch script read a file that's continously written
  • FormsAuthentication.CookieDomain property
  • Alphabetical array sort - lowercase first
  • How do I force ASP.NET Ajax to use a script from the FS and not WebResource.axd, or to reduce its HT
  • How do I detect if an email client is configured on an Android device?
  • ClearCase can I use clearexport_ccase/clearimport to copy VOB data to a VOB on a different machine
  • device tree overlay phandle
  • Working with django : Proxy setup
  • How to resolve authentication error in npm install?
  • the IBM_JAVA error for running jobs in Hadoop 2.2.0
  • Threads and Concurrent Modification Exception working with a list
  • How to display youtube video on HTML page? [closed]
  • Load php page results into div with ajax with link?
  • NoClassDefFoundError: com.google.gson.GsonBuilder when using google play services with microsoft azu
  • How to display converted time zones in a 'generic week' (Sunday thru Saturday)?
  • “Cannot open log for source” - Windows 7 - .NET web service - event log
  • Java Collections.shuffle() weird behaviour [closed]
  • how to specify different css for ie
  • How can i move Clearcase dyamic/snapshot views to another host (Linux)
  • Google Spreadsheet Script to Blink a range of Cells
  • I am consuming a WCF service that requires headers from a .NET 2 website. How can I programmatically
  • Apple Mach-O Linker error (“duplicate symbol”)
  • Write to .csv file with PHP (Commas in Data Error)
  • No OpKernel was registered to support Op 'Conv2D' with these attrs