GithubHelp home page GithubHelp logo

ailon / markerjs2 Goto Github PK

View Code? Open in Web Editor NEW
132.0 5.0 36.0 3.06 MB

Add image annotation to your web apps.

Home Page: https://markerjs.com

License: Other

JavaScript 0.31% TypeScript 99.10% HTML 0.59%
image-manipulation library svg

markerjs2's Introduction

marker.js 2 — Add image annotation to your web apps

marker.js 2 is a JavaScript browser library to enable image annotation in your web applications. Add marker.js 2 to your web app and instantly enable users to annotate and mark up images. You can save, share or otherwise process the results.

For a more detailed "Getting started" and other docs and tutorials, please refer to the official documentation.

Installation

npm install markerjs2

or

yarn add markerjs2

Usage

To add image annotation to your web application follow these 3 easy steps:

  1. Create an instance of markerjs2.MarkerArea by passing a target image reference to the constructor.
  2. Set an event handler for render event.
  3. Call the show() method.

Here's a simple example:

// skip this line if you are importing markerjs2 into the global space via the script tag
import * as markerjs2 from 'markerjs2';

// create an instance of MarkerArea and pass the target image reference as a parameter
let markerArea = new markerjs2.MarkerArea(document.getElementById('myimg'));

// register an event listener for when user clicks OK/save in the marker.js UI
markerArea.addEventListener('render', event => {
  // we are setting the markup result to replace our original image on the page
  // but you can set a different image or upload it to your server
  document.getElementById('myimg').src = event.dataUrl;
});

// finally, call the show() method and marker.js UI opens
markerArea.show();

Demos

Check out marker.js 2 demos for various usage examples.

More docs and tutorials

For a more detailed "Getting started" and other docs and tutorials, please refer to the official documentation.

Credits

marker.js 2 is using icons from Material Design Icons for its toolbar.

License

Linkware (see LICENSE for details) - the UI displays a small link back to the marker.js 2 website which should be retained.

Alternative licenses are available through the marker.js 2 website.

markerjs2's People

Contributors

ailon avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

markerjs2's Issues

Issue with external images

Hi,
Appreciate the app. It is wonderful. I am facing an issue where the image source is from an external source. The annotations are not saved in that case. Attached is the html code. Am I missing something? Thanks again.
-Dan
index.txt

Angular Implementation

Hey, thanks for this awesome product.

I've been trying to implement the code using the node package as per the documentation, and I am running into the following issue:

image

Node version: v12.18.2
NPM version: 6.14.5
markerjs2 version: 2.3.2 (latest)

I've attempted to test a few versions going back to v2.0.0.

Please advise if there's anything I could be doing incorrectly, or if there is something I need to do specific to Angular.

Can we keep current marker enabled until another marker is clicked

Hi, is there any way that once a marker is selected it will remain selected until next marker is activated. For instance, if arrow marker is selected currently it goes unselected after each arrow creation. To create a new arrow we need to click on arrow marker again and create a new arrow. So is it possible to do it like, selected marker will remain active until another marker is clicked.

Is there a way to work with an image source's size? - thumbnail workaround

I'm trying to build out a mobile UI with small square thumbnails. I have full size preview image elements that are display: hidden, until the user taps on a thumbnail. I have an edit button to launch markerjs2 next to these thumbnails. I have tried:

  1. feed markerjs the thumbnail img element
  2. feed markerjs the display: none full size img element

Option 1 rewrites my source image to the size of the thumbnail, while option 2 makes markerjs2 error out. Specifically, option 2 brings up the tools with a white canvas in popup mode, and gives a Failed to read the 'value' property from 'SVGLength': Could not resolve relative length when trying to save.

Is there a way to preserve the source image while my ui is heavily based on thumbnails?

Failed to execute 'setTranslate' on 'SVGTransform': The provided float value is non-finite.

I am trying to pass this object to markerArea.restoreState():

// console log right before restoreState()
{
    "width": 671,
    "height": 356,
    "markers": [
        {
            "x1": 252.18359375,
            "x2": 392.7890625,
            "y1": 174.015625,
            "y2": 109.74609375,
            "state": "select",
            "typeName": "ArrowMarker",
            "arrowType": "end",
            "strokeColor": "#FF6E64",
            "strokeWidth": 3,
            "strokeDasharray": ""
        }
    ]
}

But I keep getting the error Failed to execute 'setTranslate' on 'SVGTransform': The provided float value is non-finite.. It seems somewhere inside of restoreState(), all the floats in the object above are turned into NaN:

