Skip to content

Slide Potentiometer #63

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

Merged
merged 24 commits into from
May 24, 2021
Merged

Conversation

Spinkelben
Copy link
Contributor

feat: Slide potentiometer #56

Work in progress, but submitting PR early to get feedback.

feat: Slide potentiometer
@Spinkelben
Copy link
Contributor Author

Graphics is modelled after this spec sheet PTA Series - Low Profile Slide Potentiometer
and the tips are of this style
https://www.aliexpress.com/i/32845972841.html

@urish
Copy link
Collaborator

urish commented Apr 19, 2021

@urish
Copy link
Collaborator

urish commented Apr 19, 2021

Great start!

Where would the 3 pins be located?

For the tip, you could use a single rect with a gradient (I think that'd also look a bit better).

Also, I think the body could use a gradient to give it more metallic look

@Spinkelben
Copy link
Contributor Author

Spinkelben commented Apr 20, 2021

Pins: On a real slide potentiometer they are underneath. I am not sure how to deal with that. They are close to the ends, so maybe take some artistic license and add pins that stick out from the ends.

For the tip, I am not entirely sure what you mean. I was struggling a lot with the gradients. I think it is hard to make it look right.

@urish
Copy link
Collaborator

urish commented Apr 20, 2021 via email

@Spinkelben
Copy link
Contributor Author

I'm using inkscape, but I just don't think it is that easy to use. Also I am not that experienced with drawing/graphical design so I am also not sure how to apply a gradient to make it look better. Never the less I will push a new version soon.

@urish
Copy link
Collaborator

urish commented Apr 20, 2021

Yes, inkscape is not very straight forward when it comes to gradient editing.

What I usually do, I place the original photo behind (or on top / below) the shape, and then I tinker with the gradient until I get a look that resembles the original.

If you need, I can make a short video that shows how I do this

@urish
Copy link
Collaborator

urish commented Apr 23, 2021

Good to see this slowly coming to life and taking form :)

Please let me know when you feel ready for me to go over the code and share my feedback

Works as 100 % zoom, but is messed up at other scales...
@urish urish linked an issue Apr 27, 2021 that may be closed by this pull request
@urish
Copy link
Collaborator

urish commented Apr 29, 2021

Note: for adding the keyboard interaction, you can probably use a <input type="range" /> and let that take care of the focus, similar to how it's done in the standard potentiometer element. This also means that the element will be accessible for screen readers.

@Spinkelben
Copy link
Contributor Author

I think this is close enough to done to be reviewed.

Issues:

  • No highlighting on the tip, when the element is focused
  • Weird issue when switching from mouse to keyboard and back.

Steps to reproduce the switching issue:

  1. Use mouse to move the slider
  2. Use keyboard to move the slider
  3. Use mouse to move the slider
  4. Use keyboard to move the slide

When doing step 4, the slide jumps to the last position it had after doing step 2. It is like the input element and the SVG looses synchronization when using the keyboard.

@urish
Copy link
Collaborator

urish commented May 3, 2021

Thank you!

No highlighting on the tip, when the element is focused

Seems like it could be solved using some CSS, something like:

input:focus + 
svg #tip {
   /* some style to add when the element has focus */
}

Probably some kind of bluish outline will fit.

As far as the switching issue, I don't think it's a show stopper. Sounds like an edge case we can live with.

I'm going to try and integrate your WiP into wokwi.com to see if there are any issues I can spot.

@urish
Copy link
Collaborator

urish commented May 3, 2021

Alright, you can see it in action here:

https://wokwi.com/arduino/projects/297604176384360973

Feedback I gathered so far:

  1. Can you add a pinInfo array with the location of the pins? example here, and also a nice trick how to quickly check test whether the pin positions are correct
  2. I suggest changing minValue / maxValue to min/max, to stay consistent with the potentiometer, as well as the HTML input element.
  3. I suggest making step configurable too for the same reason (it's not used by Wokwi though).
  4. This one seems tough, but it seems like rotating the part makes it unusable. I saw it in this example on Wokwi. If you want to discuss it and brainstorm a solution together, I'd love to. ping me here on on discord.

@matititam
Copy link
Contributor

Updating UX feedback

the cursor seems to fail to follow the mouse if the speed of the mouse is faster than the slide speed. Slide won't follow if the mouse pointer is outside the slider area
arduino simulator wokwi29

@Spinkelben
Copy link
Contributor Author

Thanks for the feedback!

  • I have added a pinmap attribute now, plus some highlight when the element is focused.
  • I have also improved mouse handling slightly. Slide still wont follow the mouse if it leaves the element completely. I am not sure how to deal with that, is it common practice to attach listener to the window such that the element will continue to receive mouse move events after the cursor leaves the element?

For the pins, how does the signal property work? In a real slide potentiometer the top left pin and the right pin is connected to each end of the resistor. The lower left pin is connected to the gang (tip).

For handling rotation I can imagine several approaches.

  1. Rotate coordinates back to initial position (only in code), then do calculations
  2. Vector math. A vector representing one end of the potentiometer. The direction of the vectors is perpendicular to the direction of the slide. Use some distance from a point to the line vector math to get the position of the tip.

@urish
Copy link
Collaborator

urish commented May 4, 2021

Thanks!

For the pins, how does the signal property work? In a real slide potentiometer the top left pin and the right pin is connected to each end of the resistor. The lower left pin is connected to the gang (tip).

You can set the lower left pin (the one that is connected to the tip) to analog(0), and then one of the other pins to { type: 'power', signal: 'GND' } and the other one to { type: 'power', signal: 'VCC' }.

This is a bit arbitrary, but the simulator uses the singals property of pinInfo to give you hints where to connect the wires.

That's what I did with the standard potentiometer. Also called the pins VCC, SIG and GND:

  readonly pinInfo: ElementPin[] = [
    { name: 'GND', x: 29, y: 68.5, number: 1, signals: [{ type: 'power', signal: 'GND' }] },
    { name: 'SIG', x: 37, y: 68.5, number: 2, signals: [analog(0)] },
    { name: 'VCC', x: 44.75, y: 68.5, number: 3, signals: [{ type: 'power', signal: 'VCC' }] },
  ];

I figured out that while in the general sense GND and VCC are not the correct names (names like END1/END2 or FIXED1/FIXED2 are probably more accurate), these names will make more sense for beginners, and they are very common in tutorial (if you google for "potentiometer pinout" you'll see many images calling these pins GND/Ground and VCC/5V).

Thoughts?

I am not sure how to deal with that, is it common practice to attach listener to the window such that the element will continue to receive mouse move events after the cursor leaves the element?

It sounds like one possible solution. How about the "drag" event for the tip? Would that work?

For handling rotation I can imagine several approaches.

Perhaps you can take advantage of the SVG transform matrix to do that for you?
Here's a pointer that may help: https://stackoverflow.com/a/48346417/830623

@Spinkelben
Copy link
Contributor Author

Spinkelben commented May 5, 2021

For the pin modes, I don't mind calling them vcc and ground if that is easier for beginners to comprehend. I will add that soon.

It sounds like one possible solution. How about the "drag" event for the tip? Would that work?

I tried that. Adding draggable="true" to the tip, didn't result in any drag events happening. I think it only applies to html elements. I tried wrapping the whole thing in a div and make that draggable as well. The events did trigger, but then you are moving the whole element. I couldn't figure out how to disable that and still get the events. There's a bunch of libraries for making svg elements draggable, I might take a look at them for inspiration.

Perhaps you can take advantage of the SVG transform matrix to do that for you?
I'll take a look :)

@urish
Copy link
Collaborator

urish commented May 5, 2021

For the pin modes, I don't mind calling them vcc and ground if that is easier for beginners to comprehend. I will add that soon.

Thanks!

I tried that. Adding draggable="true" to the tip, didn't result in any drag events happening. I think it only applies to html elements. I tried wrapping the whole thing in a div and make that draggable as well. The events did trigger, but then you are moving the whole element. I couldn't figure out how to disable that and still get the events. There's a bunch of libraries for making svg elements draggable, I might take a look at them for inspiration.

That makes sense. So I guess adding a global listener is that way to go.

@urish
Copy link
Collaborator

urish commented May 16, 2021

Thanks Søren!

I updated the preview on wokwi.com with the new code, and now the mouse feels much smoother. I think it's perfect!

Other than the rotation issue, is there anything else left to fix?

Also, I see the the pin positions are a bit off:

image

@Spinkelben
Copy link
Contributor Author

The rotation issue is the last hurdle.

I don't know what happened to the pin positions, but it shouldn't be too hard to fix :)

@urish
Copy link
Collaborator

urish commented May 18, 2021

The rotation issue is the last hurdle.

Anything I can do to help with this?

I don't know what happened to the pin positions, but it shouldn't be too hard to fix :)

I added a new wokwi-show-pins utility that makes it easy to visualize the pins in your story, you can see more info in the contributing guide.

@Spinkelben
Copy link
Contributor Author

Spinkelben commented May 20, 2021

The rotation issue is the last hurdle.

Anything I can do to help with this?

I was playing around with it yesterday, but hit the hurdle that getClientRect returns dimensions of bounding box. I was hoping it would give me exact coordinates of corners of the element instead.

@urish
Copy link
Collaborator

urish commented May 20, 2021

I was playing around with it yesterday, but hit the hurdle that getClientRect returns dimensions of bounding box. I was hoping it would give me exact coordinates of corners of the element instead.

I see you are using getBoundingClientRect() for the left / width of #sliderCase. You can probably obtain those by querying the element directly. For SVG elements, getting the width is a bit more complex: element.width.baseVal.value.

A different approach would be to use the width value you already have in your code (width="45"), and just move it into a JavaScript constant that you can then use in both places.

Or maybe I'm just speaking nonsense?

I found the right API for the job.
I use a transformation matrix to convert a point in page space to a
point in the #caseRect space. Simple to implement and should handle all
kinds of transformations you could think of applying, except for the
zoom.
@urish urish added the enhancement New feature or request label May 23, 2021
@Spinkelben
Copy link
Contributor Author

I fixed the rotation issue. Thank you for the suggestion of using the SVGElement class. There I found the method getScreenCTM. It does the opposite of what I needed: returns a transformation matrix that converts coordinates from the element coordinate space to screen coordinate space. I needed it to do the "opposite", fortunately by inverting the matrix the result is a matrix that does the reverse operation. From there it was simple enough. So thanks for the tip :)

Copy link
Collaborator

@urish urish left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! I just tried the latest version on Wokwi, with 42° rotation, and it works like a charm! Well done!

https://wokwi.com/arduino/projects/299391106457534985

Left some comments, and we also need to fix pinInfo (should be quite easy now - basically, wrap the slide potentiometer with a <wokwi-show-pins> in one of the stories, and it should do the trick).

Also, can you please rebase on top of master to fix the merge conflicts in index.ts / react-types.ts?

@Spinkelben
Copy link
Contributor Author

Spinkelben commented May 23, 2021

I have address all your comments. Feel free to re-open if you think I didn't resolve it completely.

Also, can you please rebase on top of master to fix the merge conflicts in index.ts / react-types.ts?

I just merged the changes from master into the branch. Do you want be to do a rebase instead? I am not sure how PRs are completed with GitHub. If I were in control I would do a squash merge. That's what I am used to from Azure DevOps, but I don't know if GitHub has a similar feature.

@urish
Copy link
Collaborator

urish commented May 23, 2021

I have address all your comments. Feel free to re-open if you think I didn't resolve it completely.

Thank you! I'm at a friend's wedding, but will have a look when I get home.

Also, can you please rebase on top of master to fix the merge conflicts in index.ts / react-types.ts?

I just merged the changes from master into the branch. Do you want be to do a rebase instead? I am not sure how PRs are completed with GitHub. If I were in control I would do a squash merge. That's what I am used to from Azure DevOps, but I don't know if GitHub has a similar feature.

That's okay, I'm going to squash merge

@Spinkelben
Copy link
Contributor Author

Spinkelben commented May 23, 2021

Thank you! I'm at a friend's wedding, but will have a look when I get home.

No rush, it took a month to get this far, a few more days doesn't make a huge difference 😉. Enjoy the wedding! 🎉

@urish
Copy link
Collaborator

urish commented May 23, 2021 via email

Copy link
Collaborator

@urish urish left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Final round of changes :-)

@@ -0,0 +1,20 @@
import { html } from 'lit-html';
import { action } from '@storybook/addon-actions';
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

unused import? or did you want to attach an action to the potentiometer input event?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I never became good friends with storybook, what would be the advantage of adding the action on input event? :)

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It means that when you move the potentiometer, you'll see the events firing in the "Actions" tab:

pot-actions.mp4

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see. Still not 100 % what you get from that, but it is quick to wire up, so I have done it.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you!

It's just a quick way to test that the component emits the events correctly. There's an issue where it doesn't show the detail value of the events, otherwise this would also show users the information contained in events.

@urish urish merged commit 83ed853 into wokwi:master May 24, 2021
@urish
Copy link
Collaborator

urish commented May 24, 2021

Alright, I released this as wokwi-element 0.37.0, and it's now also available on Wokwi:

https://wokwi.com/arduino/projects/297604176384360973

and docs: https://docs.wokwi.com/parts/wokwi-slide-potentiometer

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Add a Slide Potentiometer
3 participants