type
This commit is contained in:
parent
2b2a74147c
commit
2ac58a3d14
1 changed files with 104 additions and 0 deletions
104
type.html
Normal file
104
type.html
Normal file
|
|
@ -0,0 +1,104 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Typewriter Upward Swing</title>
|
||||
<style>
|
||||
body {
|
||||
font-family: monospace;
|
||||
padding: 40px;
|
||||
font-size: 2rem;
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
#typewriter {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
white-space: pre;
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
#text {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
#typebar {
|
||||
position: absolute;
|
||||
width: 40px;
|
||||
height: 800px; /* long typebar */
|
||||
transform-origin: bottom center;
|
||||
opacity: 0;
|
||||
transition:
|
||||
transform 0.12s ease-out,
|
||||
opacity 0.15s ease-out;
|
||||
pointer-events: none;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div id="typewriter">
|
||||
<span id="text"></span>
|
||||
|
||||
<svg id="typebar" viewBox="0 0 20 500">
|
||||
<rect x="7" y="0" width="6" height="500" fill="#333"/>
|
||||
</svg>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
const fullText = "Typed text";
|
||||
const textEl = document.getElementById("text");
|
||||
const typebar = document.getElementById("typebar");
|
||||
const container = document.getElementById("typewriter");
|
||||
|
||||
let i = 0;
|
||||
|
||||
function nextChar() {
|
||||
if (i >= fullText.length) return;
|
||||
|
||||
|
||||
|
||||
// Measure character position
|
||||
const range = document.createRange();
|
||||
range.setStart(textEl.firstChild, i);
|
||||
range.setEnd(textEl.firstChild, i + 1);
|
||||
const charRect = range.getBoundingClientRect();
|
||||
const containerRect = container.getBoundingClientRect();
|
||||
|
||||
// Random downward rest angle between 20° and 60°
|
||||
const restAngle = 20 + Math.random() * 40;
|
||||
|
||||
// Position typebar's pivot slightly below the text
|
||||
typebar.style.left = (charRect.left - containerRect.left) + "px";
|
||||
typebar.style.top = (charRect.top - containerRect.top + 20) + "px";
|
||||
|
||||
// Set initial REST POSITION
|
||||
typebar.style.transform = `rotate(${restAngle}deg)`;
|
||||
|
||||
// FADE IN before swing
|
||||
|
||||
|
||||
// STRIKE
|
||||
requestAnimationFrame(() => {
|
||||
typebar.style.transform = `rotate(0deg)`;
|
||||
typebar.style.opacity = 1;
|
||||
|
||||
// Add next character
|
||||
textEl.textContent += fullText[i];
|
||||
|
||||
// Retract + FADE OUT
|
||||
setTimeout(() => {
|
||||
typebar.style.transform = `rotate(${restAngle}deg)`;
|
||||
typebar.style.opacity = 0;
|
||||
}, 120);
|
||||
});
|
||||
|
||||
i++;
|
||||
setTimeout(nextChar, 300);
|
||||
}
|
||||
|
||||
nextChar();
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
Loading…
Add table
Add a link
Reference in a new issue