Open marlitas opened 3 weeks ago
Here is a patch where I have some debugging code to indicate when cubes reach an "out of order" state. This patch also changes how cubes are initially placed to match the "free drag" aesthetic and remove cube separator reliance on "snap to positions"
Assigning myself to look at the above patch. @marlitas and I will pair on this tomorrow.
We met with @catherinecarter and decided the following things:
A few other notes from this morning's meeting:
Property<number[]>
, whose IOType is ArrayIO( NumberIO )
. Since the array length is so small, it should be fine to replace the entire array. I committed what I believe to be a step in the right direction. There are still some questions that pop up that I think would be good to discuss with @catherinecarter and @pixelzoom. Not sure if you want to use design meeting time for that.
You should be able to take a peek on main. There is some overlap stuff that I need to create a more sophisticated algorithm for, but I think it helps give an idea of what things may look like.
I also haven't added the vertical separator yet. I wanted to focus mostly on behavior.
It looks really good and in the right direction. I'll add it to the agenda for folks to get a glimpse of the behavior, as well as bring up the possible occlusion to brainstorm solutions. Thanks for spending time on that.
I agree -- this seems like the right direction.
I'm also surprised at how much I like the simple rounded rectangles for "beads". This says "abacus" to me loud and clear.
@pixelzoom is going to take a look at the behavior of the beads. Here are some of the strange behaviors and bugs I am noticing. I am able to achieve these scenarios by quickly moving a large group of beads back and forth. I can replicate with any number of beads on the wire, but it is easiest to achieve with 20.
On the Twenty Screen:
?dev
moving beads quickly across can lead to beads going out of order. There is currently no code that would logically allow this to happen. The only place is in the Sum Screen where beads can be added/removed in the same scene.Below are some images of the buggy scenarios.
If you look closely you can see that 17 and 2 are covering up other beads:
The beads should not overlap the wire end caps:
When reading BeadsOnWireNode.ts, I found myself getting confused about which things were model elements and which things were view elements, because "bead" was being used for both. So in https://github.com/phetsims/number-pairs/commit/4107b0a49dbe17b48ff3face6801354b1b4bdcc1, I renamed things so that "bead" is used for model elements, "beadNode" is used for view elements -- that is, the typical PhET naming convention. There were no logic changes. I also replace "cube" with "bead" throughout.
@marlitas ... a few more cleanup commits above to improve readability. Let me know if you have questions, or would prefer that I don't make these kinds of changes.
@marlitas I was able to spend ~2.5 hours on this today while traveling. See above commits.
Some things that I discovered, we'll probably need to discuss these.
Beads are getting out of order when dragging quickly because the logic in handleBeadMove
does not consider that the dragged bead may "jump over" the x-position of other beads. This entire method seems a little dubious to me, difficult (for me anyway) to understand, and we might consider a different implementation. Hard for me to explain what I had in mind in a comment but... As we drag, note the direction of dragging. Then examine the other beads to the left (lower index) or right (higher index) of the dragged bead, compare adjacent beads need have their x-position changed, and which beads need to move to left/right addends.
Right addend beads were also getting out of order (order was being reversed) when using the "group of 5" button. There seem to be assumptions about the ordering of CountingObjects in leftAddendCountingObjectsProperty
and rightAddendCountingObjectsProperty
that are not being verified (or documented?) That’s causing objects to be out of order, and organizeInGroupsOfFive
to be out of order. I addressed this in https://github.com/phetsims/number-pairs/commit/aff67540bdeb7918ce08265c8c125f79722eaddb, but see the TODOs in NumberPairsModel.
Re drag bounds problems... You shouldn’t have to deal with drag bounds constraints in handleBeadMove
. dragBoundsProperty
for each BeadNode's drag listener can be derived from model.totalProperty
, the bead’s CountingObject.id, and the wire length. You’ll need to decide whether to use also add a transform
option value for the drag listener.
Dragging doesn’t know about offset of the pointer from the bead’s position. So if you grab a bead someplace other than the center, it immediately snaps to the pointer’s location. This may be OK, but it’s not what we typically do in PhET sims. See applyOffset
options for DragListener.
When drag ends (onDragEnd
), need to check if the dragged bead overlaps the separator. If it does, then snap the dragged bead to a new position. Based on which direction it snaps in, also move adjacent beads.
Grabbing a bead and moving it to the left sometime results in adjacent beads moving slightly to the right. I don’t see something similar when moving a bead to the right.
The current use of modelViewTransform is confusing, because it doesn’t involve the wire length.
Bead x-positions are not being restored when switching scenes (totals). I'm guesing you just haven't implemented that yet.
Supporting multitouch (allowing multiple beads to be dragged at the same time) would be horribly complicated and not necessary. I addressed that in https://github.com/phetsims/number-pairs/commit/4bbe0993c7174823d886cbe3169225d7877d7136 - when you grab a bead, and bead that you've interacting with will be interrupted.
Computation of initialBeadXPositions is duplicated in NumberPairsScene and SumModel. See TODO in NumberPairsScene.
Hard for me to explain what I had in mind in a comment
Yes what you proceeded to explain feels like what I am already doing in handleBeadMove
... I think a convo to get on the same page would be helpful. I am also going to look through it and try to improve documentation since I think I did a poor job with that in this function. Perhaps that will help as we converse about it moving forward as well.
There seem to be assumptions about the ordering of CountingObjects in leftAddendCountingObjectsProperty and rightAddendCountingObjectsProperty that are not being verified (or documented?)
I don't know if out of order is inherently a thing to avoid. I think it will be difficult to avoid in the Sum screen no matter what since beads are being added and removed. It was just an easy way for me to quickly identify that something was not behaving as I would have expected while dragging, because nothing in handleBeadMove
should change the order.
So... I don't know if it's actually necessary to have an assertion, unless we truly do feel this is a critical standard to ensure that the sim is working properly...
dragBoundsProperty for each BeadNode's drag listener can be derived from model.totalProperty, the bead’s CountingObject.id, and the wire length.
Mmmm that's interesting. I'm not sure if the ID will be enough to ensure we are considering all beads that are in the way of the moving bead's direction... Especially if we can't rely on the bead order (re: Sum screen issue I mentioned above). However, if we refactor to be confident that the bead order is maintained in all use cases this would be good.
When drag ends (onDragEnd), need to check if the dragged bead overlaps the separator. If it does, then snap the dragged bead to a new position. Based on which direction it snaps in, also move adjacent beads.
I have this happening at the end of handleBeadMove
so that it is updating overlapping beads as they are jumping over the separator as well... I'm not sure if handling that only when a drag ends is enough. I think it needs to be handled during drag as well.
The current use of modelViewTransform is confusing, because it doesn’t involve the wire length.
yes that's an oversight on my part and good recommendation. I'll apply a fix for that.
Bead x-positions are not being restored when switching scenes (totals). I'm guesing you just haven't implemented that yet.
Correct, I have not.
Supporting multitouch would be horribly complicated and not necessary. I addressed that
I completely agree. Thanks for that code change.
Moving forward here before @pixelzoom and I can discuss more fully in person, I am going to:
handleBeadMove
The rest should be put on hold until we can discuss in more detail. That combined with other alt-input work should be enough to keep me busy.
Cubes should default to "free dragging". There will be an organize button that groups them in 5's.