mirror of
https://github.com/kristoferssolo/kristofersxyz.git
synced 2025-10-21 18:30:34 +00:00
Added lightsaber
This commit is contained in:
parent
3df0dc5a6d
commit
5503e15593
@ -1,212 +1,378 @@
|
||||
:root {
|
||||
--blade-hue: 120;
|
||||
--blade-lightness: 50%;
|
||||
}
|
||||
|
||||
*,
|
||||
*::before,
|
||||
*::after {
|
||||
*:before,
|
||||
*:after {
|
||||
position: relative;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
body {
|
||||
background: #222;
|
||||
.body {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(6, 1fr);
|
||||
grid-template-rows: 100px 50px 1fr;
|
||||
min-height: 100vh;
|
||||
place-items: center;
|
||||
font-family: "Source Sans Pro", sans-serif;
|
||||
text-transform: uppercase;
|
||||
font-size: 1.5rem;
|
||||
height: 80vh;
|
||||
}
|
||||
|
||||
/* The color pickers */
|
||||
|
||||
[name="color"] {
|
||||
grid-row: 1 / 2;
|
||||
align-self: end;
|
||||
margin: 0.5em;
|
||||
}
|
||||
|
||||
label:not(.hilt) {
|
||||
color: white;
|
||||
font-weight: bold;
|
||||
align-self: start;
|
||||
}
|
||||
|
||||
/* Lightsaber styling */
|
||||
|
||||
.lightsaber {
|
||||
margin-top: 25vh;
|
||||
grid-column: 1 / -1;
|
||||
position: relative;
|
||||
/* outline: 1px dotted white; */
|
||||
transition: transform 0.3s ease-in-out;
|
||||
/* transform: scale(0.5); */
|
||||
width: 30vw;
|
||||
height: 5vw;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
#on-off {
|
||||
position: absolute;
|
||||
width: 0;
|
||||
height: 0;
|
||||
/* .lightsaber > * { */
|
||||
/* outline: 1px solid white; */
|
||||
/* } */
|
||||
|
||||
.metal {
|
||||
background: linear-gradient(
|
||||
to bottom,
|
||||
#ccdbee 10%,
|
||||
#607088 35%,
|
||||
#ccdbee 70%,
|
||||
#607088
|
||||
);
|
||||
}
|
||||
|
||||
.black-metal {
|
||||
background: linear-gradient(
|
||||
to bottom,
|
||||
#767a83 10%,
|
||||
#202432 35%,
|
||||
#767a83 70%,
|
||||
#202432
|
||||
);
|
||||
}
|
||||
|
||||
.copper {
|
||||
background: linear-gradient(
|
||||
to bottom,
|
||||
#70413a 10%,
|
||||
#90645a 35%,
|
||||
#70413a 70%,
|
||||
#401f21
|
||||
);
|
||||
}
|
||||
|
||||
.pommel-cap {
|
||||
height: 90%;
|
||||
width: 10%;
|
||||
border-radius: 10% 0 0 10%;
|
||||
box-shadow: 0 0 5vw black;
|
||||
}
|
||||
|
||||
.grip {
|
||||
height: 100%;
|
||||
width: 45%;
|
||||
border-radius: 5%;
|
||||
box-shadow: 0 0 5vw black;
|
||||
}
|
||||
|
||||
.hilt {
|
||||
cursor: pointer;
|
||||
display: block;
|
||||
width: 0.75rem;
|
||||
height: 7rem;
|
||||
background-color: red;
|
||||
border-radius: 0 0 4px 4px;
|
||||
background-image: linear-gradient(
|
||||
silver 0 10px,
|
||||
hsl(39 75% 50%) 0 14px,
|
||||
silver 0 15px,
|
||||
black 0 20px,
|
||||
silver 0 22px,
|
||||
black 0 25px,
|
||||
silver 0 27px,
|
||||
black 0 30px,
|
||||
silver 0 32px,
|
||||
black 0 35px,
|
||||
silver 0 37px,
|
||||
black 0 40px,
|
||||
silver 0 42px,
|
||||
black 0 45px,
|
||||
silver 0 47px,
|
||||
black 0 50px,
|
||||
silver 0 60px,
|
||||
hsl(39 75% 50%) 60px 80px,
|
||||
silver 0 100%
|
||||
);
|
||||
height: 80%;
|
||||
width: 35%;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: flex-start;
|
||||
}
|
||||
|
||||
.hilt > .segment {
|
||||
width: 8%;
|
||||
height: 100%;
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
.hilt > .segment .black-metal {
|
||||
width: 20%;
|
||||
}
|
||||
|
||||
.focusing-ring {
|
||||
height: 70%;
|
||||
width: 15%;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.focusing-ring > .segment {
|
||||
width: 40%;
|
||||
height: 100%;
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
.focusing-ring > .segment .metal {
|
||||
width: 8%;
|
||||
}
|
||||
|
||||
.blade-emitter {
|
||||
height: 100%;
|
||||
width: 10%;
|
||||
z-index: 1;
|
||||
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.blade-emitter > .segment {
|
||||
width: 40%;
|
||||
height: 100%;
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
.blade-emitter > .segment .start {
|
||||
height: 60%;
|
||||
width: 8%;
|
||||
}
|
||||
|
||||
.blade-emitter > .segment .middle {
|
||||
height: 80%;
|
||||
}
|
||||
|
||||
.blade-emitter > .segment .end {
|
||||
height: 100%;
|
||||
width: 8%;
|
||||
}
|
||||
|
||||
.blade {
|
||||
position: absolute;
|
||||
background: white;
|
||||
height: 350%;
|
||||
height: 70%;
|
||||
width: 300%;
|
||||
left: 100%;
|
||||
background: linear-gradient(
|
||||
to bottom,
|
||||
var(--lightsaber-color),
|
||||
white 25%,
|
||||
white 75%,
|
||||
var(--lightsaber-color)
|
||||
);
|
||||
border-top-right-radius: 10vw;
|
||||
border-bottom-right-radius: 10vw;
|
||||
}
|
||||
|
||||
.blade > .glow {
|
||||
border-radius: inherit;
|
||||
border: inherit;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
box-shadow: 0 0 5vw var(--lightsaber-color);
|
||||
}
|
||||
.blade > .glow .large {
|
||||
box-shadow: 0 0 30vw 10vw var(--lightsaber-color);
|
||||
opacity: 0.7;
|
||||
}
|
||||
|
||||
.controls {
|
||||
height: 25%;
|
||||
width: 50%;
|
||||
position: absolute;
|
||||
left: 45%;
|
||||
bottom: 100%;
|
||||
border-radius: 100vw 100vw 0 0;
|
||||
box-shadow: inset 0 0 4px
|
||||
hsl(var(--blade-hue) 100% var(--blade-lightness) / 1),
|
||||
0 0 1em hsl(var(--blade-hue) 100% var(--blade-lightness) / 0.8),
|
||||
0 0 1.5em hsl(var(--blade-hue) 100% var(--blade-lightness) / 0.7),
|
||||
0 0 2em hsl(var(--blade-hue) 100% var(--blade-lightness) / 0.5),
|
||||
0 0 3em hsl(var(--blade-hue) 100% var(--blade-lightness) / 0.3),
|
||||
0 0 5em hsl(var(--blade-hue) 100% var(--blade-lightness) / 0.2);
|
||||
|
||||
transition: transform 50ms ease-out;
|
||||
transform-origin: bottom;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-around;
|
||||
align-items: center;
|
||||
z-index: -1;
|
||||
}
|
||||
|
||||
.blade::after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background: hsl(var(--blade-hue) 100% var(--blade-lightness));
|
||||
border-radius: inherit;
|
||||
filter: blur(0.5em);
|
||||
opacity: 1;
|
||||
-webkit-animation: pulse linear 5s infinite;
|
||||
animation: pulse linear 5s infinite;
|
||||
}
|
||||
|
||||
.blade::before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
left: 0;
|
||||
background: white;
|
||||
border-radius: inherit;
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
@-webkit-keyframes pulse {
|
||||
50% {
|
||||
opacity: 0.5;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes pulse {
|
||||
50% {
|
||||
opacity: 0.5;
|
||||
}
|
||||
}
|
||||
|
||||
/* Turn lightsaber on and off */
|
||||
|
||||
#on-off:not(:checked) + .blade {
|
||||
transform: scaleY(0);
|
||||
}
|
||||
|
||||
#on-off:checked + .blade {
|
||||
transform: scaleY(1);
|
||||
}
|
||||
|
||||
/* change the color */
|
||||
|
||||
#green:checked ~ .lightsaber {
|
||||
--blade-hue: 120;
|
||||
}
|
||||
|
||||
#blue:checked ~ .lightsaber {
|
||||
--blade-hue: 195;
|
||||
}
|
||||
|
||||
#yellow:checked ~ .lightsaber {
|
||||
--blade-hue: 60;
|
||||
}
|
||||
|
||||
#purple:checked ~ .lightsaber {
|
||||
--blade-hue: 290;
|
||||
}
|
||||
|
||||
#red:checked ~ .lightsaber {
|
||||
--blade-hue: 360;
|
||||
}
|
||||
|
||||
#darksaber:checked ~ .lightsaber {
|
||||
--blade-lightness: 100%;
|
||||
}
|
||||
|
||||
#darksaber:checked ~ .lightsaber .blade {
|
||||
border-radius: 100% / 500px 10px 0 0;
|
||||
}
|
||||
|
||||
#darksaber:checked ~ .lightsaber .blade::before {
|
||||
.controls > .button {
|
||||
height: 0.75vw;
|
||||
width: 0.75vw;
|
||||
background: black;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
/* play sound */
|
||||
|
||||
embed {
|
||||
display: none;
|
||||
.controls:before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 20%;
|
||||
bottom: 100%;
|
||||
background: #b16521;
|
||||
}
|
||||
|
||||
.button.-up {
|
||||
background-color: #117305;
|
||||
}
|
||||
|
||||
.button.-down {
|
||||
background-color: #a8141e;
|
||||
}
|
||||
|
||||
:root {
|
||||
--ease: cubic-bezier(0.5, 0, 0.2, 1);
|
||||
--duration: 10s;
|
||||
--delay: 0s;
|
||||
--speed: 0.75;
|
||||
}
|
||||
:root * {
|
||||
animation-duration: var(--duration);
|
||||
animation-delay: var(--delay);
|
||||
animation-timing-function: var(--ease);
|
||||
animation-fill-mode: both;
|
||||
}
|
||||
|
||||
.pommel-cap {
|
||||
--delay: 0s;
|
||||
--duration: 1s, 0.5s;
|
||||
animation-name: enter-reverse, fade-in;
|
||||
}
|
||||
|
||||
.grip {
|
||||
--delay: 0.3s;
|
||||
--duration: 1s, 0.5s;
|
||||
animation-name: enter, fade-in;
|
||||
}
|
||||
|
||||
.controls {
|
||||
--delay: 1s;
|
||||
--duration: 1s, 0.5s;
|
||||
animation-name: slide-down, fade-in;
|
||||
}
|
||||
|
||||
.controls .button {
|
||||
animation-name: scale-up;
|
||||
--delay: calc(1.5s + (var(--i, 0) * 0.1s));
|
||||
--duration: 0.5s;
|
||||
}
|
||||
|
||||
.hilt .segment {
|
||||
--delay: calc(1.25s + (var(--i, 0) * 0.05s));
|
||||
--duration: 1s, 1s;
|
||||
animation-name: slide-down, fade-in;
|
||||
}
|
||||
|
||||
.hilt .segment:nth-child(even) {
|
||||
animation-name: slide-up, fade-in;
|
||||
}
|
||||
|
||||
.focusing-ring .segment {
|
||||
--delay: calc(2.25s + (var(--i, 0) * 0.05s));
|
||||
--duration: 1s, 1s;
|
||||
animation-name: enter, fade-in;
|
||||
}
|
||||
|
||||
.blade-emitter .segment {
|
||||
--delay: calc(3s + (var(--i, 0) * 0.05s));
|
||||
--duration: 1s, 1s;
|
||||
animation-name: enter, fade-in;
|
||||
}
|
||||
|
||||
.lightsaber {
|
||||
animation-name: lightsaber, lightsaber-out;
|
||||
animation-fill-mode: backwards, forwards;
|
||||
--ease: cubic-bezier(0.5, 0, 0.2, 1), cubic-bezier(0.82, -0.38, 0.14, 1.35);
|
||||
--delay: 0s, 10s;
|
||||
--duration: 10s, 1s;
|
||||
}
|
||||
|
||||
.blade {
|
||||
--delay: 4.5s;
|
||||
--duration: 1s, 1s;
|
||||
transform-origin: left center;
|
||||
animation-name: blade, fade-in;
|
||||
}
|
||||
|
||||
.blade .glow {
|
||||
--delay: 4.5s;
|
||||
--duration: 3s;
|
||||
--ease: linear;
|
||||
animation-name: flicker;
|
||||
animation-iteration-count: infinite;
|
||||
}
|
||||
|
||||
@keyframes scale-up {
|
||||
from {
|
||||
transform: scale(0);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes fade-in {
|
||||
from {
|
||||
opacity: 0;
|
||||
pointer-events: 0;
|
||||
width: 0;
|
||||
height: 0;
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
#on-off:checked ~ embed {
|
||||
display: block;
|
||||
@keyframes enter {
|
||||
from {
|
||||
transform: translateX(10vw);
|
||||
}
|
||||
}
|
||||
|
||||
/* YT link */
|
||||
.yt {
|
||||
color: hsl(0 0% 100% / 0.5);
|
||||
font-size: 1rem;
|
||||
padding: 1em;
|
||||
margin: 0 0 1em 0;
|
||||
grid-column: 1 / -1;
|
||||
@keyframes enter-reverse {
|
||||
from {
|
||||
transform: translateX(-10vw);
|
||||
}
|
||||
}
|
||||
|
||||
.yt:hover {
|
||||
color: white;
|
||||
text-shadow: 0 0 0.5em hsl(var(--blade-hue) 50% 50%),
|
||||
0 0 1em hsl(var(--blade-hue) 50% 50% / 0.75);
|
||||
@keyframes slide-down {
|
||||
from {
|
||||
transform: translateY(-10vw);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes slide-up {
|
||||
from {
|
||||
transform: translateY(10vw);
|
||||
opacity: 0;
|
||||
}
|
||||
40% {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes lightsaber {
|
||||
from {
|
||||
transform: translateX(10%);
|
||||
}
|
||||
22% {
|
||||
transform: translateX(-15%);
|
||||
}
|
||||
30% {
|
||||
transform: translateX(-30%);
|
||||
}
|
||||
45% {
|
||||
transform: translateX(-40%) scale(0.9);
|
||||
animation-timing-function: cubic-bezier(0.7, 0, 0, 1);
|
||||
}
|
||||
55%,
|
||||
to {
|
||||
transform: translateX(-100%) scale(0.7);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes lightsaber-out {
|
||||
from {
|
||||
transform: translateX(-100%) scale(0.7);
|
||||
}
|
||||
to {
|
||||
transform: translateX(-100%) scale(0.7) translateX(50%) rotate(360deg)
|
||||
translateX(-50%);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes blade {
|
||||
from {
|
||||
transform: scaleX(0);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes flicker {
|
||||
20% {
|
||||
opacity: 0.5;
|
||||
}
|
||||
40% {
|
||||
opacity: 0.7;
|
||||
}
|
||||
60% {
|
||||
opacity: 0.2;
|
||||
}
|
||||
80% {
|
||||
opacity: 0.6;
|
||||
}
|
||||
}
|
||||
|
||||
28
static/main/js/lightsaber.js
Normal file
28
static/main/js/lightsaber.js
Normal file
@ -0,0 +1,28 @@
|
||||
const COLORS = [
|
||||
"#2ff924",
|
||||
"#2e67f8",
|
||||
"#871efe",
|
||||
"#eb212e",
|
||||
"#ff8f18",
|
||||
"#ffffff",
|
||||
]
|
||||
let random_color = COLORS[Math.floor(Math.random() * COLORS.length)]
|
||||
document.documentElement.style.setProperty("--lightsaber-color", random_color)
|
||||
|
||||
let body = document.body
|
||||
body.addEventListener("click", () => {
|
||||
body.hidden = true
|
||||
requestAnimationFrame(() => {
|
||||
body.hidden = false
|
||||
})
|
||||
})
|
||||
|
||||
let style = document.createElement("style")
|
||||
style.innerHTML =
|
||||
" *, *:before, *:after { animation-play-state: paused !important; }"
|
||||
|
||||
document.addEventListener("keypress", () => {
|
||||
style.parentNode
|
||||
? document.head.removeChild(style)
|
||||
: document.head.appendChild(style)
|
||||
})
|
||||
@ -1,36 +1,52 @@
|
||||
{% extends "layout.html" %}
|
||||
{% load static %}
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<title>Lightsaber</title>
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" />
|
||||
<link href="https://fonts.googleapis.com/css2?family=Source+Sans+Pro:wght@900&display=swap"
|
||||
rel="stylesheet"/>
|
||||
<link rel="stylesheet"
|
||||
href="https://cdnjs.cloudflare.com/ajax/libs/normalize/5.0.0/normalize.min.css"/>
|
||||
{% block title %}{{ title }}{% endblock %}
|
||||
{% block meta %}
|
||||
<link rel="stylesheet"
|
||||
type="text/css"
|
||||
href="{% static 'main/css/lightsaber.css' %}"/>
|
||||
</head>
|
||||
<body>
|
||||
<label for="green">Green</label>
|
||||
<input type="radio" id="green" name="color" checked />
|
||||
<label for="blue">Blue</label>
|
||||
<input type="radio" id="blue" name="color" />
|
||||
<label for="yellow">Yellow</label>
|
||||
<input type="radio" id="yellow" name="color" />
|
||||
<label for="purple">Purple</label>
|
||||
<input type="radio" id="purple" name="color" />
|
||||
<label for="red">Red</label>
|
||||
<input type="radio" id="red" name="color" />
|
||||
<label for="darksaber">Darksaber</label>
|
||||
<input type="radio" id="darksaber" name="color" />
|
||||
<script src="{% static 'main/js/lightsaber.js' %}" defer></script>
|
||||
{% endblock %}
|
||||
{% block content %}
|
||||
<div class="body">
|
||||
<div class="lightsaber">
|
||||
<input type="checkbox" id="on-off" />
|
||||
<div class="blade"></div>
|
||||
<label class="hilt" for="on-off"></label>
|
||||
<embed src="https://assets.codepen.io/308367/coolsaber.mp3" type="" />
|
||||
<div class="pommel-cap metal"></div>
|
||||
<div class="grip metal">
|
||||
<div class="controls metal">
|
||||
<div style="--i: 0" class="button"></div>
|
||||
<div style="--i: 1" class="button"></div>
|
||||
<div style="--i: 2" class="button -down"></div>
|
||||
<div style="--i: 3" class="button -up"></div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
</div>
|
||||
<div class="hilt">
|
||||
<div style="--i: 0" class="segment black-metal"></div>
|
||||
<div style="--i: 1" class="segment metal"></div>
|
||||
<div style="--i: 2" class="segment black-metal"></div>
|
||||
<div style="--i: 3" class="segment metal"></div>
|
||||
<div style="--i: 4" class="segment black-metal"></div>
|
||||
<div style="--i: 5" class="segment metal"></div>
|
||||
<div style="--i: 6" class="segment black-metal"></div>
|
||||
<div style="--i: 7" class="segment metal"></div>
|
||||
<div style="--i: 8" class="segment black-metal"></div>
|
||||
<div style="--i: 9" class="segment metal"></div>
|
||||
<div style="--i: 10" class="segment black-metal"></div>
|
||||
<div style="--i: 11" class="segment metal"></div>
|
||||
</div>
|
||||
<div class="focusing-ring">
|
||||
<div style="--i: 0" class="segment black-metal"></div>
|
||||
<div style="--i: 1" class="segment metal"></div>
|
||||
<div style="--i: 2" class="segment copper"></div>
|
||||
</div>
|
||||
<div class="blade-emitter">
|
||||
<div style="--i: 0" class="segment metal start"></div>
|
||||
<div style="--i: 1" class="segment metal middle"></div>
|
||||
<div style="--i: 2" class="segment metal end"></div>
|
||||
</div>
|
||||
<div class="blade">
|
||||
<div class="glow"></div>
|
||||
<div class="glow large"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
@ -80,10 +80,10 @@
|
||||
<div class="card-content">
|
||||
<div class="card-info-wrapper">
|
||||
<div class="card-info-title">
|
||||
<h2>Surprise me</h2>
|
||||
<h2>Become a Jedi</h2>
|
||||
</div>
|
||||
<div class="card-info-text">
|
||||
<p>CSS Lightsaber.</p>
|
||||
<p>or Sith.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Loading…
Reference in New Issue
Block a user