This commit is contained in:
2024-09-27 10:48:26 +02:00
parent 787ed89c85
commit 089dbf52f2
7 changed files with 55 additions and 7 deletions

View File

@ -1,8 +1,8 @@
const deltaX: number = 12; const deltaX: number = 20;
const ymax: number = 1; const ymax: number = 1.8;
function f(a: number, x: number): number { function f(a: number, x: number): number {
return Math.exp(-1 * Math.pow((x - a), 2) / 30); return (1.2 + 0.75 * Math.cos(0.8 * (x - a))) * Math.exp(-1 * Math.pow(x - a - 5, 2) / 100);
} }
// helper function // helper function

View File

@ -5,11 +5,23 @@
<meta charset="UTF-8" /> <meta charset="UTF-8" />
<meta name="viewport" content="width=device-width" /> <meta name="viewport" content="width=device-width" />
<link rel="stylesheet" href="/bootstrap.min.css" /> <link rel="stylesheet" href="/bootstrap.min.css" />
<link rel="stylesheet" href="/styles.css" />
<script src="/bootstrap.bundle.min.js"></script> <script src="/bootstrap.bundle.min.js"></script>
<script src="/confetti.min.js"></script>
<title>Nestabilní body</title> <title>Nestabilní body</title>
<style>
#confetti-canvas {
pointer-events: none;
position: absolute;
top: 0;
left: 5;
z-index: 10;
}
</style>
</head> </head>
<body data-bs-theme="dark"> <body data-bs-theme="dark">
<canvas id="confetti-canvas"></canvas>
<nav class="navbar navbar-expand-lg bg-body-tertiary"> <nav class="navbar navbar-expand-lg bg-body-tertiary">
<div class="container-fluid"> <div class="container-fluid">
<a class="nav-link" href="/">Hlavní stránka</a> <a class="nav-link" href="/">Hlavní stránka</a>
@ -22,7 +34,18 @@
<script> <script>
setTimeout(() => { setTimeout(() => {
window.location.href='/'; window.location.href='/';
}, 20*1000); }, 2000*1000);
const confettiSettings = {
target: 'confetti-canvas',
max: "200",
rotate: true,
respawn: false,
size: 1,
fade: true
}
let confetti = new ConfettiGenerator(confettiSettings);
confetti.render();
</script> </script>
</body> </body>
</html> </html>

View File

@ -5,6 +5,7 @@
<meta charset="UTF-8" /> <meta charset="UTF-8" />
<meta name="viewport" content="width=device-width" /> <meta name="viewport" content="width=device-width" />
<link rel="stylesheet" href="/bootstrap.min.css" /> <link rel="stylesheet" href="/bootstrap.min.css" />
<link rel="stylesheet" href="/styles.css" />
<script src="/bootstrap.bundle.min.js"></script> <script src="/bootstrap.bundle.min.js"></script>
<title>Nestabilní body</title> <title>Nestabilní body</title>
</head> </head>

View File

