Add last year's projects to the jam page

This commit is contained in:
Ben Visness 2022-08-02 14:56:47 -05:00
parent 6982503393
commit e84754eda0
10 changed files with 273 additions and 134 deletions

71
public/js/carousel.js Normal file
View File

@ -0,0 +1,71 @@
function initCarousel(container, durationMS = 0) {
const numCarouselItems = container.querySelectorAll('.carousel-item').length;
const buttonContainer = container.querySelector('.carousel-buttons');
let current = 0;
function activateCarousel(i) {
const items = document.querySelectorAll('.carousel-item');
for (const item of items) {
item.classList.remove('active');
}
items[i].classList.add('active');
const smallItems = document.querySelectorAll('.carousel-item-small');
if (smallItems.length > 0) {
for (const item of smallItems) {
item.classList.remove('active');
}
smallItems[i].classList.add('active');
}
const buttons = document.querySelectorAll('.carousel-button');
for (const button of buttons) {
button.classList.remove('active');
}
buttons[i].classList.add('active');
current = i;
}
function activateNext() {
activateCarousel((current + numCarouselItems + 1) % numCarouselItems);
}
function activatePrev() {
activateCarousel((current + numCarouselItems - 1) % numCarouselItems);
}
const carouselTimer = durationMS > 0 && setInterval(() => {
if (numCarouselItems === 0) {
return;
}
activateNext();
}, durationMS);
function carouselButtonClick(i) {
activateCarousel(i);
if (carouselTimer) {
clearInterval(carouselTimer);
}
}
for (let i = 0; i < numCarouselItems; i++) {
const button = document.createElement('div');
button.classList.add('carousel-button', 'br-pill', 'w1', 'h1', 'mh2');
button.classList.toggle('active', i === 0);
const clickIndex = i;
button.addEventListener('click', () => {
carouselButtonClick(clickIndex);
});
buttonContainer.appendChild(button);
}
activateCarousel(0);
return {
next: activateNext,
prev: activatePrev,
};
}

View File

