带有棱角和火焰的协作式画布

问题描述 投票:1回答:1

我正在尝试在ionic / angular + fabric.js + firestore上创建实时协作画布。我有画布,我将其序列化为json,进行存储(并从其他用户进行更新),但是我无法刷新每个用户的画布。我该怎么做?

首先,我与收藏集建立了联系:

this.imageCollection = database.collection<MyImage>("images");
this.drawing = this.imageCollection.doc(this.chatId).valueChanges();
this.writeCanvas();

然后,我有在每个“鼠标向上”处调用的函数:

loadOnCanvas(){
    var json = JSON.stringify(this.f_canvas);
    this.us.addCanvastoDB(json, this.chatId);
    this. writeCanvas();
   }

并且以下功能是我尝试写入共享画布(实际上未共享)的地方,因为它不会使用其他用户的图纸进行更新。在类的开头(ngOnInit)以及每个loadOnCanvas之后调用此函数(请参见上文):

writeCanvas(){
    let that = this;
    this.drawing.pipe(take(1)).subscribe(data=>{
      that.read_json = data[0]['canvas'];
      if(that.read_json){
        this.f_canvas.clear();
        console.log("data loaded", that.read_json);
      that.f_canvas.loadFromJSON(that.read_json, that.f_canvas.renderAll.bind(that.f_canvas));
      }
    });

[当我开始绘制时,来自firestore的数据已保存在数据库中,但是如果另一个用户(或离开应用程序后的同一用户)再次输入,则会显示一个空画布,并且不会加载数据库中的数据。

这是将数据存储在数据库中的功能。它在服务中:

addCanvastoDB(canvas: any, chatId:string) {
    //Create an ID for document
    const id = this.database.createId();
    console.log("chat id: ", chatId);
    //Set document id with value in database
    this.imageCollection
      .doc(chatId)
      .set({canvas: canvas, chatid: chatId},
        { merge: true })
      .then(resp => {
        console.log("resp", resp);
      })
      .catch(error => {
        console.log("error " + error);
      });
  }

这是我组件中的所有相关代码:

    export class DrawComponent implements OnInit {
  @Input() chatId: string;
  @Input() typeOfImg: string;
  @Input() userId: string;

  @Output() passEntry: EventEmitter<any> = new EventEmitter();

 @ViewChild('my_canvas', {static: false}) my_canvas: ElementRef;

  images: Observable<MyImage[]>;
  private imageCollection: AngularFirestoreCollection<MyImage>;

  private f_canvas:any;
  private read_json: any;
  drawing: any;

  constructor(
     public popoverCtrl: PopoverController,
    public cs: ChatService,
    public us: UploadService,
    private modalController: ModalController,
    private database: AngularFirestore,
    public events: Events,

  ) {
    this.availableColours = ["#dd0000", "#000000", "#00dd00", "#ffdd00"];
    //Set collection where our documents/ images info will save
    this.imageCollection = database.collection("images");  
  }

  ngOnInit() {
    this.f_canvas = new fabric.Canvas('my_canvas', {selection: true});
    this.f_canvas.setHeight(window.innerHeight);
    this.f_canvas.setWidth(window.innerWidth);
    this.f_canvas.selection = true;
    this.currentColour = '#000000';
    this.f_canvas.freeDrawingBrush.width = 3; // size of the drawing brush
    this.tool_selected = "selection_tool";
    this.background_visible = false;
    this.load_background();
    let that = this;
    this.f_canvas.on("mouse:down", function(o) {
      that.mousedown(o);
    });
    this.f_canvas.on("mouse:move", function(e) {
      that.mousemove(e);
    });
    this.f_canvas.on("mouse:up", function(e) {
      that.mouseup(e);
    });
    console.log("chatid en draw", this.chatId);
    this.drawing = this.imageCollection.doc(this.chatId).valueChanges();
  }
  ionViewDidLoad() {
    this. writeCanvas();
  }
  ngAfterViewInit(){

  }
  //save canvas in firestore
  loadOnCanvas(){
    var json = JSON.stringify(this.f_canvas);
    console.log("chat id sent to store canvas");
    this.us.addCanvastoDB(json, this.chatId);
    this. writeCanvas();
   }
//draw the canvas with the data from firestore  
   writeCanvas(){
    let that = this;
    console.log("writing canvas");
      this.drawing.pipe(tap(data=>{
        console.log(data);
        if(data[0]['canvas']){
          that.read_json = data[0]['canvas'];
          if(that.read_json){
            this.f_canvas.clear();
            console.log("data loaded", that.read_json);
          that.f_canvas.loadFromJSON(that.read_json, that.f_canvas.renderAll.bind(that.f_canvas));
          }
        }
      }));
   }

任何想法都将不胜感激。在此先多谢!!

javascript angular canvas google-cloud-firestore fabricjs
1个回答
0
投票

我不知道为什么,但是当我改变了从数据库中读取数据的方式时,我可以正常工作。我不是使用tap,而是使用take(1)。新的块是这样的:

this.drawing.pipe(take(1)).subscribe(data=>{
  //OLD WAY: this.drawing.pipe(tap(data=>{

    if(data.canvas){
      that.read_json = data.canvas;
      if(that.read_json){
        this.f_canvas.clear();
      that.f_canvas.loadFromJSON(that.read_json, that.f_canvas.renderAll.bind(that.f_canvas));
      }
    }
  });

非常感谢您的帮助!

© www.soinside.com 2019 - 2024. All rights reserved.