# Changing enableRotate after pointerDown

**URL:** <https://discourse.threejs.org/t/changing-enablerotate-after-pointerdown/57175>\
**Category:** Questions\
**Tags:** pointerdown, enable-rotate\
**Created:** [October 18, 2023, 10:42pm UTC](https://discourse.threejs.org/t/changing-enablerotate-after-pointerdown/57175 "2023-10-18T22:42:11Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![mhfaust](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/mhfaust/32/40895_2.png) [@mhfaust](https://discourse.threejs.org/u/mhfaust)\
**Post date:** [October 18, 2023, 10:42pm UTC](https://discourse.threejs.org/t/changing-enablerotate-after-pointerdown/57175/1 "2023-10-18T22:42:11Z")

</div>

Making a 3D rotatable cube, I want a user experience where if they “flick” a layer (quickly pointerDown then pointerUp in a direction) it spins a1/4 turn, but if they hold for more than 500ms, instead of spinning the layer, I set enableRotate to true, and if they subsequently move the cursor before letting up, the whole cube’s orientation (the scene, actually) becomes draggable.

The problem is that it seems setting enableRotate=true on the controls object after pointerDown does not result in that pointer being able to drag the scene, and the user has to life their finger up and put it back down, ruining the simple UX I’m after.

So my question is: is there a way to effect what I want, or will I have to go with a different user interaction model?

---

<div class="post-metadata">

**Author:** ![PavelBoytchev](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/pavelboytchev/32/38639_2.png) [@PavelBoytchev](https://discourse.threejs.org/u/PavelBoytchev)\
**Post date:** [October 19, 2023, 7:07pm UTC](https://discourse.threejs.org/t/changing-enablerotate-after-pointerdown/57175/2 "2023-10-19T19:07:15Z")

</div>

Would this help? The magic is done in lines 73-81 (the threshold is set to 300ms):  
[https://codepen.io/boytchev/full/ExrYyXr](https://codepen.io/boytchev/full/ExrYyXr)

A slow drag will activate rotation with `OrbitControls`.  
A flick will make the model jitter, but no rotation will happen.

---

<div class="post-metadata">

**Author:** ![mhfaust](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/mhfaust/32/40895_2.png) [@mhfaust](https://discourse.threejs.org/u/mhfaust)\
**Post date:** [October 19, 2023, 7:35pm UTC](https://discourse.threejs.org/t/changing-enablerotate-after-pointerdown/57175/3 "2023-10-19T19:35:59Z")

</div>

Well that’s pretty similar to what I tried, but I failed where you succeeded. Looks like I just need to debug. Thanks for showing me it’s possible!

---

<div class="post-metadata">

**Author:** ![mhfaust](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/mhfaust/32/40895_2.png) [@mhfaust](https://discourse.threejs.org/u/mhfaust)\
**Post date:** [October 19, 2023, 8:39pm UTC](https://discourse.threejs.org/t/changing-enablerotate-after-pointerdown/57175/4 "2023-10-19T20:39:44Z")

</div>

Just can’t figure it out. Here’s my onDownPointer handler:

```javascript
	const handlePointerDown = (e: ThreeEvent<PointerEvent>) => {
			addPointer(downPointers, e)
			controls.current!.enableRotate = false
			setTimeout(() => {controls.current!.enableRotate = true}, 500)
	}

```

(addPointer is just a stack of current pointers & has no bearing on this)

The only other difference I see is that I’m developing in React + R3-Fiber, hence the `.current` property on controls, which is a ref object.

Maybe React’s render cycle is the problem here??

---

<div class="post-metadata">

**Author:** ![manthrax](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/manthrax/32/2596_2.png) [@manthrax](https://discourse.threejs.org/u/manthrax)\
**Post date:** [October 19, 2023, 11:53pm UTC](https://discourse.threejs.org/t/changing-enablerotate-after-pointerdown/57175/5 "2023-10-19T23:53:56Z")

</div>

I don’t fully understand the question, but wanted to mention the .reset() method of OrbitControls… I’ve used it to prevent unwanted behavior when toggling the controls mid-gesture.

---

<div class="post-metadata">

**Author:** ![mhfaust](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/mhfaust/32/40895_2.png) [@mhfaust](https://discourse.threejs.org/u/mhfaust)\
**Post date:** [October 22, 2023, 9:45pm UTC](https://discourse.threejs.org/t/changing-enablerotate-after-pointerdown/57175/6 "2023-10-22T21:45:27Z")

</div>

Alright, I think there is some interference from either NextJS or (more likely) React/R3-Fiber.  
So I’ve put up a repo with my case stripped down to the bare minimum.

I’m logging enable/disable actions in the console. You can see the assignments are happening as expected, but the scene doesn’t actually become rotatable when the timeOut is called.

Try mouse-down, wait half a sec, then drag both on and outside of the cube. Once disabled by the downPointer event, the scene doesn’t become draggable again until a new down-pointer event is in play. This is unlike the experience that I get in @PavelBoytchev’s sandbox , though it’s really the exact same approach, just wrapped in all the react stuff.

Here is the url to the page src up in github:

> <https://github.com/mhfaust/fiddle/blob/66b3c554b6894d592d07fd3a9273a81af7a36cd8/src/app/page.tsx>

Here’s the running app you can poke at.

> **[Create Next App](https://fiddle-steel.vercel.app/)**
>
> Generated by create next app

@PavelBoytchev , @manthrax, @seanwasere

---

<div class="post-metadata">

**Author:** ![mhfaust](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/mhfaust/32/40895_2.png) [@mhfaust](https://discourse.threejs.org/u/mhfaust)\
**Post date:** [October 23, 2023, 2:32am UTC](https://discourse.threejs.org/t/changing-enablerotate-after-pointerdown/57175/7 "2023-10-23T02:32:29Z")

</div>

OK, I found a workaround, though I do not really understand why it works over the original attempt.

When setting enableRotate to false at the beginning of the handler, wrap it in its own setTimeout with a value of 0 for the time. That’s it:

```javascript
const handlePointerDown = (e: ThreeEvent<PointerEvent>) => {
    setTimeout(() => {
        console.log('disable')
        controls.current!.enableRotate = false
    }, 0)
    setTimeout(() => {
        console.log('enable')
        controls.current!.enableRotate = true
    }, 500)
}

```

---

<div class="post-metadata">

**Author:** ![manthrax](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/manthrax/32/2596_2.png) [@manthrax](https://discourse.threejs.org/u/manthrax)\
**Post date:** [October 24, 2023, 11:40am UTC](https://discourse.threejs.org/t/changing-enablerotate-after-pointerdown/57175/8 "2023-10-24T11:40:43Z")

</div>

Ship it! 😃
