-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.js
116 lines (88 loc) · 2.82 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
/* ========================================
State
======================================== */
const state = {
current: { x: 0, y: 0 },
target: { x: 0, y: 0 },
};
/* ========================================
Elements
======================================== */
const container = document.querySelector(".container");
const text = document.querySelector(".text");
/* ========================================
Functions
======================================== */
function getTextShadowValue(xPercentage, yPercentage) {
const shadowAmount = 50;
const maxVw = 2;
let result = "";
for (let index = 0; index < shadowAmount; index++) {
const isLast = index === shadowAmount - 1;
const percentage = (index + 1) / shadowAmount;
const xValue = maxVw * percentage * (xPercentage * -1);
const yValue = maxVw * percentage * yPercentage;
result +=
`${xValue}vw ` +
`${yValue}vw ` +
`var(--foreground-color)${isLast ? "" : ","}`;
}
return result;
}
function getTransformValue(xPercentage, yPercentage) {
const maxDegrees = 20;
const rotateXValue = yPercentage * maxDegrees;
const rotateYValue = xPercentage * maxDegrees;
return `rotateX(${rotateXValue}deg) rotateY(${rotateYValue}deg)`;
}
function getPositionWithInertia(current, target) {
const distance = target - current;
if (Math.abs(distance) < 0.01) {
return target;
}
return current + distance * 0.1;
}
function updateTarget(event) {
state.target.x = event.x;
state.target.y = event.y;
}
/* ========================================
Rendering
======================================== */
function render() {
if (
state.current.x !== state.target.x ||
state.current.y !== state.target.y
) {
const x = getPositionWithInertia(state.current.x, state.target.x);
const y = getPositionWithInertia(state.current.y, state.target.y);
const halfWidth = window.innerWidth * 0.5;
const halfHeight = window.innerHeight * 0.5;
// left is negative, right is posivite
const xPercentage = (x - halfWidth) / halfWidth;
// bottom is negative, top is posivite
const yPercentage = ((y - halfHeight) / halfHeight) * -1;
// update dom
container.style.transform = getTransformValue(xPercentage, yPercentage);
text.style.textShadow = getTextShadowValue(xPercentage, yPercentage);
// update state
state.current.x = x;
state.current.y = y;
}
// render loop
requestAnimationFrame(render);
}
/* ========================================
Handlers
======================================== */
function handleMouseMove(event) {
updateTarget(event);
}
function handleLoad(event) {
render();
}
/* ========================================
Events
======================================== */
window.addEventListener("mousemove", handleMouseMove);
window.addEventListener("load", handleLoad);