Any ideas of what might be happening?

Markerjs2 placed incorrectly when triggered

Hi,

I'm trying to use markerjs2 in a project but when I implement the code from the examples, the elements that are generated when clicking on the image are not correctly aligned.

The attached screenshots show a basic example in a white page but the real implementation I'm trying to do is inside a bootstrap modal and the elements then appears under the modal on the top left corner of the page, it's not placed at all over the original image.

Do you have any idea why I get such position issues ?

Is it normal that the generated elements are inserted at the end of the DOM and not next the original image element ?

Here is my very simple vue component :

<template>
    <div class="marker-container">
        <img
                ref="screenshot"
                :src="screenshot"
                class="screenshot"
                @click="showMarkerArea"
        />
    </div>
</template>

<script>
    import * as markerjs2 from 'markerjs2';

    export default {
        name: "Annotation",
        props: {
            screenshot: {
                type: String,
                required: true,
            },
            screenshotId: {
                type: Number,
                required: true,
            },
        },
        methods: {
            showMarkerArea() {
                // create a marker.js MarkerArea
                const markerArea = new markerjs2.MarkerArea(this.$refs.screenshot);

                // attach an event handler to assign annotated image back to our image element
                markerArea.addRenderEventListener(dataUrl => {
                    this.$refs.screenshot.src = dataUrl;
                });

                // launch marker.js
                markerArea.show();
            },
        },
    }
</script>

Capture d’écran 2021-03-08 à 15 47 58

Capture d’écran 2021-03-08 à 15 48 03

Capture d’écran 2021-03-08 à 15 52 40

Custom action on save

I'm trying to trigger an automatic upload action upon saving an annotated image. Is there an event I can bind to accomplish this? Or, perhaps can I modify the default save button to execute a custom method?

Generate rasterized image on the fly from MarkerAreaState + original image

Hi @ailon,

First of all thank you very much for this great tool!

What do you think is the best way to store the MarkerAreaState (e.g., in a backend) in order to later fetch it and display the annotated image without opening the marker area first? Is there a way to do it without having to also store the annotated image alongside the MarkerAreaState?

Thanks!

Some actions throw exceptions when nothing is selected

Hi, thanks for creating markerjs2!

I've noticed that some actions lead to exceptions being thrown, when nothing is selected:

  • Pressing delete
  • Changing any property of arrows, text and callouts
markerjs-exceptions.mp4

How to release focus on the current marker?

After annotating with some shape, The final annotated image needs to be saved with some label, so i want to allow the user to enter name while annotating, but when user moves to text input and starts typing the last Drawing shape is getting removed.

Note: there is not a problem if User clicks out of the shape after using Marker type , it's happening only last drawing shape was in focus.

is there any way to release focus?

Uncaught TypeError: can't access property "style", this.textEditor is undefined

We use a custom button to place text markers on the image. 99% of the time it works, but every once in a while, when performing a .restoreState() after a .show() in an image with text markers, we get the following error:

image

And the source map shows the error happens in this line:

image

We are not sure how to even begin debugging this! Is this a known issue? Any pointer of what to do to avoid this?

Draw tool in Markerjs2

The annotation draw tool is not working on IOS mobile browsers. can you help with this.

Persist marker selection

Is there a way to persist the last selected marker? Currently the marker has to be selected before each annotation.

Great project by the way!

Force RectangleMarkers and other markers to be reused after each creation

Is there any way to set default markers to be selected and create multiple elements of the marker without clicking the toolbar every time an element is created?

Because right now when adding a FrameMarker, an ArrowMarker, or a TextMarker, the tool is automatically deselected after drawing.

Js function for remove a marker

Hi, I would like to use a custom button or keyboard shortcut for removing a marker, but I can't find a function like "deleteActiveMarker()" in the first version of markerjs,
I tried some shady things like

const index = this.markerArea.markers.indexOf(this.markerArea.currentMarker);
				if (index > -1) {
					this.markerArea.markers.splice(index, 1);
				}

but with no success. Is there a correct way to do this with markerjs2 ?
Regards,

Safari: text do not scale nor translate when resizing

Either using the raw text or the text bubble, when resizing the marker, the text does not get translated or scaled.

If the marker is double clicked to edit the text, the position and scale get fixed.

Incorrect (after resize)

Screenshot 2021-06-25 at 17 40 39

Correct (after double click)

Screenshot 2021-06-25 at 17 40 51

