Skip to content

Instantly share code, notes, and snippets.

@andfanilo
Last active August 3, 2020 17:57
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save andfanilo/d3cdf2fade69f6a14922f8a2b84d3f05 to your computer and use it in GitHub Desktop.
Save andfanilo/d3cdf2fade69f6a14922f8a2b84d3f05 to your computer and use it in GitHub Desktop.
Streamlit version of 3D Book Image CSS Generator. Also test st.experimental_(get|set)_query_params !
import streamlit as st
import streamlit.components.v1 as components
app_state = st.experimental_get_query_params()
app_state = {k: v[0] if isinstance(v, list) else v for k, v in app_state.items()}
image_url = st.sidebar.text_input("Image URL", "https://d2sofvawe08yqg.cloudfront.net/outstanding-developer/hero2x?1595108679")
bg_color = st.sidebar.beta_color_picker("Book color", "#01060f")
app_state['rotate'] = st.sidebar.slider("Rotate (deg)", 0, 45, 30)
app_state['rotate_hover'] = st.sidebar.slider("Rotate (hover) (deg)", 0, 45, 0)
perspective = st.sidebar.slider("Perspective (px)", 300, 1300, 600)
transition_duration = st.sidebar.slider("Animation duration (s)", 0, 5, 1)
radius = st.sidebar.slider("Radius (px)", 0, 5, 2)
thickness = st.sidebar.slider("Thickness (px)", 5, 100, 50)
width = st.sidebar.slider("Width (px)", 50, 300, 200)
height = st.sidebar.slider("Height (px)", 75, 450, 300)
pages_offset = st.sidebar.slider("Pages offset (px)", 0, 10, 3)
st.experimental_set_query_params(**app_state)
st.title("3D Book Image CSS Generator")
st.markdown("Check the original implementation : https://3d-book-css.netlify.app/ or https://github.com/scastiel/3d-book-image-css-generator")
html = f"""
<!DOCTYPE html>
<html>
<head>
<style>
.book-container {{
margin: 100px;
display: flex;
align-items: center;
perspective: {perspective}px;
}}
.book {{
width: {width}px;
height: {height}px;
position: relative;
transform-style: preserve-3d;
transform: rotateY({-app_state['rotate']}deg);
transition: {transition_duration}s ease;
animation: 1s ease 0s 1 initAnimation;
}}
.book:hover {{
transform: rotateY({-app_state['rotate_hover']}deg);
}}
@keyframes initAnimation {{
0% {{
transform: rotateY({-app_state['rotate_hover']}deg);
}}
100% {{
transform: rotateY({-app_state['rotate']}deg);
}}
}}
.book > :first-child {{
position: absolute;
top: 0;
left: 0;
background-color: red;
width: {width}px;
height: {height}px;
transform: translateZ({thickness / 2}px);
background-color: {bg_color};
border-radius: 0 {radius}px {radius}px 0;
box-shadow: 5px 5px 20px #666;
}}
.book::before {{
position: absolute;
content: ' ';
background-color: blue;
left: 0;
top: {pages_offset}px;
width: {thickness - 2}px;
height: {height - 2 * pages_offset}px;
transform: translateX({width - thickness / 2 - pages_offset}px) rotateY(90deg);
background: linear-gradient(90deg,
#fff 0%,
#f9f9f9 5%,
#fff 10%,
#f9f9f9 15%,
#fff 20%,
#f9f9f9 25%,
#fff 30%,
#f9f9f9 35%,
#fff 40%,
#f9f9f9 45%,
#fff 50%,
#f9f9f9 55%,
#fff 60%,
#f9f9f9 65%,
#fff 70%,
#f9f9f9 75%,
#fff 80%,
#f9f9f9 85%,
#fff 90%,
#f9f9f9 95%,
#fff 100%
);
}}
.book::after {{
position: absolute;
top: 0;
left: 0;
content: ' ';
width: {width}px;
height: {height}px;
transform: translateZ(-{thickness / 2}px);
background-color: ${bg_color};
border-radius: 0 {radius}px {radius}px 0;
box-shadow: -10px 0 50px 10px #666;
}}
</style>
</head>
<body>
<div class="book-container">
<div class="book">
<img src="{image_url}"/>
</div>
</div>
</body>
</html>
"""
components.html(html, height=height + 200)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment