Skip to content

Instantly share code, notes, and snippets.

@andfanilo
Created July 23, 2022 15:32
Show Gist options
  • Save andfanilo/8d749a602925b80fef32aa45547b3943 to your computer and use it in GitHub Desktop.
Save andfanilo/8d749a602925b80fef32aa45547b3943 to your computer and use it in GitHub Desktop.
Intersection Observer API + CSS Transition
import base64
import streamlit as st
import streamlit.components.v1 as components
import plotly.express as px
df = px.data.iris()
@st.experimental_memo
def get_img_as_base64(file):
with open(file, "rb") as f:
data = f.read()
return base64.b64encode(data).decode()
img = get_img_as_base64("image.jpg")
page_bg_img = f"""
<style>
.main h2 {{
opacity: 0;
}}
[data-testid="stSidebar"] > div:first-child {{
background-image: url("data:image/png;base64,{img}");
background-position: center;
background-repeat: no-repeat;
background-attachment: fixed;
}}
@keyframes animateHeader {{
from {{
transform: translateY(-100px);
opacity: 0;
}}
to {{
transform: translateY(0);
opacity: 1;
}}
}}
@keyframes animateMarkdown {{
from {{
transform: translateX(-50px);
opacity: 0;
}}
to {{
transform: translateX(0);
opacity: 1;
}}
}}
@keyframes animateImage {{
from {{
transform: translateY(10px);
opacity: 0;
}}
to {{
transform: translateY(0);
opacity: 1;
}}
}}
</style>
"""
st.markdown(page_bg_img, unsafe_allow_html=True)
st.title("Hello Animations")
st.sidebar.header("Configuration")
with st.container():
st.header("A chart")
st.markdown(
"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."
)
st.plotly_chart(px.scatter(df, x="sepal_width", y="sepal_length", color="species"))
with st.container():
st.header("An image")
st.markdown(
"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."
)
st.image("https://images.unsplash.com/photo-1658494787698-cc4371e62441", width=400)
with st.container():
st.header("Another image")
st.markdown(
"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."
)
st.image("https://images.unsplash.com/photo-1588345921523-c2dcdb7f1dcd", width=200)
with st.container():
st.header("Maths")
st.markdown(
"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."
)
st.latex(
r"""
a + ar + a r^2 + a r^3 + \cdots + a r^{n-1} =
\sum_{k=0}^{n-1} ar^k =
a \left(\frac{1-r^{n}}{1-r}\right)
"""
)
components.html(
"""<script>
const streamlitDoc = window.parent.document;
let options = {
rootMargin: '0px',
threshold: 1.0
};
function handleIntersect(entries, observer) {
entries.forEach(entry => {
if (entry.target.tagName == 'H2') {
handleIntersectHeader(entry);
} else if (entry.target.tagName == 'IMG') {
handleIntersectImage(entry);
} else if (entry.target.tagName == 'P') {
handleIntersectMarkdown(entry);
}
});
}
function handleIntersectHeader(entry) {
if (entry.intersectionRatio > 0.9) {
entry.target.style.animation = `animateHeader 0.5s forwards ease-out`
} else {
entry.target.style.animation = 'none';
entry.target.style.opacity = 0;
}
}
function handleIntersectMarkdown(entry) {
if (entry.intersectionRatio > 0.9) {
entry.target.style.animation = `animateMarkdown 1s forwards ease-out`
} else {
entry.target.style.animation = 'none';
entry.target.style.opacity = 0;
}
}
function handleIntersectImage(entry) {
if (entry.intersectionRatio > 0.9) {
entry.target.style.animation = `animateImage 5s forwards ease-out`
} else {
entry.target.style.animation = 'none';
entry.target.style.opacity = 0;
}
}
let observer = new IntersectionObserver(handleIntersect, options);
let targetHeaders = Array.from(streamlitDoc.querySelectorAll('.main h2'));
let targetMarkdown = Array.from(streamlitDoc.querySelectorAll('.main .stMarkdown p'));
let targetImages = Array.from(streamlitDoc.querySelectorAll('.main img'));
let targetElements = [].concat.apply([], [targetHeaders, targetMarkdown, targetImages])
targetElements.forEach((targetElement) => {
observer.observe(targetElement);
});
</script>""",
height=0,
)
@andfanilo
Copy link
Author

test

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment