Skip to content

Commit 144dff1

Browse files
committed
fix animations
1 parent e4d7f82 commit 144dff1

5 files changed

Lines changed: 246 additions & 27 deletions

File tree

book.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ additional-js = [
2121
"theme/pagetoc.js",
2222
"theme/ht_searcher.js",
2323
"theme/sponsor.js",
24+
"theme/motion.js",
2425
"theme/ai.js"
2526
]
2627
no-section-label = true

src/README.md

Lines changed: 0 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -49,18 +49,6 @@ You can check their **blog** in [**https://blog.stmcyber.com**](https://blog.stm
4949

5050
---
5151

52-
### [RootedCON](https://www.rootedcon.com/)
53-
54-
<figure><img src="images/image (45).png" alt=""><figcaption></figcaption></figure>
55-
56-
[**RootedCON**](https://www.rootedcon.com) is the most relevant cybersecurity event in **Spain** and one of the most important in **Europe**. With **the mission of promoting technical knowledge**, this congress is a boiling meeting point for technology and cybersecurity professionals in every discipline.
57-
58-
{{#ref}}
59-
https://www.rootedcon.com/
60-
{{#endref}}
61-
62-
---
63-
6452
### [Intigriti](https://www.intigriti.com)
6553

6654
<figure><img src="images/image (47).png" alt=""><figcaption></figcaption></figure>
@@ -75,21 +63,6 @@ https://go.intigriti.com/hacktricks
7563

7664
---
7765

78-
### [Trickest](https://trickest.com/?utm_campaign=hacktrics&utm_medium=banner&utm_source=hacktricks)
79-
80-
<figure><img src="images/image (48).png" alt=""><figcaption></figcaption></figure>
81-
82-
\
83-
Use [**Trickest**](https://trickest.com/?utm_campaign=hacktrics&utm_medium=banner&utm_source=hacktricks) to easily build and **automate workflows** powered by the world's **most advanced** community tools.
84-
85-
Get Access Today:
86-
87-
{{#ref}}
88-
https://trickest.com/?utm_campaign=hacktrics&utm_medium=banner&utm_source=hacktricks
89-
{{#endref}}
90-
91-
---
92-
9366
### [HACKENPROOF](https://bit.ly/3xrrDrL)
9467

9568
<figure><img src="images/image (3).png" alt=""><figcaption></figcaption></figure>

theme/css/general.css

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,49 @@ body {
6969
animation: float-particle 16s infinite;
7070
}
7171

72+
html.motion-paused .bg-animation,
73+
html.motion-paused .grid-overlay,
74+
html.motion-paused .particle,
75+
html.motion-paused #ht-ai-btn {
76+
animation-play-state: paused !important;
77+
}
78+
79+
html.motion-reduced .bg-animation,
80+
html.motion-reduced .grid-overlay,
81+
html.motion-reduced .particles {
82+
display: none !important;
83+
}
84+
85+
html.motion-reduced .particle,
86+
html.motion-reduced #ht-ai-btn {
87+
animation: none !important;
88+
}
89+
90+
html.motion-reduced #ht-ai-btn {
91+
background: linear-gradient(45deg, #b31328, #d42d3f) !important;
92+
background-size: auto !important;
93+
box-shadow: 0 8px 18px rgba(0, 0, 0, 0.3) !important;
94+
}
95+
96+
@media (prefers-reduced-motion: reduce) {
97+
.bg-animation,
98+
.grid-overlay,
99+
.particles {
100+
display: none !important;
101+
}
102+
103+
.particle,
104+
#ht-ai-btn {
105+
animation: none !important;
106+
}
107+
108+
#ht-ai-btn {
109+
background: linear-gradient(45deg, #b31328, #d42d3f) !important;
110+
background-size: auto !important;
111+
box-shadow: 0 8px 18px rgba(0, 0, 0, 0.3) !important;
112+
}
113+
}
114+
72115
@keyframes bg-drift {
73116
0% { transform: translate3d(0, 0, 0) scale(1); }
74117
100% { transform: translate3d(-2%, 1%, 0) scale(1.04); }

theme/index.hbs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -558,6 +558,12 @@
558558
(function initParticles() {
559559
var container = document.querySelector('.particles');
560560
if (!container) { return; }
561+
if (
562+
document.documentElement.classList.contains('motion-reduced') ||
563+
(window.__hacktricksMotion && window.__hacktricksMotion.shouldReduceMotion())
564+
) {
565+
return;
566+
}
561567
var count = 28;
562568
for (var i = 0; i < count; i++) {
563569
var particle = document.createElement('span');

theme/motion.js

Lines changed: 196 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,196 @@
1+
(function () {
2+
var docEl = document.documentElement;
3+
var REDUCED_CLASS = "motion-reduced";
4+
var PAUSED_CLASS = "motion-paused";
5+
var motionState = {
6+
mode: "normal",
7+
reason: "default"
8+
};
9+
10+
function setMode(mode, reason) {
11+
var nextMode = mode === "reduced" ? "reduced" : "normal";
12+
if (motionState.mode === nextMode && motionState.reason === reason) {
13+
return;
14+
}
15+
16+
motionState.mode = nextMode;
17+
motionState.reason = reason || motionState.reason;
18+
docEl.classList.toggle(REDUCED_CLASS, nextMode === "reduced");
19+
docEl.dataset.motionMode = nextMode;
20+
window.__hacktricksMotion = {
21+
mode: motionState.mode,
22+
reason: motionState.reason,
23+
shouldReduceMotion: function () {
24+
return motionState.mode === "reduced";
25+
}
26+
};
27+
28+
document.dispatchEvent(
29+
new CustomEvent("hacktricks:motionchange", {
30+
detail: {
31+
mode: motionState.mode,
32+
reason: motionState.reason
33+
}
34+
})
35+
);
36+
}
37+
38+
function updateVisibilityState() {
39+
docEl.classList.toggle(PAUSED_CLASS, document.visibilityState === "hidden");
40+
}
41+
42+
function getMediaQuery() {
43+
if (typeof window.matchMedia !== "function") {
44+
return null;
45+
}
46+
return window.matchMedia("(prefers-reduced-motion: reduce)");
47+
}
48+
49+
function getDeviceHints() {
50+
var hints = {
51+
lowCapability: false,
52+
hardwareConcurrency: null,
53+
deviceMemory: null
54+
};
55+
56+
if (typeof navigator.hardwareConcurrency === "number") {
57+
hints.hardwareConcurrency = navigator.hardwareConcurrency;
58+
}
59+
60+
if (typeof navigator.deviceMemory === "number") {
61+
hints.deviceMemory = navigator.deviceMemory;
62+
}
63+
64+
hints.lowCapability =
65+
(hints.hardwareConcurrency !== null && hints.hardwareConcurrency <= 4) ||
66+
(hints.deviceMemory !== null && hints.deviceMemory <= 4);
67+
68+
return hints;
69+
}
70+
71+
function monitorAnimationHealth() {
72+
if (
73+
document.visibilityState === "hidden" ||
74+
typeof window.requestAnimationFrame !== "function"
75+
) {
76+
return;
77+
}
78+
79+
var mediaQuery = getMediaQuery();
80+
if (mediaQuery && mediaQuery.matches) {
81+
setMode("reduced", "prefers-reduced-motion");
82+
return;
83+
}
84+
85+
var hints = getDeviceHints();
86+
var perfState = {
87+
frameCount: 0,
88+
firstFrameAt: 0,
89+
longTaskTime: 0,
90+
worstFrameGap: 0
91+
};
92+
93+
var observer = null;
94+
if (typeof PerformanceObserver === "function") {
95+
try {
96+
observer = new PerformanceObserver(function (list) {
97+
list.getEntries().forEach(function (entry) {
98+
perfState.longTaskTime += entry.duration;
99+
});
100+
});
101+
observer.observe({ type: "longtask", buffered: true });
102+
} catch (error) {
103+
observer = null;
104+
}
105+
}
106+
107+
var targetDuration = 2500;
108+
var fpsThreshold = hints.lowCapability ? 50 : 42;
109+
var longTaskThreshold = hints.lowCapability ? 160 : 240;
110+
var frameGapThreshold = hints.lowCapability ? 90 : 120;
111+
var lastFrameAt = 0;
112+
113+
function finish(now) {
114+
if (observer) {
115+
observer.disconnect();
116+
}
117+
118+
var elapsed = now - perfState.firstFrameAt;
119+
if (elapsed <= 0) {
120+
return;
121+
}
122+
123+
var fps = (perfState.frameCount * 1000) / elapsed;
124+
var shouldReduce =
125+
fps < fpsThreshold ||
126+
perfState.longTaskTime > longTaskThreshold ||
127+
perfState.worstFrameGap > frameGapThreshold;
128+
129+
if (shouldReduce) {
130+
setMode("reduced", "runtime-performance");
131+
}
132+
}
133+
134+
function sample(now) {
135+
if (!perfState.firstFrameAt) {
136+
perfState.firstFrameAt = now;
137+
}
138+
139+
perfState.frameCount += 1;
140+
if (lastFrameAt) {
141+
perfState.worstFrameGap = Math.max(
142+
perfState.worstFrameGap,
143+
now - lastFrameAt
144+
);
145+
}
146+
lastFrameAt = now;
147+
148+
if (now - perfState.firstFrameAt >= targetDuration) {
149+
finish(now);
150+
return;
151+
}
152+
153+
window.requestAnimationFrame(sample);
154+
}
155+
156+
window.requestAnimationFrame(sample);
157+
}
158+
159+
var mediaQuery = getMediaQuery();
160+
if (mediaQuery && mediaQuery.matches) {
161+
setMode("reduced", "prefers-reduced-motion");
162+
} else {
163+
setMode("normal", "default");
164+
if (document.readyState === "complete") {
165+
window.setTimeout(monitorAnimationHealth, 1200);
166+
} else {
167+
window.addEventListener(
168+
"load",
169+
function () {
170+
window.setTimeout(monitorAnimationHealth, 1200);
171+
},
172+
{ once: true }
173+
);
174+
}
175+
}
176+
177+
if (mediaQuery) {
178+
var handlePreferenceChange = function (event) {
179+
if (event.matches) {
180+
setMode("reduced", "prefers-reduced-motion");
181+
} else if (motionState.reason === "prefers-reduced-motion") {
182+
setMode("normal", "preference-restored");
183+
window.setTimeout(monitorAnimationHealth, 600);
184+
}
185+
};
186+
187+
if (typeof mediaQuery.addEventListener === "function") {
188+
mediaQuery.addEventListener("change", handlePreferenceChange);
189+
} else if (typeof mediaQuery.addListener === "function") {
190+
mediaQuery.addListener(handlePreferenceChange);
191+
}
192+
}
193+
194+
updateVisibilityState();
195+
document.addEventListener("visibilitychange", updateVisibilityState);
196+
})();

0 commit comments

Comments
 (0)