Infinite loop when overriding graphHandlerMouseUp on MxGraph using Angular - javascript

I have a difficult question to explain and I'm way out of my comfort zone as far as expertise in Javascript, TrueType, Angular and MxGraph are concerned... Hope to be able to explain.
I have an Angular component displaying and MxGraph. I was able to integrate MxGraph with Angular following this link (How to integrate mxGraph with Angular 4?). Even if I use Angular 7, the solution still works...
The graph is displayed correctly on the page and everything works fine, including my override of the function graphHandlerMouseUp, which I do with this code:
// Save the position of the mouse when releasing the button: used for
// detecting the target in a drag and drop
mx.graphHandlerMouseUp = mx.mxGraphHandler.prototype.mouseUp;
mx.mxGraphHandler.prototype.mouseUp = function( graph, evt ) {
currentdropX = evt.graphX;
currentdropY = evt.graphY;
mx.graphHandlerMouseUp.apply(this, arguments);
}
When I run this page for the first time, no problem happens.
Then through a button I call a page with another component (through routing). If from this page I go back to the first component (again through a routerlink) the page and the component with the MxGraph loads correctly, BUT when I use this function (i.e., release the mouse button).
It seems to me a recoursive problem, as when I put a console output like this:
// Save the position of the mouse when releasing the button: used for
// detecting the target in a drag and drop
mx.graphHandlerMouseUp = mx.mxGraphHandler.prototype.mouseUp;
mx.mxGraphHandler.prototype.mouseUp = function( graph, evt ) {
currentdropX = evt.graphX;
currentdropY = evt.graphY;
// INIFINTE LOOP HERE
console.log("Test");
mx.graphHandlerMouseUp.apply(this, arguments);
}
The "Test" is written a number of times which is continuously growing. Yet, if I understood, this was the correct way of overriding the function. Of course on the first load of the page, "Test" is displayed once. Passing to another component and then back on this it is displayed an "infinite" number of times (until I reach the: "ERROR RangeError: Maximum call stack size exceeded")...
I tried also to remove that override, and besides the obvious lack of the functionality, the very same problem happened to the function "mxDragSource", which is overridden with the same approach.
As I said: I'm not expert enough in javascript, truetype, MxGraph or Angular, so any hint, even if obvious, is very welcome!
Thanks!

The first time you run your code, you store mx library's mouseUp event in a variable and you assign a new function to mouseUp event in which you call the old mouseUpEvent.
The second time you run your code, you store your current mouseUp event (that you have modified) and you assign a function in which you call the old mouseUpEvent, which is the same you stored previously. There goes your recursion !
What you need to do is override the third-party function properly, so you don't execute your code twice.
How to do it ?
You can create a mixin and use this mixin in your componentB/ If you have no idea what is it and how to do it, please reproduce your problem in a stackblitz I'll be glad to help you to implement it.

Related

framer-motion - dom node does not unmounts immediately after exit animation

I have created an animated modal container
it's working fine for the most part
the only issue is after doing the exit animation it takes a second or two to unmount (in that period cannot click anywhere else)
code sandbox - https://codesandbox.io/s/restless-platform-oovo1?file=/src/App.js
To see the issue 👇🏻
click show modal button
Click anywhere to close the modal
notice that the scrollbar still exist denoting modal is not unmounted
Also, you cannot reopen modal immediately on clicking of the open modal button after exit animation (for that 1 sec)
I had seen safeToremove but didn't understand how to use it as there is no proper documentation
I agree that the documentation is a little frustrating where this is concerned - here's what I've learned through playing around with it.
The documentation shows the code for usePresence() within the presence component to be:
import { usePresence } from "framer-motion"
export const Component = () => {
const [isPresent, safeToRemove] = usePresence()
useEffect(() => {
!isPresent && setTimeout(safeToRemove, 1000)
}, [isPresent])
return <div />
}
This initially seemed arbitrary/purely an example. However, after playing around with it, it turns out that if you initialize usePresence(), this useEffect code is now necessary for the presence to work correctly and in part determining the functionality of the presence. Try initializing usePresence and then commenting out the line
// !isPresent && setTimeout(safeToRemove, 1000)
It will break your animate presence.
So the setTimeout function wrapping safeToRemove is, in fact, determining core functionality of the AnimatePresence and able to determine the timing of the virtual DOM becoming clickable again, etc.
Now, I was playing around with the crossfade AnimateSharedLayout, so it was a little weird to be messing with the safeToRemove timing when I wasn't determining the animations themselves, but if you are setting up the animations for the modal yourself, I think that if you sync the time in that setTimeout function with the length of your animations, it should solve your problem.
I'm still trying to figure out exactly how all this works, so comment back and let me know what you find and we'll be one step closer to mastering using Framer v2's newest tools.

Cesuim handle timebar click

