I am currently working on a Vuejs3 application with the fabricjs library added.
Now I am trying to add an external library called fabricPublisherTools in the application. But the method/function "_registerSnaps" that is being called is somehow "undefined".
The external library gives me the following working example.
<script type="module">
import {fabricAddSnapper,fabricAddSmartGuides} from 'https://cdn.jsdelivr.net/gh/mtrudw/fabricPublisherTools/dist/fabricPublisherTools.min.js';
fabricAddSnapper();
fabricAddSmartGuides();
var canvas = new fabric.Canvas('c4');
var rect = new fabric.Rect({left: 100,top:100,width:150,height:100,fill:'blue'});
var rect2 = new fabric.Rect({left: 500,top:500,width:150,height:100,fill:'green'});
var rect3 = new fabric.Rect({left: 400,top:200,width:150,height:100,fill:'yellow'});
canvas._registerSnaps(canvas._getSmartGuides.bind(canvas));
rect.doesSnap();
rect2.doesSnap();
rect3.doesSnap();
canvas.add(rect,rect2,rect3);
</script>
The way I implemented in Vuejs3 is as follows:
<script setup>
import { onMounted } from "vue"
import { fabric } from 'fabric';
import {fabricAddSmartGuides,fabricAddSnapper,fabricAddUndoRedo} from 'https://cdn.jsdelivr.net/gh/mtrudw/fabricPublisherTools/dist/fabricPublisherTools.min.js';
let canvas;
const setupEditor = () => {
fabricAddSnapper();
fabricAddSmartGuides();
canvas = new fabric.Canvas('canvas');
canvas.setHeight(500);
canvas.setWidth(500);
canvas.backgroundColor = "#f00";
canvas.setDimensions({width: 500, height: 500});
var rect = new fabric.Rect({left: 100,top:100,width:150,height:100,fill:'blue'});
var rect2 = new fabric.Rect({left: 500,top:500,width:150,height:100,fill:'green'});
var rect3 = new fabric.Rect({left: 400,top:200,width:150,height:100,fill:'yellow'});
canvas._registerSnaps(canvas._getSmartGuides.bind(canvas));
rect.doesSnap();
rect2.doesSnap();
rect3.doesSnap();
canvas.add(rect,rect2,rect3);
canvas.renderAll();
}
onMounted(() => {
setupEditor()
})
</script>
It gives me the following error when I try to run it:
Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'bind')
And its about this line:
canvas._registerSnaps(canvas._getSmartGuides.bind(canvas));
When I console log "_registerSnaps" I see it's undefined which means something has not been appended/added by the library.
I just don't know if I did something wrong when I imported the library that caused the problem.
What exactly am I doing wrong?
Thank you in advance.
If bind is what's undefined, have you checked if your problem is with _getSmartGuides since that is what calls the bind() function?
You'll need to call fabricAddSmartGuides();
purely from reading the (fabricPublisherTools) source: _getSmartGuides is created in fabricAddSmartGuides(). Do you / where do you call fabricAddSmartGuides ?
Related
I am trying to add a texture to a sphere, specifically by mapping an image to it using TextureLoader.
However, I can add the material perfectly fine, without the image that is. For example, if I removed the line "map: TextureLoader().load(earthUV)" and replaced it with "color: 0xFF0000", the sphere would load perfectly fine with no errors, but with the TextureLoader I just receive the error log found below.
Please feel free to ask questions as I do not know what else I should provide to help fix this error.
Error Log:
TypeError: Cannot set properties of undefined (setting 'manager')
at Loader (three.module.js?5a89:34164:1)
at TextureLoader (three.module.js?5a89:34947:1)
at VueComponent.mounted (about.vue?9043:39:1)
at invokeWithErrorHandling (vue.runtime.esm.js?2b0e:1863:1)
at callHook (vue.runtime.esm.js?2b0e:4235:1)
at Object.insert (vue.runtime.esm.js?2b0e:3158:1)
at invokeInsertHook (vue.runtime.esm.js?2b0e:6390:1)
at Vue.patch [as __patch__] (vue.runtime.esm.js?2b0e:6538:1)
at Vue._update (vue.runtime.esm.js?2b0e:3960:1)
at Vue.updateComponent (vue.runtime.esm.js?2b0e:4075:1)
Please find the code for my attempt below:
<template>
<div>
<canvas ref="aboutCanvas"></canvas>
</div>
</template>
<script>
import {
Scene,
PerspectiveCamera,
WebGLRenderer,
Mesh,
SphereGeometry,
MeshBasicMaterial,
TextureLoader,
} from "three";
import earthUV from "~/assets/earthUV.jpg";
export default {
mounted() {
const scene = new Scene();
const camera = new PerspectiveCamera(
75,
innerWidth / innerHeight,
0.1,
1000
);
const renderer = new WebGLRenderer({
canvas: this.$refs.aboutCanvas,
});
renderer.setSize(innerWidth, innerHeight);
document.body.appendChild(renderer.domElement);
// Create a sphere
const sphere = new Mesh(
new SphereGeometry(5, 50, 50),
new MeshBasicMaterial({
map: TextureLoader().load(earthUV)
})
);
// Add objects into scene
scene.add(sphere);
camera.position.z = 10;
function animate() {
requestAnimationFrame(animate);
renderer.render(scene, camera);
}
animate();
},
};
</script>
When creating a TextureLoader, you have to use the new keyword. You can use that single TextureLoader multiple times to load as many textures as you need.
const texLoader = new TextureLoader();
const sphere = new Mesh(
new SphereGeometry(5, 50, 50),
new MeshBasicMaterial({
map: texLoader.load(earthUV)
})
);
I'm using the Vue-FilePond library to upload user avatars, and am trying to implement a max-file-size. For testing purposes, I've set it to 1MB. When I try uploading anything larger than 1MB, I receive an error:
TypeError: Cannot read property 'data' of undefined
This happens in my addFile method where I attempt to use the method getFileENcodeDataURL(), so that I can send it along to my GraphQL server. Does anybody have any suggestions for how to fix this?
<template>
<file-pond
ref="filepondUploader"
accepted-file-types="image/jpeg, image/png"
:allow-multiple="false"
:instant-upload="false"
max-file-size="1MB"
name="avatar"
#addfile="addFile"
#removefile="removeFile" />
</template>
<script>
import vueFilePond, { setOptions } from 'vue-filepond';
import FilePondPluginFileValidateType from 'filepond-plugin-file-validate-type';
import FilePondPluginFileValidateSize from 'filepond-plugin-file-validate-size';
import FilePondPluginImagePreview from 'filepond-plugin-image-preview';
import FilePondPluginFileEncode from 'filepond-plugin-file-encode';
import 'filepond/dist/filepond.min.css';
import 'filepond-plugin-image-preview/dist/filepond-plugin-image-preview.min.css';
const FilePond = vueFilePond(
FilePondPluginFileValidateType,
FilePondPluginFileValidateSize,
FilePondPluginImagePreview,
FilePondPluginFileEncode
);
setOptions({
labelIdle: 'Drag & Drop your picture<br/>or <span class="filepond--label-action">Browse</span>',
imagePreviewHeight: 170,
imageCropAspectRatio: '1:1',
imageResizeTargetWidth: 200,
imageResizeTargetHeight: 200,
stylePanelLayout: 'compact circle',
styleLoadIndicatorPosition: 'center bottom',
styleButtonRemoveItemPosition: 'center bottom'
});
export default {
methods: {
addFile () {
const initial = this.$refs.filepondUploader.getFile(0);
const file = initial.getFileEncodeDataURL(); <--- where error occurs
this.$emit('handle-image-upload', file);
}
}
}
</script>
I found a simple fix for this issue when I was looking through the docs, specifically this part that discusses the methods. In the addFile method, I realized that it passes an event which contains the error if a file is too large. If the file is not too large, the event is null. So I simply do a check, remove the file and return before it gets to the point that it was causing me issues, like so:
addFile (e) {
if (e) {
this.error = e;
this.$refs.filepondUploader.removeFile();
return;
}
const initial = this.$refs.filepondUploader.getFile(0);
const file = initial.getFileEncodeDataURL();
this.$emit('handle-image-upload', file);
}
I am using vue 2.6.10 and I have the following dependencies vue-mapbox 0.4.1 and mapbox-gl 1.3.2
The map works, but I cannot get all the points of the map, create bounds and make the map zoom there.
What I am doing now, based on this and this
In my template
<MglMap
ref="map"
#load="mapLoaded()">
and then in my javascript
import Mapbox from "mapbox-gl";
components: { Mapbox}
methods :{
mapLoaded(){
let coords = [];
//coords is array , contains arrays like [-118.578, 51.524]
let bounds = coords.reduce((bounds, coord)=> {
return bounds.extend(coord);
}, this.mapbox.LngLatBounds(coords[0], coords[0])
);
this.$refs['map'].map.fitBounds(bounds, { padding: 20 });
}
},
created(){
this.mapbox = Mapbox;
}
This should work, but I keep getting
TypeError: this.setSouthWest is not a function
so I guess there is a problem in this.mapbox.LngLatBounds(coords[0], coords[0]) , maybe the this.mapbox. or the LngLatBounds does not work.
If I console log the coords[0], prints an array [10.467778, 37.600833]
What am I missing? Thanks
I have got the same error. Turns out I have missed "new" keyword.
You can try adding the "new" keyword for "this.mapbox.LngLatBounds"
The following code worked for me.
import mapboxgl from 'mapbox-gl';
Vue.prototype.$maps = mapboxgl
this.map = new this.$maps.Map({container: 'mapContainer', // container ID
style: 'mapbox://styles/mapbox/streets-v11', // style URL
zoom: 9 // starting zoom
});
const sourceMarker = new this.$maps.Marker().setLngLat(origin).addTo(this.map);
const destMarker = new this.$maps.Marker().setLngLat(destination).addTo(this.map);
const bounds = new this.$maps.LngLatBounds(origin, destination);
this.map.fitBounds(bounds);
I'm new on ArcGis (and also Angular, I start today developing in both), can't find an example on how to move the map to certain point, I was trying:
this.mapa.map.centerAt(new Point(-118.15, 33.80));
But I have a javascript error TocComponent.html:10 ERROR ReferenceError: Point is not defined
When I do console.log(this.mapa.map); I got this (I put this in case someone is wondering if this.mapa.map was incorrect):
EDIT: My solution, same as the answer. It not all, it's a demo of my app with Angular:
import { MapaComponent } from '../mapa/mapa.component';
// some code
export class MyComponent implements OnInit {
constructor(private arcgisService: ArcgisApiService, private mapa: MapaComponent) { }
// another code
onChangeSomething(evt: any): void {
// more code
loadModules([
'esri/geometry/Point'
]).then(([Point]) => {
const my_center = new Point([-99.94867549215655, 20.55088183550196]);
this.mapa.map.centerAndZoom(my_center, 5);
});
You may not be including the Point module in your AMD includes at the top of your file. Your list should include esri/geometry/Point like this:
require([
"esri/map",
"esri/layers/FeatureLayer",
"esri/geometry/Point",
], function(Map, FeatureLayer, Point) {
[... the rest of your code ...]
});
With the code bellow I'm trying to assign a new store to a FilteringSelect that had no store associated with it.
My issue is that I get a error when clicking the FilteringSelect witch is:
*Uncaught TypeError: Object [object Object] has no method 'query' *
console.log("alternate on movement create");
storeData = new Write({url: "/account/getall", clearOnClose: true, urlPreventCache: true});
storeData.fetch({ onComplete: function () { console.log("done");} });
console.log("after new read");
dijit.byId("far_mt_accountbundle_movementtype_toAccount").store = storeData;
I'm using dojo 1.8
Thank you for any help.
It looks like you are using an ItemFileWriteStore, which is an implementation of the deprecated dojo.data API. To use an ItemFileWriteStore with a FilteringSelect, you should wrap it in a dojo/store/DataStore
require(['dojo/store/DataStore','dojo/data/ItemFileWriteStore'],function(DataStore,Write){
var writeStore = new Write({url: "/account/getall", clearOnClose: true, urlPreventCache: true});
var dataStore = new DataStore({store: writeStore});
dijit.byId('filteringSelect').set('store',dataStore);
});