Snippets

Filteren op

Button RGB-shadow

HTML CSS
                                        
                                            <button class="button" role="button">Button</button>                                        
                                    
                                        
                                            /* CSS */
.button {
  padding: 0.6em 2em;
  border: none;
  outline: none;
  color: rgb(255, 255, 255);
  background: #111;
  cursor: pointer;
  position: relative;
  z-index: 0;
  border-radius: 10px;
  user-select: none;
  -webkit-user-select: none;
  touch-action: manipulation;
  margin:10px;
}

.button:before {
  content: "";
  background: linear-gradient(
    45deg,
    #ff0000,
    #ff7300,
    #fffb00,
    #48ff00,
    #00ffd5,
    #002bff,
    #7a00ff,
    #ff00c8,
    #ff0000
  );
  position: absolute;
  top: -2px;
  left: -2px;
  background-size: 400%;
  z-index: -1;
  filter: blur(5px);
  -webkit-filter: blur(5px);
  width: calc(100% + 4px);
  height: calc(100% + 4px);
  animation: glowing-button 20s linear infinite;
  transition: opacity 0.3s ease-in-out;
  border-radius: 10px;
}

@keyframes glowing-button {
  0% {
    background-position: 0 0;
  }
  50% {
    background-position: 400% 0;
  }
  100% {
    background-position: 0 0;
  }
}

.button:after {
  z-index: -1;
  content: "";
  position: absolute;
  width: 100%;
  height: 100%;
  background: #222;
  left: 0;
  top: 0;
  border-radius: 10px;
}                                        
                                    

Button

Close button

HTML CSS
                                        
                                            <button>
  Close
</button>                                        
                                    
                                        
                                            html, body {
  margin: 0;
  min-height: 200px;
  padding: 0;
}

body {
  background: #8A2387;
  background: linear-gradient(to right, #F27121, #E94057, #8A2387);
  position: relative;
  text-align: center;
}

button {
  background: none;
  border: 0;
  box-sizing: border-box;
  color: transparent;
  cursor: pointer;
  font-size: 18px;
  left: 50%;
  letter-spacing: 1.5px;
  line-height: 90px;
  outline: none;
  overflow: hidden;
  padding: 10px 0 0;
  position: absolute;
  text-transform: uppercase;
  top: 50%;
  transform: translate(-50%, -50%);
  transition: all 0.2s ease-in;
  width: 100px;
}

button::before,
button::after {
  background-color: white;
  content: '';
  display: block;
  height: 3px;
  left: 0;
  position: absolute;
  transform-origin: center left;
  transition: all 0.2s ease-in;
  width: 141.4214px;
  z-index: -1;
}

button::before {
  top: 0;
  transform: rotate(45deg);
}

button::after {
  bottom: 0;
  transform: rotate(-45deg);
}

button:hover {
  color: #8A2387;
}

button:hover::before,
button:hover::after {
  height: 50px;
  transform: rotate(0deg);
}
                                        
                                    

Button zoom/fade

HTML CSS
                                        
                                            <div class="text-box">
    <a href="#" class="btn btn-white btn-				 animate">click me</a>
</div>                                        
                                    
                                        
                                            body {
    font-family: sans-serif;
    background-color: #fd2c5e;
    font-weight: bold;
}

.text-box {
    margin-left: 44vw;
	 margin-top: 50px;
    padding-bottom:50px;
}

.btn:link,
.btn:visited {
    text-transform: uppercase;
    text-decoration: none;
    padding: 15px 40px;
    display: inline-block;
    border-radius: 100px;
    transition: all .2s;
    position: absolute;
}

.btn:hover {
    transform: translateY(-3px);
    box-shadow: 0 10px 20px rgba(0, 0, 0, 0.2);
}

.btn:active {
    transform: translateY(-1px);
    box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);
}

.btn-white {
    background-color: #fff;
    color: #777;
}

.btn::after {
    content: "";
    display: inline-block;
    height: 100%;
    width: 100%;
    border-radius: 100px;
    position: absolute;
    top: 0;
    left: 0;
    z-index: -1;
    transition: all .4s;
}

.btn-white::after {
    background-color: #fff;
}

.btn:hover::after {
    transform: scaleX(1.4) scaleY(1.6);
    opacity: 0;
}

.btn-animated {
    animation: moveInBottom 5s ease-out;
    animation-fill-mode: backwards;
}

@keyframes moveInBottom {
    0% {
        opacity: 0;
        transform: translateY(30px);
    }

    100% {
        opacity: 1;
        transform: translateY(0px);
    }
}                                        
                                    

Bool toggle

HTML CSS
                                        
                                            <div class="is-active-toggle">
  <input value="" type="checkbox" class="switch" id="toggle-switch" name="service">
  <label for="toggle-switch" class="label"></label>
</div>
<div class="is-active-toggle">
  <input checked="checked" type="checkbox" class="switch" id="toggle-switch-1" name="service">
  <label for="toggle-switch-1" class="label"></label>
</div>                                        
                                    
                                        
                                            .is-active-toggle {
    position: relative;
    display: inline-block;
    width: 40px;
    height: 21px;
}

.is-active-toggle .switch {
    opacity: 0;
    width: 0;
    height: 0;
}

.is-active-toggle .label {
    background-color: #e5e5e5;
    border-radius: 34px;
    display: block;
    position: absolute;
    cursor: pointer;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    transition: background-color 0.4s;
}

.is-active-toggle .switch:checked + .label {
    background-color: #4cd964; /* Green color for the ON state */
}

.is-active-toggle .label::before {
    content: "";
    position: absolute;
    height: 17px;
    width: 17px;
    left: 2px;
    bottom: 2px;
    background-color: white;
    border-radius: 50%;
    transition: transform 0.4s;
}

.is-active-toggle .switch:checked + .label::before {
    transform: translateX(19px);
}
                                        
                                    

Popup basc

HTML CSS JavaSript
                                        
                                            <div class="fuze-popup">
		<div class="fuze-popup-inner">
			<h3>Dit is een titel</h3>
			<p>Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.
Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum</p>

			<span class="close-btn">&times;</span>
		</div>
</div>                                        
                                    
                                        
                                            .fuze-popup{
     position: fixed;
     left:0px;
     top:0px;
     width:100%;
     height:100%;
     background-color: rgba(0,0,0,0.1);
     z-index: 999;
}

