Utilize JSON FabricJS to incorporate image data seamlessly

Currently, I am working with the FabricJS canvas and my goal is to export the canvas as JSON.

I have experimented with loading images using both new fabric.Image and fabric.Image.fromURL, and both methods have worked well for me.

My next task is to obtain JSON data from the canvas. However, I require two different types of JSON outputs. One should include a link to the image used initially, while the other should directly embed base64 data within the JSON itself. I have attempted to use canvas.toJSON() and canvas.toDatalessJSON(), but surprisingly, they both only provide results with a link and do not contain any image data.

How can I generate JSON output that actually INCLUDES image data directly in the JSON? (I already have it with the link)

I have created a simple demo showcasing my current progress. Upon clicking on the export button and checking the console, you will notice that both objects display the source link without any base64 data included.

The reason I am interested in base64 data is because I want immediate access when reusing the JSON elsewhere.

Despite searching online and consulting the documentation, it appears that toJSON function only captures shape data and not image information. Have I overlooked something crucial?

Thank you in advance!

Answer №1

How to Extend the toObject Method of fabric.Image

Extend the toObject method of fabric.Image by adding the src property with the value of this.toDataURL().

fabric.Image.prototype.toObject = (function(toObject) {
  return function() {
    return fabric.util.object.extend(toObject.call(this), {
      src: this.toDataURL()
    });
  };
})(fabric.Image.prototype.toObject);

To set the src property, use object.toDataURL()

DEMO

const useFabricImage = () => {
  const c = document.getElementById("designer");
  const canvas = new fabric.Canvas(c, {width: 500, height: 500})
  const url = "https://i.imgur.com/KxijB.jpg";
  const img = new Image();
  img.src = url;
  const fabricImage = new fabric.Image(img, {});
  canvas.add(fabricImage);
  
  return canvas;
}
const useFromURL = () => {
  const c = document.getElementById("designer");
  const canvas = new fabric.Canvas(c, {width: 500, height: 500})
  const url = "https://i.imgur.com/KxijB.jpg";
  fabric.Image.fromURL(url, (img) => {
    canvas.add(img);
  },{
    crossOrigin:'annonymous'
  });
  return canvas;
}
fabric.Image.prototype.toDatalessObject = fabric.Image.prototype.toObject;

fabric.Image.prototype.toObject = (function(toObject) {
  return function() {
    return fabric.util.object.extend(toObject.call(this), {
      src: this.toDataURL()
    });
  };
})(fabric.Image.prototype.toObject);


const canvas = useFromURL();

const button = document.getElementById("export");
button.addEventListener("click", () => {
  console.log(canvas.toJSON());
  console.log(canvas.toDatalessJSON());
})
#designer {
  border: 1px solid aqua;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/2.3.3/fabric.min.js"></script>
<canvas id="designer" height="500" width="500"></canvas>
<button id="export">Export</button>

Answer №2

To enhance the functionality of fabric.Image.protype.toObject():

fabric.Image.prototype.toObject = (function (toObject) {

    return function () {
        var image = this;

        var getData = function () {
            var canvas = document.createElement("canvas");
            canvas.width = image.width;
            canvas.height = image.height;

            context = canvas.getContext('2d');

            context.drawImage(image.getElement(), 0, 0);

            return canvas.toDataURL('image/png').replace(/^data:image\/png;base64,/, '');
        };

        return fabric.util.object.extend(toObject.call(this), {
            dataURL: getData(),
        });
    };
})(fabric.Image.prototype.toObject);

Subsequently, the dataURL attribute will be automatically appended to your object.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

I'm looking for a way to implement a jQuery-style initialization pattern using TypeScript - how can I

My library utilizes a jQuery-like initialization pattern, along with some specific requirements for the types it should accept and return: function JQueryInitializer ( selector /*: string | INSTANCE_OF_JQUERY*/ ) { if ( selector.__jquery ) return select ...

Tips for removing ASP.NET MVC controller name from angular route

My ASP.NET MVC login page leads to a different page that is integrated with Angular. After logging in, the URL looks something like this: http://localhost:5083/Home#/home I want to remove the ASP MVC controller name ("Home") from the URL. Is there a ...

Can I obtain a link through the branch_match_id parameter?

Within my application, there exists a hyperlink: hxxp://get.livesoccer.io/IuKk/0CRq5vArLx which leads to the following destination: hxxp://livesoccer.io/news.html?url=http%3A%2F%2Fwww.90min.com%2Fembed%2Fposts%2F4003374-chelsea-star-pedro-loving-life-at-s ...

Does a Javascript event get triggered when the currentSrc attribute of an <img> element is modified?

Let's imagine we have an image tag like this: <img id="my_tag" src="/default.jpg" srcset="/small.jpg 500w, /medium.jpg 1000w, /large.jpg 2000w"> Upon loading the page, JavaScript can determine which source from t ...

Having issues with setTimeout on Chrome for Android when the browser is out of focus. Any ideas for resolving this?

I developed a web application that functions as a messaging system, where users can submit messages and others can receive them. The system operates through AJAX, with the front end using JavaScript to interact with a PHP backend. Everything runs smoothly ...

Is it possible to insert JavaScript code with the <link> element?

Is it possible to include JavaScript code using the <link> tag on my website? For instance, if I have a JavaScript file named test.js that includes the simple code alert('hello'); Can I trigger a popup window to appear by using the follow ...

Variation in Map Behavior in d3 Due to Datum-Data Discrepancy

I'm relatively new to utilizing d3js and I am endeavoring to grasp the distinction between employing data and datum for associating data with elements. Despite having spent quite some time reading various materials online, I still lack an instinctive ...

Problem with AngularJS factory causing issues with promises

I have a factory in AngularJS set up like this: 'use strict'; angular.module('frontRplApp') .factory('paymentService', function ($rootScope, $http, config, tools) { var urlBase = config.baseUrl; var payme ...

Angular view fails to update after form submission when using ngDialog to change the scope

After starting my Angular journey, I decided to challenge myself by creating a comprehensive todo app for educational purposes. I seem to be missing something pretty basic, although I can't quite put my finger on it. It seems like there might be an is ...

Uploading multiple images with a custom meta box in Wordpress

I'm currently working on a project that involves creating a custom post type with a custom meta box. Within this meta box, I am attempting to include a media uploader for multiple images. The goal is to save multiple image IDs in an array. However, I& ...

How can I utilize Handlebars and a JSON API call to effectively transfer data from an array response and display it within a Handlebars modal?

$("#searchMovieBtn").click(() => { const movieSource = $("#movie-template").html(); const movieList = Handlebars.compile(movieSource); const movieSearch = $("#addMovie").val(); console.log(movieSearch); queryURL = `https://ap ...

Dramatist: What are effective methods for distinguishing and monitoring frames within a webpage?

When it comes to storing my own copy of frames, I want to utilize the page.on("frameattached") and page.on("framedetached") events to properly manage the lifecycle of the frames. My main concern is how I can uniquely identify them across these events. I ...

Leverage the power of regular expressions in JavaScript for organizing and handling source files

Embarking on my coding journey with JavaScript, I have also been exploring the world of Three.js, a webgl library. After watching tutorials and conducting experiments, I am proud to share my latest creation: . In my code, you'll notice that the obje ...

Struggling to interpret the data received from an API request

I am currently struggling to parse the response object from an API call. Initially, I decoded the returned JSON like this: let responseObject = (try? JSONSerialization.jsonObject(with: data)) as? [String: Any] if let result = responseObject["result&q ...

I find the JSX syntax to be quite perplexing

While examining some code, I came across the following: const cardSource = { beginDrag(props) { return { text: props.text }; } }; When working with JSX block code or building objects, I usually use {}. The cardSource variable in this co ...

Error: Attempting to access an undefined property ('useParams') which cannot be read

Hey there, I'm currently facing some challenges with the new react-router-dom v6. As I am still in the learning phase of this latest version, I could really use some assistance. import React from 'react' function Bookingscrren({match}) { ...

Convert a JSON array with a single element into a valid JavaScript object

Within my programming scripts, I frequently utilize PHP arrays with numeric keys. However, these keys are not necessarily sequential from 0 to n; they can be randomly chosen. Specifically, I am working on a script that organizes scheduled events at specifi ...

What is the best way to apply a border-radius to the top of bars in @nivo/bar?

Is it possible to apply a border radius to the tops of each stack in a stacked responsive bar created from the Nivo library, without affecting the bottom? Currently, the responsive bar's border radius applies to both the top and bottom. Thank you! ...

Transforming JSON data in a Node.js API using JSONata

In need of developing a Node.js REST API for transforming JSON to JSON format. After researching multiple libraries, I have narrowed down my options to "JSONata". You can find a simple sample of JSONata here. The main challenge lies in the fact that the ...

saving filter configurations in JSON format using SQLite in a Node.js environment

Currently, my nodejs web server is up and running with express and sqlite. Now I am faced with the task of storing all filter selections for tables, trees, combos, checks, radios, etc. There are approximately twelve filters per section, spread across eight ...