Reputation: 139
I want to create a button that recenter the canvas. Clicking the button should call the rec()
method, which should recenter the canvas created in mounted()
.
But that doesn't work. I suspect that the methods can't really refer to things created in mounted()
.
How to fix this?
<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/[email protected]/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>
Upvotes: 1
Views: 403
Reputation: 446
You can use the window
to save the current created instance of the fabric
class; I created a computed to do this and a state for the current status of the class.
If an instance is created of the fabric
class then the value of fabricHaveAnActiveInstance
going to be true.
And in computed I checked if that value was true don't make another instance and read them from the window
object.
And for access a computed inside methods or mounted, you just use this
keyword in Vue.
Also, I set an object as an active object, because if no object was selected and click on the recenter
button you will get an error.
A note for your method definition: You don't have to write a name for your function.
In the below, I added a working example of your code:
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/[email protected]/dist/vue.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/4.5.0/fabric.js"></script>
Reference: for make center the object I used a function in this pen (pen link)
Upvotes: 1