.fuze-popup .fuze-popup-inner{
     position: fixed;
     left:50%;
     top:50%;
     transform:translate(-50%, -50%);
     background-color: #fff;
     padding:50px;
     width:50%;
     min-width:350px;
}

.fuze-popup .fuze-popup-inner h3{
     margin-bottom:16px;
     display: block;
}

.fuze-popup .fuze-popup-inner .close-btn{
     position: absolute;
     right:15px;
     top:15px;
     color:black;
     font-size:20px;
     line-height: 20px;
     cursor: pointer;
}                                        
                                    
                                        
                                            // Assume you have an element with the ID 'myElement'
$(document).ready(function() {
    // Set a timeout for 6 seconds (6000 milliseconds)
    	if (!sessionStorage.getItem('popupShown')) {
         setTimeout(function() {
            // Add a class to the element after 6 seconds
            $('.fuze-popup').addClass('open');
        }, 6000);
     }
});

// Notification
	jQuery(".close-btn").on("click", function () {
    jQuery(this).parents(".fuze-popup").removeClass("open");
    sessionStorage.setItem('popupShown', 'true');
	});

	jQuery(document).keyup(function (e) {
		if (e.key === "Escape") {
    // escape key maps to keycode `27`
    jQuery(".fuze-popup").removeClass("open");
    sessionStorage.setItem('popupShown', 'true');
		}
	});                                        
                                    

Custom mouse follower

HTML CSS JavaSript
                                        
                                            <div id="cursor"></div>                                        
                                    
                                        
                                            #cursor {
    width: 20px;
    height: 20px;
    background: radial-gradient(#DC0059 0% , #DC0059 10%, rgb(220, 0, 89, 0) 100%);
    filter: blur(8px);
    position: absolute;
    pointer-events: none;
    transition: transform 0.1s ease;
    opacity: 0.7;
}                                        
                                    
                                        
                                            // Custom mouse cursor
    let mouseX = 0, mouseY = 0;
    let lastX = 0, lastY = 0;
    let isMoving = false;

    // Size of the custom cursor
    const cursorSize = 20; // Diameter of the cursor
    const cursorOffset = cursorSize / 2; // Offset to position the center

    // Update mouse position
    document.addEventListener('mousemove', (event) => {
        mouseX = event.clientX - cursorOffset;
        mouseY = event.clientY - cursorOffset;
        if (!isMoving) {
            requestAnimationFrame(updateCursor);
        }
    });

    // Update cursor on scroll
    window.addEventListener('scroll', () => {
        if (!isMoving) {
            requestAnimationFrame(updateCursor);
        }
    });

    function updateCursor() {
        isMoving = true;

        const cursor = document.getElementById('cursor');
        const scrollY = window.scrollY;

        const factor = 0.25; // Interpolation factor for movement
        lastX += (mouseX - lastX) * factor;
        lastY += (mouseY + scrollY - lastY) * factor;

        cursor.style.left = lastX + 'px';
        cursor.style.top = lastY + 'px';

        if (Math.abs(mouseX - lastX) < 1 && Math.abs(mouseY + scrollY - lastY) < 1) {
            isMoving = false;
        } else {
            requestAnimationFrame(updateCursor);
        }
    }                                        
                                    

Infite Scrolling tags

