From 81d41a90779f0c6cd4a26ca3ca27e7fb8dcbcf6f Mon Sep 17 00:00:00 2001 From: Eduard Urbach Date: Wed, 18 Apr 2018 20:11:20 +0200 Subject: [PATCH] Tooltips respect left and right content borders --- pages/profile/watching.scarlet | 6 ++ scripts/AnimeNotifier.ts | 35 ++++++++++++ scripts/AudioPlayer.ts | 5 ++ styles/mixins/anime-grid.scarlet | 1 + styles/tip.scarlet | 98 +++++++++++++++++++++----------- 5 files changed, 112 insertions(+), 33 deletions(-) diff --git a/pages/profile/watching.scarlet b/pages/profile/watching.scarlet index 82b2bcd3..232fdcb2 100644 --- a/pages/profile/watching.scarlet +++ b/pages/profile/watching.scarlet @@ -2,6 +2,12 @@ horizontal-wrap justify-content center + // CSS grid variant: + // display grid + // grid-gap 0.5rem + // grid-template-columns repeat(auto-fill, 55px) + // justify-content center + .profile-watching-list-item anime-mini-item diff --git a/scripts/AnimeNotifier.ts b/scripts/AnimeNotifier.ts index 66c10fe5..d12ff1d3 100644 --- a/scripts/AnimeNotifier.ts +++ b/scripts/AnimeNotifier.ts @@ -158,6 +158,7 @@ export default class AnimeNotifier { Promise.resolve().then(() => this.assignActions()), Promise.resolve().then(() => this.updatePushUI()), Promise.resolve().then(() => this.dragAndDrop()), + Promise.resolve().then(() => this.assignTooltipOffsets()), Promise.resolve().then(() => this.colorStripes()), Promise.resolve().then(() => this.countUp()) ]) @@ -236,6 +237,40 @@ export default class AnimeNotifier { } } + assignTooltipOffsets() { + let contentRect = this.app.content.getBoundingClientRect() + + for(let element of findAll("tip")) { + Diff.mutations.queue(() => { + let rect = element.getBoundingClientRect() + let tipStyle = window.getComputedStyle(element, ":before") + let tipWidth = parseInt(tipStyle.width) + parseInt(tipStyle.paddingLeft) * 2 + let tipStartX = rect.left + rect.width / 2 - tipWidth / 2 - contentRect.left + let tipEndX = tipStartX + tipWidth + let leftOffset = 0 + + if(tipStartX < 0) { + leftOffset = -tipStartX + 5 + } else if(tipEndX > contentRect.width) { + leftOffset = -(tipEndX - contentRect.width + 5) + } + + if(leftOffset !== 0) { + element.classList.remove("tip") + element.classList.add("tip-offset-root") + + let tipChild = document.createElement("div") + tipChild.classList.add("tip-offset-child") + tipChild.setAttribute("aria-label", element.getAttribute("aria-label")) + tipChild.style.left = leftOffset + "px" + tipChild.style.width = rect.width + "px" + tipChild.style.height = rect.height + "px" + element.appendChild(tipChild) + } + }) + } + } + dragAndDrop() { for(let element of findAll("inventory-slot")) { // Skip elements that have their event listeners attached already diff --git a/scripts/AudioPlayer.ts b/scripts/AudioPlayer.ts index a654454b..618a805a 100644 --- a/scripts/AudioPlayer.ts +++ b/scripts/AudioPlayer.ts @@ -41,6 +41,11 @@ export default class AudioPlayer { // Play audio file play(trackId: string, trackUrl: string) { + if(typeof AudioContext === "undefined") { + alert("Your browser doesn't support web audio!") + return + } + if(!this.audioContext) { this.audioContext = new AudioContext() this.gainNode = this.audioContext.createGain() diff --git a/styles/mixins/anime-grid.scarlet b/styles/mixins/anime-grid.scarlet index ced3df5b..28f7cfa3 100644 --- a/styles/mixins/anime-grid.scarlet +++ b/styles/mixins/anime-grid.scarlet @@ -1,5 +1,6 @@ mixin anime-mini-item margin 0.25rem + flex-basis anime-image-small-width mixin anime-generic-item-image object-fit cover diff --git a/styles/tip.scarlet b/styles/tip.scarlet index 41e653c6..ad593843 100644 --- a/styles/tip.scarlet +++ b/styles/tip.scarlet @@ -2,44 +2,56 @@ const tip-opacity = 0.94 const tip-transform-hidden = rotate(0.02deg) translateX(-50%) translateY(-80%) const tip-transform-visible = rotate(0.02deg) translateX(-50%) translateY(-100%) +mixin tip-before + content attr(aria-label) + position absolute + top -10px + left 50% + z-index 100000 + pointer-events none + opacity 0 + transform tip-transform-hidden + font-size 0.92rem + color text-color + text-shadow none + padding 0.2rem 0.7rem + background ui-background + border 1px solid ui-border-color + border-radius ui-element-border-radius + box-shadow shadow-light + white-space nowrap + default-transition + +mixin tip-after + content "" + position absolute + top -4px + left 50% + z-index 100001 + pointer-events none + opacity 0 + width 0 + height 0 + border-style solid + border-width 8px 8px 0 8px + border-color ui-background transparent transparent transparent + transform tip-transform-hidden + default-transition + +.tip-offset-child + position absolute !important + left 0 + top 0 + pointer-events none + .tip position relative :before - content attr(aria-label) - position absolute - top -10px - left 50% - z-index 100000 - pointer-events none - opacity 0 - transform tip-transform-hidden - font-size 0.92rem - color text-color - text-shadow none - padding 0.2rem 0.7rem - background ui-background - border 1px solid ui-border-color - border-radius ui-element-border-radius - box-shadow shadow-light - white-space nowrap - default-transition + tip-before :after - content "" - position absolute - top -4px - left 50% - z-index 100001 - pointer-events none - opacity 0 - width 0 - height 0 - border-style solid - border-width 8px 8px 0 8px - border-color ui-background transparent transparent transparent - transform tip-transform-hidden - default-transition + tip-after :hover :before @@ -48,4 +60,24 @@ const tip-transform-visible = rotate(0.02deg) translateX(-50%) translateY(-100%) :after opacity tip-opacity - transform tip-transform-visible \ No newline at end of file + transform tip-transform-visible + +.tip-offset-root + position relative + + :after + tip-after + + .tip-offset-child + :before + tip-before + + :hover + :after + opacity tip-opacity + transform tip-transform-visible + + .tip-offset-child + :before + opacity tip-opacity + transform tip-transform-visible \ No newline at end of file