It seems to work on Edge/Chrome. Most probably a Webkit issue...

Safari 14.1.1 / macOS Big Sur 11.4

Autosaving feature?

Thank you for this library and all the effort you put into it.

Quick question: is there a good way to implement an autosave feature?
For example, detecting whenever something changes within the marker area and autosave.

We could detect clicks outside the marker area, or use an interval to save regularly, but were wondering if the library has any built-in, more performant way to achieve this?

Render at Natural Size

Sorry to be a pain, is there a way to manually pass a size?

I'm currently working with base64 and it's taking the size of the img element even when using renderAtNaturalSize?

Error with the backspace-to-delete feature

Hi Alan,

Thanks for adding the feature in 2.4.0 that enables marker deletion with the backspace keystroke, very helpful!

Unfortunately now if you use the backspace key while typing text into a text-based marker, it deletes the marker as you're typing.

Jeff

Blurred image output in popup.

Image gets blurred on opening the Annotation toolbar in popup mode. Is there a way to fix the styling of the popup so that the original image dimensions are retained?

Support of Zoom / Pinch-zoom

Hi @ailon, I'm interested to use this in mobile device where user can zoom into an image to have better annotation.

Doing a search, I didn't not find anything related to zoom. Is part of your development roadmap?

Thanks.

It's not possible to add text on Android in 'popup' display mode

This issue occurs only on Android. On iOS, keyboard doesn't change viewport height.

Steps to reproduce:

  1. Select 'text' tool
  2. Tap somewhere on the image
  3. Keyboard appears, viewport shrinks, keyboard closes

In my case it happens with both inline and popup display mode because body's height is 100vh. In case of inline mode I can set fixed height to the image container and it prevents target image from resizing, which makes text add/edit possible.

I'd appreciate any workaround for popup mode

Screen_Recording_20210429-112236_Chrome.mp4

Picture as overlay

Hi there, found out this awesome library and interested to add this to my project.

However, I needed to add a transparent image on another image as the marker, which it should be scaled, moved and rotated.

Will this be considered?

Thanks in advance.

Rendering previous state without having to open and close the marker area

Hi

Does anyone know if there is a way to render an existing state from a previously saved state without having to open and close the marker area?

Currently, we are doing the following:

  1. Fetch previous marker state JSON from the backend
  2. Parsing it
  3. Applying it via the restoreState function
  4. Calling startRenderAndClose to have the image updated with the existing annotations

The result of this is there is a quick flash on the UI which is not the best user experience at the moment.

const restorePanelDrawingArea = (drawing?: PanelDrawingDocument) => {
    if (!drawing || !markerAreaElement) return undefined;

    markerAreaElement.show();
    setTimeout(() => {
      markerAreaElement.restoreState(JSON.parse(drawing.drawingData));
      markerAreaElement.startRenderAndClose();
    }, 100);
  };

Are there any events for clicking on marks?

Hi,

I've read through the docs and your TS file and I can't find any support for an event when a mark is clicked.

Is there a way for me to receive an event with a mark is clicked, or do you plan on adding support for this in the future?

Thanks for an awesome library!

Handle color event and save last used color

Hi,

I trying to achieve the following use case:
"As a user, when I add, for example, a line or text to an image and change the color of that line or text to, for example, blue next time I add a line or text, the default color will be the last used color, that is blue".

Technically, the way I see this is as follows :
1- detect/handle event when color is changed
2-set the default color to the selected color

I have the same question with line types : set the default line type (arrow, double arrow, simple) to last selected type.

I've read your documents but for the moment I'm unable to achieve this. Is it possible to achieve this use case and if so could you please explain how it's done ?

Thank you.

Is it possible to allow putting some icons

Hi,
I don't have enough word to appreciate your efforts.
I have a request which might be helpful for other users also. Which is allow putting different types of icons. At lest few. Is it possible to add please.

Annotating SVG images

I am attempting to annotate SVG images, however I am unable to save the resulting image as I get an error