HTML
                                        
                                            <p class="codepen" data-height="500" data-default-tab="html,result" data-slug-hash="KKezJzz" data-user="ykadosh" style="height: 500px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/ykadosh/pen/KKezJzz">
  Infinite Scroll Animation</a> by Yoav Kadosh (<a href="https://codepen.io/ykadosh">@ykadosh</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>                                        
                                    

Bubble footer

HTML
                                        
                                            <p class="codepen" data-height="500" data-default-tab="html,result" data-slug-hash="mdGjXLN" data-user="borab2001" style="height: 500px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/borab2001/pen/mdGjXLN">
  Footer Animation</a> by Borab2001 (<a href="https://codepen.io/borab2001">@borab2001</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>                                        
                                    

Mobile diagonal nav animation

HTML
                                        
                                            <p class="codepen" data-height="500" data-default-tab="html,result" data-slug-hash="aNYWKE" data-user="karlovidek" style="height: 500; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/karlovidek/pen/aNYWKE">
  Mobile navigation  animation</a> by Karlo Videk (<a href="https://codepen.io/karlovidek">@karlovidek</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>                                        
                                    

Glassmorphism buttons

HTML CSS
                                        
                                            <head>
	<meta charset="UTF-8">
	<meta http-equiv="X-UA-Compatible" content="IE=edge">
	<meta name="viewport" content="width=device-width, initial-scale=1.0">
	<title>Glassmorphism button</title>
</head>

<body>
	<div class="container">
		<div class="btn"><a href="#">Read more 1</a></div>
		<div class="btn"><a href="#" >Read more 2</a></div>
				<div class="btn"><a href="#" >Read more 3</a></div>

	</div>		
</body>                                        
                                    
                                        
                                            @import url("https://fonts.googleapis.com/css2?family=Poppins:wght@400;500;600;700;800;900&family=Roboto:wght@400;500;700&display=swap");

* {
	margin: 0;
	padding: 0;
	box-sizing: border-box;
	font-family: "Roboto", sans-serif;
}
body {
	position: relative;
	display: flex;
	justify-content: center;
	align-items: center;
	min-height: 100vh;
	background: linear-gradient(to bottom, #5d326c, #350048); /*fiolet*/
}
.container {
	width: 1000px;
	display: flex;
	flex-wrap: wrap;
	justify-content: space-around;
}
.container .btn {
	position: relative;
	top: 0;
	left: 0;
	width: 250px;
	height: 50px;
	margin: 0;
	display: flex;
	justify-content: center;
	align-items: center;
}
.container .btn a {
	position: absolute;
	top: 0;
	left: 0;
	width: 100%;
	height: 100%;
	display: flex;
	justify-content: center;
	align-items: center;
	background: rgba(255, 255, 255, 0.05);
	box-shadow: 0 15px 15px rgba(0, 0, 0, 0.3);
	border-bottom: 1px solid rgba(255, 255, 255, 0.1);
	border-top: 1px solid rgba(255, 255, 255, 0.1);
	border-radius: 30px;
	padding: 10px;
	letter-spacing: 1px;
	text-decoration: none;
	overflow: hidden;
	color: #fff;
	font-weight: 400px;
	z-index: 1;
	transition: 0.5s;
	backdrop-filter: blur(15px);
}
.container .btn:hover a {
	letter-spacing: 3px;
}
.container .btn a::before {
	content: "";
	position: absolute;
	top: 0;
	left: 0;
	width: 50%;
	height: 100%;
	background: linear-gradient(to left, rgba(255, 255, 255, 0.15), transparent);
	transform: skewX(45deg) translate(0);
	transition: 0.5s;
	filter: blur(0px);
}
.container .btn:hover a::before {
	transform: skewX(45deg) translate(200px);
}
.container .btn::before {
	content: "";
	position: absolute;
	left: 50%;
	transform: translatex(-50%);
	bottom: -5px;
	width: 30px;
	height: 10px;
	background: #f00;
	border-radius: 10px;
	transition: 0.5s;
	transition-delay: 0.5;
}
.container .btn:hover::before /*lightup button*/ {
	bottom: 0;
	height: 50%;
	width: 80%;
	border-radius: 30px;
}

.container .btn::after {
	content: "";
	position: absolute;
	left: 50%;
	transform: translatex(-50%);
	top: -5px;
	width: 30px;
	height: 10px;
	background: #f00;
	border-radius: 10px;
	transition: 0.5s;
	transition-delay: 0.5;
}
.container .btn:hover::after /*lightup button*/ {
	top: 0;
	height: 50%;
	width: 80%;
	border-radius: 30px;
}
.container .btn:nth-child(1)::before, /*chnage 1*/
.container .btn:nth-child(1)::after {
	background: #ff1f71;
	box-shadow: 0 0 5px #ff1f71, 0 0 15px #ff1f71, 0 0 30px #ff1f71,
		0 0 60px #ff1f71;
}
.container .btn:nth-child(2)::before, /* 2*/
.container .btn:nth-child(2)::after {
	background: #2db2ff;
	box-shadow: 0 0 5px #2db2ff, 0 0 15px #2db2ff, 0 0 30px #2db2ff,
		0 0 60px #2db2ff;
}
.container .btn:nth-child(3)::before, /* 3*/
.container .btn:nth-child(3)::after {
	background: #1eff45;
	box-shadow: 0 0 5px #1eff45, 0 0 15px #1eff45, 0 0 30px #1eff45,
		0 0 60px #1eff45;
}
                                        
                                    

Button met background transition

HTML SCSS
                                        
                                            <a href="#" class="btn btn--primary">Button</a>                                        
                                    
                                        
                                            .btn {
    padding: 0.75rem 1.5rem;
    border-radius: 6.25rem;
    font-size: 1rem;
    font-weight: 450;
    border: none;
    cursor: pointer;
    line-height: 160%;
    text-align: center;
    text-decoration: none;
    display: inline-block;
    position: relative;
    z-index: 1;
    overflow: hidden;
    transition: .3s ease;
    background-color: transparent;

    &::after {
        position: absolute;
        left: 0;
        top: 0;
        height: 100%;
        width: 100%;
        border-radius: 6.25rem;
        content: "";
        display: block;
        z-index: -2;
    }

    &::before {
        position: absolute;
        left: 0;
        top: 0;
        height: 100%;
        width: 0;
        border-radius: 6.25rem;
        content: "";
        display: block;
        z-index: -1;
        transition: .3s ease;
        background: #fd2c5e;
    }

    &:hover {
        &::before {
            width: 100%;
        }
    }

    &--primary {
        color: #fff;

        &::after {
            background-color: #fd2c5e;
        }

        &::before {
            background-color: darken(#fd2c5e, 10%);
        }
    }
}                                        
                                    

Simple background color hover (left to right)

HTML CSS
                                        
                                            <h1>Hover Me</h1>                                        
                                    
                                        
                                            h1::before {  
  transform: scaleX(0);
  transform-origin: bottom right;
}

h1:hover::before {
  transform: scaleX(1);
  transform-origin: bottom left;
}

h1::before {
  content: " ";
  display: block;
  position: absolute;
  top: 0; right: 0; bottom: 0; left: 0;
  inset: 0 0 0 0;
  background: hsl(200 100% 80%);
  z-index: -1;
  transition: transform .3s ease;
}

h1 {
  position: relative;
  font-size: 5rem;
}

html {
  block-size: 100%;
  inline-size: 100%;
}

body {
  min-block-size: 100%;
  min-inline-size: 100%;
  margin: 0;
  box-sizing: border-box;
  display: grid;
  place-content: center;
  font-family: system-ui, sans-serif;
}

@media (orientation: landscape) {
  body {
    grid-auto-flow: column;
  }
}                                        
                                    

Cool menu animation

HTML CSS
                                        
                                            <nav class="nav">
  <input id="menu" type="checkbox">
  <label for="menu">Menu</label>
  <ul class="menu">
    <li>
      <a href="#0">
        <span>About</span>
        <i class="fas fa-address-card" aria-hidden="true"></i>
      </a>
    </li>
    <li>
      <a href="#0">
        <span>Projects</span>
        <i class="fas fa-tasks" aria-hidden="true"></i>
      </a>
    </li>
    <li>
      <a href="#0">
        <span>Clients</span>
        <i class="fas fa-users" aria-hidden="true"></i>
      </a>
    </li>
    <li>
      <a href="#0">
        <span>Contact</span>
        <i class="fas fa-envelope-open-text" aria-hidden="true"></i>
      </a>
    </li>
  </ul>
</nav>

<p class="notification">Click on the Menu</p>
<footer class="page-footer">
  <span>made by </span>
  <a href="https://georgemartsoukos.com/" target="_blank">
    <img width="24" height="24" src="https://assets.codepen.io/162656/george-martsoukos-small-logo.svg" alt="George Martsoukos logo">
  </a>
</footer>                                        
                                    
                                        
                                            /* RESET/BASIC STYLES
–––––––––––––––––––––––––––––––––––––––––––––––––– */
@import url('https://fonts.googleapis.com/css2?family=Inter&display=swap');

:root {
  --white: #ffffff;
  --light-grey: #edf0f1;
  --violet: #655be1;
  --dark-violet: #5146e1;
  --black: #21232a;
}

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

ul {
  list-style: none;
}

a {
  color: inherit;
  text-decoration: none;
}

body {
  font-family: "Inter", sans-serif;
  text-align: center;
  padding: 0 20px;
  background: var(--light-grey);
  color: var(--white);
}

.notification {
  position: absolute;
  top: 0;
  right: 0;
  padding: 10px;
  background: var(--violet);
}

/* MAIN STYLES
–––––––––––––––––––––––––––––––––––––––––––––––––– */
.nav {
  position: relative;
  display: flex;
  justify-content: center;
  max-width: 400px;
  padding-bottom: 20px;
  border-radius: 5px 5px 25px 25px;
  margin: 300px auto 0;
  background: var(--white);
  box-shadow: rgb(50 50 93 / 10%) 0 30px 60px -12px,
    rgb(0 0 0 / 15%) 0 18px 36px -18px;
}

.nav [type="checkbox"] {
  position: absolute;
  left: -9999px;
}

.nav [type="checkbox"] + label {
  position: relative;
  width: 75px;
  height: 75px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 16px;
  cursor: pointer;
  z-index: 1;
  background: var(--violet);
  border-radius: 50%;
  transform: translateY(-50%);
  transition: all 0.2s;
}

.nav [type="checkbox"] + label:hover {
  background: var(--dark-violet);
}

.menu li {
  position: absolute;
  top: -25px;
  left: 50%;
  transform: translateX(-50%);
  transition: all 0.4s;
}

.menu li:nth-child(1) {
  transition-delay: 0.2s;
}

.menu li:nth-child(2) {
  transition-delay: 0.15s;
}

.menu li:nth-child(3) {
  transition-delay: 0.1s;
}

.menu li:nth-child(4) {
  transition-delay: 0.05s;
}

.menu li a {
  width: 50px;
  height: 50px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--violet);
}

.menu li a span {
  position: absolute;
  top: 0;
  left: 0;
  transform: translateY(calc(-100% - 5px));
  width: 100%;
  font-size: 13px;
  white-space: nowrap;
  pointer-events: none;
  opacity: 0;
  transition: opacity 0.3s;
  color: var(--black);
  font-weight: bold;
}

.nav input:checked + label {
  background: var(--black);
  transform: translateY(calc(-50% + 4px));
}

.nav input:checked ~ .menu li:nth-child(1) {
  top: -210px;
  transition-delay: 0.1s;
}

.nav input:checked ~ .menu li:nth-child(2) {
  top: -160px;
  left: calc(50% - 75px);
  transition-delay: 0.2s;
}

.nav input:checked ~ .menu li:nth-child(3) {
  top: -160px;
  left: calc(50% + 75px);
  transition-delay: 0.3s;
}

.nav input:checked ~ .menu li:nth-child(4) {
  top: -110px;
  transition-delay: 0.4s;
}

.nav input:checked ~ .menu li a span {
  opacity: 1;
  transition-delay: 0.9s;
}

/* FOOTER STYLES
–––––––––––––––––––––––––––––––––––––––––––––––––– */
.page-footer {
  position: fixed;
  right: 0;
  bottom: 60px;
  display: flex;
  align-items: center;
  padding: 5px;
  color: var(--black);
}

.page-footer a {
  display: flex;
  margin-left: 4px;
}
                                        
                                    

Directional blur

HTML CSS
                                        
                                            <div class='wrapper' id='hermes'>
  <div class='blurred-wrapper'>
    <div class='blurred'>swift as hermes</div>
  </div>
  <div class='still'>swift as hermes</div>
</div>

<div class='wrapper' id='sonic'>
  <div class='blurred-wrapper'>
    <img class='blurred' src='http://2.bp.blogspot.com/-IixO6EttRfY/T25DaTUWJ-I/AAAAAAAAAUo/1lJ7DuKYS6k/s1600/Sonic_runsmall.png' height='100'></img>
  </div>
  <img class='still' src='http://2.bp.blogspot.com/-IixO6EttRfY/T25DaTUWJ-I/AAAAAAAAAUo/1lJ7DuKYS6k/s1600/Sonic_runsmall.png' height='100'></img>
</div>

<div class='wrapper' id='spacex'>
  <div class='blurred-wrapper'>
    <div class='blurred'>SPAAACE</div>
  </div>
  <div class='still'>SPAAACE</div>
</div>                                        
                                    
                                        
                                            .wrapper {
  
  --blur: 5;
  
  font-size: 5rem;
  margin:1rem 0;
  position:relative;
  display:flex;
  flex-direction:row;
  justify-content:center;
  border-radius:1rem;
  padding:1rem 0;
  
}

.blurred-wrapper {
  
  position: absolute;
  filter: blur(1rem);
  
  transform: scale(
    var(--blur),
    0.001
  )
    
}

.blurred {
  
  transform: scale(
    calc( 1/var(--blur) ),
    1000
  )
    
}

#hermes{
  background:lightgray;
  color:#555;
}

#sonic{
  background:#000;
}

#spacex{
  background:hsl(250,50%,10%);
  font-family:sans-serif;
  color:hsl(200,100%,80%)
}
#spacex>.still{
  color:white
}                                        
                                    

