Red Light Saber

by Luis Martin

HTML

<script src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
<canvas id="space"></canvas>
<div class="light_saber">
<div class="back">
  <div class="outer_glow" style="background-color: #ff1d1d;"></div>
  <div class="middle_glow" style="background-color: #faccd2;"></div>
  <div class="core_glow"></div>
  <div class="handle"><img src="https://codeorum.com/images/article_images/300/20190328T135948_300.png"></div>
  </div>
</div>
<p class="text">
Click on the handle
</p>

CSS

body{
  padding:0px;
  margin:0px;
}
#space{
    position: fixed;
}
.light_saber {
  height: 460px;
  width: 10px;
  margin-left: auto;
  margin-right: auto;
}
.back{
  height: 460px;
  width: 10px;
  position: relative;  
  transform: rotate(180deg);
}
.outer_glow{
  height: 0px;
  width: 26px;
  border-radius:5px;
  filter: blur(10px);
    position: absolute;
    left: -8px;
    top:85px;
    transition: all 0.6s cubic-bezier(0.860, 0.000, 0.070, 1.000);
    //animation: lightUp2 0.6s cubic-bezier(0.860, 0.000, 0.070, 1.000);
    //animation: glow_animation 1.8s infinite;
}
.middle_glow{
  height: 0px;
  width: 10px;
  border-radius:5px;
  position: absolute;
  top:85px;
  filter: blur(2px);
  transition: all 0.6s cubic-bezier(0.860, 0.000, 0.070, 1.000);
  animation: lightUp1 0.6s cubic-bezier(0.860, 0.000, 0.070, 1.000);
  //animation: glow_animation 1.8s infinite ;
}
.core_glow{
  height: 0px;
  width: 6px;
  background-color: #fff;
  border-radius:5px;
  position: absolute;
  top:85px;
  filter: blur(1px);
  transition: all 0.6s cubic-bezier(0.860, 0.000, 0.070, 1.000);
  //animation: lightUp3 1.6s cubic-bezier(0.860, 0.000, 0.070, 1.000);
  left: 2px;
}

.handle{
  height: 30px;
  width: 55px;
  position: absolute;
  top:0;
  left: -22px;
  cursor:pointer;
}
.handle img{
  width: 100%;
  height: auto;
  transform: rotate(180deg);
}
.text{
  font-family: "Lucida Sans Unicode", "Lucida Grande", sans-serif;
  color:#fff;
  position:absolute;
  left:50%;
  transform:translate(-50%,0);
}

.open .outer_glow{ height: 370px; animation: glow_animation 1.8s infinite ;}
.open .middle_glow{ height: 350px; animation: glow_animation 1.8s infinite ;}
.open .core_glow{ height: 347px;}

@keyframes glow_animation {
  0% {
   transform: scaleX(1);
  }
  20% {
   transform: scaleX(1.1);
  }
  30% {
    transform: scaleX(1.2);
  }
  60% {
    transform: scaleX(1.05);
  }
  80% {
    transform: scaleX(1.1);
  }
  100% {
    transform: scaleX(1);
  }
}

JavaScript

window.requestAnimFrame = (function () { return window.requestAnimationFrame })();
var canvas = document.getElementById("space");
var c = canvas.getContext("2d");

var numStars = 1900;
var radius = '0.' + Math.floor(Math.random() * 9) + 1;
var focalLength = canvas.width * 2;
var warp = 0;
var centerX, centerY;

var stars = [], star;
var i;

var animate = true;

initializeStars();

function executeFrame() {

    if (animate)
        requestAnimFrame(executeFrame);
    moveStars();
    drawStars();
}

function initializeStars() {
    centerX = canvas.width / 2;
    centerY = canvas.height / 2;

    stars = [];
    for (i = 0; i < numStars; i++) {
        star = {
            x: Math.random() * 1920,
            y: Math.random() * 1080,
            z: Math.random() * 1920,
            o: '0.' + Math.floor(Math.random() * 99) + 1
        };
        stars.push(star);
    }
}

function moveStars() {
    for (i = 0; i < numStars; i++) {
        star = stars[i];
        star.z--;

        if (star.z <= 0) {
            star.z = 1920;
        }
    }
}

function drawStars() {
    var pixelX, pixelY, pixelRadius;

    // Resize to the screen
    if (canvas.width != window.innerWidth || canvas.width != window.innerWidth) {
        canvas.width = window.innerWidth;
        canvas.height = window.innerHeight;
        initializeStars();
    }

    c.fillStyle = "rgba(0,0,0,1)";
    c.fillRect(0, 0, canvas.width, canvas.height);
    c.fillStyle = "rgba(0, 0, 0, " + radius + ")";
    for (i = 0; i < numStars; i++) {
        star = stars[i];

        pixelX = (star.x - centerX) * (focalLength / star.z);
        pixelX += centerX;
        pixelY = (star.y - centerY) * (focalLength / star.z);
        pixelY += centerY;
        pixelRadius = 1 * (focalLength / star.z);

        c.fillRect(pixelX, pixelY, pixelRadius, pixelRadius);
        c.fillStyle = "rgba(255, 255, 255, " + star.o + ")";
        //c.fill();
   ...