Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Colors of TransformControls' Axes Not Rendering Correctly After Mouse Hover #60

Closed
TimJJTing opened this issue May 21, 2021 · 6 comments
Labels
bug Something isn't working

Comments

@TimJJTing
Copy link

  • three version: 0.128.0
  • @react-three/fiber version: 6.0.19
  • @react-three/drei version: 4.3.3
  • node version: 15.10.0
  • npm version: 7.5.3

Problem description:

Colors of TransformControls' axes become white after mouse hover.
Their original color (red, green, and blue) are gone, which differs from the example shows in the official Three.js documentation.

Before mouse hover:
Screen Shot 2021-05-21 at 11 10 02 AM

After mouse hover:
Screen Shot 2021-05-21 at 11 09 45 AM

Relevant code:

Not sure what causes this bug, but you can find it here

@joshuaellis
Copy link
Member

This is an issue in three-stdlib so i'm going to move it there.

@flixr
Copy link

flixr commented May 27, 2021

Running into the same problem...

@Amaranthos
Copy link

Amaranthos commented Jun 3, 2021

So I tried to track down the cause of this one was it's affecting a project where I'm trying to use TransformControls from pmndrs/drei. It seems like it was introduced in cc079be, but I can't quite figure out what is causing the issue exactly

@orivier3
Copy link
Contributor

orivier3 commented Jun 10, 2021

I think I have found the root cause of this issue. I have looked at the original implementation of the transform control in the threejs library and tried to replicate the visual feedback.

I netted out with something like this :
newHandles

Cause

So what seems to be wrong in the TransfromControl.js is the state management when the pointer is not hovering on a gizmo axis. The error is probably in the following code block;

//@ts-ignore
handle.material.opacity = handle.material.opacity || handle.material.opacity
//@ts-ignore
handle.material.color = handle.material.color || handle.material.color.clone()
//@ts-ignore
handle.material.color.copy(handle.material.color)
//@ts-ignore
handle.material.opacity = handle.material.opacity
if (!this.enabled) {
//@ts-ignore
handle.material.opacity *= 0.5
//@ts-ignore
handle.material.color.lerp(new Color(1, 1, 1), 0.5)
} else if (this.axis) {
if (handle.name === this.axis) {
//@ts-ignore
handle.material.opacity = 1.0
//@ts-ignore
handle.material.color.lerp(new Color(1, 1, 1), 0.5)
} else if (
this.axis.split('').some(function (a) {
return handle.name === a
})
) {
//@ts-ignore
handle.material.opacity = 1.0
//@ts-ignore
handle.material.color.lerp(new Color(1, 1, 1), 0.5)
} else {
//@ts-ignore
handle.material.opacity *= 0.25
//@ts-ignore
handle.material.color.lerp(new Color(1, 1, 1), 0.5)
}
}

Broken code

This block of code doesn't make sense to me

// highlight selected axis
//@ts-ignore
handle.material.opacity = handle.material.opacity || handle.material.opacity
//@ts-ignore
handle.material.color = handle.material.color || handle.material.color.clone()
//@ts-ignore
handle.material.color.copy(handle.material.color)
//@ts-ignore
handle.material.opacity = handle.material.opacity

I suppose that it was used to cache the axis colour in a previous revision, but as @Amaranthos mentioned cc079be commenting this block of code doesn't seem to do anything.
Maybe @joshuaellis, this could be the key to solve that problem, but I couldn't make sense of it.

Axes disappearing

At the end of the main code block

} else {
//@ts-ignore
handle.material.opacity *= 0.25
//@ts-ignore
handle.material.color.lerp(new Color(1, 1, 1), 0.5)

This called as soon as the component is enabled, for me resulting in the axes disappearing entirely before the first hover when dynamically attaching TransfromControl to an object, the *= is the culprit here.

Proposed solution : managing the end of the hover state

Looking at the pointerHover event, the axis property is set to null when the user not hovering on top transform gizmo. So we can use that to reset the opacity of the gizmo. The following code created the gif that I shared at the top.

         if (!this.enabled) {  //component is not enabled. Hide the axes
          
           handle.material.opacity = 0; 

        } else if (this.axis) { 
          if (handle.name === this.axis) { // pointer hover an axis, set opacity of this.axis to 1 
            
            handle.material.opacity = 1.0;

          } else if (this.axis.split('').some(function (a) {  //don't understand this bit
            return handle.name === a;    
          })) {                                                

            handle.material.opacity = 1.0; 

          } else {  //set all other axis to 0.25 
            
            handle.material.opacity = 0.25; 
            
          }
        }else{   //when this.axis is null set all axis to maximum opacity expect the planar ones
          handle.material.opacity = handle.name==='XY'||handle.name==='YZ'||handle.name==='XZ'? 0.5 : 1;
        }

Please, @joshuaellis let me know the best course of action. Do you want me to create a PR with the following changes?
I think it would be ideal for the @react/three-drei TransfromControl component to follow the original three js behaviour.

@joshuaellis
Copy link
Member

joshuaellis commented Jun 10, 2021

@orivier3 think that's a good idea, this is definitely a bug. So your PR is certainly more than welcome if you have an idea how to solve said issue!

@orivier3
Copy link
Contributor

newHandlesStoryboard

The solution was in the end pretty simple! See the PR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

5 participants