1-col w offset title layout

HTML SCSS
                                        
                                            <section class="container section section--content-1-col" role="region" id="block-mb-block-b1891c75-2202-402e-acdb-eb031851191c">
    <div class="row no-gutters">
        <div class="col-12 col-lg-6 overflow-title aos-init aos-animate" data-aos="fade-up" data-aos-delay="50">
            <h2>Het beste <span class="indent indent--4">materieel voor</span> <span class="indent indent--1">een scherpe prijs</span></h2>
        </div>
            
        <div class="col-12 col-lg-6 aos-init aos-animate" data-aos="fade-up" data-aos-delay="50">
            <div class="content-wrapper content-wrapper__has-subtitle">
                                        <span class="subtitle">Materieel voor professionals.</span>
                                    <p>Toolsrent is een verhuurbedrijf voor bouwgerichte ondernemingen, klein zelfstandigen en de evenementenbranche. Wij zijn gevestigd in Winterswijk en werken met een enthousiast team met veel ervaring. Doordat we beschikken over een zeer divers assortiment, bestaande uit onder andere bouwplaatsinrichting, elektrisch gereedschap, betonbekisting, steigers en rijdend materieel hebben we voor veel uitdagingen een oplossing voorradig.</p>
            </div>
        </div>
                    
    </div>
</section>                                        
                                    
                                        
                                            /*
 * @package:    fuze
 * @author:     bryanfervent - Fervent Digital
 * @copyright:  2018 - 2021
 * --------------
 * Created:     06-12-2021, 16:36:43
 * Modified:    02-02-2022, 15:36:33
 * Modified By: Remco Hendriks
 */
