Day 22 JavaScript 乱薍覼釠亂碼效果

今天我們要來做一些乱薍覼釠亂碼效果。

成果

效過在手,氣氛要有。

基本版面

HTML

一個標題,一個 <div> 放亂碼,一個 <span> 拿來測長寬,稍後用到。

1<h1>ITHOME</h1>
2<div>LDHELDMEW...</div>
3<span>a</span>

CSS

抓個 Google Font 來用,我用的是 Space Mono

 1@import url("https://fonts.googleapis.com/css2?family=Space+Mono:wght@700&display=swap");
 2
 3body {
 4  background: #000;
 5  height: 100svh;
 6  overflow: hidden;
 7  color: #fff;
 8}
 9
10h1 {
11  font-size: 4em;
12  font-family: "Space Mono", monospace;
13  position: absolute;
14  top: 50%;
15  left: 50%;
16  transform: translate(-50%, -100%);
17}
18div {
19  width: 100%;
20  word-wrap: break-word;
21}

word-wrap: break-word; 這個屬性是讓文字超出邊界時,自動換行。

有趣的 JavaScript

一步一步來

亂碼

來做個亂碼函式,輸入一個數字,就會回傳那麼多個亂碼。

一個變數 box 放著所有可能的字元,

1const box = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"

Math.random() 會回傳一個 0 到 1 之間的數字

1Math.random()
2// 0.946621565811897

Math.random()*5 會回傳一個 0 到 4 之間的數字

1Math.random()*5
2//4.603685644684928

Math.floor() 會無條件捨去小數點

1Math.floor(4.603685644684928)
2//4

這樣就有隨機取數了😯

我們把它乘上 box.length,就會得到一個 0 到 box.length 之間的數字,再用 Math.floor() 取整數,就會得到一個 0 到 box.length - 1 之間的數字,這個數字就是 box 的索引,我們就可以從 box 裡面隨機取出一個字元。

1box[Math.floor(Math.random() * box.length)];
2//A

寫一個函式,輸入一個數字,就會用迴圈回傳那麼多個亂碼。

1const box = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
2
3const randomText = (amount) => {
4  var a = "";
5  for (var i = 0; i < amount; i++)
6    a += box[Math.floor(Math.random() * box.length)];
7  return a;
8};

測試一下

1randomText(10)
2//"XVDBHCCQ39" 

喔~😯

需要幾個

螢幕有大有小,字體大小又都不一樣。沒關係,量一下就好了。

<span> 裡面有一個字母a。量螢幕大小除以字母大小就是大約需要多少個字母

1const singleText = document.querySelector("span");
2const total =
3  window.innerWidth * window.innerHeight /
4  singleText.offsetWidth / singleText.offsetHeight;
5//2736

喔~😯

解碼效果

settimeout可以讓函式延遲執行

1console.log("never gonna give you up")
2window.setTimeout(function () {
3  console.log("never gonna let you down")
4}, 2000);
5
6  //never gonna give you up
7  //(過了兩秒)
8  //never gonna let you down

一個雙層迴圈,每6次洗牌多顯示一個字。直到最後6個字都顯示完畢。

 1  for (let j = 0; j <= titleText.length; j++) {
 2    window.setTimeout(function () {
 3      var current = j;
 4      for (let k = 0; k <= 5; k++) {
 5        window.setTimeout(function () {
 6          var correct = titleText.slice(0, current);
 7          correct += randomText(titleText.length - current);
 8          title.innerText = correct;
 9        }, 50 * k);
10      }
11    }, 300 * j);
12  }

迴圈的延遲邏輯大概是這樣。

延遲邏輯

喔~😯

滑鼠位置

偵測滑鼠移動

1document.onmousemove = (e) => console.log(e);
2// mousemove { target: html, buttons: 0, clientX: 1004, clientY: 242, layerX: 1004, layerY: 242 }

改成執行我們的函式

1document.onmousemove = (e) => bluh(e);

我們把讀到的滑鼠位置,放進 CSS 屬性 --x--y 裡面。讓遮罩來定位。

1  bg.style.setProperty("--x", `${e.clientX}px`);
2  bg.style.setProperty("--y", `${e.clientY}px`);

完整函式

 1const bluh = (e) => {
 2  const bg = document.querySelector("div");
 3  const singleText = document.querySelector("span");
 4  const total =
 5    (window.innerWidth * window.innerHeight) /
 6    singleText.offsetWidth /
 7    singleText.offsetHeight;
 8  bg.innerText = randomText(total);
 9  bg.style.setProperty("--x", `${e.clientX}px`);
10  bg.style.setProperty("--y", `${e.clientY}px`);
11};
12
13document.onmousemove = (e) => bluh(e);
14bluh();

喔~😯

遮罩 CSS 了解一下

 1div {
 2  --x: -100vw;
 3  --y: -100vh;
 4  width: 100%;
 5  word-wrap: break-word;
 6  -webkit-mask-image: radial-gradient(
 7    circle at var(--x) var(--y),
 8    #fff,
 9    #ffffff44 15em
10  );
11}

遮罩設置成一個圓形漸層,並定位到 --x--y 的位置。

成果

https://codepen.io/edit-mr/pen/bGOxLoV

成果

1<h1>ITHOME</h1>
2<div></div>
3<span>a</span>
 1@import url("https://fonts.googleapis.com/css2?family=Space+Mono:wght@700&display=swap");
 2
 3body {
 4  background: #000;
 5  height: 100svh;
 6  overflow: hidden;
 7  color: #fff;
 8}
 9
10h1 {
11  font-size: 4em;
12  color: #fff;
13  font-family: "Space Mono", monospace;
14  position: absolute;
15  top: 50%;
16  left: 50%;
17  transform: translate(-50%, -100%);
18}
19div {
20  --x: -100vw;
21  --y: -100vh;
22  width: 100%;
23  word-wrap: break-word;
24  -webkit-mask-image: radial-gradient(
25    circle at var(--x) var(--y),
26    #fff,
27    #ffffff44 15em
28  );
29}
 1const title = document.querySelector("h1");
 2
 3const titleText = "ITHOME";
 4
 5setInterval(function () {
 6  for (let j = 0; j <= titleText.length; j++) {
 7    window.setTimeout(function () {
 8      var current = j;
 9      for (let k = 0; k <= 5; k++) {
10        window.setTimeout(function () {
11          var correct = titleText.slice(0, current);
12          correct += randomText(titleText.length - current);
13          title.innerText = correct;
14        }, 50 * k);
15      }
16    }, 300 * j);
17  }
18}, 5000);
19
20const box = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
21
22const randomText = (amount) => {
23  var a = "";
24  for (var i = 0; i < amount; i++)
25    a += box[Math.floor(Math.random() * box.length)];
26  return a;
27};
28
29const bluh = (e) => {
30  const bg = document.querySelector("div");
31  const singleText = document.querySelector("span");
32  const total =
33    (window.innerWidth * window.innerHeight) /
34    singleText.offsetWidth /
35    singleText.offsetHeight;
36  bg.innerText = randomText(total);
37  bg.style.setProperty("--x", `${e.clientX}px`);
38  bg.style.setProperty("--y", `${e.clientY}px`);
39};
40
41document.onmousemove = (e) => bluh(e);
42bluh();

以上就是我今天的分享,歡迎在 InstagramGoogle 新聞追蹤毛哥EM資訊密技,也歡迎訂閱我新開的YouTube頻道:網棧

我是毛哥EM,讓我們明天再見。

Posts in this Series