Add last year's projects to the jam page
This commit is contained in:
parent
6982503393
commit
e84754eda0
|
@ -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,
|
||||||
|
};
|
||||||
|
}
|
|
@ -8512,7 +8512,6 @@ input[type=submit] {
|
||||||
.avatar-icon {
|
.avatar-icon {
|
||||||
width: 40px;
|
width: 40px;
|
||||||
height: 40px;
|
height: 40px;
|
||||||
object-fit: cover;
|
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
border-radius: 100%;
|
border-radius: 100%;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
@ -9135,6 +9134,33 @@ span.icon-rss::before {
|
||||||
padding: 0px;
|
padding: 0px;
|
||||||
min-height: 0em; }
|
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 {
|
.project .pair {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: flex-start; }
|
align-items: flex-start; }
|
||||||
|
@ -9365,37 +9391,14 @@ span.icon-rss::before {
|
||||||
max-height: calc(100vh - 2rem); } }
|
max-height: calc(100vh - 2rem); } }
|
||||||
|
|
||||||
.carousel-container .carousel {
|
.carousel-container .carousel {
|
||||||
box-sizing: content-box;
|
|
||||||
position: relative; }
|
position: relative; }
|
||||||
|
|
||||||
.carousel-container .carousel-item {
|
|
||||||
position: absolute;
|
|
||||||
top: 0;
|
|
||||||
left: 0; }
|
|
||||||
.carousel-container .carousel-item:not(.active) {
|
.carousel-container .carousel-item:not(.active) {
|
||||||
display: none; }
|
display: none; }
|
||||||
.carousel-container .carousel-item br {
|
|
||||||
line-height: 0.6em; }
|
|
||||||
|
|
||||||
.carousel-container .carousel-description {
|
.carousel-container .carousel-buttons {
|
||||||
max-height: 14rem;
|
display: flex;
|
||||||
overflow: hidden; }
|
justify-content: center; }
|
||||||
|
|
||||||
.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-button {
|
.carousel-container .carousel-button {
|
||||||
border: 1px solid;
|
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 |
|
@ -1,51 +1,15 @@
|
||||||
.carousel-container {
|
.carousel-container {
|
||||||
.carousel {
|
.carousel {
|
||||||
box-sizing: content-box;
|
|
||||||
position: relative;
|
position: relative;
|
||||||
// height: 12rem;
|
|
||||||
|
|
||||||
@media #{$breakpoint-large} {
|
|
||||||
// height: $height-5;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.carousel-item {
|
.carousel-item:not(.active) {
|
||||||
position: absolute;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
|
|
||||||
&:not(.active) {
|
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
br {
|
.carousel-buttons {
|
||||||
line-height: 0.6em;
|
display: flex;
|
||||||
}
|
justify-content: center;
|
||||||
}
|
|
||||||
|
|
||||||
.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-button {
|
.carousel-button {
|
||||||
|
|
|
@ -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 {
|
.project {
|
||||||
.pair {
|
.pair {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|
|
@ -1,9 +1,13 @@
|
||||||
{{ template "base.html" . }}
|
{{ template "base.html" . }}
|
||||||
|
|
||||||
|
{{ define "extrahead" }}
|
||||||
|
<script src="{{ static "js/carousel.js" }}"></script>
|
||||||
|
{{ end }}
|
||||||
|
|
||||||
{{ define "content" }}
|
{{ define "content" }}
|
||||||
<div>
|
<div>
|
||||||
{{ with .CarouselProjects }}
|
{{ 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">
|
<div class="carousel pa3 h5 overflow-hidden bg--dim br2-ns">
|
||||||
{{ range $index, $project := . }}
|
{{ range $index, $project := . }}
|
||||||
<div class="carousel-item flex pa3 w-100 h-100 bg--dim items-center {{ if eq $index 0 }}active{{ end }}">
|
<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>
|
</div>
|
||||||
{{ end }}
|
{{ end }}
|
||||||
</div>
|
</div>
|
||||||
<div class="flex justify-center pv2">
|
<div class="carousel-buttons pv2"></div>
|
||||||
{{ 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>
|
</div>
|
||||||
{{ end }}
|
{{ end }}
|
||||||
<div class="flex flex-column flex-row-l mv3 items-start">
|
<div class="flex flex-column flex-row-l mv3 items-start">
|
||||||
|
@ -74,38 +71,6 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
const numCarouselItems = {{ len .CarouselProjects }};
|
initCarousel(document.querySelector('.project-carousel'), 10000);
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
{{ end }}
|
{{ end }}
|
||||||
|
|
|
@ -183,6 +183,30 @@
|
||||||
text-transform: uppercase;
|
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) {
|
@media screen and (min-width: 30em) {
|
||||||
/* not small styles */
|
/* not small styles */
|
||||||
|
|
||||||
|
@ -226,6 +250,8 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
|
<script src="{{ static "js/carousel.js" }}"></script>
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
|
@ -266,7 +292,64 @@
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</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">
|
<div class="section mw8 margin-center ph3 ph4-l">
|
||||||
<h2>Details / Rules</h2>
|
<h2>Details / Rules</h2>
|
||||||
<p>
|
<p>
|
||||||
|
@ -308,11 +391,13 @@
|
||||||
<li>If at all possible, please provide a way for people to either build or download your program.</li>
|
<li>If at all possible, please provide a way for people to either build or download your program.</li>
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</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>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="flex-ns flex-row-ns mw8 margin-center ph3 ph4-l mv4">
|
<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">
|
<div class="section flex-fair mb4 mb0-ns">
|
||||||
<h2>Make it by hand.</h2>
|
<h2>Make it by hand.</h2>
|
||||||
<p>
|
<p>
|
||||||
|
@ -335,11 +420,25 @@
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="mw8 margin-center ph3-m ph4-l">
|
<div class="mw8 margin-center ph3-m ph4-l">
|
||||||
{{ template "footer.html" . }}
|
{{ template "footer.html" . }}
|
||||||
</div>
|
</div>
|
||||||
</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>
|
</body>
|
||||||
|
|
||||||
</html>
|
</html>
|
||||||
|
|
Loading…
Reference in New Issue