.btn__content {
    color: $grayDark;
    font-size: 18px;
    padding: 0;
    margin-top: 55px;
    &:hover {
        color: $fuze_secondary;
        text-decoration: underline;
        .btn-svg {
            transform: rotateY(0deg) rotate(45deg);
            margin-right: 28px;
        }
    }
    .btn-svg {
        margin-left: 60px;
        width: 19px;
        height: 19px;
        transition: 0.2s ease-in-out;
    }
}

.container.section.section--content-1-col {
    position: relative;
    .spinning-circle {
        width: 150px;
        height: 150px;
        position: absolute;
        top: 125px;
        right: calc(var(--bs-gutter-x) * 0.5);
        svg {
            margin-top: -50px;
            margin-left: -50px;
            animation: rotateSvg 30s linear infinite;
            -webkit-animation: rotateSvg 30s linear infinite;
            -moz-animation: rotateSvg 30s linear infinite;
            width: 250px;
            height: 250px;
            path {
                fill: transparent;
            }
            textPath {
                font-size: 11.5px;
            }
        }
    }
    @-webkit-keyframes rotateSvg {
        0% {
            transform: rotate(0deg) translate3d(0, 0, 0);
        }
        to {
            transform: rotate(360deg) translate3d(0, 0, 0);
        }
    }
    @-moz-keyframes rotateSvg {
        0% {
            transform: rotate(0deg) translate3d(0, 0, 0);
        }
        to {
            transform: rotate(360deg) translate3d(0, 0, 0);
        }
    }
    @keyframes rotateSvg {
        0% {
            transform: rotate(0deg) translate3d(0, 0, 0);
        }
        to {
            transform: rotate(360deg) translate3d(0, 0, 0);
        }
    }
}

@include media-breakpoint-up(lg) {
    .container.section.section--content-1-col {
        padding-top: 200px;
        h2 {
            margin-top: -60px;
        }
    }
}
                                        
                                    

Link underline

HTML SCSS
                                        
                                            <a href="#" class="link link--underline">Dit is een link</a>                                        
                                    
                                        
                                            .link {
    color: #fd2c5e;
    text-decoration: none;
    cursor: pointer;
    position: relative;
    overflow: hidden;
    display: inline-block;
    font-size: calc(clamp(0.875rem, 0.188vw + 0.831rem, 1rem));

    &--underline {
        &::before {
            position: absolute;
            bottom: 0;
            background-color: #fd2c5e;
            height: 1px;
            width: 100%;
            content: "";
            display: block;
            left: 0;
        }

        &:hover::before {
            animation: slideOutAndIn .75s ease-in-out;
        }
    }
}

@keyframes slideOutAndIn {
    0% {
        transform: translateX(0);
    }
    49.9% {
        transform: translateX(100%);
        width: 100%
    }
    50% {
        width: 0;
    }
    50.1% {
        transform: translateX(-100%);
        width: 0;
    }
    50.2% {
        width: 100%;
    }
    100% {
        transform: translateX(0);
    }
}                                        
                                    

Tubes

HTML
                                        
                                            <p class="codepen" data-height="500" data-default-tab="html,result" data-slug-hash="zYWPXWz" data-user="schwiiiii" style="height: 500px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/schwiiiii/pen/zYWPXWz">
  Spinning Tubes</a> by Brett Schwickerath (<a href="https://codepen.io/schwiiiii">@schwiiiii</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>                                        
                                    

Pure CSS quote-transition

HTML CSS
                                        
                                            <div id="rotate-words">  
<div>Cinematic, Animated Text Effect<br />  <span>Someone</span></div>
<div>Perfect for Any Movie<br />  <span>No one</span></div>
<div>Loops for Eternity<br />  <span>Anyone</span></div>
<div>Simple CSS Tricks<br />  <span>Everyone</span></div>
<div>Cinematic, Animated Text Effect<br />  <span>Everyone</span></div>
<div>Perfect for Any Movie<br />  <span>Someone</span></div>
<div>Loops for Eternity<br />  <span>No one</span></div>
<div>Simple CSS Tricks<br />  <span>Someone</span></div>
</div>                                        
                                    
                                        
                                            @import url('https://fonts.googleapis.com/css?family=Oswald:700');
@import url('https://fonts.googleapis.com/css?family=Rubik');
body {
  background-color:#3757D0;
  background-image:radial-gradient(#81BCFF, #303391);
  background-size:100%;
  background-repeat:no-repeat;
  background-attachment:fixed;
  color:#fff;
  text-align:center;
}

#rotate-words {
  max-width:400px;
  margin:auto;
  padding:20% 0;
  font-size:2.2em;
  text-transform:uppercase;
  font-family: 'Oswald', sans-serif;
}

#rotate-words span {
  display:block;
  height:50px;
  font-size:.7em;
  text-transform:lowercase;
  opacity:.8;
  font-family: 'Rubik', sans-serif;
}

#rotate-words div {
 position:absolute;
 opacity:0;
 overflow:hidden;
 left:10vw;
 width:80vw;
 line-height:1.2em;
 animation: rotate-word 32s linear infinite 0s;
}

@keyframes rotate-word {
    0% { opacity: 0;  transform: translateX(0);filter:blur(10px);transform:scale(1.2)}
    3% { opacity: 1;  transform: translateX(0);filter:blur(0px);transform:scale(.9)}
    12% { opacity: 1; transform: translateX(0);filter:blur(0px);transform:scale(1)}
    16% { opacity: 0; transform: translateX(0);filter:blur(10px);transform:scale(1.2)}
    80% { opacity: 0}
    100% { opacity: 0}
}

#rotate-words div:nth-child(2) { animation-delay: 4s}
#rotate-words div:nth-child(3) { animation-delay: 8s}
#rotate-words div:nth-child(4) { animation-delay: 12s}
#rotate-words div:nth-child(5) { animation-delay: 16s}
#rotate-words div:nth-child(6) { animation-delay: 20s}
#rotate-words div:nth-child(7) { animation-delay: 24s}
#rotate-words div:nth-child(8) { animation-delay: 28s}

@keyframes author {
    0% { opacity: 0;  transform: translateY(100px);filter:blur(10px);transform: scaleY(2)}
    20% { opacity:0; transform: translateY(200px);filter:blur(10px); transform: scaleY(2)}
    30% { opacity:1; transform: translateY(0);filter:blur(0px);transform: scaleY(1)}
    90% { opacity:1; transform: translateY(0);filter:blur(0px);transform: scaleY(.9)}
    100% { opacity:0; transform: translateY(0);filter:blur(10px);transform: scale(2)}
}                                        
                                    

