Vue + Fabric.js + Video

一、Vue + Fabric.js

canvas 一定要定義在 createApp 外面,否則會無法調整物件的大小或旋轉物件。
import { createApp } from "vue";
import { fabric } from 'fabric';

var canvas;

window.app = createApp({
    mounted() {
        canvas = new fabric.Canvas('canvas', {
            preserveObjectStacking: true
        });

        canvas.loadFromJSON('json from database');
    },
    methods: {
        save: function() {
            axios
                .put(route('your save route'), {
                    json: JSON.stringify(canvas)
                })
                .then(function(response) {
                    if (response.data.result) {
                        alert("儲存成功。");
                    } else {
                        alert("儲存失敗。");
                    }
                });
        }
    }
}).mount("#app");

二、Vue + Fabric.js + Video

主要邏輯是為 fabric.Image 物件加上 video_src 屬性,記錄影片的來源網址。
import { createApp } from "vue";
import { fabric } from 'fabric';

var canvas;

window.app = createApp({
    data() {
        return {
            creative: {},
            creativeFilePath: '',
            currentItemIndex: -1,
        }
    },
    mounted() {
        var obj = this;

        canvas = new fabric.Canvas('canvas', {
            preserveObjectStacking: true
        });

        canvas.loadFromJSON('json from database', function() {
            canvas.renderAll.bind(canvas);

            var objects = JSON.parse('json from database')['objects'];
            for (var i = 0; i < objects.length; i++) {
                if (objects[i].hasOwnProperty('video_src')) {
                    obj.addVideoElement(objects[i]);
                }
            }
        });

        fabric.util.requestAnimFrame(function render() {
            canvas.renderAll();
            fabric.util.requestAnimFrame(render);
        });
    },
    methods: {
        save: function() {
            axios
                .put(route('your save route'), {
                    json: JSON.stringify(canvas)
                })
                .then(function(response) {
                    if (response.data.result) {
                        alert("儲存成功。");
                    } else {
                        alert("儲存失敗。");
                    }
                });
        }
        addVideoElement(object) {
            var videoE = document.createElement('video');
            videoE.muted = true;

            var source = document.createElement('source');
            source.src = object['video_src'];
            videoE.appendChild(source);

            videoE.addEventListener("loadedmetadata", function(e) {
                videoE.width = this.videoWidth;
                videoE.height = this.videoHeight;

                var fab_video = new fabric.Image(videoE, object);
                fab_video.toObject = (function(toObject) {
                    return function() {
                        return fabric.util.object.extend(toObject.call(this), {
                            video_src: this.video_src
                        });
                    };
                })(fab_video.toObject);
                fab_video.set('video_src', object['video_src']);
                canvas.add(fab_video);
                fab_video.getElement().play();
            }, false);
        }
    }
}).mount("#app");

留言