From e7df21e91aa9afa4a26b79e8f8a9a9f22e792234 Mon Sep 17 00:00:00 2001 From: InsanusMokrassar Date: Wed, 28 Oct 2020 13:57:24 +0600 Subject: [PATCH] common js visibility and on screen extensions --- CHANGELOG.md | 5 ++ .../micro_utils/common/HtmlElementOnScreen.kt | 43 +++++++++++++++++ .../dev/inmo/micro_utils/common/Visibility.kt | 48 +++++++++++++++++++ 3 files changed, 96 insertions(+) create mode 100644 common/src/jsMain/kotlin/dev/inmo/micro_utils/common/HtmlElementOnScreen.kt create mode 100644 common/src/jsMain/kotlin/dev/inmo/micro_utils/common/Visibility.kt diff --git a/CHANGELOG.md b/CHANGELOG.md index cb038e88fdc..365c09a5908 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,11 @@ ## 0.2.3 +* `Common` + * `K/JS` + * Add several extensions for `Element` objects to detect that object is on screen viewport + * Add several extensions for `Element` objects to detect object visibility + ## 0.2.2 * `Repos` diff --git a/common/src/jsMain/kotlin/dev/inmo/micro_utils/common/HtmlElementOnScreen.kt b/common/src/jsMain/kotlin/dev/inmo/micro_utils/common/HtmlElementOnScreen.kt new file mode 100644 index 00000000000..93a27d3812f --- /dev/null +++ b/common/src/jsMain/kotlin/dev/inmo/micro_utils/common/HtmlElementOnScreen.kt @@ -0,0 +1,43 @@ +package dev.inmo.micro_utils.common + +import kotlinx.browser.window +import org.w3c.dom.DOMRect +import org.w3c.dom.Element + +val DOMRect.isOnScreenByLeftEdge: Boolean + get() = left >= 0 && left <= window.innerWidth +inline val Element.isOnScreenByLeftEdge + get() = getBoundingClientRect().isOnScreenByLeftEdge + +val DOMRect.isOnScreenByRightEdge: Boolean + get() = right >= 0 && right <= window.innerWidth +inline val Element.isOnScreenByRightEdge + get() = getBoundingClientRect().isOnScreenByRightEdge + +internal val DOMRect.isOnScreenHorizontally: Boolean + get() = isOnScreenByLeftEdge || isOnScreenByRightEdge + + +val DOMRect.isOnScreenByTopEdge: Boolean + get() = top >= 0 && top <= window.innerHeight +inline val Element.isOnScreenByTopEdge + get() = getBoundingClientRect().isOnScreenByTopEdge + +val DOMRect.isOnScreenByBottomEdge: Boolean + get() = bottom >= 0 && bottom <= window.innerHeight +inline val Element.isOnScreenByBottomEdge + get() = getBoundingClientRect().isOnScreenByBottomEdge + +internal val DOMRect.isOnScreenVertically: Boolean + get() = isOnScreenByLeftEdge || isOnScreenByRightEdge + + +val DOMRect.isOnScreenFully: Boolean + get() = isOnScreenByLeftEdge && isOnScreenByTopEdge && isOnScreenByRightEdge && isOnScreenByBottomEdge +val Element.isOnScreenFully: Boolean + get() = getBoundingClientRect().isOnScreenFully + +val DOMRect.isOnScreen: Boolean + get() = isOnScreenFully || (isOnScreenHorizontally && isOnScreenVertically) +inline val Element.isOnScreen: Boolean + get() = getBoundingClientRect().isOnScreen diff --git a/common/src/jsMain/kotlin/dev/inmo/micro_utils/common/Visibility.kt b/common/src/jsMain/kotlin/dev/inmo/micro_utils/common/Visibility.kt new file mode 100644 index 00000000000..d81fef3f27d --- /dev/null +++ b/common/src/jsMain/kotlin/dev/inmo/micro_utils/common/Visibility.kt @@ -0,0 +1,48 @@ +package dev.inmo.micro_utils.common + +import kotlinx.browser.window +import org.w3c.dom.Element +import org.w3c.dom.css.CSSStyleDeclaration + +sealed class Visibility +object Visible : Visibility() +object Invisible : Visibility() +object Gone : Visibility() + +var CSSStyleDeclaration.visibilityState: Visibility + get() = when { + display == "none" -> Gone + visibility == "hidden" -> Invisible + else -> Visible + } + set(value) { + when (value) { + Visible -> { + if (display == "none") { + display = "initial" + } + visibility = "visible" + } + Invisible -> { + if (display == "none") { + display = "initial" + } + visibility = "hidden" + } + Gone -> { + display = "none" + } + } + } +inline var Element.visibilityState: Visibility + get() = window.getComputedStyle(this).visibilityState + set(value) { + window.getComputedStyle(this).visibilityState = value + } + +inline val Element.isVisible: Boolean + get() = visibilityState == Visible +inline val Element.isInvisible: Boolean + get() = visibilityState == Invisible +inline val Element.isGone: Boolean + get() = visibilityState == Gone