markerjs2.esm.js?4931:15 Uncaught DOMException: Failed to execute 'toDataURL' on 'HTMLCanvasElement': Tainted canvases may not be exported. at Image.h.onload (webpack-internal:///./node_modules/markerjs2/markerjs2.esm.js:47:5795)

Setting markerArea.renderMarkersOnly = true; gets rid of the error, but then only the annotation is saved. I could combine the 2 layers myself, but was hoping there was a way to do so in markerjs.

Force FreehandMarker to end after each stroke?

We created a custom toolbar that calls createNewMarker() functions to add markers to our marker area.
All markers work the same, except the FreehandMarker.

  • When adding a FrameMarker, an ArrowMarker, or a TextMarker, the tool is automatically deselected after drawing; you can use the transformation handles and move the marker around; it is also registered in the state
  • When adding a FreehandMarker, you can keep drawing until you select another tool; only then, all shapes drawn are stored as a single marker, and you can select it to use its transformation handles

We feel this is counterintuitive and would love to have the FreehandMarker behave like the other tools: as soon as you finish drawing a stroke, the stroke is selected, the handles are shown, and is stored in state.

Any simple way to do this? Or should we go ahead and dive into creating a custom marker?

How to manually save the image

Hi,

For my project I need to be able to trigger the same action as the one triggered by the click on the save button.

I did succeed by doing something like that :

markerArea = new markerjs2.MarkerArea(screenshot);
markerArea.addRenderEventListener((dataUrl) => {
    screenshot.src = dataUrl;
});

$('.my-custom-save-button').click(() => {
    await markerArea.renderClicked();

    const canvas = document.createElement('canvas');
    const ctx = canvas.getContext('2d');

    // Set width and height
    canvas.width = $(screenshot).width();
    canvas.height = $(screenshot).height();

    // Draw the image
    ctx.drawImage(screenshot, 0, 0);

    const savedImage = canvas.toDataURL('image/png');
});

With this code I'm able to get the rasterized image out of marker.js to use it the way I want.

Everything is perfect except that it doesn't work in Firefox.
It works without issues in Chrome and Edge but in Firefox, I end up with only something like a quarter of the image and I don't understand why.

So now I'm thinking, there is probably a better way to do that.

Also, to remove the save and delete buttons that I don't need, I do as follow but again, there is probably a better way to do that :

$($($(markerArea.uiDiv.firstElementChild).find('.__markerjs2_toolbar_button')[9])[0]).hide();
$($($(markerArea.uiDiv.firstElementChild).find('.__markerjs2_toolbar_button')[10])[0]).hide();

Thank you in advance for your help !

Default Fill Colour not working?

Hi,

Working great, except the default fill colour doesn't seem to be working.

 markerArea.settings.defaultColor = 'black';
 markerArea.settings.defaultFillColor = 'black';
markerArea.availableMarkerTypes = [markerjs2.EllipseMarker];

This just gives me a black outline when adding the Ellipse marker?

Any help appreciated.

Thanks

Feature Requests

My company recently purchased the license for the markerjs2 library and I imported it into my project at work. I just wanted to say thank you as it's working great. I did come across two features that would be nice if ever the possibility of adding them were to arise. One would be to enable deleting a selected marker by pressing the delete key instead of clicking on the trash can. Second, would be provide a way when initially loading an image to show the saved off marker data. I am currently saving off the marker data, which works great with a single session of making annotations on an image. However, it would be nice to be able to come back to an image at a later date and be able to pass the saved off marker data to display on the image without having to first launch the editor and run through the addRenderEventListener method. Thank you and please let me know if you have any questions.

Error when inputting text markers

Hi Alan,

When I input a text marker and finish typing, if I click inside of the marker area, the text area turns into normal marker that I can resize, as expected. But if I click anywhere outside the marker area (like for example, another tool on the toolbar, or the save button), the text area blurs, but the element hasn't actually been created. If I then save the image without clicking inside the marker area, the text area disappears.

Jeff

Plot image icons

There is any way to plot a series of pre defined images as a little icon at the image?

Ellipse as highlighter

Is it possible to add an ellipse highlighter? or perhaps a way to set the default opacity for the EllipseMarker?

In MarkerArea.ts, showUI, this.target.top and this.target.left is incorrect for dynamically created images

Alan,

When I create a markerArea from an image in my application, the position does not match where the image appears on the screen. I believe this is because my images are dynamically created and perhaps the top and left values are relative to their containers instead of the absolute position on the page.

image

image

If I use getBoundingClientRect instead of target.offsetTop the markerArea displays where it should.

image

image

I believe this code change will address the issue:

image

What do you think?

RectangleMarker initialization

Hello,

I want to create rectangle markers from the code that can then be edited by the user. So I try to create them with the RectangleMarker class but I don't understand what exactly the constructor parameters correspond to (despite the documentation). Would it be possible to have an example of initialization of a RectangleMarker or a more precise explanation of what its parameters (especially container, overlayContainer) correspond to ?

Thanks

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.