Added search bar.
This commit is contained in:
parent
ab43e0ed74
commit
11e1f4593a
6 changed files with 300 additions and 4 deletions
|
@ -14,7 +14,7 @@
|
||||||
export let profile = 'https://i.pravatar.cc/300';
|
export let profile = 'https://i.pravatar.cc/300';
|
||||||
|
|
||||||
let post_div;
|
let post_div;
|
||||||
let title_h1;
|
let title_h1;
|
||||||
let cursorX = 0;
|
let cursorX = 0;
|
||||||
let cursorY = 0;
|
let cursorY = 0;
|
||||||
let updateX = true;
|
let updateX = true;
|
||||||
|
@ -26,12 +26,12 @@
|
||||||
}
|
}
|
||||||
cursorY = event.clientY - rect.top;
|
cursorY = event.clientY - rect.top;
|
||||||
post_div.style.backgroundImage = `radial-gradient(circle farthest-corner at ${Math.floor(cursorX)}px ${Math.floor(cursorY)}px, var(--color-background) 0%, #958a98 100%)`;
|
post_div.style.backgroundImage = `radial-gradient(circle farthest-corner at ${Math.floor(cursorX)}px ${Math.floor(cursorY)}px, var(--color-background) 0%, #958a98 100%)`;
|
||||||
}
|
}
|
||||||
|
|
||||||
function animateForeground(isEntering) {
|
function animateForeground(isEntering) {
|
||||||
const targetOpacity = isEntering ? 1 : 0;
|
const targetOpacity = isEntering ? 1 : 0;
|
||||||
title_h1.style.textDecoration = isEntering ? "underline 3px" : "";
|
title_h1.style.textDecoration = isEntering ? 'underline 3px' : '';
|
||||||
animation = anime({
|
anime({
|
||||||
targets: post_div,
|
targets: post_div,
|
||||||
opacity: [1 - targetOpacity, targetOpacity],
|
opacity: [1 - targetOpacity, targetOpacity],
|
||||||
duration: 400,
|
duration: 400,
|
||||||
|
|
107
frontend/src/lib/components/search.svelte
Normal file
107
frontend/src/lib/components/search.svelte
Normal file
|
@ -0,0 +1,107 @@
|
||||||
|
<script>
|
||||||
|
import '$lib/css/base.css';
|
||||||
|
import '$lib/css/search.css';
|
||||||
|
|
||||||
|
import SvgIcon from '$lib/components/svg-icon-custom.svelte';
|
||||||
|
import { mdiContentSavePlusOutline, mdiMagnify } from '@mdi/js';
|
||||||
|
import anime from 'animejs';
|
||||||
|
|
||||||
|
let div_search;
|
||||||
|
let input_search;
|
||||||
|
let svgIcon;
|
||||||
|
let search_box;
|
||||||
|
let selected = false;
|
||||||
|
|
||||||
|
function animate() {
|
||||||
|
// Animating the Svg Icon
|
||||||
|
if (selected) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
selected = true;
|
||||||
|
animateButton(true);
|
||||||
|
showSearch(true);
|
||||||
|
|
||||||
|
// Animating the div
|
||||||
|
const max = div_search.getBoundingClientRect().right - div_search.getBoundingClientRect().left;
|
||||||
|
anime({
|
||||||
|
targets: { position_var: 0 },
|
||||||
|
position_var: [0, max],
|
||||||
|
easing: 'linear',
|
||||||
|
duration: 300,
|
||||||
|
update: function (anim) {
|
||||||
|
div_search.style.background = `radial-gradient(circle farthest-corner at ${anim.animations[0].currentValue}px 0px, #958a98 0%, var(--color-background) 100%)`;
|
||||||
|
},
|
||||||
|
complete: function () {
|
||||||
|
anime({
|
||||||
|
targets: { percent_var: 0, opacity_var: 1 },
|
||||||
|
percent_var: [0, 100],
|
||||||
|
opacity_var: [1, 0],
|
||||||
|
easing: 'easeOutQuad',
|
||||||
|
duration: 400,
|
||||||
|
update: function (anim) {
|
||||||
|
div_search.style.background = `radial-gradient(circle farthest-corner at 0px 0px, var(--color-background) ${anim.animations[0].currentValue}%, rgba(149,138,152,${anim.animations[1].currentValue}) 100%)`;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function closeSearch(event) {
|
||||||
|
if (selected && event.target != input_search && event.target != svgIcon.svgElement) {
|
||||||
|
animateButton(false);
|
||||||
|
showSearch(false);
|
||||||
|
selected = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function animateButton(isEntering) {
|
||||||
|
const tvalue = isEntering ? [0, -0.8] : [-0.8, 0];
|
||||||
|
const svalue = isEntering ? [1, 1.2] : [1.2, 1];
|
||||||
|
anime({
|
||||||
|
targets: { transform: 0, scale: 1 },
|
||||||
|
transform: tvalue,
|
||||||
|
scale: svalue,
|
||||||
|
duration: 300,
|
||||||
|
easing: 'easeOutQuad',
|
||||||
|
update: function (anim) {
|
||||||
|
svgIcon.svgElement.style.transform = `scale(${anim.animations[1].currentValue}) translateX(${anim.animations[0].currentValue}rem)`;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function showSearch(isEntering) {
|
||||||
|
//transform: ;
|
||||||
|
if (isEntering) {
|
||||||
|
search_box.style.display = 'block';
|
||||||
|
}
|
||||||
|
|
||||||
|
const ovalue = isEntering ? [0, 1] : [1, 0];
|
||||||
|
anime({
|
||||||
|
targets: { opacity: 0 },
|
||||||
|
opacity: ovalue,
|
||||||
|
duration: 200,
|
||||||
|
easing: 'easeInOutQuad',
|
||||||
|
update: function (anim) {
|
||||||
|
search_box.style.opacity = `${anim.animations[0].currentValue}`;
|
||||||
|
search_box.style.transform = `translateX(-1rem) translateY(${anim.animations[0].currentValue}rem)`;
|
||||||
|
},
|
||||||
|
complete: function () {
|
||||||
|
if (!isEntering) {
|
||||||
|
search_box.style.display = 'none';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<svelte:window on:click={closeSearch} />
|
||||||
|
|
||||||
|
<!-- svelte-ignore a11y-click-events-have-key-events -->
|
||||||
|
<!-- svelte-ignore a11y-no-static-element-interactions -->
|
||||||
|
<div style="width:50%;">
|
||||||
|
<div class="search" on:click={animate} bind:this={div_search}>
|
||||||
|
<SvgIcon type="mdi" path={mdiMagnify} size="20" bind:this={svgIcon}></SvgIcon>
|
||||||
|
<input type="text" placeholder="Rechercher..." bind:this={input_search} />
|
||||||
|
</div>
|
||||||
|
<div class="search-box" bind:this={search_box}></div>
|
||||||
|
</div>
|
56
frontend/src/lib/components/svg-icon-custom.svelte
Normal file
56
frontend/src/lib/components/svg-icon-custom.svelte
Normal file
|
@ -0,0 +1,56 @@
|
||||||
|
<svelte:options accessors={true} />
|
||||||
|
|
||||||
|
<script>
|
||||||
|
const types = {
|
||||||
|
mdi: {
|
||||||
|
size: 24,
|
||||||
|
viewbox: '0 0 24 24'
|
||||||
|
},
|
||||||
|
'simple-icons': {
|
||||||
|
size: 24,
|
||||||
|
viewbox: '0 0 24 24'
|
||||||
|
},
|
||||||
|
default: {
|
||||||
|
size: 0,
|
||||||
|
viewbox: '0 0 0 0'
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export let type = null;
|
||||||
|
export let path;
|
||||||
|
export let size = null;
|
||||||
|
export let viewbox = null;
|
||||||
|
export let flip = 'none';
|
||||||
|
export let rotate = 0;
|
||||||
|
|
||||||
|
// Reactive statements to set default values based on type
|
||||||
|
$: defaults = types[type] || types.default;
|
||||||
|
$: sizeValue = size || defaults.size;
|
||||||
|
$: viewboxValue = viewbox || defaults.viewbox;
|
||||||
|
$: sx = ['both', 'horizontal'].includes(flip) ? '-1' : '1';
|
||||||
|
$: sy = ['both', 'vertical'].includes(flip) ? '-1' : '1';
|
||||||
|
$: r = isNaN(rotate) ? rotate : rotate + 'deg';
|
||||||
|
|
||||||
|
export let svgElement; // To expose the reference
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<svg
|
||||||
|
bind:this={svgElement}
|
||||||
|
width={sizeValue}
|
||||||
|
height={sizeValue}
|
||||||
|
viewBox={viewboxValue}
|
||||||
|
style="--sx: {sx}; --sy: {sy}; --r: {r}"
|
||||||
|
{...$$restProps}
|
||||||
|
>
|
||||||
|
<path d={path} />
|
||||||
|
</svg>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
svg {
|
||||||
|
transform: rotate(var(--r, 0deg)) scale(var(--sx, 1), var(--sy, 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
path {
|
||||||
|
fill: currentColor;
|
||||||
|
}
|
||||||
|
</style>
|
49
frontend/src/lib/css/search.css
Normal file
49
frontend/src/lib/css/search.css
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
.search {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
box-shadow: rgba(79, 50, 93, 0.25) 0px 30px 60px -12px, rgba(0, 0, 0, 0.3) 0px 18px 36px -18px;
|
||||||
|
border-radius: 5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search input {
|
||||||
|
padding: 1rem;
|
||||||
|
background-color: var(--color-background);
|
||||||
|
font-family: 'JetBrains Mono';
|
||||||
|
font-size: 1.2rem;
|
||||||
|
background-color: #00000000;
|
||||||
|
color: var(--color-subtext);
|
||||||
|
border: 0;
|
||||||
|
width: 100%;
|
||||||
|
border-top-right-radius: 5rem;
|
||||||
|
border-bottom-right-radius: 5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search input:focus {
|
||||||
|
border: 0;
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search svg {
|
||||||
|
width: 3rem;
|
||||||
|
height: auto;
|
||||||
|
padding: 1rem;
|
||||||
|
color: var(--color-background);
|
||||||
|
background-color: var(--color-text);
|
||||||
|
border-radius: 3rem;
|
||||||
|
box-shadow: #4f325d40 15px 0px 60px -12px, #0000004d 15px 0px 36px -18px;
|
||||||
|
background: radial-gradient(circle farthest-corner at 0px 0px, var(--color-subtext) 0%, var(--color-text) 80%);
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-box {
|
||||||
|
width: inherit;
|
||||||
|
height: 16rem;
|
||||||
|
background-color: var(--color-background);
|
||||||
|
box-shadow: rgba(79, 50, 93, 0.25) 0px 30px 60px -12px, rgba(0, 0, 0, 0.3) 0px 18px 36px -18px;
|
||||||
|
border-radius: 1rem;
|
||||||
|
position: absolute;
|
||||||
|
z-index: 1;
|
||||||
|
transform: translateX(-1rem);
|
||||||
|
display: none;
|
||||||
|
opacity: 0;
|
||||||
|
}
|
50
frontend/src/lib/css/style.css
Normal file
50
frontend/src/lib/css/style.css
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
.base {
|
||||||
|
margin-left: 3rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.blank {
|
||||||
|
height: 10rem;
|
||||||
|
background-color: #00000000;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Menu */
|
||||||
|
|
||||||
|
.menu-border {
|
||||||
|
background-image: -webkit-gradient(linear, right bottom, left bottom, color-stop(0, rgb(52, 42, 58)), color-stop(100, rgb(38, 28, 44)));
|
||||||
|
background-image: -webkit-linear-gradient(left, rgb(52, 42, 58) 0%, rgb(38, 28, 44) 100%);
|
||||||
|
background-image: -moz-linear-gradient(left, rgb(52, 42, 58) 0%, rgb(38, 28, 44) 100%);
|
||||||
|
background-image: -o-linear-gradient(left, rgb(52, 42, 58) 0%, rgb(38, 28, 44) 100%);
|
||||||
|
background-image: linear-gradient(to left, rgb(52, 42, 58) 0%, rgb(38, 28, 44) 100%);
|
||||||
|
padding: 0.8rem;
|
||||||
|
width: 40rem;
|
||||||
|
border-radius: 1rem;
|
||||||
|
box-shadow: rgba(52, 42, 58, 0.25) 0px 50px 100px -20px, rgba(0, 0, 0, 0.3) 0px 30px 60px -30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.menu {
|
||||||
|
border-radius: 0.8rem;
|
||||||
|
background-image: -webkit-gradient(linear, left bottom, right bottom, color-stop(0, rgb(52, 42, 58)), color-stop(100, rgb(38, 28, 44)));
|
||||||
|
background-image: -webkit-linear-gradient(right, rgb(52, 42, 58) 0%, rgb(38, 28, 44) 100%);
|
||||||
|
background-image: -moz-linear-gradient(right, rgb(52, 42, 58) 0%, rgb(38, 28, 44) 100%);
|
||||||
|
background-image: -o-linear-gradient(right, rgb(52, 42, 58) 0%, rgb(38, 28, 44) 100%);
|
||||||
|
background-image: linear-gradient(to right, rgb(52, 42, 58) 0%, rgb(38, 28, 44) 100%);
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
min-height: 10rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.menu p {
|
||||||
|
font-family: 'JetBrains Mono';
|
||||||
|
font-weight: 600;
|
||||||
|
margin: 0 !important;
|
||||||
|
font-size: 5rem;
|
||||||
|
color: var(--color-background);
|
||||||
|
filter: drop-shadow(0px 15px 25px rgba(0, 0, 0, 0.3)) drop-shadow(0px 5px 10px rgba(0, 0, 0, 0.1));
|
||||||
|
}
|
||||||
|
|
||||||
|
.menu svg {
|
||||||
|
margin-right: 3rem;
|
||||||
|
color: var(--color-background);
|
||||||
|
filter: drop-shadow(rgba(0, 0, 0, 0.3) 0px 15px 25px) drop-shadow(rgba(0, 0, 0, 0.1) 0px 5px 10px);
|
||||||
|
}
|
34
frontend/src/routes/style/+page.svelte
Normal file
34
frontend/src/routes/style/+page.svelte
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
<script>
|
||||||
|
import '$lib/css/base.css';
|
||||||
|
import '$lib/css/style.css';
|
||||||
|
import SvgIcon from '@jamescoyle/svelte-icon';
|
||||||
|
import { mdiAccount } from '@mdi/js';
|
||||||
|
|
||||||
|
import Post from '$lib/components/post-min.svelte';
|
||||||
|
import Search from '$lib/components/search.svelte';
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div class="base">
|
||||||
|
<br /><br />
|
||||||
|
<div class="menu-border">
|
||||||
|
<div class="menu flex-row">
|
||||||
|
<SvgIcon type="mdi" path={mdiAccount} size="120"></SvgIcon>
|
||||||
|
<p>Test</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="blank"></div>
|
||||||
|
<Post
|
||||||
|
cover="https://share.etheryo.fr/Rando-01.11.2023/Groupe%20Ombre%20Lac%20Montagne%20Rouge%20Bleu.jpg"
|
||||||
|
profile="https://avatars.githubusercontent.com/u/115081848?v=4"
|
||||||
|
title="Le lorem est-il 'Ipsum' ? C'est une question que je me pose souvent"
|
||||||
|
text="Petit texte explicatif sans vraiment de grande importance, hormis le fait que ce soit le meilleur texte de tous les temps, après je ne suis pas ouvert au débat mais on peut essayer... bref"
|
||||||
|
author="Yohan boujon"
|
||||||
|
date="26/07/2024"
|
||||||
|
/>
|
||||||
|
<div class="blank"></div>
|
||||||
|
<Post/>
|
||||||
|
<div class="blank"></div>
|
||||||
|
<Search/>
|
||||||
|
<div class="blank"></div>
|
||||||
|
<Post/>
|
||||||
|
</div>
|
Loading…
Add table
Reference in a new issue