diff --git a/nicegui/elements/scene.js b/nicegui/elements/scene.js index 26ddc010a..ecc4f9aed 100644 --- a/nicegui/elements/scene.js +++ b/nicegui/elements/scene.js @@ -149,7 +149,6 @@ export default { }; const handleDrag = (event) => { this.drag_constraints.split(",").forEach((constraint) => applyConstraint(constraint, event.object.position)); - if (event.type === "drag") return; this.$emit(event.type, { type: event.type, object_id: event.object.object_id, @@ -158,7 +157,8 @@ export default { y: event.object.position.y, z: event.object.position.z, }); - this.controls.enabled = event.type == "dragend"; + if (event.type === "dragstart") this.controls.enabled = false; + if (event.type === "dragend") this.controls.enabled = true; }; this.drag_controls.addEventListener("dragstart", handleDrag); this.drag_controls.addEventListener("drag", handleDrag); diff --git a/website/documentation/content/scene_documentation.py b/website/documentation/content/scene_documentation.py index 693f60aa4..36998feaa 100644 --- a/website/documentation/content/scene_documentation.py +++ b/website/documentation/content/scene_documentation.py @@ -88,6 +88,28 @@ def handle_drag(e: events.SceneDragEventArguments): on_change=lambda e: sphere.draggable(e.value)) +@doc.demo('Subscribe to the drag event', ''' + By default, a draggable object is only updated when the drag ends to avoid performance issues. + But you can explicitly subscribe to the "drag" event to get immediate updates. + In this demo we update the position and size of a box based on the positions of two draggable spheres. +''') +def immediate_updates() -> None: + from nicegui import events + + with ui.scene(drag_constraints='z=0') as scene: + box = scene.box(1, 1, 0.2).move(0, 0).material('Orange') + sphere1 = scene.sphere(0.2).move(0.5, -0.5).material('SteelBlue').draggable() + sphere2 = scene.sphere(0.2).move(-0.5, 0.5).material('SteelBlue').draggable() + + def handle_drag(e: events.GenericEventArguments) -> None: + x1 = sphere1.x if e.args['object_id'] == sphere2.id else e.args['x'] + y1 = sphere1.y if e.args['object_id'] == sphere2.id else e.args['y'] + x2 = sphere2.x if e.args['object_id'] == sphere1.id else e.args['x'] + y2 = sphere2.y if e.args['object_id'] == sphere1.id else e.args['y'] + box.move((x1 + x2) / 2, (y1 + y2) / 2).scale(x2 - x1, y2 - y1, 1) + scene.on('drag', handle_drag) + + @doc.demo('Rendering point clouds', ''' You can render point clouds using the `point_cloud` method. The `points` argument is a list of point coordinates, and the `colors` argument is a list of RGB colors (0..1).