diff --git a/public/js/carousel.js b/public/js/carousel.js new file mode 100644 index 00000000..d251cd7f --- /dev/null +++ b/public/js/carousel.js @@ -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, + }; +} diff --git a/public/style.css b/public/style.css index 07374a5a..628e8b00 100644 --- a/public/style.css +++ b/public/style.css @@ -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; diff --git a/public/wheeljam2022/databaseexplorer.png b/public/wheeljam2022/databaseexplorer.png new file mode 100644 index 00000000..2ac8f90d Binary files /dev/null and b/public/wheeljam2022/databaseexplorer.png differ diff --git a/public/wheeljam2022/nearmanager.gif b/public/wheeljam2022/nearmanager.gif new file mode 100644 index 00000000..3eaa4587 Binary files /dev/null and b/public/wheeljam2022/nearmanager.gif differ diff --git a/public/wheeljam2022/scroll.png b/public/wheeljam2022/scroll.png new file mode 100644 index 00000000..f7efa911 Binary files /dev/null and b/public/wheeljam2022/scroll.png differ diff --git a/public/wheeljam2022/visaviz.png b/public/wheeljam2022/visaviz.png new file mode 100644 index 00000000..c5866d9c Binary files /dev/null and b/public/wheeljam2022/visaviz.png differ diff --git a/src/rawdata/scss/_carousel.scss b/src/rawdata/scss/_carousel.scss index c4ee964f..2527b944 100644 --- a/src/rawdata/scss/_carousel.scss +++ b/src/rawdata/scss/_carousel.scss @@ -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 { diff --git a/src/rawdata/scss/_projects.scss b/src/rawdata/scss/_projects.scss index 046ad7a2..5c817c62 100644 --- a/src/rawdata/scss/_projects.scss +++ b/src/rawdata/scss/_projects.scss @@ -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; diff --git a/src/templates/src/project_index.html b/src/templates/src/project_index.html index 571a04c9..ea28d42c 100644 --- a/src/templates/src/project_index.html +++ b/src/templates/src/project_index.html @@ -1,9 +1,13 @@ {{ template "base.html" . }} +{{ define "extrahead" }} + +{{ end }} + {{ define "content" }}
{{ with .CarouselProjects }} - -
+
+
+

Last year's entries

+

+ We had many incredible entries last year. Here are a few of our favorites: +

+ + +
+
+ +

Details / Rules

@@ -308,31 +391,34 @@

  • If at all possible, please provide a way for people to either build or download your program.
  • +
  • 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.
  • -
    -
    -

    Make it by hand.

    -

    - 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. -

    -

    - 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. -

    -
    -
    -

    Don't just rebuild. Reinvent.

    -

    - This is a chance to build something truly new. 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. -

    -

    - 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. -

    -

    - In the end, this is a jam. Get weird and try something different. -

    +
    +
    +
    +

    Make it by hand.

    +

    + 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. +

    +

    + 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. +

    +
    +
    +

    Don't just rebuild. Reinvent.

    +

    + This is a chance to build something truly new. 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. +

    +

    + 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. +

    +

    + In the end, this is a jam. Get weird and try something different. +

    +
    @@ -340,6 +426,19 @@ {{ template "footer.html" . }}
    + +