@ -5,9 +5,10 @@
<meta charset="UTF-8" /> <meta charset="UTF-8" />
<meta name="viewport" content="width=device-width" /> <meta name="viewport" content="width=device-width" />
<link rel="stylesheet" href="/bootstrap.min.css" /> <link rel="stylesheet" href="/bootstrap.min.css" />
<link rel="stylesheet" href="/styles.css" />
<meta http-equiv="refresh" content="36000"> <meta http-equiv="refresh" content="36000">
<script src="/bootstrap.bundle.min.js"></script> <script src="/bootstrap.bundle.min.js"></script>
<title>Nestabilnější body</title> <title>Body stabilní jak česká vláda</title>
</head> </head>
<% <%
@ -18,7 +19,7 @@ function hsl2rgb(h,s,l) {
} }
function getRandomHoverBg() { function getRandomHoverBg() {
let rgb = hsl2rgb(Math.random()*360,0.4,0.2) let rgb = hsl2rgb(Math.random()*360,0.4,0.4)
let hex = '#' let hex = '#'
for (let i = 0; i < 3; i++) { for (let i = 0; i < 3; i++) {
let subcolorValue = rgb[i]; let subcolorValue = rgb[i];
@ -32,7 +33,7 @@ function getRandomHoverBg() {
<body data-bs-theme="dark"> <body data-bs-theme="dark">
<div class="w-100 text-center p-5"> <div class="w-100 text-center p-5">
<h1>Nestabilnější body</h1> <h1>Body stabilní jak česká vláda</h1>
</div> </div>
<div class="container-fluid"> <div class="container-fluid">
<div class="row p-5"> <div class="row p-5">

View File

@ -5,6 +5,7 @@
<meta charset="UTF-8" /> <meta charset="UTF-8" />
<meta name="viewport" content="width=device-width" /> <meta name="viewport" content="width=device-width" />
<link rel="stylesheet" href="/bootstrap.min.css" /> <link rel="stylesheet" href="/bootstrap.min.css" />
<link rel="stylesheet" href="/styles.css" />
<script src="/bootstrap.bundle.min.js"></script> <script src="/bootstrap.bundle.min.js"></script>
<script src="/chart.js"></script> <script src="/chart.js"></script>
<title>Person <%= person.name %></title> <title>Person <%= person.name %></title>

1
www/confetti.min.js vendored Normal file
View File

@ -0,0 +1 @@
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e=e||self).ConfettiGenerator=t()}(this,function(){"use strict";return function(e){var a={target:"confetti-holder",max:80,size:1,animate:!0,respawn:!0,props:["circle","square","triangle","line"],colors:[[165,104,246],[230,61,135],[0,199,228],[253,214,126]],clock:25,interval:null,rotate:!1,start_from_edge:!1,width:window.innerWidth-10,height:window.innerHeight};if(e&&(e.target&&(a.target=e.target),e.max&&(a.max=e.max),e.size&&(a.size=e.size),null!=e.animate&&(a.animate=e.animate),null!=e.respawn&&(a.respawn=e.respawn),e.props&&(a.props=e.props),e.colors&&(a.colors=e.colors),e.clock&&(a.clock=e.clock),null!=e.start_from_edge&&(a.start_from_edge=e.start_from_edge),e.width&&(a.width=e.width),e.height&&(a.height=e.height),null!=e.rotate&&(a.rotate=e.rotate)),"object"!=typeof a.target&&"string"!=typeof a.target)throw new TypeError("The target parameter should be a node or string");if("object"==typeof a.target&&(null===a.target||!a.target instanceof HTMLCanvasElement)||"string"==typeof a.target&&(null===document.getElementById(a.target)||!document.getElementById(a.target)instanceof HTMLCanvasElement))throw new ReferenceError("The target element does not exist or is not a canvas element");var t="object"==typeof a.target?a.target:document.getElementById(a.target),o=t.getContext("2d"),r=[];function n(e,t){e=e||1;var r=Math.random()*e;return t?Math.floor(r):r}var i=a.props.reduce(function(e,t){return e+(t.weight||1)},0);function s(){var e=a.props[function(){for(var e=Math.random()*i,t=0;t<a.props.length;++t){var r=a.props[t].weight||1;if(e<r)return t;e-=r}}()];return{prop:e.type?e.type:e,x:n(a.width),y:a.start_from_edge?a.clock<0?parseFloat(a.height)+10:-10:n(a.height),src:e.src,radius:n(4)+1,size:e.size,rotate:a.rotate,line:Math.floor(n(65)-30),angles:[n(10,!0)+2,n(10,!0)+2,n(10,!0)+2,n(10,!0)+2],color:a.colors[n(a.colors.length,!0)],rotation:n(360,!0)*Math.PI/180,speed:n(a.clock/7)+a.clock/30}}function l(e){if(e)switch(o.fillStyle=o.strokeStyle="rgba("+e.color+", "+(3<e.radius?.8:.4)+")",o.beginPath(),e.prop){case"circle":o.moveTo(e.x,e.y),o.arc(e.x,e.y,e.radius*a.size,0,2*Math.PI,!0),o.fill();break;case"triangle":o.moveTo(e.x,e.y),o.lineTo(e.x+e.angles[0]*a.size,e.y+e.angles[1]*a.size),o.lineTo(e.x+e.angles[2]*a.size,e.y+e.angles[3]*a.size),o.closePath(),o.fill();break;case"line":o.moveTo(e.x,e.y),o.lineTo(e.x+e.line*a.size,e.y+5*e.radius),o.lineWidth=2*a.size,o.stroke();break;case"square":o.save(),o.translate(e.x+15,e.y+5),o.rotate(e.rotation),o.fillRect(-15*a.size,-5*a.size,15*a.size,5*a.size),o.restore();break;case"svg":o.save();var t=new window.Image;t.src=e.src;var r=e.size||15;o.translate(e.x+r/2,e.y+r/2),e.rotate&&o.rotate(e.rotation),o.drawImage(t,-r/2*a.size,-r/2*a.size,r*a.size,r*a.size),o.restore()}}function c(){a.animate=!1,clearInterval(a.interval),requestAnimationFrame(function(){o.clearRect(0,0,t.width,t.height);var e=t.width;t.width=1,t.width=e})}return{render:function(){t.width=a.width,t.height=a.height,r=[];for(var e=0;e<a.max;e++)r.push(s());return requestAnimationFrame(function e(){for(var t in o.clearRect(0,0,a.width,a.height),r)l(r[t]);!function(){for(var e=0;e<a.max;e++){var t=r[e];t&&(a.animate&&(t.y+=t.speed),t.rotate&&(t.rotation+=t.speed/35),(0<=t.speed&&a.height<t.y||t.speed<0&&t.y<0)&&(a.respawn?(r[e]=t,r[e].x=n(a.width,!0),r[e].y=t.speed<0?parseFloat(a.height):-10):r[e]=void 0))}r.every(function(e){return void 0===e})&&c()}(),a.animate&&requestAnimationFrame(e)})},clear:c}}});

21
www/styles.css Normal file
View File

@ -0,0 +1,21 @@
body {
/*background: linear-gradient(-45deg, #ee7752, #e73c7e, #23a6d5, #23d5ab);*/
background: linear-gradient(-37deg, #66241a, #520820, #073645, #075239);
background-size: 400% 400%;
animation: gradient 20s ease infinite;
height: 100vh;
}
@keyframes gradient {
0% {
background-position: 0% 50%;
}
50% {
background-position: 100% 50%;
}
100% {
background-position: 0% 50%;
}
}