<!--
--  Uploaded on : https://haxor.my.id/open/rpl.html
--  Official Web : https://prinsh.com
--  script-deface-generator.prinsh.com
-->
<!DOCTYPE html>
<!-- saved from url=(0033)http://127.0.0.1:5500/index.html# -->
<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>I LOVE YOU</title>
<style>
 body {
  text-align: center;
  min-height: 100vh;
  background: black;
  color: whitesmoke;
  display: flex;
  overflow: hidden;
}
h1 {
  margin: auto;
  font-family: Gorditas;
  font-size: 6rem;
}

canvas {
  position: absolute;
  left: 0;
  top: 0;
  opacity: 1;
  pointer-events: none;
}
.td-wrapper,
canvas {
  transition: opacity 1s;
}
.td-wrapper:not(.td-hide) + canvas,
.td-hide {
  opacity: 0;
}
</style>
<script>
class TextDesintegrator {
  constructor(el, options) {
    const defaultOptions = {
      padding: 160,
      density: 4,
      duration: 2500 // in ms
    };
    this.step = 0;
    this.count = 0;
    this.data = [];
    this.scale = 2; // pixel density
    this.el = el;
    this.el.style.position = "relative";
    this.el.innerHTML = `<span class="td-wrapper">${this.el.textContent}</span>`;
    this.inner = this.el.querySelector("span");
    this.options = { ...defaultOptions, ...options };
    this.reverse = false;
    // copy el to canvas

    document.fonts.ready.then(() => {
      this.createCanvas();
      this.fillCanvas();
      this.pixelize();
      setTimeout(() => {
        this.start();
      }, 0);
    });
  }
  createCanvas() {
    // get the width and the height of the span element
    // canvas will have the same dimensions
    const { width, height } = this.el.getBoundingClientRect();
    this.height = height;
    this.width = width;
    this.canvas = document.createElement("canvas");
    this.canvas.width = this.scale * (this.width + 2 * this.options.padding);
    this.canvas.height = this.scale * (this.height + 2 * this.options.padding);
    this.canvas.style.width = `${this.width + 2 * this.options.padding}px`;
    this.canvas.style.height = `${this.height + 2 * this.options.padding}px`;
    this.canvas.style.transform = `translate3d(${-this.options
      .padding}px, ${-this.options.padding}px, 0)`;
    this.context = this.canvas.getContext("2d");
    this.context.scale(this.scale, this.scale);
    this.el.append(this.canvas);
  }
  clearContext() {
    this.context.clearRect(0, 0, this.canvas.width, this.canvas.height);
  }
  fillCanvas() {
    const style = getComputedStyle(this.el);
    this.color = style.getPropertyValue("color");
    this.context.fillStyle = this.color;
    this.context.font = style.getPropertyValue("font");
    this.context.textBaseline = "ideographic";
    this.context.fillText(
      this.el.textContent,
      this.options.padding,
      (this.canvas.height / this.scale + this.height) / 2
    );
  }
  start() {
    this.t0 = 0;
    this.id = window.requestAnimationFrame((t) => this.render(t));
  }
  stop() {
    if (this.id) {
      window.cancelAnimationFrame(this.id);
    }
  }
  pixelize() {
    const { padding, density, duration } = this.options;
    for (
      let y = 0;
      y < this.canvas.height + 2 * padding - Math.floor(density / 2);
      y += density
    ) {
      for (
        let x = 0;
        x < this.canvas.width + 2 * padding - Math.floor(density / 2);
        x += density
      ) {
        const { data } = this.context.getImageData(
          x + Math.floor(density / 4),
          y + Math.floor(density / 4),
          1,
          1
        );
        const [, , , a] = data;
        if (a > 0) {
          this.data.push({
            alpha: a / 255,
            longevity: Math.min(
              duration * 0.25 + Math.random() * duration * 0.75,
              duration - 1
            ),
            x,
            y,
            initialX: x,
            initialY: y,
            finalX: x + 2 * (Math.random() - 0.5) * this.canvas.width,
            finalY: y + 2 * (Math.random() - 0.5) * this.canvas.width
          });
        }
      }
    }
  }

