【发布时间】:2020-07-13 04:14:17
【问题描述】:
我正在尝试在 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));
}
}
}));
}
任何想法将不胜感激。 提前非常感谢!!!
【问题讨论】:
-
画布更新是否正确推送到 Firestore?即:如果用户更改画布,更改是否序列化并从 Firestore 页面可见?如果是这种情况,错误可能出在渲染端而不是数据库端。
-
感谢您的关注。是的,画布中的 JSON 已从不同的用户正确存储和更新,但不知何故,画布既没有加载也没有在不同的用户中刷新。这意味着当第二个用户进入画布时,已经存在的画布甚至不会被加载。第二个用户可以进行绘图并且数据会更新,但不会更新任何画布。
-
“当第二个用户进入画布时,已经存在的画布甚至没有被加载”是什么意思?它是否显示一个新的空画布?可能是您没有引用同一个文档。另外,你为什么打电话给
const id = this.database.createId();?以及为什么在将画布写入 Firestore 时更新 chatId?不应该是与同一个画布交互的所有用户共享的静态Id吗? -
嗨,再次感谢您的提示!很抱歉关于
createId的那一行,因为它来自之前的测试,我在发布之前忘记删除它。 -
无论如何,按照您的提示,我意识到问题是我试图在画布上绘制之前我得到了 JSON 数据的值。你是对的,我的意思是当我打开绘图组件时,即使有从 `revious 绘图加载的数据,它也会显示一个空画布。你对我有什么暗示吗?我对 firestore 和这种使用 javascript 的异步方式很陌生...
标签: javascript angular canvas google-cloud-firestore fabricjs