How to handle Cesuim timebar click?
It would be very comfortable to get clicked time in callback.
Im nearly sure that it is implemented, so im looking for something like this.
function handleClick(event) {
console.log(event.CLICKED_DATETIME);
}
viewer.timebar.ON_TIMEBAR_CLICK = handleClick;
Thanks.
Yes, that's pretty simple. Here's what Viewer does currently:
viewer.timeline.addEventListener('settime', onTimelineScrubfunction, false);
But, some caveats:
This event will fire quite rapidly if the user "scrubs" (drags the current time bar across the timeline). Be prepared for a lot of events at once, like mousemove or touch/pointer move. Don't try to animate the globe during the event, just set some variable to take effect on the next animation frame like Viewer does.
This API is technically "private", which just means it is subject to change in any release without Cesium's normal deprecation policy. Even so, it's the only way to get this event, so go ahead and use it, just be careful to retest it particularly after reading about any timeline changes in the release notes (this is uncommon, as the timeline has been static for a long time now, but someday a full replacement could happen).
not too elegant but also an option
viewer.timeline.container.onmouseup = (e) => {
console.log(viewer.clock.currentTime);
}

How to find out what JavaScript function triggered HTML change?

I am having a problem on a WordPress site. I have a function which slides down a certain <div>. It is:
jQuery(function($){
$(document).on('click','.tb_usertask_title',function(){
var title = $(this);
var key = title.data('key');
var msg = $('#tb_msg_'+key);
msg.slideDown('fast');
}
});
After executing this function, the <div> slides up again immediately. I think this might be due another script, but I have absolutely no idea how to find which function does this. Is there any way of finding this out? Things I have tried:
Adding breakpoints in my function. This showed me that the folding up happened outside my function.
Using Firebug to break on HTML change. This however redirected to jquery.js, but I did not know how to find out which function triggered the jQuery.
Using Firebug to list the events of my onclick event, but this only showed my function.
These didn't work for me. I also searched for a way to do a function backtrace in Firebug, but without any success.
Use unminified version of jQuery (just for the test and because its more easy to debug).
Look for the dispatch function.
Put a breakpoint in the function where there is an apply usage.
After the code breaks use the F11 to navigate to the binding function.

In Metaio Creator - How would I prevent fullscreenVideo from auto playing?

I'm posting here because the Metaio forums are awful and nobody responds so I figured it can't hurt to try here. Metaio Creator is an augmented reality software program.
I don't want the fullscreen Video to go auto play but wait until I touch a 3D object to trigger that fullscreen function.
Half an answer I found said to export the Creator project and edit the logic.js file by removing "fullscreenVideo1.display();" from the trackable's "onDetected" function.
I'm wondering how to import that edited logic.js file back into my project.
Or better yet, how I could edit the custom arel script from within Metaio Creator's UI.
Here is a link to the half answer:
http://helpdesk.metaio.com/questions/19749/how-to-stop-auto-loading-of-fullscreen-video
Here is what the editable arel script looks like for all fullscreen Videos by default.
// Will be executed when the viewer for this object has been closed.
fullscreenVideo3.onClosed = function () {
};
// Will be executed when this object has been loaded.
// Corresponds to arel.Events.Object.ONREADY event.
fullscreenVideo3.onLoaded = function () {
};
fullscreenVideo3.onDisplayed = function () {
};
You can edit arel code from Creator, just right click on the object and edit the arel file or in the menu "extras" > "open arel editor"
Basically, you can change the video to be played using either Metaio Creator or changing the script as you said. If you change it using Metaio Creator, it will do all the work for you, so no changes need to be done.
In the object properties, in the behaviour tab there is an option to enable/disable playing the video on detection.
When the play box is checked, something like the next piece of code is added to the logic.js script by Metaio Creator.
pattern2.onDetected = function () {
arel.Debug.log(this.objectName + ".onDetected()");
fullscreenVideo2.display();
};
If it’s not checked, the code shown above is not added to the AREL package, so it won’t be played on detection.

Impromptu - prompt will not close

I am trying Impromptu in my javascript and for some reason it will load fine, all the functionality I apply within works but calling a close or using the 'x' in the upper right will not close the prompt. The opacity of the overlay lightens slightly but the prompt is model and I can continue to interact with it but not the underlying page.
I have gone back to basics and I am using this function;
$Kurve.prototype.tooltip = function(){
$.prompt('Hello World',{ opacity: 0.1 });
}
It is being called a part of a JQPlot chart;
$l_jqPlotArg.highlighter.tooltipContentEditor = $.jqplot.eventListenerHooks.push(['jqplotClick', this.tooltip]);
Any help appreciated and if you need more info I will do my best to supply it...also, if you have a better suggestion on an overlaying prompt (with good appearance) that can handle a JSON please don't hesitate to tell me!
I have asked th
Thanks
C
Ok, I figured this out...the click listener was fine but I had to move the handler to a var inside the chart function. All is well :)

Categories

Resources