when I do raycasting trying to apply function from clicked object. without a problem I found which object clicked via raycaster. But when I try to get the function -I already gave it to the mesh- it doesn't display.
mesh.children.forEach((child: any) => {
child.name = "portal"
child.userData.clickable = true
child.userData.dblclick = function () {
window.location.href = "example"
}
})
console.log(mesh)
I can see the clickable prop, but not the dblclick prop. But If I change the value to string, then dblclick shows as a prop.
raycasting:
this.raycaster.setFromCamera(this.mouse, this.camera);
const intersects = this.raycaster.intersectObjects(this.scene.children, true);
if (intersects.length > 0) {
intersects.forEach((mesh: any) => {
if (mesh.object.userData.hasOwnProperty("clickable")) {
console.log(mesh.object.userData)
mesh.object.userData.dblclick();
}
});
}
Is it mean that intersects doesn't apply function as a value?
Related
I have create a function which scrolls a ScrollView to a set position when it is called (near top). I would like for the function to be called from the react-navigation tab bar. Calling the function is easy, but I am struggling to get it to communicate with the scrollRef from the screen component.
Here's my snack: https://snack.expo.dev/#dazzerr/scroll-to-top-function
You'll find this function in App.js which is called when the tab bar is pressed:
const onTabPress = () => {
scrollRef.current?.scrollTo({ // how do I get ref={scrollRef} from component.js ScrollView?
y: 0,
animated: true,
});
};
and in component.js is the ScrollView in question:
<ScrollView
ref={scrollRef}
style={styles.container}
scrollEventThrottle={16}
>
{ScreenContent()}
</ScrollView>
How can I get the scrollRef from component.js called from inside the onTabPress function from app.js? 🤔
You'll need to pass the function through react-navigation setParams like this:
This goes inside your createBottomTabNavigator:
tabBarOnPress: (scene, jumpToIndex) => {
scene.navigation.state.params.scrollToTop(); // Here's the magic!
},
And this inside your component:
useEffect(() => {
props.navigation.setParams({
scrollToTop: () => {
onTabPress();
},
});
}, []);
const onTabPress = () => {
scrollRef.current?.scrollTo({
y: 600, // whatever number you want here
animated: true,
});
};
Of course don't forget to add the scrollRef to your ScrollView, and make sure that your ScrollView is from react-native and not react-navigation. You might also want to add conditionals inside the tabBarOnPress such as:
if (
isFocused &&
typeof route.routes[0]?.params?.onTabBarPress !== "function"
)
But that's your doing 👍
Here's a working snack: https://snack.expo.dev/#dazzerr/ontabpress-scrollto
I started messing about with Three.js a couple of months ago.
I have basic js knowledge, most of the code was adapted from the Three.js Examples.
I want to load a model selected from a dropdown list.
There is only one model displayed at once, so I didnt want to add a new gltf loader for each model.
I have 1 gltf loader and I want to change the path based upon the option the user selects from the dropdown.
VARIABLES
let pathSelected, pathHe, pathCat, pathGears;
pathHe = ('./MODEL/he.gltf');
pathCat = ('./MODEL/cat/cat.gltf');
pathGears = ('./MODEL/gears/gears.gltf');
.....
GLTF LOADER
function init() {
...
loader = new GLTFLoader();
loader.load(pathSelected, function (gltf) {
gltf.scene.traverse(function (child) {
if (child.isMesh) {
children.push(child);
}
});
...
}
DAT.GUI PANEL
function createPanel() {
...
var objSelector = objectShow.add(settings, 'modelOptions', ["HE", "Cat", "Gear Box"]).name("Seclect").listen();
objSelector.onChange(function (value) {
var value = settings.modelOptions;
if (value == "Heat Exchanger") {
pathSelected = pathHe;
console.log('Dropdown: HE', pathSelected);
}
else if (value == "Cat") {
pathSelected = pathCat;
console.log('Dropdown: Cat', pathSelected);
}
else if (value == "Gear Box") {
pathSelected = pathGears;
console.log('Dropdown: Cat', pathSelected);
}
else { ... }
});
...
}
DEMO:
https://mellowmonks.in/demos/9/
PW: MellowMonk#123
I made a inline widget similar a placeholder (ckeditor4), but now I want to render a dropdown when the widget is selected to show options values to replace the placeholder. I trying use BalloonPanelView but no success until now, someone have a idea about how to make it?
this.editor.editing.view.document.on('click', (evt, data) => {
evt.stop();
const element = data.target;
if (element && element.hasClass('placeholder')) {
if (!element.getAttribute('data-is-fixed')) {
const balloonPanelView = new BalloonPanelView();
balloonPanelView.render();
['option1', 'option2', 'option3'].forEach((value) => {
const view = new View();
view.set({
label: value,
withText: true
});
balloonPanelView.content.add(view);
});
balloonPanelView.pin({
target: element
});
}
}
});
I found the solution using ContextualBalloon class:
import ContextualBalloon from "#ckeditor/ckeditor5-ui/src/panel/balloon/contextualballoon";
// Define ballon
const balloon = editor.plugins.get(ContextualBalloon);
const placeholderOptions = // Here I defined list with buttons '<li><button></li>'
// Finnaly render ballon
balloon.add({
view: placeholderOptions,
singleViewMode: true,
position: {
target: data.domTarget
}
});
I have to disable panning from mouse left button in d3-v4, it should pan only using mouse right button. My below code was working in d3-v3 but not in v4
this.zoomListener = d3.zoom().on("start", this.zoomstart.bind(this)).on("zoom", this.zoom.bind(this)).on("end", this.zoomend.bind(this));
const eventProxy = (fn: any) => {
return () => {
// Enable events if enableEvents=== true
if (d3.event.which === 3) {
fn.apply(this, arguments);
}
};
};
this.parentSvg.call(this.zoomListener).on("dblclick.zoom", null);
const mouseDownTarget = this.parentSvg.on("mousedown.zoom");
this.parentSvg.on("mousedown.zoom", eventProxy(mouseDownTarget));
Does anyone know how to do it in V4
I have created a ckeditor plugin that wraps the selected text into a span.
I wonder how can I unwrap the selected when I apply this plugin on a text that has been previously wrapped into the span.
CKEDITOR.plugins.add('important', {
// Register the icons. They must match command names.
//trick to get a 16*16 icon : http://www.favicomatic.com
icons: 'important',
init: function (editor) {
editor.addCommand('important', {
// Define the function that will be fired when the command is executed.
exec: function (editor) {
var selected_text = editor.getSelection().getSelectedText();
console.log(editor.getSelection()) ;
var newElement = new CKEDITOR.dom.element("span");
newElement.setAttributes({class: 'important'});
newElement.setText(selected_text);
editor.insertElement(newElement);
//how to unwrap the selected text ?
});
// Create the toolbar button that executes the above command.
editor.ui.addButton('important', {
label: 'Set this as important',
command: 'important',
toolbar: 'insert'
});
}
});
Finally, using editor.getSelection().getStartElement(), I can check if the starting element has already been wrapped with the class and remove it if necessary.
CKEDITOR.plugins.add('important', {
//trick to get a 16*16 icon : http://www.favicomatic.com
icons: 'important',
init: function (editor) {
var className = 'important';
editor.addCommand('important', {
// Define the function that will be fired when the command is executed.
exec: function (editor) {
var editorSelection = editor.getSelection();
var selected_text = editorSelection.getSelectedText();
var startElement = editorSelection.getStartElement();
//if the element has already been wrapped, let's UNwrap it
if (className === startElement.$.className) {
var html = startElement.$.innerHTML;
editor.getSelection().getStartElement().remove();
editor.insertHtml(html);
} else {
//if the element has NOT already been wrapped, let's wrap it
var newElement = new CKEDITOR.dom.element("span");
newElement.setAttributes({class: 'important'});
newElement.setText(selected_text);
editor.insertElement(newElement);
}
}
});
// Create the toolbar button that executes the above command.
editor.ui.addButton('important', {
label: 'Set this as important',
command: 'important',
toolbar: 'insert'
});
}
});