Loading animations

HTML CSS
                                        
                                            
source: <a href="https://css-loaders.com/" target="_blank">https://css-loaders.com/</a>

<div class="container">
    <div class="loader"></div>
    <div class="loader1"></div>
    <div class="loader2"></div>
    <div class="loader3"></div>
    <div class="loader4"></div>
    <div class="loader5"></div>
</div>

                                        
                                    
                                        
                                            .container{
  display:flex;
  gap:20px;
}

/* HTML: 
*/ .loader { width: 50px; height: 50px; aspect-ratio: 1; border-radius: 50%; border: 8px solid; border-color: #000 #0000; animation: l1 1s infinite; } @keyframes l1 {to{transform: rotate(.5turn)}} /* HTML:
*/ .loader1 { width: 50px; height: 50px; padding: 8px; aspect-ratio: 1; border-radius: 50%; background: #25b09b; --_m: conic-gradient(#0000 10%,#000), linear-gradient(#000 0 0) content-box; -webkit-mask: var(--_m); mask: var(--_m); -webkit-mask-composite: source-out; mask-composite: subtract; animation: l3 1s infinite linear; } @keyframes l3 {to{transform: rotate(1turn)}} /* HTML:
*/ .loader2 { width: 50px; height: 50px; --b: 8px; aspect-ratio: 1; border-radius: 50%; padding: 1px; background: conic-gradient(#0000 10%,#f03355) content-box; -webkit-mask: repeating-conic-gradient(#0000 0deg,#000 1deg 20deg,#0000 21deg 36deg), radial-gradient(farthest-side,#0000 calc(100% - var(--b) - 1px),#000 calc(100% - var(--b))); -webkit-mask-composite: destination-in; mask-composite: intersect; animation:l4 1s infinite steps(10); } @keyframes l4 {to{transform: rotate(1turn)}} /* HTML:
*/ .loader4 { width: 50px; height: 50px; aspect-ratio: 1; display: grid; border-radius: 50%; background: linear-gradient(0deg ,rgb(0 0 0/50%) 30%,#0000 0 70%,rgb(0 0 0/100%) 0) 50%/8% 100%, linear-gradient(90deg,rgb(0 0 0/25%) 30%,#0000 0 70%,rgb(0 0 0/75% ) 0) 50%/100% 8%; background-repeat: no-repeat; animation: l23 1s infinite steps(12); } .loader4::before, .loader4::after { content: ""; grid-area: 1/1; border-radius: 50%; background: inherit; opacity: 0.915; transform: rotate(30deg); } .loader4::after { opacity: 0.83; transform: rotate(60deg); } @keyframes l23 { 100% {transform: rotate(1turn)} } /* HTML:
*/ .loader5 { width: 50px; height: 50px; aspect-ratio: 1; border-radius: 50%; border: 8px solid #514b82; animation: l20-1 0.8s infinite linear alternate, l20-2 1.6s infinite linear; } @keyframes l20-1{ 0% {clip-path: polygon(50% 50%,0 0, 50% 0%, 50% 0%, 50% 0%, 50% 0%, 50% 0% )} 12.5% {clip-path: polygon(50% 50%,0 0, 50% 0%, 100% 0%, 100% 0%, 100% 0%, 100% 0% )} 25% {clip-path: polygon(50% 50%,0 0, 50% 0%, 100% 0%, 100% 100%, 100% 100%, 100% 100% )} 50% {clip-path: polygon(50% 50%,0 0, 50% 0%, 100% 0%, 100% 100%, 50% 100%, 0% 100% )} 62.5% {clip-path: polygon(50% 50%,100% 0, 100% 0%, 100% 0%, 100% 100%, 50% 100%, 0% 100% )} 75% {clip-path: polygon(50% 50%,100% 100%, 100% 100%, 100% 100%, 100% 100%, 50% 100%, 0% 100% )} 100% {clip-path: polygon(50% 50%,50% 100%, 50% 100%, 50% 100%, 50% 100%, 50% 100%, 0% 100% )} } @keyframes l20-2{ 0% {transform:scaleY(1) rotate(0deg)} 49.99%{transform:scaleY(1) rotate(135deg)} 50% {transform:scaleY(-1) rotate(0deg)} 100% {transform:scaleY(-1) rotate(-135deg)} }

Confetti cursor

CSS JavaSript
                                        
                                            .confetti {
            position: absolute;
            width: 8px;
            height: 8px;
            pointer-events: none;
            opacity: 0;
        }                                        
                                    
                                        
                                            document.addEventListener('DOMContentLoaded', function () {
    const confettiCount = 20;
    const confettiColors = ['#f00', '#0f0', '#00f', '#ff0', '#f0f', '#0ff'];
    const confettiElements = [];

    // Create confetti elements and add them to the body
    for (let i = 0; i < confettiCount; i++) {
        const confetti = document.createElement('div');
        confetti.classList.add('confetti');
        document.body.appendChild(confetti);
        confettiElements.push(confetti);
    }

    document.addEventListener('mousemove', (e) => {
        confettiElements.forEach((confetti, index) => {
            // Delay each confetti piece to create a trail effect
            setTimeout(() => {
                confetti.style.opacity = 1;
                confetti.style.backgroundColor = confettiColors[Math.floor(Math.random() * confettiColors.length)];
                confetti.style.left = e.pageX + Math.random() * 20 - 10 + 'px'; // Randomize position slightly for effect
                confetti.style.top = e.pageY + Math.random() * 20 - 10 + 'px';

                // Fade out confetti piece
                setTimeout(() => {
                    confetti.style.opacity = 0;
                }, 600);
            }, index * 20);
        });
    });
});                                        
                                    

Netflix intro animatie

HTML
                                        
                                            <iframe height="500" style="width: 100%;" scrolling="no" title="Netflix Intro Animation Pure CSS" src="https://codepen.io/claudio_bonfati/embed/mdryxPv?default-tab=html%2Cresult" frameborder="no" loading="lazy" allowtransparency="true" allowfullscreen="true">
  See the Pen <a href="https://codepen.io/claudio_bonfati/pen/mdryxPv">
  Netflix Intro Animation Pure CSS</a> by Claudio Bonfati (<a href="https://codepen.io/claudio_bonfati">@claudio_bonfati</a>)
  on <a href="https://codepen.io">CodePen</a>.
</iframe>                                        
                                    

Galaxy

HTML CSS
                                        
                                            <canvas id="canvas"></canvas>

<script type="module">
import { AdditiveBlending, BufferAttribute, BufferGeometry, CanvasTexture, Color, PerspectiveCamera, Points, RawShaderMaterial, Scene, WebGLRenderer } from "https://cdn.skypack.dev/three@0.136.0"
import { OrbitControls } from "https://cdn.skypack.dev/three@0.136.0/examples/jsm/controls/OrbitControls"
import GUI from "https://cdn.skypack.dev/three@0.136.0/examples/jsm/libs/lil-gui.module.min.js"
import { TWEEN } from "https://cdn.skypack.dev/three@0.136.0/examples/jsm/libs/tween.module.min.js"



console.clear()
// ------------------------ //
// SETUP

const count = 128 ** 2

const scene = new Scene()

const camera = new PerspectiveCamera(
  60, innerWidth / innerHeight, 0.1, 100
)
camera.position.set(0, 2, 3)

const renderer = new WebGLRenderer({ canvas })
renderer.setSize(innerWidth, innerHeight)
renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2))

const orbit = new OrbitControls(camera, canvas)



// ------------------------ //
// STAR ALPHA TEXTURE

const ctx = document.createElement("canvas").getContext("2d")
ctx.canvas.width = ctx.canvas.height = 32

ctx.fillStyle = "#000"
ctx.fillRect(0, 0, 32, 32)

let grd = ctx.createRadialGradient(16, 16, 0, 16, 16, 16)
grd.addColorStop(0.0, "#fff")
grd.addColorStop(1.0, "#000")
ctx.fillStyle = grd
ctx.beginPath(); ctx.rect(15, 0, 2, 32); ctx.fill()
ctx.beginPath(); ctx.rect(0, 15, 32, 2); ctx.fill()

grd = ctx.createRadialGradient(16, 16, 0, 16, 16, 16)
grd.addColorStop(0.1, "#ffff")
grd.addColorStop(0.6, "#0000")
ctx.fillStyle = grd
ctx.fillRect(0, 0, 32, 32)

const alphaMap = new CanvasTexture(ctx.canvas)



// ------------------------ //
// GALAXY

const galaxyGeometry = new BufferGeometry()

const galaxyPosition = new Float32Array(count * 3)
const galaxySeed = new Float32Array(count * 3)
const galaxySize = new Float32Array(count)

for (let i = 0; i < count; i++) {
  galaxyPosition[i * 3] = i / count
  galaxySeed[i * 3 + 0] = Math.random()
  galaxySeed[i * 3 + 1] = Math.random()
  galaxySeed[i * 3 + 2] = Math.random()
  galaxySize[i] = Math.random() * 2 + 0.5
}

galaxyGeometry.setAttribute(
  "position", new BufferAttribute(galaxyPosition, 3)
)
galaxyGeometry.setAttribute(
  "size", new BufferAttribute(galaxySize, 1)
)
galaxyGeometry.setAttribute(
  "seed", new BufferAttribute(galaxySeed, 3)
)



const innColor = new Color("#f40")
const outColor = new Color("#a7f")

const galaxyMaterial = new RawShaderMaterial({

  uniforms: {
    uTime: { value: 0 },
    uSize: { value: renderer.getPixelRatio() },
    uBranches: { value: 2 },
    uRadius: { value: 0 },
    uSpin: { value: Math.PI * 0.25 },
    uRandomness: { value: 0 },
    uAlphaMap: { value: alphaMap },
    uColorInn: { value: innColor },
    uColorOut: { value: outColor },
  },

  vertexShader:
`
precision highp float;

attribute vec3 position;
attribute float size;
attribute vec3 seed;
uniform mat4 projectionMatrix;
uniform mat4 modelViewMatrix;

uniform float uTime;
uniform float uSize;
uniform float uBranches;
uniform float uRadius;
uniform float uSpin;
uniform float uRandomness;

varying float vDistance;

#define PI  3.14159265359
#define PI2 6.28318530718

#include <random, scatter>



void main() {

  vec3 p = position;
  float st = sqrt(p.x);
  float qt = p.x * p.x;
  float mt = mix(st, qt, p.x);

  // Offset positions by spin (farther wider) and branch num
  float angle = qt * uSpin * (2.0 - sqrt(1.0 - qt));
  float branchOffset = (PI2 / uBranches) * floor(seed.x * uBranches);
  p.x = position.x * cos(angle + branchOffset) * uRadius;
  p.z = position.x * sin(angle + branchOffset) * uRadius;

  // Scatter positions & scale down by Y-axis
  p += scatter(seed) * random(seed.zx) * uRandomness * mt;
  p.y *= 0.5 + qt * 0.5;

  // Rotate (center faster)
  vec3 temp = p;
  float ac = cos(-uTime * (2.0 - st) * 0.5);
  float as = sin(-uTime * (2.0 - st) * 0.5);
  p.x = temp.x * ac - temp.z * as;
  p.z = temp.x * as + temp.z * ac;



  vDistance = mt;

  vec4 mvp = modelViewMatrix * vec4(p, 1.0);
  gl_Position = projectionMatrix * mvp;
  gl_PointSize = (10.0 * size * uSize) / -mvp.z;
}
`,

  fragmentShader:
`
precision highp float;

uniform vec3 uColorInn;
uniform vec3 uColorOut;
uniform sampler2D uAlphaMap;

varying float vDistance;

#define PI  3.14159265359



void main() {
  vec2 uv = vec2(gl_PointCoord.x, 1.0 - gl_PointCoord.y);
  float a = texture2D(uAlphaMap, uv).g;
  if (a < 0.1) discard;

  vec3 color = mix(uColorInn, uColorOut, vDistance);
  float c = step(0.99, (sin(gl_PointCoord.x * PI) + sin(gl_PointCoord.y * PI)) * 0.5);
  color = max(color, vec3(c));

  gl_FragColor = vec4(color, a);
}
`,

  transparent: true,
  depthTest: false,
  depthWrite: false,
  blending: AdditiveBlending,
})



const galaxy = new Points(galaxyGeometry, galaxyMaterial)
galaxy.material.onBeforeCompile = (shader) => {
  shader.vertexShader = shader.vertexShader
    .replace("#include <random, scatter>", shaderUtils)
}
scene.add(galaxy)



// ------------------------ //
// UNIVERSE

const universeGeometry = new BufferGeometry()

const universePosition = new Float32Array(count * 3 / 2)
const universeSeed = new Float32Array(count * 3 / 2)
const universeSize = new Float32Array(count / 2)

for (let i = 0; i < count / 2; i++) {
  universeSeed[i * 3 + 0] = Math.random()
  universeSeed[i * 3 + 1] = Math.random()
  universeSeed[i * 3 + 2] = Math.random()
  universeSize[i] = Math.random() * 2 + 0.5
}

universeGeometry.setAttribute(
  "position", new BufferAttribute(universePosition, 3)
)
universeGeometry.setAttribute(
  "seed", new BufferAttribute(universeSeed, 3)
)
universeGeometry.setAttribute(
  "size", new BufferAttribute(universeSize, 1)
)



const universeMaterial = new RawShaderMaterial({

  uniforms: {
    uTime: { value: 0 },
    uSize: galaxyMaterial.uniforms.uSize,
    uRadius: galaxyMaterial.uniforms.uRadius,
    uAlphaMap: galaxyMaterial.uniforms.uAlphaMap,
  },

  vertexShader:
`
precision highp float;

attribute vec3 seed;
attribute float size;
uniform mat4 projectionMatrix;
uniform mat4 modelViewMatrix;

uniform float uTime;
uniform float uSize;
uniform float uRadius;

#define PI  3.14159265359
#define PI2 6.28318530718

#include <random, scatter>

// Universe size factor
const float r = 3.0;
// Scale universe sphere 
const vec3 s = vec3(2.1, 1.3, 2.1);



void main() {

  vec3 p = scatter(seed) * r * s;

  // Sweep to center
  float q = random(seed.zx);
  for (int i = 0; i < 3; i++) q *= q;
  p *= q;

  // Sweep to surface
  float l = length(p) / (s.x * r);
  p = l < 0.001 ? (p / l) : p;

  // Rotate (center faster)
  vec3 temp = p;
  float ql = 1.0 - l;
  for (int i = 0; i < 3; i++) ql *= ql;
  float ac = cos(-uTime * ql);
  float as = sin(-uTime * ql);
  p.x = temp.x * ac - temp.z * as;
  p.z = temp.x * as + temp.z * ac;



  vec4 mvp = modelViewMatrix * vec4(p * uRadius, 1.0);
  gl_Position = projectionMatrix * mvp;

  // Scale up core stars
  l = (2.0 - l) * (2.0 - l);

  gl_PointSize = (r * size * uSize * l) / -mvp.z;
}
`,

  fragmentShader:
`
precision highp float;

uniform sampler2D uAlphaMap;

#define PI 3.14159265359

void main() {
  vec2 uv = vec2(gl_PointCoord.x, 1.0 - gl_PointCoord.y);
  float a = texture2D(uAlphaMap, uv).g;
  if (a < 0.1) discard;

  gl_FragColor = vec4(vec3(1.0), a);
}
`,

  transparent: true,
  depthTest: false,
  depthWrite: false,
  blending: AdditiveBlending,
})



const universe = new Points(universeGeometry, universeMaterial)
universe.material.onBeforeCompile = (shader) => {
  shader.vertexShader = shader.vertexShader
    .replace("#include <random, scatter>", shaderUtils)
}
scene.add(universe)



// ------------------------ //
// GUIs

const gui = new GUI().close()
const u = galaxyMaterial.uniforms

gui.add(u.uSize, "value", 0, 4, 0.01)
.name("star size")
gui.add(u.uBranches, "value", 1, 5, 1)
.name("branch num")

const cRadius = gui.add(u.uRadius, "value", 0, 5, 0.01)
.name("scale")
const cSpin = gui.add(u.uSpin, "value", -12.57, 12.57, 0.01)
.name("spin")
const cRandomness = gui.add(u.uRandomness, "value", 0, 1, 0.01)
.name("scatter")

gui.addColor({ color: innColor.getHexString()}, "color")
.name("inn color")
.onChange((hex) => {
  const { r, g, b } = new Color(hex)
  u.uColorInn.value = [ r, g, b ]
})
gui.addColor({ color: outColor.getHexString()}, "color")
.name("out color")
.onChange((hex) => {
  const { r, g, b } = new Color(hex)
  u.uColorOut.value = [ r, g, b ]
})



// ------------------------ //
// ANIMATION

new TWEEN.Tween({
  radius: 0,
  spin: 0,
  randomness: 0,
  rotate: 0,
}).to({
  radius: 1.618,
  spin: Math.PI * 2,
  randomness: 0.5,
  rotate: Math.PI * 4,
})
.duration(5000)
.easing(TWEEN.Easing.Cubic.InOut)
// .repeat(Infinity)
// .repeatDelay(1000)
// .yoyo(true)
.onUpdate(({ radius, spin, randomness, rotate }) => {
  cRadius.setValue(radius)
  cRadius.updateDisplay()

  cSpin.setValue(spin)
  cSpin.updateDisplay()

  cRandomness.setValue(randomness)
  cRandomness.updateDisplay()

  galaxy.rotation.y = rotate
  universe.rotation.y = rotate / 3
})
.onComplete(() => gui.open())
.start()



// ------------------------ //
// LOOPER

const t = 0.001
renderer.setAnimationLoop(() => {
  galaxyMaterial.uniforms.uTime.value += t / 2
  universeMaterial.uniforms.uTime.value += t / 3
  TWEEN.update()
  orbit.update()
  renderer.render(scene, camera)
})



// ------------------------ //
// HELPERS

addEventListener("resize", () => {
  camera.aspect = innerWidth / innerHeight
  camera.updateProjectionMatrix()
  renderer.setSize(innerWidth, innerHeight)  
})

const shaderUtils =
`
float random (vec2 st) {
  return fract(sin(dot(st.xy, vec2(12.9898, 78.233))) * 43758.5453123);
}

vec3 scatter (vec3 seed) {
  float u = random(seed.xy);
  float v = random(seed.yz);
  float theta = u * 6.28318530718;
  float phi = acos(2.0 * v - 1.0);

  float sinTheta = sin(theta);
  float cosTheta = cos(theta);
  float sinPhi = sin(phi);
  float cosPhi = cos(phi);

  float x = sinPhi * cosTheta;
  float y = sinPhi * sinTheta;
  float z = cosPhi;

  return vec3(x, y, z);
}
`
</script>                                        
                                    
                                        
                                            canvas {
  display: block;
  width: 100%;
  height: 100%;
  margin: 0;
  position: fixed;
  background: black;
}

// enable this to enable controls
	.lil-gui.root.autoPlace.allow-touch-styles {
   display: none !important;
}