  render(timestamp) {
    if (!this.t0) {
      this.t0 = timestamp;
    }
    const elapsed = timestamp - this.t0;
    if (this.step < Math.min(500, this.options.duration * 0.5)) {
      if (this.reverse) {
        this.inner.classList.remove("td-hide");
      } else {
        this.inner.classList.add("td-hide");
      }
    }
    this.updateData();
    this.clearContext();
    for (const sq of this.data) {
      this.context.globalAlpha = sq.alpha;
      this.context.fillStyle = this.color;
      this.context.fillRect(
        sq.x / 2,
        sq.y / 2,
        this.options.density / 2,
        this.options.density / 2
      );
    }
    this.step = this.reverse ? this.options.duration - elapsed : elapsed;
    if (elapsed > this.options.duration) {
      this.onComplete();
    }
    this.id = requestAnimationFrame((t) => this.render(t));
  }
  onComplete() {
    this.reverse = !this.reverse;
    this.t0 = 0;
  }
  updateData() {
    for (const sq of this.data) {
      sq.alpha = this.calculateOpacity(sq.longevity, this.step);
      sq.x = this.calculatePosition(
        sq.initialX,
        sq.finalX,
        sq.longevity,
        this.step
      );
      sq.y = this.calculatePosition(
        sq.initialY,
        sq.finalY,
        sq.longevity,
        this.step
      );
    }
  }
  calculatePosition(xS, xE, l, x) {
    const expo = (l, x) => {
      return x < l ? 1 - Math.pow(2, 10 * (x / l) - 10) : 0;
    };
    const val = (xS - xE) * expo(l, x) + xE;
    return val;
  }
  calculateOpacity(l, x) {
    return x <= l ? 1 - Math.pow(x / l, 1) : 0;
  }
}

const h1 = document.querySelectorAll("h1 span");

h1.forEach((el) => new TextDesintegrator(el));
</script>
</head>
<body>
    <h1>
        <span>Rekayasa</span> 
        <span style="color: rgb(255, 4, 92)">Perangkat</span>
        <span>Lunak</span>
      </h1>
<!-- Code injected by live-server -->
<script>
	// <![CDATA[  <-- For SVG support
	if ('WebSocket' in window) {
		(function () {
			function refreshCSS() {
				var sheets = [].slice.call(document.getElementsByTagName("link"));
				var head = document.getElementsByTagName("head")[0];
				for (var i = 0; i < sheets.length; ++i) {
					var elem = sheets[i];
					var parent = elem.parentElement || head;
					parent.removeChild(elem);
					var rel = elem.rel;
					if (elem.href && typeof rel != "string" || rel.length == 0 || rel.toLowerCase() == "stylesheet") {
						var url = elem.href.replace(/(&|\?)_cacheOverride=\d+/, '');
						elem.href = url + (url.indexOf('?') >= 0 ? '&' : '?') + '_cacheOverride=' + (new Date().valueOf());
					}
					parent.appendChild(elem);
				}
			}
			var protocol = window.location.protocol === 'http:' ? 'ws://' : 'wss://';
			var address = protocol + window.location.host + window.location.pathname + '/ws';
			var socket = new WebSocket(address);
			socket.onmessage = function (msg) {
				if (msg.data == 'reload') window.location.reload();
				else if (msg.data == 'refreshcss') refreshCSS();
			};
			if (sessionStorage && !sessionStorage.getItem('IsThisFirstTime_Log_From_LiveServer')) {
				console.log('Live reload enabled.');
				sessionStorage.setItem('IsThisFirstTime_Log_From_LiveServer', true);
			}
		})();
	}
	else {
		console.error('Upgrade your browser. This Browser is NOT supported WebSocket for Live-Reloading.');
	}
	// ]]>
</script>

</body></html>