Vue: как создать методы, которые изменяют вещи, созданные в mount()?

avatar
Duh Huh
9 августа 2021 в 01:06
106
1
1

Я хочу создать кнопку, центрирующую холст. Нажатие кнопки должно вызвать метод rec(), который должен центрировать холст, созданный в mounted().

.

Но это не работает. Я подозреваю, что методы не могут ссылаться на вещи, созданные в mounted().

Как это исправить?

<div id="main">
    <canvas id="c" width="400" height="400"></canvas>
</div>
<button v-on:click="recenter">Recenter</button>

<script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/4.5.0/fabric.js"></script>

<script>
    const app = new Vue(
        {
            el: '#main',
            methods: {
                recenter: function rec() {
                    var fabric_canvas = new fabric.Canvas('c')
                    fabric_canvas.setViewportTransform([1,0,0,1,0,0]);
                }
            },
            mounted() {
                var fabric_canvas = new fabric.Canvas('c');
                var group = [];
                var myurl = "https://upload.wikimedia.org/wikipedia/commons/a/a0/Svg_example1.svg";
                fabric.loadSVGFromURL(
                    myurl,
                    function(objects,options) {
                        var loadedObjects = new fabric.Group(group);
                        fabric_canvas.add(loadedObjects);
                        fabric_canvas.renderAll();
                    },
                    function(item, object) {
                        group.push(object);
                    }
                );
            }
        }
    );
</script>
Источник
Estus Flask
9 августа 2021 в 01:43
0

который должен центрировать холст, созданный в Mounted() - вы создаете новый в методе, а не центрируете существующий.

Duh Huh
9 августа 2021 в 01:48
0

да. Я не могу понять, как использовать существующий. я полный нуб в js.

Ответы (1)

avatar
Mohammad Masoudi
9 августа 2021 в 08:08
1

Вы можете использовать window для сохранения текущего созданного экземпляра класса fabric; Я создал вычисление для этого и состояние для текущего состояния класса.

Если создается экземпляр класса fabric, значение fabricHaveAnActiveInstance будет истинным.

И в вычислении я проверил, было ли это значение истинным, не создавайте еще один экземпляр и читайте их из объекта window.

А для доступа к вычисляемым внутренним методам или смонтированным вы просто используете ключевое слово this в Vue.

Кроме того, я установил объект как активный объект, потому что если ни один объект не был выбран и нажата кнопка recenter, вы получите сообщение об ошибке.

Примечание к определению вашего метода: вам не нужно писать имя для вашей функции.

Ниже я добавил рабочий пример вашего кода:

const app = new Vue(
        {
            el: '#main',
            data: function(){
                return {
                    fabricHaveAnActiveInstance: false
                }
            },
            methods: {
                recenter: function () {
                  // this.fabric_canvas.setViewportTransform([1,0,0,1,0,0]);
                    let object = this.fabric_canvas.getActiveObject()
                    let objWidth = object.getScaledWidth()
                    let objHeight = object.getScaledHeight()
                    let zoom = this.fabric_canvas.getZoom()
                    let panX = 0
                    let panY = 0
                    
                    console.log("object width is: " + object.width)
                    console.log(" object.getScaledWidth.x is: " + object.getScaledWidth())
                    

                    panX = ((this.fabric_canvas.getWidth() / zoom / 2) - (object.aCoords.tl.x) - (objWidth / 2)) * zoom
                    panY = ((this.fabric_canvas.getHeight() / zoom / 2) - (object.aCoords.tl.y) - (objHeight / 2)) * zoom
                                          
                    this.fabric_canvas.setViewportTransform([zoom, 0, 0, zoom, panX, panY])
                      
                }
            },
            mounted() {
                console.log(this.fabric_canvas)
                var fabric_canvas = this.fabric_canvas;
                var group = [];
                var myurl = "https://upload.wikimedia.org/wikipedia/commons/a/a0/Svg_example1.svg";
                fabric.loadSVGFromURL(
                    myurl,
                    function(objects,options) {
                        var loadedObjects = new fabric.Group(group);
                        fabric_canvas.add(loadedObjects);
                        fabric_canvas.renderAll();
                        fabric_canvas.setActiveObject(fabric_canvas.item(0))
                    },
                    function(item, object) {
                        group.push(object);
                    }
                );
                
            },
            computed:{
                fabric_canvas: function(){
                    if(this.fabricHaveAnActiveInstance){
                        return window.fabric_canvas
                    }else{
                        const fabric_instance = new fabric.Canvas('c'); 
                        window.fabric_canvas = fabric_instance;
                        this.fabricHaveAnActiveInstance = true;
                        return fabric_instance;
                    }
                }

            }
        }
    );
<div id="main">
    <canvas id="c" width="400" height="400"></canvas>

    <button v-on:click="recenter">Recenter</button>
</div>

<script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/4.5.0/fabric.js"></script>

Ссылка: для центрирования объекта я использовал функцию этого пера (ссылка пера)

Duh Huh
9 августа 2021 в 14:51
0

Я нашел два других способа использования холста в приложении vue: > Кажется, они напрямую создают холст в mounted() без использования compute(). По сравнению с созданием холста в compute(), создание холста в mounted() лучше? Кстати, функция центрирования объекта мне точно пригодится.