Skip to content

Commit

Permalink
Merge pull request #7 from daily-demos/add-sticky-position-demo
Browse files Browse the repository at this point in the history
Add sticky positioning demo
  • Loading branch information
jessmitch42 committed Aug 15, 2023
2 parents 6cfbca1 + 48cf39c commit fe8baa0
Show file tree
Hide file tree
Showing 7 changed files with 330 additions and 0 deletions.
46 changes: 46 additions & 0 deletions samples/daily-prebuilt/sticky-positioning/README.md
@@ -0,0 +1,46 @@
# Daily Prebuilt: Sticky positioning demo

This demo shows one way to keep your Daily Prebuilt video call on screen even while a user is scrolling through a page. It uses the `display: sticky;` property in the CSS styles to keep the video at the top regardless of where the user is on the page. It also resizes the video on scroll to allow for more text to be visible.

![Video call after scrolling](./assets/scrolled.png)

This is a basic demo to show the general idea behind this feature. Use it as inspiration to improve the user experience of your own (hopefully better designed) app. :)

## Run locally

Clone the parent repo ([daily-samples-js](https://github.com/daily-demos/daily-samples-js)) and then open the `index.html` file in the browser. To open it, you can drag `index.html` from your editor to the browser or use the third command below.

```bash
git clone https://github.com/daily-demos/daily-samples-js.git
cd daily-samples-js/samples/daily-prebuilt/sticky-positioning/
open ./index.html
```

## How to use the demo

### Create a Daily room

To use this demo, you will need a public Daily room to join.

To get a Daily room URL, [create a Daily account](https://dashboard.daily.co/signup).

Once you have an account and are logged into the [Daily dashboard](https://dashboard.daily.co/), you can [create a new Daily room](https://dashboard.daily.co/rooms/create).

Copy the new room's URL. You can use this in the form on the home page.

The room URL will be in the following format:

`https://<your-daily-domain>.daily.co/<room-name>`

**Note**: Because this is a "bare-bones" demo, error handling has not been added if your Daily room is private or the URL is invalid/not formatted correctly. Keep your browser console open to see errors if you are having any issues!

### Join your Daily call

Once you have a Daily room and have the demo open in your browser of choice, enter the Daily room URL into the form.
![Home screen before joining the call](./assets/home.png)

Join the room and scroll to see how the video "sticks" to the top. This is a result of the `display: sticky;` setting in the CSS styles.

![Home screen after joining the call and before scrolling](./assets/incall.png)

![Video call after scrolling](./assets/scrolled.png)
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
171 changes: 171 additions & 0 deletions samples/daily-prebuilt/sticky-positioning/index.html
@@ -0,0 +1,171 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Daily Prebuilt - Sticky positioning example</title>
<script src="https://unpkg.com/@daily-co/daily-js"></script>
<link rel="stylesheet" href="style.css" />
<script src="index.js"></script>
</head>
<body>
<main>
<h1>Daily Prebuilt - Sticky positioning example</h1>

<h2>Enter a Daily room URL to join a Daily call</h2>
<form id="joinForm">
<label for="url"
>Room URL (e.g. https://domain.daily.co/room-name)</label
>
<input id="url" type="url" pattern="https://.*" required />
<input type="submit" value="Join room" />
</form>
<div id="dailyContainer"></div>

<h3>
Scroll to read the text below while keeping the video on the screen
</h3>
<p>
The content below is placeholder text generated by
<a href="https://jeffsum.com/">https://jeffsum.com/</a>
</p>
<hr />
<section>
<h2>Header one</h2>
<p>
This thing comes fully loaded. AM/FM radio, reclining bucket seats,
and... power windows. Forget the fat lady! You're obsessed with the
fat lady! Drive us out of here! We gotta burn the rain forest, dump
toxic waste, pollute the air, and rip up the OZONE! 'Cause maybe if we
screw up this planet enough, they won't want it anymore!
</p>
</section>
<section>
<h2>Header two</h2>
<p>
Yes, Yes, without the oops! God help us, we're in the hands of
engineers. I was part of something special. You're a very talented
young man, with your own clever thoughts and ideas. Do you need a
manager? Life finds a way. Must go faster. Life finds a way.
</p>
</section>
<section>
<h2>Header three</h2>
<p>
Yeah, but your scientists were so preoccupied with whether or not they
could, they didn't stop to think if they should. Yeah, but your
scientists were so preoccupied with whether or not they could, they
didn't stop to think if they should. God help us, we're in the hands
of engineers.
</p>
</section>
<section>
<h2>Header four</h2>
<p>
Jaguar shark! So tell me - does it really exist? Yeah, but John, if
The Pirates of the Caribbean breaks down, the pirates don’t eat the
tourists. Must go faster. They're using our own satellites against us.
And the clock is ticking. Forget the fat lady! You're obsessed with
the fat lady! Drive us out of here!
</p>
</section>
<section>
<h2>Header five</h2>
<p>
Jaguar shark! So tell me - does it really exist? What do they got in
there? King Kong? Checkmate... Eventually, you do plan to have
dinosaurs on your dinosaur tour, right? Did he just throw my cat out
of the window? I was part of something special. Hey, you know how I'm,
like, always trying to save the planet? Here's my chance.
</p>
</section>
<section>
<h2>Header six</h2>
<p>
Jaguar shark! So tell me - does it really exist? Did he just throw my
cat out of the window? Yeah, but John, if The Pirates of the Caribbean
breaks down, the pirates don’t eat the tourists. They're using our own
satellites against us. And the clock is ticking.
</p>
</section>
<section>
<h2>Header seven</h2>
<p>
Eventually, you do plan to have dinosaurs on your dinosaur tour,
right? Must go faster. Hey, you know how I'm, like, always trying to
save the planet? Here's my chance. Just my luck, no ice. We gotta burn
the rain forest, dump toxic waste, pollute the air, and rip up the
OZONE! 'Cause maybe if we screw up this planet enough, they won't want
it anymore!
</p>
</section>
<section>
<h2>Header eight</h2>
<p>
Life finds a way. Yeah, but John, if The Pirates of the Caribbean
breaks down, the pirates don’t eat the tourists. Must go faster. Just
my luck, no ice. I gave it a cold? I gave it a virus. A computer
virus. I gave it a cold? I gave it a virus. A computer virus.
</p>
</section>
<section>
<h2>Header eight</h2>
<p>
Life finds a way. Yeah, but John, if The Pirates of the Caribbean
breaks down, the pirates don’t eat the tourists. Must go faster. Just
my luck, no ice. I gave it a cold? I gave it a virus. A computer
virus. I gave it a cold? I gave it a virus. A computer virus.
</p>
</section>
<section>
<h2>Header nine</h2>
<p>
Must go faster... go, go, go, go, go! Must go faster. Remind me to
thank John for a lovely weekend. Hey, take a look at the earthlings.
Goodbye! Life finds a way. So you two dig up, dig up dinosaurs? Life
finds a way. Jaguar shark! So tell me - does it really exist?
</p>
</section>
<section>
<h2>Header ten</h2>
<p>
Jaguar shark! So tell me - does it really exist? Yeah, but John, if
The Pirates of the Caribbean breaks down, the pirates don’t eat the
tourists. Yeah, but your scientists were so preoccupied with whether
or not they could, they didn't stop to think if they should.
</p>
</section>
<section>
<h2>Header eleven</h2>
<p>
LYeah, but John, if The Pirates of the Caribbean breaks down, the
pirates don’t eat the tourists. Yeah, but your scientists were so
preoccupied with whether or not they could, they didn't stop to think
if they should. You're a very talented young man, with your own clever
thoughts and ideas. Do you need a manager?
</p>
</section>
<section>
<h2>Header twelve</h2>
<p>
God creates dinosaurs. God destroys dinosaurs. God creates Man. Man
destroys God. Man creates Dinosaurs. God creates dinosaurs. God
destroys dinosaurs. God creates Man. Man destroys God. Man creates
Dinosaurs. This thing comes fully loaded. AM/FM radio, reclining
bucket seats, and... power windows.
</p>
</section>
<section>
<h2>Header thirteen</h2>
<p>
You know what? It is beets. I've crashed into a beet truck. Remind me
to thank John for a lovely weekend. They're using our own satellites
against us. And the clock is ticking. Checkmate... Must go faster. Is
this my espresso machine? Wh-what is-h-how did you get my espresso
machine?
</p>
</section>
</main>
<footer>This is a footer.</footer>
</body>
</html>
84 changes: 84 additions & 0 deletions samples/daily-prebuilt/sticky-positioning/index.js
@@ -0,0 +1,84 @@
let callFrame = null;

document.addEventListener('DOMContentLoaded', () => {
const joinForm = document.getElementById('joinForm');
const callContainer = document.getElementById('dailyContainer');

function handleLeftMeeting() {
// Show the form and hide the call container
joinForm.style.display = 'block';
callContainer.style.display = 'none';
callFrame.destroy().then(() => {
callFrame = null;
});
}

function createAndJoinCall(e) {
e.preventDefault();
const dailyRoomUrl = e.target.url.value;
callFrame = window.DailyIframe.createFrame(callContainer);
callFrame.on('left-meeting', handleLeftMeeting);

// Hide the form and show the call container
joinForm.style.display = 'none';
callContainer.style.display = 'block';

try {
callFrame.join({
url: dailyRoomUrl,
showLeaveButton: true,
});
} catch (error) {
console.error(error);
}
}

joinForm.onsubmit = createAndJoinCall;
});

/**
* SCROLL EVENT: UPDATE VIDEO CALL ELEMENT SIZE ON SCROLL
*/

// Reusable throttle function for scroll event
function throttle(func, timeFrame) {
let lastTime = 0;
function checkTime() {
const now = new Date();
if (now - lastTime >= timeFrame) {
func();
lastTime = now;
}
}
return checkTime;
}

// Add the `scrolled` class when the window is scrolled
function handleScroll() {
const callContainer = document.getElementById('dailyContainer');
const notInCall = window.getComputedStyle(callContainer).display === 'none';
const { top } = callContainer.getBoundingClientRect(); // 0 (px) when scrolled and at the top of the screen.
const scrolled = callContainer.classList.contains('scrolled');
/*
The width+height change that occurs when the scrolled class is applied
will affect the value of "top". The threshold provides some wiggle room
to avoid toggling the class on/off if scrolling slowly.
*/
const threshold = 80; // px

// Don't apply scroll logic when the local participant isn't in the call.
if (notInCall) return;
// Don't update the class list if it's already marked correctly for its placement.
if ((scrolled && top === 0) || (!scrolled && top > 0)) return;

// Remove scrolled class if it's scrolled back up.
if (scrolled && top > threshold) {
callContainer.classList.remove('scrolled');
}
// Add scrolled class otherwise.
else {
callContainer.classList.add('scrolled');
}
}

document.addEventListener('scroll', throttle(handleScroll, 100));
29 changes: 29 additions & 0 deletions samples/daily-prebuilt/sticky-positioning/style.css
@@ -0,0 +1,29 @@
body {
font-family: Arial, Helvetica, sans-serif;
background: #eff3f5;
}

main {
max-width: 700px;
margin: 0 auto;
}

#dailyContainer {
aspect-ratio: 16/12;
position: sticky;
top: 0;
margin-left: auto;
display: none;
width: 100%;
transition-property: width;
transition-duration: 0.5s;
}

#dailyContainer.scrolled {
width: 60%;
}

form input,
form label {
display: block;
}

0 comments on commit fe8baa0

Please sign in to comment.