your programing

Fabric.js - 커스텀 속성을 사용하여 서버에 캔버스를 저장하는 방법

lovepro 2023. 4. 2. 12:17
반응형

Fabric.js - 커스텀 속성을 사용하여 서버에 캔버스를 저장하는 방법

현재 캔버스의 상태를 서버측 데이터베이스(아마도 JSON 문자열)에 저장한 후 나중에 다음을 사용하여 복원할 수 있습니다.loadFromJSON일반적으로, 이것은 다음의 방법으로 간단하게 실시할 수 있습니다.

var canvas = new fabric.Canvas();
function saveCanvas() {
    // convert canvas to a json string
    var json = JSON.stringify( canvas.toJSON() );

    // save via xhr
    $.post('/save', { json : json }, function(resp){ 
        // do whatever ...
    }, 'json');
}

그리고 나서.

function loadCanvas(json) {

  // parse the data into the canvas
  canvas.loadFromJSON(json);

  // re-render the canvas
  canvas.renderAll();

  // optional
  canvas.calculateOffset();
}

단, 빌트인을 사용하여 캔버스에 추가하는 패브릭 객체에 대한 몇 가지 커스텀 속성도 설정했습니다.Object#set방법:

// get some item from the canvas
var item = canvas.item(0);

// add misc properties
item.set('wizard', 'gandalf');
item.set('hobbit', 'samwise');

// save current state
saveCanvas();

문제는 서버 측에서 요청을 확인했을 때 캔버스에서 커스텀 속성이 해석되어 다른 모든 것과 함께 전송되지 않았다는 것입니다.이건 아마 어떻게 해야 하는지와 관련이 있을 것이다.toObjectmethod는 오브젝트 클래스의 기본 속성이 아닌 모든 속성을 제거합니다.서버에서 전송된 JSON 문자열에서 캔버스를 저장 및 복원할 수 있고 복원된 캔버스에도 커스텀 속성이 포함되도록 이 문제를 해결하는 좋은 방법은 무엇입니까?감사해요.

좋은 질문입니다.

개체에 사용자 지정 속성을 추가하는 경우 이러한 개체는 어떤 식으로든 "특별한" 개체일 수 있습니다.그것들을 하위 분류하는 것이 합리적인 해결책인 것 같습니다.

예를 들어 다음과 같이 분류합니다.fabric.Image이미지화 할 수 있습니다.그런 다음 이러한 이미지 개체는 "Gandalf" 또는 "Samwise"와 같은 이름을 가질 수 있습니다.

fabric.NamedImage = fabric.util.createClass(fabric.Image, {

  type: 'named-image',

  initialize: function(element, options) {
    this.callSuper('initialize', element, options);
    options && this.set('name', options.name);
  },

  toObject: function() {
    return fabric.util.object.extend(this.callSuper('toObject'), { name: this.name });
  }
});

먼저, 우리는 이 물건들에 유형을 부여합니다.이 유형은 에 의해 사용됩니다.loadFromJSON자동적으로 불러내다fabric.<type>.fromObject방법.이 경우에는fabric.NamedImage.fromObject.

그 후 덮어씁니다.initialize(instance method) 오브젝트를 초기화할 때 (속성이 지정된 경우) "name" 속성도 설정합니다.

그 후 덮어씁니다.toObjectinstance 메서드를 사용하여 반환되는 오브젝트에 "name"을 포함합니다(이것은 패브릭 내의 오브젝트시리얼라이제이션의 초석입니다).

마지막으로, 우리는 그것을 실장할 필요가 있습니다.fabric.NamedImage.fromObject아까 말씀드렸듯이loadFromJSON는 JSON 해석 중에 어떤 메서드를 호출하는지 알 수 있습니다.

fabric.NamedImage.fromObject = function(object, callback) {
  fabric.util.loadImage(object.src, function(img) {
    callback && callback(new fabric.NamedImage(img, object));
  });
};

여기서 ("object.src"에서) 이미지를 로드하고 나서fabric.NamedImage그만 둬요.앞에서 "초기화" 메서드를 오버로드했으므로 이 시점에서 컨스트럭터는 이미 "이름" 설정을 처리합니다.

그리고 다음 사항을 명시해야 합니다.fabric.NamedImage는 비동기 "클래스"입니다.즉,fromObject는 인스턴스를 반환하지 않고 콜백에 전달합니다.

fabric.NamedImage.async = true;

이제 이 모든 것을 시도해 볼 수 있습니다.

// create image element
var img = document.createElement('img');
img.src = 'https://www.google.com/images/srpr/logo3w.png';

// create an instance of named image
var namedImg = new fabric.NamedImage(img, { name: 'foobar' });

// add it to canvas
canvas.add(namedImg);

// save json
var json = JSON.stringify(canvas);

// clear canvas
canvas.clear();

// and load everything from the same json
canvas.loadFromJSON(json, function() {

  // making sure to render canvas at the end
  canvas.renderAll();

  // and checking if object's "name" is preserved
  console.log(canvas.item(0).name);
});

내가 뭘 놓쳤나?

나는 이것을 여러 번 했고 그것은 화려한 하위 분류가 필요하지 않다.

이 내용은 http://fabricjs.com/docs/fabric.Canvas.html#toJSON에서 다룹니다.

JSON()에 대한 호출에 속성 이름의 배열을 문자열로 포함하기만 하면 됩니다.

canvas.toJSON(['wizard','hobbit']);

바라건대...보너스 포인트의 경우 커스텀 속성을 재하이드화하는 리바이버 함수를 추가할 수 있습니다.

이것도 문서에서 다루며 예를 제시하겠습니다.

저도 같은 문제가 있었지만 fabric.js 클래스를 연장하고 싶지 않았습니다.

패브릭 캔버스를 파라미터로 사용하여 특별한 속성을 가진 문자열화 버전을 반환하는 함수를 작성했습니다.

function stringifyCanvas(canvas)
{
    //array of the attributes not saved by default that I want to save
    var additionalFields = ['selectable', 'uid', 'custom']; 

    sCanvas = JSON.stringify(canvas);
    oCanvas = JSON.parse(sCanvas) ;
    $.each(oCanvas.objects, function(n, object) {
        $.each(additionalFields, function(m, field) {
            oCanvas.objects[n][field] = canvas.item(n)[field];
        });
    });

    return JSON.stringify(oCanvas);     
}

Import하다를 하면 특별한 속성이 되는 것 .canvas.loadFromJSON()1.7.2.

보다 간단한 접근방식은 스트링화 후 속성을 추가하는 것입니다.

var stringJson = JSON.stringify(this.canvas);
var objectJson = JSON.parse(string.Json);

//remove property1 property
delete objectJson.property1;

//add property2 property
delete objectJson.property2;

// stringify the object again
stringJson = JSON.stringify(objectJson);

// at this point stringJson is ready to be sent over to the server
$http.post('http://serverurl/',stringJson);

를 호출할 하고 있는 canvas.toJSON()어프로치를 않은 Fabric의 「Fabric」의 「Fabric」의 「Fabric」의 「Fabric」의 「Fabric」의 「Fabric」의 「Fabric」의 「Fabric」의 「Fabric」의 「Fabric」의 「Fabric」을하는 간단한 방법을 소개합니다.toObject★★★★★★ 。

//EXTEND THE PROPS FABRIC WILL EXPORT TO JSON
fabric.Object.prototype.toObject = (function(toObject) {
    return function() {
        return fabric.util.object.extend(toObject.call(this), {
            id: this.id,
            wizard: this.wizard,
            hobbit: this.hobbit,
        });
    };
})(fabric.Object.prototype.toObject);

그런 다음 패브릭 개체에 사용자 지정 속성을 설정할 수 있습니다.

item.set("wizard","gandalf");
item.set("hobbit","bilbo");

당신이 했을 때canvas.toJSON()이러한 속성은 출력에 반영됩니다. 후 그를 사용하면,canvas.loadFromJSON()커스텀 애트리뷰트가 Import되어 패브릭오브젝트에 적용됩니다.

http://fabricjs.com/fabric-intro-part-3#serialization

var rect = new fabric.Rect();

rect.toObject = (function(toObject) {
  return function() {
    return fabric.util.object.extend(toObject.call(this), {
      name: this.name
    });
  };
})(rect.toObject);

canvas.add(rect);

rect.name = 'trololo';

console.log(JSON.stringify(canvas));

언급URL : https://stackoverflow.com/questions/11272772/fabric-js-how-to-save-canvas-on-server-with-custom-attributes

반응형