@ -8512,7 +8512,6 @@ input[type=submit] {
.avatar-icon {
width: 40px;
height: 40px;
object-fit: cover;
flex-shrink: 0;
border-radius: 100%;
overflow: hidden;
@ -9135,6 +9134,33 @@ span.icon-rss::before {
padding: 0px;
min-height: 0em; }
.project-carousel .carousel-item {
position: absolute;
top: 0;
left: 0; }
.project-carousel .carousel-item br {
line-height: 0.6em; }
.project-carousel .carousel-item-small {
position: absolute;
top: 0;
left: 0; }
.project-carousel .carousel-item-small:not(.active) {
display: none; }
.project-carousel .carousel-description {
max-height: 14rem;
overflow: hidden; }
.project-carousel .carousel-fade {
position: absolute;
left: 0;
right: 0;
bottom: 0;
height: 30px;
background: linear-gradient( rgba(240, 240, 240, 0) , #f0f0f0 );
background: linear-gradient( var(--dim-background-transparent) , var(--dim-background) ); }
.project .pair {
display: flex;
align-items: flex-start; }
@ -9365,37 +9391,14 @@ span.icon-rss::before {
max-height: calc(100vh - 2rem); } }
.carousel-container .carousel {
box-sizing: content-box;
position: relative; }
.carousel-container .carousel-item {
position: absolute;
top: 0;
left: 0; }
.carousel-container .carousel-item:not(.active) {
display: none; }
.carousel-container .carousel-item br {
line-height: 0.6em; }
.carousel-container .carousel-item:not(.active) {
display: none; }
.carousel-container .carousel-description {
max-height: 14rem;
overflow: hidden; }
.carousel-container .carousel-fade {
position: absolute;
left: 0;
right: 0;
bottom: 0;
height: 30px;
background: linear-gradient( rgba(240, 240, 240, 0) , #f0f0f0 );
background: linear-gradient( var(--dim-background-transparent) , var(--dim-background) ); }
.carousel-container .carousel-item-small {
position: absolute;
top: 0;
left: 0; }
.carousel-container .carousel-item-small:not(.active) {
display: none; }
.carousel-container .carousel-buttons {
display: flex;
justify-content: center; }
.carousel-container .carousel-button {
border: 1px solid;

Binary file not shown.

After

Width:  |  Height:  |  Size: 217 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 472 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 159 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 MiB

View File

@ -1,51 +1,15 @@
.carousel-container {
.carousel {
box-sizing: content-box;
position: relative;
// height: 12rem;
@media #{$breakpoint-large} {
// height: $height-5;
}
}
.carousel-item {
position: absolute;
top: 0;
left: 0;
&:not(.active) {
display: none;
}
br {
line-height: 0.6em;
}
.carousel-item:not(.active) {
display: none;
}
.carousel-description {
max-height: 14rem;
overflow: hidden;
}
.carousel-fade {
position: absolute;
left: 0;
right: 0;
bottom: 0;
height: 30px;
@include usevar(background, "linear-gradient(" dim-background-transparent "," dim-background ")")
}
.carousel-item-small {
position: absolute;
top: 0;
left: 0;
&:not(.active) {
display: none;
}
.carousel-buttons {
display: flex;
justify-content: center;
}
.carousel-button {

View File

@ -1,3 +1,40 @@
.project-carousel {
.carousel-item {
position: absolute;
top: 0;
left: 0;
br {
line-height: 0.6em;
}
}
.carousel-item-small {
position: absolute;
top: 0;
left: 0;
&:not(.active) {
display: none;
}
}
.carousel-description {
max-height: 14rem;
overflow: hidden;
}
.carousel-fade {
position: absolute;
left: 0;
right: 0;
bottom: 0;
height: 30px;
@include usevar(background, "linear-gradient(" dim-background-transparent "," dim-background ")")
}
}
.project {
.pair {
display: flex;

View File

@ -1,9 +1,13 @@
{{ template "base.html" . }}
{{ define "extrahead" }}
<script src="{{ static "js/carousel.js" }}"></script>
{{ end }}
{{ define "content" }}
<div>
{{ with .CarouselProjects }}
<div class="carousel-container mw-100 mv2 mv3-ns margin-center dn db-ns">
<div class="carousel-container project-carousel mw-100 mv2 mv3-ns margin-center dn db-ns">
<div class="carousel pa3 h5 overflow-hidden bg--dim br2-ns">
{{ range $index, $project := . }}
<div class="carousel-item flex pa3 w-100 h-100 bg--dim items-center {{ if eq $index 0 }}active{{ end }}">
@ -24,14 +28,7 @@
</div>
{{ end }}
</div>
<div class="flex justify-center pv2">
{{ range $index, $project := . }}
<div
class="carousel-button br-pill w1 h1 mh2 {{ if eq $index 0 }}active{{ end }}"
onclick="carouselButtonClick({{ $index }})"
></div>
{{ end }}
</div>
<div class="carousel-buttons pv2"></div>
</div>
{{ end }}
<div class="flex flex-column flex-row-l mv3 items-start">
@ -74,38 +71,6 @@
</div>
<script>
const numCarouselItems = {{ len .CarouselProjects }};
function activateCarousel(i) {
const items = document.querySelectorAll('.carousel-item');
items.forEach(item => item.classList.remove('active'));
items[i].classList.add('active');
const smallItems = document.querySelectorAll('.carousel-item-small');
if (smallItems.length > 0) {
smallItems.forEach(item => item.classList.remove('active'));
smallItems[i].classList.add('active');
}
const buttons = document.querySelectorAll('.carousel-button');
buttons.forEach(button => button.classList.remove('active'));
buttons[i].classList.add('active');
}
let carouselTimerCurrent = 0;
const carouselTimer = setInterval(() => {
if (numCarouselItems === 0) {
return;
}
const next = (carouselTimerCurrent + 1) % numCarouselItems;
activateCarousel(next);
carouselTimerCurrent = next;
}, 10000);
function carouselButtonClick(i) {
activateCarousel(i);
clearInterval(carouselTimer);
}
initCarousel(document.querySelector('.project-carousel'), 10000);
</script>
{{ end }}

View File

@ -183,6 +183,30 @@
text-transform: uppercase;
}
.carousel-thinger {
position: absolute;
top: 0;
width: 6rem;
height: 100%;
background-color: rgba(255, 255, 255, 0.1); /* bg-white-10 */
border-radius: 0.5rem; /* br3 */
cursor: pointer;
}
.carousel-thinger.prev {
left: -7rem;
border-top-left-radius: 0;
border-bottom-left-radius: 0;
background: linear-gradient(to left, rgba(255, 255, 255, 0.1), transparent);
}
.carousel-thinger.next {
right: -7rem;
border-top-right-radius: 0;
border-bottom-right-radius: 0;
background: linear-gradient(to right, rgba(255, 255, 255, 0.1), transparent);
}
@media screen and (min-width: 30em) {
/* not small styles */
@ -226,6 +250,8 @@
}
}
</style>
<script src="{{ static "js/carousel.js" }}"></script>
</head>
<body>
@ -266,7 +292,64 @@
</p>
</div>
<div class="bg-black-20 pt4 pb3 pb4-ns">
<div class="section bg-black-20 pv4">
<div class="mw8 margin-center ph3 ph4-l">
<h2>Last year's entries</h2>
<p>
We had many incredible entries last year. Here are a few of our favorites:
</p>
<div class="carousel-container">
<div class="carousel bg-white-10 br3 pa3 pa4-ns">
<div class="carousel-item active">
<img class="br2" src="{{ static "wheeljam2022/scroll.png" }}">
<h3>Scroll</h3>
<p>
Scroll is an experimental new typesetting format and editor. The document structure is inherently non-textual; in fact, even words within paragraphs are individual nodes that can easily be selected and moved as a whole. It's a great proof-of-concept of what "word processors" could be—and it even has a PDF export.
</p>
<a class="b db" href="https://handmade.network/forums/jam/t/8116-jam_submition_-_scroll%252C_a_experiment_in_a_non_text_typesetting_file_format">Full Submission ➜</a>
<a class="b db" href="https://youtu.be/1RjU5XJqysc?t=1083" target="_blank">Recap Interview ➜</a>
</div>
<div class="carousel-item">
<img class="br2" src="{{ static "wheeljam2022/nearmanager.gif" }}">
<h3>Near</h3>
<p>
Near (or Near Manager) is an experimental file viewer that breaks away from a plain hierarchy. By allowing you to flatten folder hierarchies, create custom groups, and reorder your files, Near allows you to tame any complex file structure and view it in a way that works for you.
</p>
<a class="b db" href="https://handmade.network/forums/jam/t/8120-jam_submission_-_near%252C_a_file_explorer_with_interesting_ideas">Full Submission ➜</a>
<a class="b db" href="https://youtu.be/1RjU5XJqysc?t=435" target="_blank">Recap Interview ➜</a>
</div>
<div class="carousel-item">
<img class="br2" src="{{ static "wheeljam2022/visaviz.png" }}">
<h3>Twitter Thread Graph Explorer</h3>
<p>
This project extended an existing personal project with a unique way of exploring Twitter threads. When the author found existing layout algorithms insufficient, he decided to roll his own. The project submission is an insightful look at why you sometimes need to do things yourself.
</p>
<p>
This project was featured as a demo at Handmade Seattle 2021.
</p>
<a class="b db" href="https://handmade.network/forums/jam/t/8137-jam_submission_-_twitter_thread_graph_explorer">Full Submission ➜</a>
<a class="b db" href="https://youtu.be/1RjU5XJqysc?t=7519" target="_blank">Recap Interview ➜</a>
<a class="b db" href="https://media.handmade-seattle.com/visa-viz/" target="_blank">Handmade Seattle Demo ➜</a>
</div>
<div class="carousel-item">
<img class="br2" src="{{ static "wheeljam2022/databaseexplorer.png" }}">
<h3>Database Explorer</h3>
<p>
This project explores a new way of querying SQL databases, by throwing away SQL in favor of a visual node graph. It allows you to incrementally build queries, seeing the data at every point along the way, and to reuse smaller queries in a way SQL cannot.
</p>
<a class="b db" href="https://handmade.network/forums/jam/t/8127-jam_submission__database_explorer">Full Submission ➜</a>
<a class="b db" href="https://youtu.be/1RjU5XJqysc?t=6390" target="_blank">Recap Interview ➜</a>
</div>
<div class="carousel-thinger next"></div>
<div class="carousel-thinger prev"></div>
</div>
<div class="carousel-buttons mt2 pv2"></div>
</div>
</div>
</div>
<div class="pt4 pb3 pb4-ns">
<div class="section mw8 margin-center ph3 ph4-l">
<h2>Details / Rules</h2>
<p>
@ -308,31 +391,34 @@
<li>If at all possible, please provide a way for people to either build or download your program.</li>
</ul>
</li>
<li>There are no explicit winners, but we will be selecting a few of our favorite projects to highlight in a recap stream following the jam.</li>
</ul>
</div>
</div>
<div class="flex-ns flex-row-ns mw8 margin-center ph3 ph4-l mv4">
<div class="section flex-fair mb4 mb0-ns">
<h2>Make it by hand.</h2>
<p>
The Handmade ethos and Handmade community are software development superpowers. Don't be afraid to question your foundations and rebuild what needs rebuilding. The community is here to help you take on those challenges and do what others might consider impossible.
</p>
<p>
Of course, this is a jam, so focus on what matters to your project. There are many excellent libraries in the community that can save you time and help you focus on your core ideas. Don't be afraid to use them. But don't be afraid to do your own thing if they're holding you back.
</p>
</div>
<div class="section flex-fair ml4-m ml5-l">
<h2>Don't just rebuild. Reinvent.</h2>
<p>
This is a chance to build something <em>truly new</em>. Learn from previous work, but don't settle for “the same, but better”. It would be a huge shame to spend a week building nothing more than a clone of the same broken software we use today.
</p>
<p>
This is where working with a team can really help. Bounce ideas off each other, do some research, and brainstorm before the jam starts. The software you end up building might be pretty different from your original ideas.
</p>
<p>
In the end, this is a jam. Get weird and try something different.
</p>
<div class="bg-black-20 pt4 pb3 pb4-ns">
<div class="flex-ns flex-row-ns mw8 margin-center ph3 ph4-l">
<div class="section flex-fair mb4 mb0-ns">
<h2>Make it by hand.</h2>
<p>
The Handmade ethos and Handmade community are software development superpowers. Don't be afraid to question your foundations and rebuild what needs rebuilding. The community is here to help you take on those challenges and do what others might consider impossible.
</p>
<p>
Of course, this is a jam, so focus on what matters to your project. There are many excellent libraries in the community that can save you time and help you focus on your core ideas. Don't be afraid to use them. But don't be afraid to do your own thing if they're holding you back.
</p>
</div>
<div class="section flex-fair ml4-m ml5-l">
<h2>Don't just rebuild. Reinvent.</h2>
<p>
This is a chance to build something <em>truly new</em>. Learn from previous work, but don't settle for “the same, but better”. It would be a huge shame to spend a week building nothing more than a clone of the same broken software we use today.
</p>
<p>
This is where working with a team can really help. Bounce ideas off each other, do some research, and brainstorm before the jam starts. The software you end up building might be pretty different from your original ideas.
</p>
<p>
In the end, this is a jam. Get weird and try something different.
</p>
</div>
</div>
</div>
@ -340,6 +426,19 @@
{{ template "footer.html" . }}
</div>
</div>
<script>
const { next, prev } = initCarousel(document.querySelector('.carousel-container'));
document.querySelector('.carousel-thinger.next')
.addEventListener('click', () => {
next();
});
document.querySelector('.carousel-thinger.prev')
.addEventListener('click', () => {
prev();
});
</script>
</body>
</html>