Open halloffame opened 11 years ago
I added a pull request for this. Let me know what you think. https://github.com/linkedin/hopscotch/pull/31
The pull request appears to only address bottom or top placed bubbles. What about left or right placed ones that show up off screen?
Hi all - thanks for the great plugin. Has there been any progress made for responsive design?
Sorry, not presently. @kate2753, I think we need to come to some sort of conclusion if this is a plugin candidate or core enhancement. Feels like this should be an update to core since all the placement logic is currently the responsibility of the core library... perhaps a broader rewrite of our placement logic to consider if a given bubble placement will end up off screen. Though, then what edge cases might we start crashing into if we start assuming alternate placements and bubble sizes for tour steps?
I can partially address this by separating steps from placement and creating multiple placement configurations. However, it's not great because the same element might be in different positions depending on viewport size (line-wrapping) so I would need to either go even more granular on widths or just deal with it looking bad.
All this really needs to do is intelligently say, "If I am placed off-screen, how far do I need to move (x/y) to be on-screen and then readjust the arrow (if no hard-coded offset, or just override) to still point correctly."
It would be ideal to sort of define placement separately and responsively:
var responsiveTour = {
id: "responsive",
steps: [
{
target: ".target",
xOffset: "center",
arrowOffset: "target",
media: {
"min-width: 480px": {
// exact same options as normal step, but cascades
},
"min-width: 768px": {
// exact same options as normal step, but cascades
}
}
}
]
Would use window.matchMedia
if available or use matchMedia poly.
By the way, target
option for arrow would have it try its best to position itself along x-axis of bubble closest to target element.
For this to work nicely, calculating positioning should always happen after calling onShow
or if possible, onBeforeShow
because I might take action that adjusts the DOM in preparation for a step (right now I do this in onShow
).
This is what I added after VERTICAL OFFSET
conditional in setPosition
.
// ADJUST FOR VIEWPORT
var wd = { width: $(window).outerWidth(), height: $(window).outerHeight() };
var right = (left + bubbleBoundingWidth),
bottom = (top + bubbleBoundingHeight);
if (right > wd.width) {
left -= (right - wd.width + 20);
if (arrowOffset !== 'center' && (step.placement === 'bottom' || step.placement === 'top')) {
arrowEl.style.left = (arrowOffset + (right - wd.width + 20)) + "px";
}
}
if (left < 0) {
left += (-left + 20);
}
if (bottom > wd.height) {
top -= (bottom - wd.height + 20);
}
I know I'm missing a couple cases (moving arrow when top changes) but this fixed my issues. I combined it with the approach I mentioned above (though simpler), like this:
var isMobile = $("header.mobile").css("display") === "block";
// step
{
target: isMobile ? "#toggle-sidebar" : "#sidebar header",
placement: isMobile ? "bottom" : "right",
title: "Foo",
content: "Bar"
}
I could have just as easily done my own matchMedia query but I use bootstrap so some things are visible/hidden depending on screen size and I'd rather just test the display state of an element.
This pretty much resolves it for me. The code I added to bubbles will simply nudge it back into the viewport. If a user wants to handle special cases, they can do it themselves like I did. A more formal way to declare responsive placement would be the next step.
Note: this doesn't make the tour "responsive" when adjusting viewport because I don't need to handle that. The only use case that would make sense for is ensuring orientation change works.
I just wanted to note that kamranayub's solution above worked perfectly for me, except I had some issues with the first line and ended up changing it to:
var wd = { width: screen.availWidth, height: screen.availHeight };
After that minor change, my tour bubbles all now stay within the viewport on mobile devices (though I haven't tested it extensively with every possible option or OS yet).
The bubbles should check to see if they are displaying off screen and if they are they should move and/or resize automatically.