Compare commits

18 Commits
Author SHA1 Message Date
vgaNAR6ta 9f7e957979 edit: icon player + modif noise fermé + panneau plus large en format tres grand écran 2026-07-07 16:05:56 +02:00
vgaNAR6ta 7c25390ead edit: audioData est mtn const reactive() et playlist editor fonctionne coté client 2026-07-07 01:23:27 +02:00
vgaNAR6ta 874226a140 tunnel: interface pour page admin sans backend + problème de gestion de la playlist (importé dans 2 script, l'un demande un focntion, l'autre une array et on est là hum...) 2026-07-06 22:32:41 +02:00
vgaNAR6ta eaba21e126 edit: style de l'indicateur d'ouverture 2026-07-06 04:21:38 +02:00
vgaNAR6ta 55bf14fc73 edit: recadrage video fond + blend mode event pour lisibilité 2026-07-06 00:33:14 +02:00
vgaNAR6ta 9b9ba2bbdd edit: animationn en mode ouvert un peu plus trql mais + saturé 2026-07-05 23:59:43 +02:00
vgaNAR6ta b7a7583ad0 edit: background animé réactif à l'ouverture 2026-07-05 23:50:23 +02:00
vgaNAR6ta 45b54193d6 edit: explication du panneau lien utiles 2026-07-05 23:49:28 +02:00
vgaNAR6ta ad870bd070 edit: interface pour le player et le panneau liens + fix z-index 2026-07-05 06:13:26 +02:00
vgaNAR6ta b1622d0008 edit: z-index menu sur tel 2026-07-04 20:05:42 +02:00
vgaNAR6ta 7682a79e13 edit: bug responsive n°35469874684654 voilà 2026-07-04 19:40:07 +02:00
vgaNAR6ta 4bdd4561a8 edit: interface évènement + modif typo texte (légèrement +gras) 2026-07-04 19:32:56 +02:00
vgaNAR6ta 80629f785a edit: bug responsive n°1312 plan qui passait sous interface + ajout des liens 2026-07-03 22:38:18 +02:00
vgaNAR6ta a5e64c49e5 edit: favicon change de couleur à l'ouverture ^^ 2026-07-03 18:38:03 +02:00
vgaNAR6ta 126d3f81b9 edit: bug responsive n°333 corrigé en fixant la taille des ligne de la grid display (dans #mainInfo) 2026-07-03 17:59:07 +02:00
vgaNAR6ta 4ab2e8d6f3 edit: read me à jour 2026-07-03 17:37:06 +02:00
vgaNAR6ta bcfc5b318f tunnel: {
création structure hors vue (et sans js sur pc) pour infos 
essentielles
     création de l'interactivité pour indiquer l'ouverture du lieu (sans 
'backend', automatisation et lien avec capteur à faire)
     liens inactifs pour l'instant
     infos pour remplir et prévisualiser à mettre à jour en fonction de 
ce qu'on décide ^^
          c'est tout pour cette fois
}
2026-07-03 17:27:45 +02:00
vgaNAR6ta 8bea3c547e init: empty vite + vue3 template 2026-07-01 14:09:16 +02:00
93 changed files with 5197 additions and 2759 deletions
+24 -1
View File
@@ -1 +1,24 @@
status/index.html
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*
node_modules
dist
dist-ssr
*.local
# Editor directories and files
.vscode/*
!.vscode/extensions.json
.idea
.DS_Store
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?
+3
View File
@@ -0,0 +1,3 @@
{
"recommendations": ["Vue.volar"]
}
+20
View File
@@ -0,0 +1,20 @@
yoooo
petite propositionn de refonte du site du LOL
(d'après qq idées perso et des remarques des utilisateurices)
POUR LE STATUT D'OUVERTURE DU LIEU IL FAUT :
> IMPORTER LE FICHIER ./src/lolStatus.js idéalement :
import { lolState } from './src/lolStatus.js'
> ÉDITER LE PARAMÈTRE (boolean) lolState.isOpen
=> true pour ouvert
> L'INTERFACE SE MET À JOUR AUTOMATIQUEMENT (déjà en place)
NB: les infos indiquées sont surtout là pour prévisualiser, mais ne sont pour l'instant pas plus que des envies personelles par rapport au lieu (rien d'officiel pour l'instant, juste des idées)
PS: BESOIN DE QQN POUR FAIRE LE BACKEND SVP <3 <3 <3
333
+26
View File
@@ -0,0 +1,26 @@
<template>
<eventEditor></eventEditor>
<linkEditor></linkEditor>
<playlistEditor></playlistEditor>
</template>
<style scoped>
</style>
<script>
export default {
name : 'Admin',
data() {
return {
}
},
computed: {
},
methods: {
},
mounted(){
console.log("Admin app is fully loaded!");
}
};
</script>
+359
View File
@@ -0,0 +1,359 @@
<template>
<Teleport to="#event .windowContent" defer>
<div class="sectionTitle" v-show="eventPannel">
<p>{{newEventText}} &emsp; &emsp;&emsp;&emsp;&emsp; &rarr; </p>
<button type="button" class="toggleBtn" ref="newEventBtn" @click="toggleNewEvent">
<svg class="icon" viewBox="0 0 53.73 53.59">
<path d="M26.87,40.16l-13.43,13.43L0,40.16l13.43-13.43L.29,13.43,13.72,0l13.15,13.29L40.01.14l13.43,13.43-13,13.15,13.29,13.29-13.43,13.43-13.43-13.29Z"/>
</svg>
</button>
</div>
<div class="editor" v-show="newEvent">
<div class="inputDiv" id="title">
<p>&emsp; Titre &emsp;&emsp;&emsp; &rarr;</p>
<input type="text" name="eventTitle" v-model="title">
</div>
<div class="inputDiv" id="date">
<p>&emsp; Date &emsp;&emsp;&emsp; &rarr;</p>
<input type="text" name="eventDate" v-model="date">
</div>
<div class="inputDiv" id="time">
<p>&emsp; Heure &emsp;&emsp;&ensp; &rarr;</p>
<input type="text" name="eventTime" v-model="time">
</div>
<div class="inputDiv" id="subtitle">
<p>&emsp; Sous-titre &emsp; &rarr;</p>
<input type="text" name="eventSub" v-model="sub">
</div>
<div class="inputDiv" id="desc">
<p> Description &emsp; &emsp;</p>
<textarea name="eventDesc" rows="8" cols="80" v-model="desc"></textarea>
</div>
<button type="button" name="saveChanges" class="textBtnStyle" @click="saveEvent" :class="{alert: eventAlertActive}">SAUVEGARDER !</button>
</div>
<div class="sectionTitle" v-show="eventPannel">
<p>Éditer les évènements &ensp; &emsp;&emsp;&emsp; &rarr; </p>
<button type="button" class="toggleBtn" ref="oldEventBtn" @click="toggleOldEvent">
<svg class="icon" viewBox="0 0 53.73 53.59">
<path d="M26.87,40.16l-13.43,13.43L0,40.16l13.43-13.43L.29,13.43,13.72,0l13.15,13.29L40.01.14l13.43,13.43-13,13.15,13.29,13.29-13.43,13.43-13.43-13.29Z"/>
</svg>
</button>
</div>
<div class="content" v-show="oldEvent">
<div class="eventEntry" v-for="item of displayedEvents" ref="item.title">
<p>{{item.title}}</p>
<div class="controls">
<button type="button" name="edit" class="toggleBtn" id="edit" @click='editEvent(item)'>
<svg class="icon" viewBox="0 0 40.19 38.9">
<path d="M8.61,30.26c-.64-.64-.96-1.41-.96-2.31s.32-1.63.96-2.26,1.41-.94,2.31-.94,1.67.31,2.31.94c.64.63.96,1.38.96,2.26s-.32,1.67-.96,2.31-1.41.96-2.31.96-1.67-.32-2.31-.96ZM17.78,30.26c-.64-.64-.96-1.41-.96-2.31s.32-1.63.96-2.26c.64-.63,1.41-.94,2.31-.94s1.67.31,2.31.94c.64.63.96,1.38.96,2.26s-.32,1.67-.96,2.31c-.64.64-1.41.96-2.31.96s-1.67-.32-2.31-.96ZM26.96,30.26c-.64-.64-.96-1.41-.96-2.31s.32-1.63.96-2.26c.64-.63,1.41-.94,2.31-.94s1.67.31,2.31.94c.64.63.96,1.38.96,2.26s-.32,1.67-.96,2.31-1.41.96-2.31.96-1.67-.32-2.31-.96Z"/>
<path d="M34.91,7.2l-1.92-1.92L27.71,0H0v38.9h40.19V12.48l-5.28-5.28ZM32.3,33.62H5.28V5.28h2.61s17.64,0,17.64,0v9.84h9.38v18.5h-2.61Z"/>
</svg>
</button>
<button type="button" name="remove" class="toggleBtn" id="remove" @click='removeEvent(item)'>
<svg class="icon" viewBox="0 0 53.73 53.59">
<path d="M26.87,40.16l-13.43,13.43L0,40.16l13.43-13.43L.29,13.43,13.72,0l13.15,13.29L40.01.14l13.43,13.43-13,13.15,13.29,13.29-13.43,13.43-13.43-13.29Z"/>
</svg>
</button>
</div>
</div>
</div>
</Teleport>
</template>
<style scoped>
#event .windowContent{
.sectionTitle{
width: 100%;
height: 44px;
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: center;
border-style: solid;
border-color: var(--main-color);
border-radius: 0;
border-width: 0 0 1.61px 0;
padding-right: 33px;
padding-left: 33px;
box-sizing: border-box;
p{
font-family: 'velvelyne';
font-weight: bold;
font-size: 16.1px;
color: var(--main-color);
margin: 0;
}
}
.editor{
width: 100%;
height: 100%;
position: relative;
display: flex;
flex-direction: column;
align-items: center;
justify-content: flex-start;
gap: 13.12px;
overflow-y: scroll;
padding-top: 7.77px;
padding-right: 7.77px;
border-style: solid;
border-color: var(--main-color);
border-radius: 0;
border-width: 0 0 1.61px 0;
box-sizing: border-box;
.textBtnStyle{
margin-bottom: 16.1px;
margin-right: 16.1px;
min-height: 33px;
}
.textBtnStyle.alert{
color: var(--back-color);
background-color: var(--main-color);
}
.inputDiv{
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: center;
color: var(--main-color);
width: 95%;
margin: 0;
padding: 0;
height: 44px;
input{
width: 60%;
background-color: var(--back-color);
height: 33px;
padding-left: 16.1px;
border-style: solid;
border-color: var(--main-color);
border-radius: 22px;
border-width: thin;
}
p{
font-family: 'velvelyne';
font-weight: normal;
font-size: 16.1px;
color: var(--main-color);
margin: 0;
}
}
#desc.inputDiv{
flex-direction: column;
align-items: flex-end;
height: 161px;
margin-bottom: 7.77px;
textarea{
width: 92%;
align-self: center;
background-color: var(--back-color);
height: 77px;
padding-left: 16.1px;
padding-right: 16.1px;
padding-top: 7.77px;
border-style: solid;
border-color: var(--main-color);
border-radius: 22px;
border-width: thin;
resize: none;
overflow-y: scroll;
}
}
}
.content{
width: 100%;
height: 100%;
position: relative;
background-color: var(--main-color);
overflow-y: scroll;
.eventEntry{
width: 100%;
height: 44px;
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: center;
box-sizing: border-box;
border-style: solid;
border-color: var(--back-color);
border-radius: 0;
border-width: 0 0 1.61px 0;
padding-left: 16.1px;
padding-right: 16.1px;
p{
font-family: 'velvelyne';
font-weight: bold;
font-size: 16.1px;
color: var(--back-color);
margin: 0;
}
.controls{
width: auto;
display: flex;
flex-direction: row;
justify-content: flex-start;
align-items: center;
gap: 7.77px;
.toggleBtn{
transform: rotate(0);
cursor: cell;
}
}
}
}
}
</style>
<script>
import { lolLinkList } from '/src/lolLinks.js'
import { lolEventsList } from '/src/lolEvents.js'
import { loadAudioData } from '/src/data/audioData.js'
import { pannelStatusList } from '../pannelStatus.js'
import { watch } from 'vue'
export default {
name : 'EventEditor',
data() {
return {
newEventText: 'Nouvel Évènement',
eventAlertActive: false,
hideTimer: null,
submitEventText: 'SAUVEGARDER',
newEvent: false,
oldEvent: false,
title: '',
date: '',
time: '',
sub: '',
desc: '',
eventDefault: {
title: 'Exemple de Titre',
date: '13/12/26',
time: '13h12',
sub: 'exemple de sous-titre',
desc: 'exemple de description \nsur plusieurs lignes'
},
editingEvent: null
}
},
computed: {
displayedEvents(){
return lolEventsList
},
eventPannel(){
return pannelStatusList.event;
}
},
methods: {
toggleNewEvent(){
this.newEvent = !this.newEvent;
if (this.newEvent){
this.oldEvent = false;
if(!this.editingEvent){
this.backToDefaultEvent();
}
}
this.$refs.newEventBtn.style.transform = this.newEvent ? 'rotate(0)' : 'rotate(45deg)';
this.$refs.oldEventBtn.style.transform = this.oldEvent ? 'rotate(0)' : 'rotate(45deg)';
},
toggleOldEvent(){
this.oldEvent = !this.oldEvent;
if (this.oldEvent){
this.newEvent = false;
}
this.$refs.newEventBtn.style.transform = this.newEvent ? 'rotate(0)' : 'rotate(45deg)';
this.$refs.oldEventBtn.style.transform = this.oldEvent ? 'rotate(0)' : 'rotate(45deg)';
},
backToDefaultEvent(){
this.title = this.eventDefault.title;
this.date = this.eventDefault.date;
this.time = this.eventDefault.time;
this.sub = this.eventDefault.sub;
this.desc = this.eventDefault.desc;
this.editingEvent = null;
this.newEventText = 'Nouvel Évènement';
},
createListEntry(){
let entry = {
title: this.title,
date: this.date,
time: this.time,
subtitle: this.sub,
desc: this.desc
}
return entry
},
saveEvent(){
let entry = this.createListEntry();
if(this.editingEvent){
Object.assign(this.editingEvent, {
title: this.title,
date: this.date,
time: this.time,
subtitle: this.sub,
desc: this.desc
})
} else {
this.displayedEvents.push(entry);
}
this.toggleOldEvent();
this.backToDefaultEvent();
},
removeEvent(obj){
let index = this.displayedEvents.indexOf(obj);
this.displayedEvents.splice(index, 1);
},
editEvent(obj){
console.log('selected :', obj)
this.editingEvent = obj;
this.title = obj.title;
this.date = obj.date;
this.time = obj.time;
this.sub = obj.subtitle;
this.desc = obj.desc;
this.newEventText = 'Éditer l\'évènement'
this.toggleNewEvent();
},
async eventSaveMsg(){
this.eventAlertActive = true;
this.submitEventText = "Enregistré !";
clearTimeout(this.hideTimer)
this.hideTimer = setTimeout(() => {
this.eventAlertActive = false;
this.submitEventText = 'SAUVEGARDER';
}, 1610)
}
},
mounted(){
watch( () => this.eventPannel, () => {
if(!this.eventPannel){
this.oldEvent = false;
this.newEvent = false;
}
})
console.log("Event editor is fully loaded!");
}
};
</script>
+363
View File
@@ -0,0 +1,363 @@
<template>
<Teleport to="#link .windowContent" defer>
<div class="sectionTitle" v-show="linkPannel">
<p>{{newLinkText}} &emsp; &emsp;&emsp; &ensp; &rarr; </p>
<button type="button" class="toggleBtn" ref="newLinkBtn" @click="toggleNewLink">
<svg class="icon" viewBox="0 0 53.73 53.59">
<path d="M26.87,40.16l-13.43,13.43L0,40.16l13.43-13.43L.29,13.43,13.72,0l13.15,13.29L40.01.14l13.43,13.43-13,13.15,13.29,13.29-13.43,13.43-13.43-13.29Z"/>
</svg>
</button>
</div>
<div class="editor" v-show="newLink">
<div class="inputDiv" id="title">
<p>&emsp; Titre &emsp;&emsp;&emsp; &rarr;</p>
<input type="text" name="linkTitle" v-model="title">
</div>
<div class="inputDiv" id="desc">
<p> Description &emsp; &emsp;</p>
<textarea name="linkDesc" rows="8" cols="80" v-model="desc"></textarea>
</div>
<div class="inputDiv" id="href">
<p> Lien &emsp; &emsp;</p>
<textarea name="linkDesc" rows="8" cols="80" v-model="href"></textarea>
</div>
<button type="button" name="saveChanges" class="textBtnStyle" @click="saveLink" :class="{alert: linkAlertActive}">SAUVEGARDER !</button>
</div>
<div class="sectionTitle" v-show="linkPannel">
<p>Éditer les liens &emsp; &emsp; &emsp; &rarr; </p>
<button type="button" class="toggleBtn" ref="oldLinkBtn" @click="toggleOldLink">
<svg class="icon" viewBox="0 0 53.73 53.59">
<path d="M26.87,40.16l-13.43,13.43L0,40.16l13.43-13.43L.29,13.43,13.72,0l13.15,13.29L40.01.14l13.43,13.43-13,13.15,13.29,13.29-13.43,13.43-13.43-13.29Z"/>
</svg>
</button>
</div>
<div class="content" v-show="oldLink">
<div class="linkEntry" v-for="item of displayedLinks" ref="item.title">
<p>{{item.title}}</p>
<div class="controls">
<button type="button" name="edit" class="toggleBtn" id="edit" @click='editLink(item)'>
<svg class="icon" viewBox="0 0 40.19 38.9">
<path d="M8.61,30.26c-.64-.64-.96-1.41-.96-2.31s.32-1.63.96-2.26,1.41-.94,2.31-.94,1.67.31,2.31.94c.64.63.96,1.38.96,2.26s-.32,1.67-.96,2.31-1.41.96-2.31.96-1.67-.32-2.31-.96ZM17.78,30.26c-.64-.64-.96-1.41-.96-2.31s.32-1.63.96-2.26c.64-.63,1.41-.94,2.31-.94s1.67.31,2.31.94c.64.63.96,1.38.96,2.26s-.32,1.67-.96,2.31c-.64.64-1.41.96-2.31.96s-1.67-.32-2.31-.96ZM26.96,30.26c-.64-.64-.96-1.41-.96-2.31s.32-1.63.96-2.26c.64-.63,1.41-.94,2.31-.94s1.67.31,2.31.94c.64.63.96,1.38.96,2.26s-.32,1.67-.96,2.31-1.41.96-2.31.96-1.67-.32-2.31-.96Z"/>
<path d="M34.91,7.2l-1.92-1.92L27.71,0H0v38.9h40.19V12.48l-5.28-5.28ZM32.3,33.62H5.28V5.28h2.61s17.64,0,17.64,0v9.84h9.38v18.5h-2.61Z"/>
</svg>
</button>
<button type="button" name="remove" class="toggleBtn" id="remove" @click='removeLink(item)'>
<svg class="icon" viewBox="0 0 53.73 53.59">
<path d="M26.87,40.16l-13.43,13.43L0,40.16l13.43-13.43L.29,13.43,13.72,0l13.15,13.29L40.01.14l13.43,13.43-13,13.15,13.29,13.29-13.43,13.43-13.43-13.29Z"/>
</svg>
</button>
</div>
</div>
</div>
</Teleport>
</template>
<style scoped>
#link .windowContent{
.sectionTitle{
width: 100%;
height: 44px;
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: center;
border-style: solid;
border-color: var(--main-color);
border-radius: 0;
border-width: 0 0 1.61px 0;
padding-right: 33px;
padding-left: 33px;
box-sizing: border-box;
p{
font-family: 'velvelyne';
font-weight: bold;
font-size: 16.1px;
color: var(--main-color);
margin: 0;
}
}
.editor{
width: 100%;
height: 100%;
position: relative;
display: flex;
flex-direction: column;
align-items: center;
justify-content: flex-start;
gap: 13.12px;
overflow-y: scroll;
padding-top: 7.77px;
padding-right: 7.77px;
border-style: solid;
border-color: var(--main-color);
border-radius: 0;
border-width: 0 0 1.61px 0;
box-sizing: border-box;
.textBtnStyle{
margin-bottom: 16.1px;
margin-right: 16.1px;
min-height: 33px;
}
.textBtnStyle.alert{
color: var(--back-color);
background-color: var(--main-color);
}
.inputDiv{
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: center;
color: var(--main-color);
width: 95%;
margin: 0;
padding: 0;
height: 44px;
input{
width: 60%;
background-color: var(--back-color);
height: 33px;
padding-left: 16.1px;
border-style: solid;
border-color: var(--main-color);
border-radius: 22px;
border-width: thin;
}
p{
font-family: 'velvelyne';
font-weight: normal;
font-size: 16.1px;
color: var(--main-color);
margin: 0;
}
}
#desc.inputDiv{
flex-direction: column;
align-items: flex-end;
height: 161px;
margin-bottom: 7.77px;
textarea{
width: 92%;
align-self: center;
background-color: var(--back-color);
height: 77px;
padding-left: 16.1px;
padding-right: 16.1px;
padding-top: 7.77px;
border-style: solid;
border-color: var(--main-color);
border-radius: 22px;
border-width: thin;
resize: none;
overflow-y: scroll;
}
}
#href.inputDiv{
flex-direction: column;
align-items: flex-end;
height: 161px;
margin-bottom: 7.77px;
textarea{
width: 92%;
align-self: center;
background-color: var(--back-color);
height: 77px;
padding-left: 16.1px;
padding-right: 16.1px;
padding-top: 7.77px;
border-style: solid;
border-color: var(--main-color);
border-radius: 22px;
border-width: thin;
resize: none;
overflow-y: scroll;
}
}
}
.content{
width: 100%;
height: 100%;
position: relative;
background-color: var(--main-color);
overflow-y: scroll;
.linkEntry{
width: 100%;
height: 44px;
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: center;
box-sizing: border-box;
border-style: solid;
border-color: var(--back-color);
border-radius: 0;
border-width: 0 0 1.61px 0;
padding-left: 16.1px;
padding-right: 16.1px;
p{
font-family: 'velvelyne';
font-weight: bold;
font-size: 16.1px;
color: var(--back-color);
margin: 0;
}
.controls{
width: auto;
display: flex;
flex-direction: row;
justify-content: flex-start;
align-items: center;
gap: 7.77px;
.toggleBtn{
transform: rotate(0);
cursor: cell;
}
}
}
}
}
</style>
<script>
import { lolLinkList } from '/src/lolLinks.js'
import { pannelStatusList } from '../pannelStatus.js'
import { watch } from 'vue'
export default {
name : 'LinkEditor',
data() {
return {
newLinkText: 'Nouveau Lien',
linkAlertActive: false,
hideTimer: null,
submitLinkText: 'SAUVEGARDER',
newLink: false,
oldLink: false,
title: '',
href: '',
desc: '',
linkDefault: {
title: 'Exemple de Titre',
href: 'https://example.com/',
desc: 'exemple de description'
},
editingLink: null
}
},
computed: {
displayedLinks(){
return lolLinkList
},
linkPannel(){
return pannelStatusList.link;
}
},
methods: {
toggleNewLink(){
this.newLink = !this.newLink;
if (this.newLink){
this.oldLink = false;
if(!this.editingLink){
this.backToDefaultLink();
}
}
this.$refs.newLinkBtn.style.transform = this.newLink ? 'rotate(0)' : 'rotate(45deg)';
this.$refs.oldLinkBtn.style.transform = this.oldLink ? 'rotate(0)' : 'rotate(45deg)';
},
toggleOldLink(){
this.oldLink = !this.oldLink;
if (this.oldLink){
this.newLink = false;
}
this.$refs.newLinkBtn.style.transform = this.newLink ? 'rotate(0)' : 'rotate(45deg)';
this.$refs.oldLinkBtn.style.transform = this.oldLink ? 'rotate(0)' : 'rotate(45deg)';
},
backToDefaultLink(){
this.title = this.linkDefault.title;
this.href = this.linkDefault.href;
this.desc = this.linkDefault.desc;
this.editingLink = null;
this.newLinkText = 'Nouveau Lien';
},
createListEntry(){
let entry = {
title: this.title,
href: this.href,
desc: this.desc
}
return entry
},
saveLink(){
let entry = this.createListEntry();
if(this.editingLink){
Object.assign(this.editingLink, {
title: this.title,
href: this.href,
desc: this.desc
})
} else {
this.displayedLinks.push(entry);
}
this.toggleOldLink();
this.backToDefaultLink();
},
removeLink(obj){
let index = this.displayedLinks.indexOf(obj);
this.displayedLinks.splice(index, 1);
},
editLink(obj){
console.log('selected :', obj)
this.editingLink = obj;
this.title = obj.title;
this.href = obj.href
this.desc = obj.desc;
this.newLinkText = 'Éditer le lien'
this.toggleNewLink();
},
async linkSaveMsg(){
this.linkAlertActive = true;
this.submitLinkText = "Enregistré !";
clearTimeout(this.hideTimer)
this.hideTimer = setTimeout(() => {
this.eventAlertActive = false;
this.submitLinkText = 'SAUVEGARDER';
}, 1610)
}
},
mounted(){
watch( () => this.linkPannel, () => {
if(!this.linkPannel){
this.oldLink = false;
this.newLink = false;
}
})
console.log("Link editor is fully loaded!");
}
};
</script>
+367
View File
@@ -0,0 +1,367 @@
<template>
<Teleport to="#playlist .windowContent" defer>
<div class="sectionTitle" v-show="playlistPannel">
<p>{{newSongText}} &emsp; &emsp; &emsp; &emsp; &emsp; &rarr; </p>
<button type="button" class="toggleBtn" ref="newSongBtn" @click="toggleNewPlaylist">
<svg class="icon" viewBox="0 0 53.73 53.59">
<path d="M26.87,40.16l-13.43,13.43L0,40.16l13.43-13.43L.29,13.43,13.72,0l13.15,13.29L40.01.14l13.43,13.43-13,13.15,13.29,13.29-13.43,13.43-13.43-13.29Z"/>
</svg>
</button>
</div>
<div class="editor" v-show="newSong">
<div class="inputDiv" id="track">
<p>&emsp; Titre &emsp;&emsp; &emsp; &rarr;</p>
<input type="text" name="songTitle" v-model="track">
</div>
<div class="inputDiv" id="artist">
<p>&emsp; Artiste &emsp;&emsp;&ensp; &rarr;</p>
<input type="text" name="songArtist" v-model="artist">
</div>
<p v-show="editingSong" id="note">Note : Laisser vide pour conserver le fichier </p>
<div class="inputDiv" id="src">
<p>&emsp; Fichier MP3 &ensp; &rarr;</p>
<input type="file" name="songFile" ref="audioFile" @change="modifyFile">
</div>
<button type="button" name="saveChanges" class="textBtnStyle" @click="savePlaylist" :class="{alert: playlistAlertActive}">SAUVEGARDER !</button>
</div>
<div class="sectionTitle" v-show="playlistPannel">
<p>Modifier la playlist &ensp; &emsp;&emsp;&emsp; &rarr; </p>
<button type="button" class="toggleBtn" ref="currentPlaylistBtn" @click="toggleCurrentPlaylist">
<svg class="icon" viewBox="0 0 53.73 53.59">
<path d="M26.87,40.16l-13.43,13.43L0,40.16l13.43-13.43L.29,13.43,13.72,0l13.15,13.29L40.01.14l13.43,13.43-13,13.15,13.29,13.29-13.43,13.43-13.43-13.29Z"/>
</svg>
</button>
</div>
<div class="content" v-show="currentPlaylist">
<div class="playlistEntry" v-for="item of displayedPlaylists" ref="item.track">
<p>{{item.track}} {{item.artist}}</p>
<div class="controls">
<button type="button" name="edit" class="toggleBtn" id="edit" @click='editPlaylist(item)'>
<svg class="icon" viewBox="0 0 40.19 38.9">
<path d="M8.61,30.26c-.64-.64-.96-1.41-.96-2.31s.32-1.63.96-2.26,1.41-.94,2.31-.94,1.67.31,2.31.94c.64.63.96,1.38.96,2.26s-.32,1.67-.96,2.31-1.41.96-2.31.96-1.67-.32-2.31-.96ZM17.78,30.26c-.64-.64-.96-1.41-.96-2.31s.32-1.63.96-2.26c.64-.63,1.41-.94,2.31-.94s1.67.31,2.31.94c.64.63.96,1.38.96,2.26s-.32,1.67-.96,2.31c-.64.64-1.41.96-2.31.96s-1.67-.32-2.31-.96ZM26.96,30.26c-.64-.64-.96-1.41-.96-2.31s.32-1.63.96-2.26c.64-.63,1.41-.94,2.31-.94s1.67.31,2.31.94c.64.63.96,1.38.96,2.26s-.32,1.67-.96,2.31-1.41.96-2.31.96-1.67-.32-2.31-.96Z"/>
<path d="M34.91,7.2l-1.92-1.92L27.71,0H0v38.9h40.19V12.48l-5.28-5.28ZM32.3,33.62H5.28V5.28h2.61s17.64,0,17.64,0v9.84h9.38v18.5h-2.61Z"/>
</svg>
</button>
<button type="button" name="remove" class="toggleBtn" id="remove" @click='removePlaylist(item)'>
<svg class="icon" viewBox="0 0 53.73 53.59">
<path d="M26.87,40.16l-13.43,13.43L0,40.16l13.43-13.43L.29,13.43,13.72,0l13.15,13.29L40.01.14l13.43,13.43-13,13.15,13.29,13.29-13.43,13.43-13.43-13.29Z"/>
</svg>
</button>
</div>
</div>
</div>
</Teleport>
</template>
<style scoped>
#playlist .windowContent{
.sectionTitle{
width: 100%;
height: 44px;
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: center;
border-style: solid;
border-color: var(--main-color);
border-radius: 0;
border-width: 0 0 1.61px 0;
padding-right: 33px;
padding-left: 33px;
box-sizing: border-box;
p{
font-family: 'velvelyne';
font-weight: bold;
font-size: 16.1px;
color: var(--main-color);
margin: 0;
}
}
.editor{
width: 100%;
height: 100%;
position: relative;
display: flex;
flex-direction: column;
align-items: center;
justify-content: flex-start;
gap: 13.12px;
overflow-y: scroll;
padding-top: 7.77px;
padding-right: 7.77px;
border-style: solid;
border-color: var(--main-color);
border-radius: 0;
border-width: 0 0 1.61px 0;
box-sizing: border-box;
.textBtnStyle{
margin-bottom: 16.1px;
margin-right: 22px;
height: 33px;
}
.textBtnStyle.alert{
color: var(--back-color);
background-color: var(--main-color);
}
#note{
width: 66%;
font-family: 'velvelyne';
font-weight: normal;
font-size: 13.12px;
color: var(--main-color);
margin: 0;
text-align: right;
}
.inputDiv{
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: center;
color: var(--main-color);
width: 95%;
margin: 0;
padding: 0;
height: 44px;
input{
width: 60%;
background-color: var(--back-color);
height: 33px;
padding-left: 16.1px;
border-style: solid;
border-color: var(--main-color);
border-radius: 22px;
border-width: thin;
}
p{
font-family: 'velvelyne';
font-weight: normal;
font-size: 16.1px;
color: var(--main-color);
margin: 0;
}
}
#src.inputDiv{
input[type=file]::file-selector-button{
font-family: 'karrik';
font-size: 10px;
background-color: var(--back-color);
color: var(--main-color);
padding-left: 0;
margin: 0;
border-width: 0 1.61px 0 0;
height: 100%;
padding-left: 16.1px;
padding-right: 7.77px;
margin-left: -22px;
margin-right: 7.77px;
outline: none;
}
input[type=file]::file-selector-button:hover{
font-family: 'karrik';
font-size: 13.12px;
background-color: var(--main-color);
color: var(--back-color);
padding-left: 0;
margin: 0;
border-width: 0 1.61px 0 0;
height: 100%;
padding-left: 16.1px;
padding-right: 7.77px;
margin-left: -22px;
margin-right: 7.77px;
outline: none;
}
}
}
.content{
width: 100%;
height: 100%;
position: relative;
background-color: var(--main-color);
overflow-y: scroll;
.playlistEntry{
width: 100%;
height: 44px;
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: center;
box-sizing: border-box;
border-style: solid;
border-color: var(--back-color);
border-radius: 0;
border-width: 0 0 1.61px 0;
padding-left: 16.1px;
padding-right: 16.1px;
p{
font-family: 'velvelyne';
font-weight: bold;
font-size: 16.1px;
color: var(--back-color);
margin: 0;
}
.controls{
width: auto;
display: flex;
flex-direction: row;
justify-content: flex-start;
align-items: center;
gap: 7.77px;
.toggleBtn{
transform: rotate(0);
cursor: cell;
}
}
}
}
}
</style>
<script>
import { loadAudioData } from '/src/data/audioData.js'
import { watch } from 'vue'
import { pannelStatusList } from '../pannelStatus.js'
export default {
name : 'PlaylistEditor',
data() {
return {
newSongText: 'Nouveau Son',
playlistAlertActive: false,
hideTimer: null,
submitPlaylistText: 'SAUVEGARDER',
newSong: false,
currentPlaylist: false,
track: '',
artist: '',
src: null,
playlistDefault: {
track: 'exemple',
artist: 'exemple',
src: null
},
editingSong: null,
selectedInput: null
}
},
computed: {
displayedPlaylists(){
return loadAudioData
},
playlistPannel(){
return pannelStatusList.playlist;
}
},
methods: {
toggleNewPlaylist(){
this.newSong = !this.newSong;
if (this.newSong){
this.currentPlaylist = false;
if(!this.editingSong){
this.backToDefaultPlaylist();
}
}
this.$refs.newSongBtn.style.transform = this.newSong ? 'rotate(0)' : 'rotate(45deg)';
this.$refs.currentPlaylistBtn.style.transform = this.currentPlaylist ? 'rotate(0)' : 'rotate(45deg)';
},
toggleCurrentPlaylist(){
this.currentPlaylist = !this.currentPlaylist;
if (this.currentPlaylist){
this.newSong = false;
}
this.$refs.newSongBtn.style.transform = this.newSong ? 'rotate(0)' : 'rotate(45deg)';
this.$refs.currentPlaylistBtn.style.transform = this.currentPlaylist ? 'rotate(0)' : 'rotate(45deg)';
},
backToDefaultPlaylist(){
this.track = this.playlistDefault.track;
this.artist = this.playlistDefault.artist;
this.editingSong = null;
this.newSongText = 'Nouveau Son';
},
createListEntry(){
let entry = {
track: this.track,
artist: this.artist,
src: this.src
}
console.log('created or modified entry :', entry)
return entry
},
savePlaylist(){
let entry = this.createListEntry();
if(this.editingSong){
Object.assign(this.editingSong, {
track: this.track,
artist: this.artist,
src: this.src
})
} else {
this.displayedPlaylists.push(entry);
}
this.toggleCurrentPlaylist();
this.backToDefaultPlaylist();
},
removePlaylist(obj){
let index = this.displayedPlaylists.indexOf(obj);
this.displayedPlaylists.splice(index, 1);
},
editPlaylist(obj){
console.log('selected :', obj)
this.editingSong = obj;
this.track = obj.track;
this.artist = obj.artist;
this.src = obj.src;
this.newSongText = 'Éditer les infos'
this.toggleNewPlaylist();
},
async playlistSaveMsg(){
this.playlistAlertActive = true;
this.submitPlaylistText = "Enregistré !";
clearTimeout(this.hideTimer)
this.hideTimer = setTimeout(() => {
this.eventAlertActive = false;
this.submitPlaylistText = 'SAUVEGARDER';
}, 1610)
},
modifyFile(){
if (this.selectedInput.files[0]){
this.src = this.selectedInput.files[0];
}
}
},
mounted(){
this.selectedInput = this.$refs.audioFile;
console.log(this.selectedInput)
watch( () => this.playlistPannel, () => {
if(!this.playlistPannel){
this.newSong = false;
this.currentPlaylist = false;
}
})
console.log("Playlist editor is fully loaded!");
}
};
</script>

Before

Width:  |  Height:  |  Size: 2.3 KiB

After

Width:  |  Height:  |  Size: 2.3 KiB

+72
View File
@@ -0,0 +1,72 @@
<!DOCTYPE html>
<html lang="fr">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>LOL : admin</title>
<link rel="icon" type="image/svg" href="./favicon.svg" />
<link type="text/css" rel="stylesheet" href="./style/css">
</head>
<body>
<div id="adminWelcome">
<p>
<strong>Bienvenue sur la page admin du LOL !</strong><br>
Ici tu peux éditer le contenu visible sur le site, dans les sections évènements & liens utiles, et aussi ajouter de la musique dans le player.<br>
On précise quand même (au cas où), que <strong>les auteurices des sons qu'on poste doivent avoir donné leur accord explicite avant que ça soit posté !</strong>
</p>
</div>
<div id="adminContainer">
<div class="">
</div>
<div class="adminSection" id="event">
<div class="windowStyle">
<div class="windowTitle">
<p>
Évènements affichés :
</p>
<button type="button" class="toggleBtn" id="eventBtn">
<svg class="icon" viewBox="0 0 53.73 53.59">
<path d="M26.87,40.16l-13.43,13.43L0,40.16l13.43-13.43L.29,13.43,13.72,0l13.15,13.29L40.01.14l13.43,13.43-13,13.15,13.29,13.29-13.43,13.43-13.43-13.29Z"/>
</svg>
</button>
</div>
<div class="windowContent">
</div>
</div>
</div>
<div class="adminSection" id="other">
<div class="windowStyle" id="link">
<div class="windowTitle">
<p>
Panneau liens :
</p>
<button type="button" class="toggleBtn" id="linkBtn">
<svg class="icon" viewBox="0 0 53.73 53.59">
<path d="M26.87,40.16l-13.43,13.43L0,40.16l13.43-13.43L.29,13.43,13.72,0l13.15,13.29L40.01.14l13.43,13.43-13,13.15,13.29,13.29-13.43,13.43-13.43-13.29Z"/>
</svg>
</button>
</div>
<div class="windowContent">
</div>
</div>
<div class="windowStyle" id="playlist">
<div class="windowTitle">
<p>
Playlist :
</p>
<button type="button" class="toggleBtn" id="playlistBtn">
<svg class="icon" viewBox="0 0 53.73 53.59">
<path d="M26.87,40.16l-13.43,13.43L0,40.16l13.43-13.43L.29,13.43,13.72,0l13.15,13.29L40.01.14l13.43,13.43-13,13.15,13.29,13.29-13.43,13.43-13.43-13.29Z"/>
</svg>
</button>
</div>
<div class="windowContent">
</div>
</div>
</div>
</div>
<div id="adminContent"></div>
<script type="module" src="./main.js"></script>
</body>
</html>
+62
View File
@@ -0,0 +1,62 @@
import { createApp } from 'vue'
// import css
import './style.css'
// import app racine pour page admin
import Admin from './Admin.vue'
// import composants
import EventEditor from './components/EventEditor.vue'
import LinkEditor from './components/LinkEditor.vue'
import PlaylistEditor from './components/PlaylistEditor.vue'
// creation app
const app = createApp(Admin);
// Composants
app.component('eventEditor', EventEditor);
app.component('linkEditor', LinkEditor);
app.component('playlistEditor', PlaylistEditor)
// montage dans div#adminContent
app.mount('#adminContent');
//import variables reactive
import { pannelStatusList } from './pannelStatus.js'
document.documentElement.setAttribute('data-theme', 'main');
let eventBtn = document.querySelector('#eventBtn');
let eventTarget = document.querySelector('#event .windowContent');
let linkBtn = document.querySelector('#linkBtn');
let linkTarget = document.querySelector('#link .windowContent');
let playlistBtn = document.querySelector('#playlistBtn');
let playlistTarget = document.querySelector('#playlist .windowContent');
eventBtn.addEventListener('click', () => {
pannelStatusList.event = !pannelStatusList.event;
eventTarget.style.height = pannelStatusList.event ? '75vh' : 'auto';
document.querySelector('#eventBtn .icon').style.transform = pannelStatusList.event ? 'rotate(45deg)' : 'rotate(0)'
})
linkBtn.addEventListener('click', () => {
pannelStatusList.link = !pannelStatusList.link;
if(pannelStatusList.link){
pannelStatusList.playlist = false;
playlistTarget.style.height = 'auto';
document.querySelector('#playlistBtn .icon').style.transform = 'rotate(45deg)'
}
linkTarget.style.height = pannelStatusList.link ? '64.5vh' : '0';
document.querySelector('#linkBtn .icon').style.transform = pannelStatusList.link ? 'rotate(45deg)' : 'rotate(0)'
})
playlistBtn.addEventListener('click', () => {
pannelStatusList.playlist = !pannelStatusList.playlist;
if(pannelStatusList.playlist){
pannelStatusList.link = false
linkTarget.style.height = 'auto';
document.querySelector('#linkBtn .icon').style.transform = 'rotate(45deg)'
}
playlistTarget.style.height = pannelStatusList.playlist ? '64.5vh' : 'auto';
document.querySelector('#playlistBtn .icon').style.transform = pannelStatusList.playlist ? 'rotate(45deg)' : 'rotate(0)'
})
+7
View File
@@ -0,0 +1,7 @@
import { reactive } from 'vue'
export const pannelStatusList = reactive({
event: false,
link: false,
playlist: false
})
+248
View File
@@ -0,0 +1,248 @@
:root[data-theme="main"]{
--back-color: #FFFF4D;
--main-color: #000000;
}
/*====================Typo*/
@font-face {
font-family: 'karrik';
src: url('/typo/Karrik-Italic.woff2').format('woff2');
font-style: italic;
}
@font-face {
font-family: 'karrik';
src: url('/typo/Karrik-Regular.woff2') format('woff2');
font-style: normal;
}
@font-face {
font-family: 'velvelyne';
src: url('/typo/Velvelyne-Book.ttf') format('truetype');
font-weight: normal;
}
@font-face {
font-family: 'avara';
src: url('/typo/Avara-Black.woff2') format('woff2');
}
@font-face {
font-family: 'pressStart2P';
src: url('/typo/PressStart2P-Regular.ttf') format('truetype');
}
@font-face {
font-family: 'velvelyne';
src:url('/typo/Velvelyne-Bold.ttf') format('truetype');
font-weight: bold;
}
/*=============Désact défault*/
input {
-webkit-appearance: none !important;
appearance: none !important;
}
a{
text-decoration: none;
color: inherit;
cursor: alias;
}
button{
cursor: cell;
}
a p{
cursor:inherit;
}
a button{
cursor: inherit;
}
p{
cursor: inherit;
pointer-events: none !important;
}
.dg{
display: none !important;
height: 0;
overflow: hidden;
}
/*====================BODY & BACKGROUND*/
html, body{
margin: 0;
padding: 0;
background-color: var(--main-color);
width: 100%;
height:100%;
position: fixed;
inset: 0;
overflow-x: hidden;
overflow-y: scroll;
display: block;
scrollbar-color: var(--back-color) var(--main-color);
scrollbar-width: thin;
z-index: -33;
display: flex;
flex-direction: column;
}
/*=======================pseudo-Fenetres*/
.windowStyle{
display: flex;
flex-direction: column;
align-items: center;
justify-content: flex-start;
background-color: var(--back-color);
border-style: solid;
border-width: thin;
border-radius: 16.1px;
border-color: var(--main-color);
overflow: hidden;
height: auto;
width: 95%;
}
.windowTitle{
width:100%;
height:44px;
background-color: var(--main-color);
border-radius: 0;
font-family: 'karrik';
font-weight: normal;
text-transform: uppercase;
font-size: 16.1px;
color: var(--back-color);
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-between;
box-sizing: border-box;
padding-left: 10px;
padding-right: 10px;
cursor: move;
}
.windowTitleLower{
font-family: 'velvelyne';
font-weight: bold;
font-size: 13.12px;
}
.toggleBtn{
color: var(--back-color);
background-color: var(--main-color);
border-style: solid;
border-width: thin;
border-radius: 16.1px;
border-color: var(--back-color);
width: 27px;
height: 27px;
display: flex;
justify-content: space-around;
align-items: center;
transform: rotate(45deg);
cursor: copy;
padding: 0;
}
.toggleBtn:hover{
color: var(--main-color);
background-color: var(--back-color);
}
.windowContent{
height:77%;
width:100%;
display: flex;
flex-direction: column;
align-items: center;
justify-content: flex-start;
}
.icon{
fill: currentColor;
height: 13.12px;
width: auto;
pointer-events: none;
padding: 0;
margin: 0;
}
.textBtnStyle{
font-family: 'karrik';
font-size: 13.12px;
background-color: var(--back-color);
color: var(--main-color);
border-color: var(--main-color);
border-style: solid;
border-width: 1.75px;
border-radius: 16.1px;
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-around;
width: 161px;
height: 77px;
align-self: flex-end;
}
.textBtnStyle:hover{
background-color: var(--main-color);
color: var(--back-color);
font-weight: bold;
}
/*==================INTERFACE*/
#adminWelcome{
width: 100%;
height: 13.12vh;
padding: 13.12px;
padding-top: 7.77px;
margin: 0;
box-sizing: border-box;
p{
font-family: 'velvelyne';
font-weight: normal;
font-size: 13.12px;
color: var(--back-color);
margin: 0;
}
strong{
font-weight: bold;
}
}
#adminContainer{
width: 100%;
height: 90vh;
inset: 0;
overflow: hidden;
background-color: var(--back-color);
display: flex;
flex-direction: row;
justify-content: flex-start;
align-items: flex-start;
}
.adminSection{
width: 50%;
height: 100%;
display: flex;
flex-direction: column;
align-items: center;
justify-content: flex-start;
padding-top: 7.77px;
gap: 1vh;
}
Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.0 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.3 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.2 MiB

-136
View File
@@ -1,136 +0,0 @@
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Permanence du mardi soir</title>
<link rel="stylesheet" href="/style/typo.css">
<link rel="stylesheet" href="/style/default.css">
<style data-import="no-import">
html{
width: 100%;
height: 100%;
overflow: hidden;
top: 0;
left: 0;
background-color: var(--mardi-back-color);
}
body{
height: 100%;
max-width: 1000px;
background-color: var(--mardi-accent-color);
margin: 0;
}
</style>
<style>
:root{
--mardi-back-color: rgb(37, 1, 65);
--mardi-main-color: rgb(255, 74, 231);
--mardi-accent-color: rgb(0, 255, 21);
}
.afficheMardis{
display: flex;
flex-direction: column;
align-items: flex-start;
justify-content: flex-start;
background-color: var(--mardi-main-color);
@container( width > 650px ){
flex-direction: row;
}
}
#imgContainer{
display: flex;
flex-direction: row;
justify-content: flex-end;
align-items: flex-start;
width: 100%;
max-height: 33vh;
box-sizing: border-box;
overflow: hidden;
gap: 3.33px;
padding-top: 3.33px;
img{
max-width: 34%;
box-sizing: border-box;
}
}
#textContainer{
padding: 13.12px;
color: var(--mardi-back-color);
h4{
font-family: 'karrik';
text-transform: uppercase;
font-size: 33px;
margin-bottom: 3.33px;
}
p{
font-family: 'velvelyne';
font-family: 16.1px;
margin-bottom: 7.77px;
}
.event-hours{
margin-left: 44px;
font-size: 22px;
font-weight: bold;
span[property="location"]{
font-size: 16.1px;
margin-left: -22px;
}
}
}
}
@container( width < 650px ){
.afficheMardis{
flex-direction: column;
}
}
</style>
</head>
<body>
<article class="afficheMardis" property="event" typeof="Event">
<div id="imgContainer">
<img src="/affiches/mardis/IMG001.jpg" alt="une lampe d'atelier sur un grand plan de travail un peu désorganisé, quelques chaises un peu disparates, on distingue un empilement de caisses et cartons à l'arrière plan">
<img src="/affiches/mardis/IMG002.jpg" alt="un coin atelier bien équipé et éclairé, beaucoup d'outils, une échelle au bord du cadre, et on aperçoit un espace avec un ordinateur sur une mezzanine, éclairé d'une lumière rouge vive">
<img src="/affiches/mardis/IMG333.jpg" alt="un grand espace de rangement très haut et plutôt ajouré décorée d'un dessin de poulpe rose fluo, qui contient des outils divers, éclairé d'un néon bleu pâle">
</div>
<div id="textContainer" property="description">
<h4 property="name">Permanences du LOL</h1>
<p>Venez chiller avec nous, partager un thé ou une bière.</p>
<p>On échange technique et savoir-faire<br>sur tous les sujets : logiciel libre, hacking,<br> couture, bricole et bidouille en tout genre,<br> mais aussi sur nos projets personnels ou collectifs</p>
<p class="event-hours">
<span property="eventSchedule" typeof="Schedule">
<data property="byDay" content="Tuesday">Tous les mardis</data><br> à partir de&nbsp;<data property="startTime" content="17:00">17h</data><br>
</span>
<span property="eventSchedule" typeof="Schedule">
<data property="byDay" content="Saturday">&emsp;Tous les samedis</data><br>&emsp;à partir de&nbsp;<data property="startTime" content="14:00">14h</data>
</span>
<br>
<span property="location" href="https://labolyon.fr/">au local du LOL &ensp; &rarr; 7 Place Chazette, 69001 Lyon</span>
</p>
</div>
</article>
</body>
</html>
-51
View File
@@ -1,51 +0,0 @@
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="icon" type="image/svg" href="../assets/favicon.svg" />
<title>TEST EVENT</title>
<style data-import="no-import">
/*=========================== INFROMATIONS AFFICHES :
le style 'no-import' est filtrée
ici on place les eléments qui entre en conflit avec
la page principale
les suivant sont inclus
IMPORTANT : il faut nommer le <article> avec un id unique
pour éviter les conflit avec les reste du site
====================================================*/
body{
width: 100%;
height: 100%;
background-color: black;
display: flex;
flex-direction: column;
justify-content: space-around;
align-items: center;
}
</style>
<style media="screen">
#testAffiche{
width: 333px;
height: 333px;
background-color: green;
}
#testAffiche p{
color: black;
font-size: 33px;
}
</style>
</head>
<body>
<article id="testAffiche">
<p>test affiche !</p>
</article>
</body>
</html>
-52
View File
@@ -1,52 +0,0 @@
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="icon" type="image/svg" href="../assets/favicon.svg" />
<link rel="stylesheet" href="./closedStyle.css">
<link rel="stylesheet" href="../style/animation.css">
<link rel="stylesheet" href="/style/typo.css">
<title>TEST EVENT 333</title>
<style data-import="no-import">
/*=========================== INFROMATIONS AFFICHES :
la balise style data-import="no-import" est filtrée
ici on place les eléments qui entre en conflit avec la page principale
les suivant sont inclus
IMPORTANT : il faut nommer le main avec un id unique pour éviter les conflit avec les reste du site
====================================================*/
body{
width: 100%;
height: 100%;
background-color: black;
display: flex;
flex-direction: column;
justify-content: space-around;
align-items: center;
}
</style>
<style media="screen">
#testAffiche333{
width: 333px;
height: 333px;
background-color: red;
}
#testAffiche333 p{
color: black;
font-size: 33px;
}
</style>
</head>
<body>
<article id="testAffiche333">
<p>test affiche 333 !</p>
</article>
</body>
</html>
-4
View File
@@ -1,4 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg id="Calque_1" data-name="Calque 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 40.19 38.9">
<path d="M33.56,0H0v38.9h40.19V0h-6.62ZM34.91,33.62H5.28V8.09l15.05,19.04,14.58-18.56v25.05ZM11.12,5.28h18.39l-9.25,12.02L11.12,5.28Z"/>
</svg>

Before

Width:  |  Height:  |  Size: 285 B

Binary file not shown.
Binary file not shown.
+72 -172
View File
@@ -1,122 +1,71 @@
<!DOCTYPE html>
<!doctype html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="style/typo.css">
<link rel="stylesheet" href="style/default.css">
<link rel="stylesheet" href="style/common.css">
<link rel="stylesheet" href="style/animation.css">
<link rel="stylesheet" href="style/main.css">
<link rel="stylesheet" href="style/responsive.css">
<link rel="stylesheet" href="style/reduced.css">
<!-- TEST CCS OUVERTURE
<link rel="stylesheet" href="status/openStyle.css">
-->
<!--
<link rel="stylesheet" href="affiches/perm.css">
<link rel="stylesheet" href="affiches/jdll2024/jdll2024.css">
<link rel="stylesheet" href="affiches/algorave.css">
-->
<title>L(. O.)L &mdash; Laboratoire Ouvert Lyonnais</title>
<link rel="icon" type="image/svg" href="./assets/favicon.svg" />
<link rel="icon" type="image/svg" href="" />
<title>L(. O.)L</title>
</head>
<body>
<header>
<h1>
<img id="logo" src="./assets/logo/logo-forme.svg" alt="">
<span aria-hidden="true" class="cool-name">L<span class="trans-symbol"></span>L</span>
<span class="plain-name">L.O.L.</span>
</h1>
<nav>
<ul>
<li><a href="https://git.labolyon.fr/explore/repos" name="git" class="textBtnStyle" target="_blank">Git</a></li>
<li><a href="https://wiki.labolyon.fr/" name="wiki" class="textBtnStyle" target="_blank">Wiki</a></li>
<li><a href="https://matrix.to/#/#general:chat.labolyon.fr" name="matrix" class="textBtnStyle" target="_blank">Matrix</a></li>
<li><a href="https://nerdculture.de/@labolyon" name="fedi" class="textBtnStyle" target="_blank">Fediverse</a></li>
</ul>
</nav>
</header>
<main>
<section id="homeContent">
<!-- MESSAGE DE BIENVENUE -->
<aside>
<button type="button" name="msgBtn" popovertarget="msgWindow" popoveraction="show" class="iconBtnStyle" id="openMsg">
<svg class="icon" viewBox="0 0 40.19 38.9">
<path d="M33.56,0H0v38.9h40.19V0h-6.62ZM34.91,33.62H5.28V8.09l15.05,19.04,14.58-18.56v25.05ZM11.12,5.28h18.39l-9.25,12.02L11.12,5.28Z"/>
</svg>
</button>
<div id="msgWindow" popover="auto">
<dialog class="floatingWindow">
<div class="title">
<h4>Bienvenue !</h4>
<button class="iconBtnStyle" popovertarget="msgWindow" popoveraction="hide">
<svg viewBox="0 0 53.73 53.59" class="icon">
<!--HORS VUE-->
<canvas id="canvas"></canvas>
<video autoplay muted loop src="./background.webm" id="background"></video>
<div id="mainContainer">
<div class="uiStyle" id="topBar">
<div class="left">
<img src="./src/assets/logo/logo-contreforme.svg" class="icon" id="mainLogo">
<p>L<strong></strong>L</p>
</div>
<div class="right">
<a href="https://git.labolyon.fr/explore/repos" name="git" class="textBtnStyle" target="_blank">Git</a>
<a href="https://wiki.labolyon.fr/" name="wiki" class="textBtnStyle" target="_blank">Wiki</a>
<a href="https://matrix.to/#/#general:chat.labolyon.fr" name="matrix" class="textBtnStyle" target="_blank">Matrix</a>
<a href="https://nerdculture.de/@labolyon" name="fedi" class="textBtnStyle" target="_blank">Fediverse</a>
<a href="https://listes.infini.fr/listes.labolyon.fr/subscribe/discussions" name="diff" class="textBtnStyle" target="_blank">Diffusion</a>
</div>
<button type="button" name="menu" class="iconBtnStyle" id="menuBtn">
<svg class="icon" viewBox="0 0 53.73 53.59">
<path d="M26.87,40.16l-13.43,13.43L0,40.16l13.43-13.43L.29,13.43,13.72,0l13.15,13.29L40.01.14l13.43,13.43-13,13.15,13.29,13.29-13.43,13.43-13.43-13.29Z"/>
</svg>
</button>
</div>
<div id="mainInfo">
<div class="uiStyle" id="title">
<p>
hellooo, <br>
bienvenue sur le site du LOL ^^<br><br>
en ce moment on cherche du monde pour nous aider à faire fonctionner le lieu, le faire évoluer et le péreniser.<br><br>
si jamais ça t'intéresse<br><strong>contacte nous sur Matrix, <br>
ou passe nous voir au local </strong>directement, quand il est ouvert !<br>
</p>
</dialog>
</div>
</aside>
<section id="titleSection" class="solidBox">
<h2>
Hackerspace queer
<small><br>
</p>
<p id="desc">
Lieu de réappropriation, <br>
réparation & recyclage <br>
des objets techniques <br>
& technologiques
</small>
</h2>
</section>
<section id="hourSection" class="solidBox">
<h3>Horaires d'ouverture</h3>
<ol>
<li>
Mar. <strong>17h &rarr; 23h</strong>
</li>
<li>
Sam. <strong>14h &rarr; 20h</strong>
</li>
</ol>
<!-- pour plus tard
<h3>Nocturne</h3>
<ol>
<li>Ven. <strong>21h &rarr; 5h</strong></li>
</ol>
-->
</section>
<address class="transparentBox">
7 place Chazette<br>
69001 Lyon<br>
</p>
</div>
<div id="address">
<p>
7 place Chazette
<br>
69001 Lyon
<br> <br>
45° 46' 23.698" N
<br>
45° 46' 23.698" N<br>
4° 50' 14.052" E
</address>
<div id="planSection" class="transparentBox">
<div id="planContainer" class="transparentBox">
<img src="./assets/plan.svg" id="plan" alt="Plan d'accès du local: sonnez à l'interphone Laboratoire Ouvert Lyonnais au 7 Place Chazette 69001, puis avancez tout droit, traversez la cour, et avancez encore, la porte se situe après l'ascenceur, sur la droite">
</p>
<a href="https://www.hackerspaces.org/" id="hackerLogo" target="_blank">
<img src="./src/assets/logo_hackerspaces_monde.png">
</a>
</div>
<div class="uiStyle" id="openingHours">
<p>
Dim. &emsp; <strong>15h &rarr; 23h</strong> <br>
Lun. &emsp; <strong>15h &rarr; 23h</strong> <br>
Mar. &emsp; <strong>15h &rarr; 23h</strong> <br><br>
&ensp; &rarr; nocturne : &ensp;<br>
Ven. &emsp; <strong>21h &rarr; 5h</strong>
</p>
</div>
<div id="planContainer">
<img src="./src/assets/plan.svg" id="plan">
<svg id="fleche" viewBox="0 0 4215.93 2604.36">
<g>
<path d="M118.58,2250.24l88.9,7.6,20.81,53.59,2035.49-1175.29,534.6-308.72c47.83-27.62,106.77-27.57,154.55.13l610.19,353.56-36.27,19.61,202.14,8.94-20.79-113.99-36.27,21.29-691.73-397.83c-65.1-37.42-145.2-37.35-210.23.2L118.58,2250.24Z"/>
@@ -138,88 +87,39 @@
<rect class="cls-1" x=".05" y=".05" width="4215.83" height="2604.26" rx="133.4" ry="133.4" fill="none"/>
</svg>
</div>
</div>
<div id="extLinkSection" class="transparentBox">
<a href="https://www.hackerspaces.org/" id="hackerLogo" target="_blank">
<img src="./assets/logo_hackerspaces_monde.png">
</a>
</div>
<div id="adhesionSection">
<button class="textBtnStyle" popovertarget="addUserWindow" popoveraction="show">Comment adhérer ?</button>
<div id="addUserWindow" popover="auto">
<dialog class="floatingWindow">
<div class="title">
<h4>Bienvenue !</h4>
<button class="iconBtnStyle" popovertarget="addUserWindow" popoveraction="hide">
<svg viewBox="0 0 53.73 53.59" class="icon">
<path d="M26.87,40.16l-13.43,13.43L0,40.16l13.43-13.43L.29,13.43,13.72,0l13.15,13.29L40.01.14l13.43,13.43-13,13.15,13.29,13.29-13.43,13.43-13.43-13.29Z"/>
</svg>
</button>
</div>
<p>
test adhésion
</p>
</dialog>
<div class="uiStyle" id="lolOpener">
<p id="desc">Le lieu est parfois ouvert en dehors des horaires habituels donc on a installé un capteur sur la porte :</p>
</div>
</div>
</section>
<section id="statuSection" class="solidBox">
<div id="statusDesc">
<p>
Le LOL peut ouvrir en dehors des horaires habituels.
En fonction de nos envies et disponibilités.
</p>
<p>
<small>Un capteur sur la porte d'entrée indique si le local est ouvert:</small>
</p>
</div>
<a href="./status/index.ouvert.html" target="_blank" class="textBtnStyle">Vérifier <br>si c'est<br> ouvert <br>&rarr; &rarr; &rarr;</a>
</section>
<section id="extraContent">
<section id="aboutSection" class="solidBox">
<div id="aboutSection">
<div class="uiStyle" id="aboutText">
<p>
Le Laboratoire Ouvert Lyonnais (LOL) est un lieu de rassemblement et d'expérimentations pour tous·tes les passionné·es d'informatique, d'électronique et de technique,
qui souhaitent réparer, recycler, et se réapproprier les objets et outils qui nous entourent.<br>
Le LOL est un lieu d'exploration des alternatives<br>et de bidouille anti-systèmes.
Le LOL est un lieu d'exploration des alternatives et de bidouille anti-systèmes.
</p>
<p>
Au LOL, nous expérimentons et créons autours du détournement, de la réutilisations d'objets en tout genre.
Nous constituons une communautée ouverte où chacun·e peut apprendre et partager avec les autres pour créer ensemble et comprendre les outils, les objets, les techniques etc.
Le lieu est autogéré, défini par ses utilisateur·ices et en fonctions de ses besoins : peu importe sur quoi tu travailles, il y'a une place pour toi !
Le lieu est autogéré, défini par ses utilisateur·ices et en fonctions de ses besoins : peu importe sur quoi tu travailles il y'a une place pour toi !
</p>
<p>
Nous revendiquons l'ouverture du code et des techniques,<br>
le partage des connaissances et l'autogestion,<br>
Nous revendiquons l'ouverture du code et des techniques,
le partage des connaissances et l'autogestion,
l'anti-capitalisme et l'anti-fascisme. <br><br>
Nous condamnons donc toute forme de violence<br>et de discrimination dans nos locaux.<br>
Tout comportement assimilé pourra, sur décision collective,<br>vous mener à la sortie.
Nous condamnons donc toute forme de violence et de discrimination dans nos locaux.<br>
Tout comportement assimilé pourra, sur décision collective, vous mener à la sortie.
</p>
</section>
<section id="eventSection" class="transparentBox">
<h3>Événements <small>à venir</small></h3>
<article class="solidBox">
<h4>Permanences du LOL</h4>
<p class="date">↻ Mardi & Samedi</p>
<a href="/affiches/mardis/" class="iconBtnStyle" target="_blank">
<svg viewBox="0 0 53.73 53.59" class="icon">
<path d="M26.87,40.16l-13.43,13.43L0,40.16l13.43-13.43L.29,13.43,13.72,0l13.15,13.29L40.01.14l13.43,13.43-13,13.15,13.29,13.29-13.43,13.43-13.43-13.29Z"/>
</svg>
</a>
</article>
</section>
</section>
<noscript>
<video src="/assets/video/closed.webm" class="closedBackground" autoplay muted loop></video>
</noscript>
<video data-cute-texture-video class="cute-texture-video" src="/assets/video/background.webm" autoplay muted loop ></video>
<canvas class="cute-texture"></canvas>
</main>
<!-- SCRIPT PRINCIPAL -->
<script type="module" src="./js/main.js"></script>
</div>
<div id="eventSection">
<div class="uiStyle" id="title">
évènements<br>&emsp;&emsp; &rarr; &rarr; &rarr; à venir :
</div>
</div>
</div>
</div>
<!--VUE ROOT APP-->
<div id="app"></div>
<script type="module" src="/src/main.js"></script>
</body>
</html>
-348
View File
@@ -1,348 +0,0 @@
const DEFAULT_VERTEX_SHADER = `
attribute float aVertexIndex;
varying highp vec2 vTextureCoord;
// This vertex shader produces the following, when drawn using indices 0..3:
//
// 1 | 0-----x.....2
// 0 | | s | . ´
// -1 | x_____x´
// -2 | : .´
// -3 | 1´
// +---------------
// -1 0 1 2 3
//
// The axes are clip-space x and y. The region marked s is the visible region.
// The digits in the corners of the right-angled triangle are the vertex
// indices.
//
// The top-left has UV 0,0, the bottom-left has 0,2, and the top-right has 2,0.
// This means that the UV gets interpolated to 1,1 at the bottom-right corner
// of the clip-space rectangle that is at 1,-1 in clip space.
void main() {
vec2 uv = vec2(floor(aVertexIndex / 2.0), floor(mod(aVertexIndex, 2.0))) * 2.0;
gl_Position = vec4(uv * vec2(2.0, -2.0) + vec2(-1.0, 1.0), 0.0, 1.0);
vTextureCoord = uv;
}
`
const FRAGMENT_SHADER_UTILITIES = `
highp float noise1(highp vec2 co){
return fract(sin(dot(co, vec2(12.9898, 78.233))) * 43758.5453);
}
// Color spaces from https://github.com/tobspr/GLSL-Color-Spaces/blob/master/ColorSpaces.inc.glsl
const highp float HCV_EPSILON = 1e-10;
const highp float HSL_EPSILON = 1e-10;
highp vec3 hue_to_rgb(highp float hue)
{
highp float R = abs(hue * 6.0 - 3.0) - 1.0;
highp float G = 2.0 - abs(hue * 6.0 - 2.0);
highp float B = 2.0 - abs(hue * 6.0 - 4.0);
return clamp(vec3(R,G,B), vec3(0), vec3(1));
}
// Converts from HSL to linear RGB
highp vec3 hsl_to_rgb(highp vec3 hsl)
{
highp vec3 rgb = hue_to_rgb(hsl.x);
highp float C = (1.0 - abs(2.0 * hsl.z - 1.0)) * hsl.y;
return (rgb - 0.5) * C + hsl.z;
}
// Converts a value from linear RGB to HCV (Hue, Chroma, Value)
highp vec3 rgb_to_hcv(highp vec3 rgb)
{
// Based on work by Sam Hocevar and Emil Persson
highp vec4 P = (rgb.g < rgb.b) ? vec4(rgb.bg, -1.0, 2.0/3.0) : vec4(rgb.gb, 0.0, -1.0/3.0);
highp vec4 Q = (rgb.r < P.x) ? vec4(P.xyw, rgb.r) : vec4(rgb.r, P.yzx);
highp float C = Q.x - min(Q.w, Q.y);
highp float H = abs((Q.w - Q.y) / (6.0 * C + HCV_EPSILON) + Q.z);
return vec3(H, C, Q.x);
}
// Converts from linear rgb to HSL
highp vec3 rgb_to_hsl(highp vec3 rgb)
{
highp vec3 HCV = rgb_to_hcv(rgb);
highp float L = HCV.z - HCV.y * 0.5;
highp float S = HCV.y / (1.0 - abs(L * 2.0 - 1.0) + HSL_EPSILON);
return vec3(HCV.x, S, L);
}
highp vec4 hue_rotate(highp vec4 rgb_input, highp float amount) {
highp vec3 hsl = rgb_to_hsl(rgb_input.xyz);
hsl.x = mod(hsl.x+amount,1.0);
return vec4(hsl_to_rgb(hsl), rgb_input.w);
}
highp vec4 grayscale(highp vec4 rgb_input, highp float amount) {
highp vec3 hsl = rgb_to_hsl(rgb_input.xyz);
hsl.y = 1.0 - amount;
return vec4(hsl_to_rgb(hsl), rgb_input.w);
}
`
const FRAGMENT_SHADER_UTILITIES_N_LINES = FRAGMENT_SHADER_UTILITIES.split(/\n/g).length
const DEFAULT_FRAGMENT_SHADER = `
// Some random values computed for each frame
uniform highp vec4 uRandom;
// Size (in logical pixel) of current CuteTexture canvas
uniform lowp vec2 uCanvasSize;
// Number of seconds since canvas was initialized
uniform lowp float uTime;
// Current frame of first video with [data-cute-texture-video] attribute
uniform sampler2D uVideo;
// Size (in pixels) of current video frame in uVideo
uniform lowp vec2 uVideoSize;
// Coordinates of current pixel being computed from [0,0] (top left) to [1,1] (bottom right)
varying highp vec2 vTextureCoord;
void main() {
gl_FragColor = vec4(vTextureCoord.x, vTextureCoord.y, 0.0, 1.0);
}
`
/**
* Initialise un canvas d'arrière plan "CuteTexture" avec les options données
*/
export function initCuteTexture(options){
let shaderSourceOption = options?.shaderSource;
/** @type {HTMLCanvasElement} */
const targetCanvas = document.querySelector("canvas[data-cute-texture]") || document.querySelector("canvas.cute-texture") || document.querySelector("canvas");
if(!targetCanvas)
throw new Error(`Aucun élément <canvas> trouvé sur la page`)
{
let computedStyle = getComputedStyle(targetCanvas)
let elementWidth = parseFloat(computedStyle.width)
let elementHeight = parseFloat(computedStyle.height)
targetCanvas.width = elementWidth
targetCanvas.height = elementHeight
}
const ctx = targetCanvas.getContext("webgl");
if(ctx == null)
throw new Error("WebGL n'ext pas supporté sur votre machine")
let mainShader = initMainShader(ctx, {
shaderSource: shaderSourceOption
})
console.log("Shader CuteTexture initialisé", mainShader)
const initTime = Date.now()
function startRender(){
renderCuteTexture(targetCanvas, mainShader, initTime)
requestAnimationFrame(startRender)
}
startRender()
return {
target: targetCanvas,
initTime,
resize: function(width, height) {
targetCanvas.width = width
targetCanvas.height = height
}
}
}
/**
* @param {WebGLRenderingContext} ctx
*/
function initMainShader(ctx, options){
let fragmentShaderCode = options?.shaderSource;
const vertexShader = ctx.createShader(ctx.VERTEX_SHADER)
ctx.shaderSource(vertexShader, DEFAULT_VERTEX_SHADER)
ctx.compileShader(vertexShader)
if (!ctx.getShaderParameter(vertexShader, ctx.COMPILE_STATUS)) {
throw new Error(`Le vertex shader n'a pas pu être compilé: ${ctx.getShaderInfoLog(vertexShader)}`)
ctx.deleteShader(vertexShader)
return null
}
if(!fragmentShaderCode){
fragmentShaderCode = getDocumentShaderSource(document);
}
if(!fragmentShaderCode){
fragmentShaderCode = DEFAULT_FRAGMENT_SHADER
}
const fragmentShader = ctx.createShader(ctx.FRAGMENT_SHADER)
ctx.shaderSource(fragmentShader, FRAGMENT_SHADER_UTILITIES+fragmentShaderCode)
ctx.compileShader(fragmentShader)
if (!ctx.getShaderParameter(fragmentShader, ctx.COMPILE_STATUS)) {
let error = ctx.getShaderInfoLog(fragmentShader)
let errorLine = error.match(/\d+:(\d+):/)
if(errorLine) {
let lineNum = parseInt(errorLine[1])
let lineNumeWithoutUtils = lineNum-FRAGMENT_SHADER_UTILITIES_N_LINES;
if(lineNumeWithoutUtils >= 0){
error = `Ligne ${lineNumeWithoutUtils}: ${error}`
}
}
ctx.deleteShader(fragmentShader)
throw new Error(`Le fragment shader n'a pas pu être compilé: ${error}`)
}
const shaderProgram = ctx.createProgram()
ctx.attachShader(shaderProgram, vertexShader)
ctx.attachShader(shaderProgram, fragmentShader)
ctx.linkProgram(shaderProgram)
if (!ctx.getProgramParameter(shaderProgram, ctx.LINK_STATUS)) {
throw new Error(`Le shader n'a pas pu être linké: ${ctx.getProgramInfoLog(shaderProgram)}`)
ctx.deleteShader(vertexShader)
ctx.deleteShader(fragmentShader)
ctx.deleteProgram(shaderProgram)
return null
}
let videoElement, videoTexture = null;
if(ctx.getUniformLocation(shaderProgram, "uVideo") != null){
videoElement = document.querySelector("video[data-cute-texture-video]") || document.querySelector("video");
if(!videoElement){
console.warn("Aucune vidéo avec l'attribut [data-cute-texture-video] n'a été trouvé sur la page");
} else {
videoTexture = ctx.createTexture();
ctx.bindTexture(ctx.TEXTURE_2D, videoTexture)
ctx.texImage2D(
ctx.TEXTURE_2D,
0,
ctx.RGBA,
1, 1,
0,
ctx.RGBA,
ctx.UNSIGNED_BYTE,
new Uint8Array([0, 0, 0, 255])
)
ctx.texParameteri(ctx.TEXTURE_2D, ctx.TEXTURE_WRAP_S, ctx.CLAMP_TO_EDGE);
ctx.texParameteri(ctx.TEXTURE_2D, ctx.TEXTURE_WRAP_T, ctx.CLAMP_TO_EDGE);
ctx.texParameteri(ctx.TEXTURE_2D, ctx.TEXTURE_MIN_FILTER, ctx.LINEAR);
}
}
const vertexIndexBuffer = ctx.createBuffer()
ctx.bindBuffer(ctx.ARRAY_BUFFER, vertexIndexBuffer)
ctx.bufferData(ctx.ARRAY_BUFFER, new Float32Array([0, 1, 2]), ctx.STATIC_DRAW)
return {
program: shaderProgram,
vertexShader,
fragmentShader,
videoElement,
videoTexture,
aVertexIndex: ctx.getAttribLocation(shaderProgram, "aVertexIndex"),
uRandom: ctx.getUniformLocation(shaderProgram, "uRandom"),
uCanvasSize: ctx.getUniformLocation(shaderProgram, "uCanvasSize"),
uTime: ctx.getUniformLocation(shaderProgram, "uTime"),
uVideo: ctx.getUniformLocation(shaderProgram, "uVideo"),
uVideoSize: ctx.getUniformLocation(shaderProgram, "uVideoSize"),
vertexIndexBuffer,
}
}
/**
* @param {HTMLCanvasElement} target
* @param {*} mainShader
*/
function renderCuteTexture(target, mainShader, initTime){
let ctx = target.getContext("webgl")
ctx.clearColor(0, 0, 0, 0)
ctx.clearDepth(1.0)
ctx.enable(ctx.DEPTH_TEST)
ctx.depthFunc(ctx.LEQUAL)
ctx.clear(ctx.COLOR_BUFFER_BIT)
ctx.bindBuffer(ctx.ARRAY_BUFFER, mainShader.vertexIndexBuffer)
ctx.vertexAttribPointer(
mainShader.aVertexIndex, // location
1, // pull out 1 value per iteration
ctx.FLOAT, // the data in the buffer is 32bit floats
false, // don't normalize
0, // how many bytes to get from one set of values to the next
0 // how many bytes inside the buffer to start from
)
ctx.enableVertexAttribArray(mainShader.aVertexIndex)
ctx.useProgram(mainShader.program)
if(mainShader.uRandom){
ctx.uniform4f(
mainShader.uRandom,
Math.random(),
Math.random(),
Math.random(),
Math.random()
)
}
if(mainShader.uCanvasSize){
ctx.uniform2f(
mainShader.uCanvasSize,
target.width,
target.height
)
}
if(mainShader.uTime){
ctx.uniform1f(
mainShader.uTime,
(Date.now() - initTime)/1000
)
}
if(mainShader.uVideo){
ctx.activeTexture(ctx.TEXTURE0);
ctx.bindTexture(ctx.TEXTURE_2D, mainShader.videoTexture);
ctx.uniform1i(
mainShader.uVideo,
0
)
}
if(mainShader.uVideo && mainShader.videoElement && mainShader.videoTexture){
ctx.activeTexture(ctx.TEXTURE0);
ctx.bindTexture(ctx.TEXTURE_2D, mainShader.videoTexture);
ctx.texImage2D(
ctx.TEXTURE_2D,
0,
ctx.RGBA,
ctx.RGBA,
ctx.UNSIGNED_BYTE,
mainShader.videoElement,
);
ctx.uniform1i(
mainShader.uVideo,
0
)
}
if(mainShader.uVideoSize && mainShader.videoElement) {
ctx.uniform2f(
mainShader.uVideoSize,
mainShader.videoElement.videoWidth,
mainShader.videoElement.videoHeight
)
}
ctx.drawArrays(ctx.TRIANGLE_STRIP, 0, 3);
}
export function getDocumentShaderSource(doc=document){
return doc.querySelector(`script[type="x-shader/glsl+fragment"]`)?.innerHTML
}
-140
View File
@@ -1,140 +0,0 @@
export async function loadEvents(){
let eventList = document.querySelectorAll('#eventSection > article');
//console.log("event list: ", eventList);
for (let event of eventList){
let title = event.querySelector('h4');
let date = event.querySelector('p.date');
let posterLink = event.querySelector('a.iconBtnStyle').href;
let posterHTML = await getPoster(posterLink);
let poster = posterHTML.querySelector('body > article');
let posterStyle = posterHTML.querySelectorAll('head > style:not([data-import="no-import"])')
console.log('entry data :', title, date, poster, posterStyle);
let selectedEntry = createEntry(title, date, poster, posterStyle)
console.log('created new details :', selectedEntry);
event.replaceChildren(selectedEntry);
}
/* let btnList = document.querySelectorAll('.eventEntry > .iconBtnStyle');
//console.log("source buttons : ", btnList)
let displayWindow = document.querySelector('#posterWindow');
let displayContainer = document.querySelector('#posterContainer');
let closeBtn = document.querySelector('#posterCloseBtn');
closeBtn.addEventListener('mousedown', () => {
displayWindow.style.visibility = 'collapse';
displayContainer.replaceChildren();
})
closeBtn.addEventListener('touchstart', () => {
displayWindow.style.visibility = 'collapse';
displayContainer.replaceChildren();
})
async function getPoster(src){
let res = await fetch(src);
if (res.ok){
let html_text = await res.text()
let html = new DOMParser().parseFromString(html_text, "text/html");
return html
} else{
console.log('error 333');
return
}
}
let eventList = [];
if( btnList.length > 0 ){
for (let btn of btnList ){
let link = btn.children[0];
link.style.pointerEvents = 'none';
//console.log(link.href);
let posterPage = await getPoster(link.href);
//console.log('selected poster: ', posterPage)
let titleData = posterPage.querySelector('title');
//console.log(titleData);
let styleList = Array.from(posterPage.querySelectorAll('head > style'));
//console.log(styleList)
styleList.splice(0,1);
//console.log(styleList)
eventList.push(
{
content: posterPage.querySelector('main'),
title: titleData.innerText,
stylesheet: styleList,
sourceBtn: btn
}
);
}
}
//console.log("event list : ", eventList);
if (eventList.length > 0){
eventList.forEach( (obj) =>{
let btn = obj.sourceBtn;
let content = obj.content;
let title = obj.title;
for (let style of obj.stylesheet){
document.head.append(style);
}
btn.addEventListener( 'click', () => {
//console.log("selection :", content)
displayWindow.style.visibility = 'visible';
let targetTitle = displayWindow.querySelector('h4');
targetTitle.innerText = title;
displayContainer.replaceChildren(content);
})
})
} */
}
async function getPoster(link){
let res = await fetch(link);
if (res.ok){
let html_text = await res.text()
let html = new DOMParser().parseFromString(html_text, "text/html");
return html
} else{
console.log('error 333');
return
}
}
function createEntry(title, date, html, style){
let newEntry = document.createElement('details');
let newSummary = document.createElement('summary');
newSummary.append(title, date);
newEntry.append(newSummary);
newEntry.append(html);
newEntry.name = "eventList"
for(let el of style){
document.head.append(el);
}
return newEntry
}
-34
View File
@@ -1,34 +0,0 @@
export function makeItFloat(target){
let startTarget = target.querySelector('.title');
console.log('selected target :', startTarget);
let startX, startY;
let clicked = false;
startTarget.addEventListener('mousedown', (event) => {
startX = event.pageX;
startY = event.pageY;
clicked = true;
console.log('clicking...')
})
document.addEventListener('mousemove', (event) => {
if(clicked){
console.log('moving...')
let currentX = event.pageX;
let currentY = event.pageY;
let moveX = target.offsetLeft + currentX - startX;
target.style.left = moveX + 'px';
let moveY = target.offsetTop + currentY - startY;
target.style.top = moveY + 'px';
startX = currentX;
startY = currentY;
}
});
document.addEventListener('mouseup', () => {
console.log('STOP !')
clicked = false;
})
}
-22
View File
@@ -1,22 +0,0 @@
async function importOuverture(){
const res = await fetch("/status/index.html")
if(!res.ok){
throw new Error(`Server responded with status ${res.status} ${res.statusText}`)
}
let html_text = await res.text()
let html = new DOMParser().parseFromString(html_text, "text/html");
for(let style of html.querySelectorAll("head > style")) {
document.head.append(style)
}
let textStatus = html.querySelector("#statusText").textContent;
let statusBox = document.querySelector('#statusText');
statusBox.textContent = textStatus;
}
importOuverture()
for( let btn of document.querySelectorAll(".iconBtnStyle")){
btn.style.visibility = 'visible';
}
-51
View File
@@ -1,51 +0,0 @@
import { loadEvents } from './events.js'
import { loadStatus } from './status.js'
import { initCuteTexture } from './cuteTexture.js'
import { makeItFloat } from './floating.js';
// ======================================== events & statut d'ouverture
loadEvents();
loadStatus()
.then((status) => {
console.log("Status actuel du LOL", status);
let cuteTexture = initCuteTexture({
shaderSource: status.shaderSource
});
cuteTexture.target.style.visibility = "visible"
});
// ======================================== floating message window
makeItFloat(document.querySelector('#msgWindow'));
makeItFloat(document.querySelector('#addUserWindow'));
/*
//================================ tentative de gestion des écran tactiles
startTarget.addEventListener('touchstart', (event) => {
startX = event.pageX;
startY = event.pageY;
clicked = true;
console.log('touching...')
})
document.addEventListener('touchmove', (event) => {
if(clicked){
console.log('moving...')
let currentX = event.pageX;
let currentY = event.pageY;
let moveX = target.offsetLeft + currentX - startX;
target.style.left = moveX + 'px';
let moveY = target.offsetTop + currentY - startY;
target.style.top = moveY + 'px';
startX = currentX;
startY = currentY;
}
});
document.addEventListener('touchend', () => {
console.log('STOP !')
clicked = false;
})
*/
-32
View File
@@ -1,32 +0,0 @@
import { getDocumentShaderSource } from './cuteTexture.js';
export async function loadStatus(){
let res = await fetch('/status/index.html');
let html_text = await res.text()
let html = new DOMParser().parseFromString(html_text, "text/html");
let shaderSource = getDocumentShaderSource(html);
let target = document.querySelector('#statuSection');
let hiddenBtn = target.querySelector('a');
hiddenBtn.style.visibility = 'collapse';
let status = html.querySelector('#lolStatus');
console.log('current status:', status.innerText);
let isOpen = status.innerText.includes('ouvert');
let icon = html.querySelector('link[rel="icon"]');
let style = html.querySelectorAll('link[rel="stylesheet"]')[0];
//console.log("selected script: ", script);
document.head.append(icon);
document.head.append(style);
target.appendChild(status);
return { open: isOpen, shaderSource };
}
+1600
View File
File diff suppressed because it is too large Load Diff
+20
View File
@@ -0,0 +1,20 @@
{
"name": "lolv333",
"private": true,
"version": "0.0.0",
"type": "module",
"scripts": {
"dev": "vite",
"build": "vite build",
"preview": "vite preview"
},
"dependencies": {
"vite-svg-loader": "^5.1.1",
"vue": "^3.5.39",
"vue3-moveable": "^0.28.0"
},
"devDependencies": {
"@vitejs/plugin-vue": "^6.0.7",
"vite": "^8.1.1"
}
}
-93
View File
@@ -1,93 +0,0 @@
Ce document sert à échanger et partager des idées et trucs à faire pour continuer la mise à jour du site du LOL :
>si possible écrire tous les noms de variables en Pascal Case (pas sur du nom maisUnTrucCommeCa), je trouve ça plus lisible
> à vérifier mais je pense que la version dégradée sans js fonctionne, il faudrait juste ajuster le contenu, et aussi pour le bouton "vérifier si le lieu est ouvert" voir dernière entrée (***)
> j'attends vos retours pour savoir qu'est ce qu'il faut rajouter/ modifier ?
> ajout du bouton plus pour les évènements => création d'event sur des pages séparées, importées avec js (remplacé par lien en version dégradé )
>(***) mise en place du statut sans le lien symbolique (devrait fonctionner si on l'ajoute mais jsep comment faire)
modifier le lien vers le dossier au lieu de ''index.ouvert.html' dans la page principale
changer le fetch dans status.js
> problème de gestion des évènement tactiles, rien ne marche ...
> problème import css directement dans main.css
* [x] changer interface évènements en article (avec lien vers affiche) qui devient details avec js qui contient l'affiche
* [x] auto scale affiche dans son conteneur
> problème à gérer dans la conception des affiches
* [x] message de bienvenue !!!
* [x] tester section event avec des vraies affiches !!!
> problème de cohérence interface / contenu sur pc, le panneau event est très large et dois afficher des affiches format vertical donc très haut si rescale sur width ou très petit si rescale sur hauteur + si format aléatoire je sais pas comment scale
* [x] performance arrière plan avec un shader
> OUVERT : texture sinusoidale en nuance de vert entre offset (161 - 255), opacité 0.5, hue-rotate 13.12deg
+ video noir & blanc au dessus en mix blend difference, opacité 0.777
> FERMÉ : texture grain aléatoire sur G et B, entre 0 - 161, opacité 0.5, hue-rotate 13.12deg
* [x] désactiver la video pour les personnes qui veulent pas d'effets visuels
* [x] fond video en version dégradée + scale video un peu plus grand car bande noire en bas
* [x] réglages padding section statut
* [ ] section adhésion et explication financement
(à discuter pour le contenu)
# Démarrer un serveur de developpement
```
python3 -m http.server
```
Et ensuite, le site est disponible sur http://localhost:8000/
## Tester sur son tel
Il faut démarrer le serveur avec la commande suivante:
```
python3 -m http.server -b 0.0.0.0
```
Ensuite il faut obtenir l'adresse IP de son ordinateur
```
ip a
```
Dans notre cas c'est `10.0.0.165` (voir l'exemple ci-dessous).
```
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
link/ether c4:9d:ed:15:78:cc brd ff:ff:ff:ff:ff:ff
inet 10.0.0.165/24 brd 10.0.0.255 scope global dynamic noprefixroute mlan0
valid_lft 5204sec preferred_lft 5204sec
```
Sur son tel, on peut alors acceder a http://10.0.0.165:8000/.
Si cela ne fonctionne pas, c'est peut être que le pare feu interdit la connexion depuis un autre ordinateur sur le port 8000.
## Lien symbolique et ouverture => comment preview pour dev
aller dans /status puis executer la commande en fonction du statut souhaité
./set-status.sh opened
> statut ouvert
./set-status.sh closed
> statut fermé
+101
View File
@@ -0,0 +1,101 @@
<script setup>
import PlayerIcon from './assets/icons/player.svg'
import LinkIcon from './assets/icons/folder.svg'
</script>
<template>
<Teleport to="#topBar .left" defer>
<lolStatusDiv></lolStatusDiv>
</Teleport>
<Teleport to="#lolOpener.uiStyle" defer>
<lolStatusDiv></lolStatusDiv>
</Teleport>
<eventDiv></eventDiv>
<eventPannel
v-show="pannelStatus.activePannels.includes('event')"
@focus="focusPannel('event')"
@close="closePannel('event')"
:class="{zBase: pannelStatus.focus !== 'event', zFocus: pannelStatus.focus === 'event'}"
></eventPannel>
<playerPannel
v-show="pannelStatus.activePannels.includes('player')"
@focus="focusPannel('player')"
@close="closePannel('player')"
:class="{zBase: pannelStatus.focus !== 'player', zFocus: pannelStatus.focus === 'player'}"
></playerPannel>
<linkPannel
v-show="pannelStatus.activePannels.includes('link')"
@focus="focusPannel('link')"
@close="closePannel('link')"
:class="{zBase: pannelStatus.focus !== 'link', zFocus: pannelStatus.focus === 'link'}"
></linkPannel>
<Teleport to="#openingHours" defer>
<div id="btnContainer">
<button type="button" name="link" class="iconBtnStyle" @click="openPannel('link')">
<LinkIcon name="close" class="icon"/>
</button>
<button type="button" name="player" class="iconBtnStyle" @click="openPannel('player')">
<PlayerIcon name="close" class="icon"/>
</button>
</div>
</Teleport>
</template>
<style scoped>
#btnContainer{
position: absolute;
left: 7.77px;
display: flex;
flex-direction: column;
gap: 7.77px;
margin-top: -88px;
.iconBtnStyle{
width: 33px;
height: 33px;
border-radius: 16.1px;
}
}
</style>
<script>
import { dataStorage } from './dataExchange.js'
import { cuteAndCyber } from './artAndTexture.js'
export default {
name : 'App',
computed: {
pannelStatus(){
return dataStorage
}
},
methods: {
focusPannel(str){
if(this.pannelStatus.activePannels.includes(str)){
this.pannelStatus.focus = str
}
},
closePannel(str){
console.log('closing...')
const index = this.pannelStatus.activePannels.indexOf(str)
if( index !== -1){
this.pannelStatus.activePannels.splice(index, 1)
if(this.pannelStatus.focus === str){
this.pannelStatus.focus = null
}
}
},
openPannel(str){
if(!(this.pannelStatus.activePannels.includes(str))){
this.pannelStatus.activePannels.push(str)
}
this.focusPannel(str)
}
},
mounted(){
cuteAndCyber();
console.log("Vue root app is fully loaded!");
}
};
</script>
+148
View File
@@ -0,0 +1,148 @@
import { lolState } from './lolStatus.js'
const arr = []
for (let i = 0; i < 256; i++){
arr.push(i)
}
function createPermTable(){
let data = [...arr]
//console.log('base :', arr)
for (let i = data.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1));
[data[i], data[j]] = [data[j], data[i]];
}
//console.log('result :', permutationTable)
return data
}
const perm = createPermTable();
const p = [...perm, ...perm];
const F2 = 0.5 * (Math.sqrt(3) - 1); // Skew factor for 2D
const G2 = (3 - Math.sqrt(3)) / 6; // Unskew factor for 2D
const scale = 0.7
const target = document.querySelector('#canvas');
const ctx = target.getContext('2d');
// 12 gradient vectors for 2D Simplex Noise
const grad3 = [
[1, 1], [-1, 1], [1, -1], [-1, -1],
[1, 0], [-1, 0], [0, 1], [0, -1],
[1, 2], [-1, 2], [2, 1], [-2, 1]
];
function simplex(x, y) {
// Step 1: Skew input coordinates to simplex grid
const s = (x + y) * F2; // Skew factor
const i = Math.floor(x + s); // Simplex grid i
const j = Math.floor(y + s); // Simplex grid j
// Step 2: Unskew to get (x0, y0) in Cartesian space (distance to (i,j))
const t = (i + j) * G2;
const x0 = x - (i - t); // Unskewed x in [0,1)
const y0 = y - (j - t); // Unskewed y in [0,1)
// Step 3: Determine which simplex (triangle) the point is in
let i1, j1; // Offsets for the other two simplex vertices
if (x0 > y0) {
i1 = 1; j1 = 0; // Lower triangle (x0 > y0)
} else {
i1 = 0; j1 = 1; // Upper triangle (x0 ≤ y0)
}
// Step 4: Coordinates of the other two simplex vertices
const x1 = x0 - i1 + G2; // Distance to (i+i1, j+j1)
const y1 = y0 - j1 + G2;
const x2 = x0 - 1 + 2 * G2; // Distance to (i+1, j+1)
const y2 = y0 - 1 + 2 * G2;
// Step 5: Hash indices for the 3 simplex vertices
const ii = i & 255;
const jj = j & 255;
const gi0 = p[ii + p[jj]] % 12; // (i,j) gradient index
const gi1 = p[ii + i1 + p[jj + j1]] % 12; // (i+i1,j+j1) gradient index
const gi2 = p[ii + 1 + p[jj + 1]] % 12; // (i+1,j+1) gradient index
// Step 6: Compute contributions from each vertex
let t0 = 0.5 - x0 * x0 - y0 * y0; // Falloff (t^4 fade)
const n0 = t0 < 0 ? 0 : Math.pow(t0, 4) * (grad3[gi0][0] * x0 + grad3[gi0][1] * y0);
let t1 = 0.5 - x1 * x1 - y1 * y1;
const n1 = t1 < 0 ? 0 : Math.pow(t1, 4) * (grad3[gi1][0] * x1 + grad3[gi1][1] * y1);
let t2 = 0.5 - x2 * x2 - y2 * y2;
const n2 = t2 < 0 ? 0 : Math.pow(t2, 4) * (grad3[gi2][0] * x2 + grad3[gi2][1] * y2);
// Step 7: Sum contributions and normalize (2D Simplex ranges ~[-1, 1])
return 70 * (n0 + n1 + n2); // 70 scales to ~[-1, 1]
}
function analogLikeNoise(){
let tH = target.height;
let tW = target.width;
//console.log('window dimensions :', tH, tW)
const img = ctx.createImageData(tW, tH);
let offset = 0;
let index = 0;
let brightness = 0;
for(let x = 0; x<tW; x++){
const sx = x * scale + offset
for(let y = 0; y<tH; y++){
let lum = Math.random()*161
//img.data[index++] = lum*150/255;
index++
img.data[index++] = lum;
img.data[index++] = lum;
img.data[index++] = 255;
}
}
ctx.putImageData(img, 0, 0);
offset ++;
if(offset>1024){
offset = 0;
}
}
let time = 0
function scanlines(){
time += 0.05;
let tH = target.height;
let tW = target.width;
//console.log('window dimensions :', tH, tW)
const img = ctx.createImageData(tW, tH);
let index = 0;
for(let y = 0; y<tH; y++){
for(let x = 0; x<tW; x++){
let lum = (Math.sin(y*2 - time *2) * 50) +128;
//img.data[index++] = lum;
index++;
img.data[index++] = lum + Math.random()*16;
//img.data[index++] = lum + Math.random()*32;
index++
img.data[index++] = 255;
}
}
ctx.putImageData(img, 0, 0);
}
export function cuteAndCyber(){
if(!(lolState.isOpen)){
document.querySelector('#background').style.visibility = 'hidden';
analogLikeNoise();
requestAnimationFrame(cuteAndCyber);
}else{
scanlines();
document.querySelector('#background').playbackRate = 0.777;
document.querySelector('#background').style.visibility = 'visible';
requestAnimationFrame(cuteAndCyber);
}
}
+76
View File
@@ -0,0 +1,76 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
id="svg2"
version="1.1"
inkscape:version="1.2.2 (b0a8486541, 2022-12-01)"
width="94.468002"
height="94.468002"
viewBox="0 0 94.468002 94.468003"
sodipodi:docname="favicon.svg"
inkscape:export-filename="logo.png"
inkscape:export-xdpi="130.08"
inkscape:export-ydpi="130.08"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:dc="http://purl.org/dc/elements/1.1/">
<metadata
id="metadata8">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title />
</cc:Work>
</rdf:RDF>
</metadata>
<defs
id="defs6" />
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1341"
inkscape:window-height="927"
id="namedview4"
showgrid="false"
inkscape:zoom="4.8680853"
inkscape:cx="38.824299"
inkscape:cy="53.306379"
inkscape:current-layer="svg2"
inkscape:window-x="56"
inkscape:window-y="50"
inkscape:window-maximized="0"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0"
inkscape:showpageshadow="0"
inkscape:pagecheckerboard="1"
inkscape:deskcolor="#d1d1d1" />
<rect
style="opacity:1;fill:#000000;fill-opacity:1;stroke:#ffff4d;stroke-width:5.58135;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
id="rect4542"
width="88.88665"
height="88.88665"
x="2.7906749"
y="2.7906749" />
<circle
style="opacity:1;fill:#ffff4d;fill-opacity:1;stroke:none;stroke-width:33.0659;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
id="circle868"
cx="47.234001"
cy="47.234001"
r="16.613539" />
</svg>

After

Width:  |  Height:  |  Size: 2.3 KiB

Before

Width:  |  Height:  |  Size: 2.3 KiB

After

Width:  |  Height:  |  Size: 2.3 KiB

Before

Width:  |  Height:  |  Size: 2.6 KiB

After

Width:  |  Height:  |  Size: 2.6 KiB

Before

Width:  |  Height:  |  Size: 433 B

After

Width:  |  Height:  |  Size: 433 B

Before

Width:  |  Height:  |  Size: 620 B

After

Width:  |  Height:  |  Size: 620 B

Before

Width:  |  Height:  |  Size: 304 B

After

Width:  |  Height:  |  Size: 304 B

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

Before

Width:  |  Height:  |  Size: 851 B

After

Width:  |  Height:  |  Size: 851 B

Before

Width:  |  Height:  |  Size: 420 B

After

Width:  |  Height:  |  Size: 420 B

Before

Width:  |  Height:  |  Size: 543 B

After

Width:  |  Height:  |  Size: 543 B

Before

Width:  |  Height:  |  Size: 260 B

After

Width:  |  Height:  |  Size: 260 B

Before

Width:  |  Height:  |  Size: 257 B

After

Width:  |  Height:  |  Size: 257 B

Before

Width:  |  Height:  |  Size: 228 B

After

Width:  |  Height:  |  Size: 228 B

Before

Width:  |  Height:  |  Size: 219 B

After

Width:  |  Height:  |  Size: 219 B

Before

Width:  |  Height:  |  Size: 626 B

After

Width:  |  Height:  |  Size: 626 B

Before

Width:  |  Height:  |  Size: 255 B

After

Width:  |  Height:  |  Size: 255 B

Before

Width:  |  Height:  |  Size: 865 B

After

Width:  |  Height:  |  Size: 865 B

Before

Width:  |  Height:  |  Size: 337 B

After

Width:  |  Height:  |  Size: 337 B

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 1.6 KiB

Before

Width:  |  Height:  |  Size: 849 B

After

Width:  |  Height:  |  Size: 849 B

Before

Width:  |  Height:  |  Size: 4.0 KiB

After

Width:  |  Height:  |  Size: 4.0 KiB

Before

Width:  |  Height:  |  Size: 5.0 KiB

After

Width:  |  Height:  |  Size: 5.0 KiB

+145
View File
@@ -0,0 +1,145 @@
<template>
<Teleport to="#eventSection" defer>
<div id="eventContainer">
<div class="eventEntry" v-for="item of displayedEvents" :key="item.title" @click="openEvent(item)">
<div class="titleSection">
<p class="title">{{item.title}}</p>
<p class="date">{{item.date}} &rarr; {{item.time}}</p>
</div>
<div class="subtitleSection">
<p class="subtitle">{{item.subtitle}}</p>
</div>
</div>
</div>
</Teleport>
</template>
<style scoped>
#eventContainer{
width:100%;
height: auto;
max-height: 90vh;
overflow-y: scroll;
display: flex;
flex-direction: column;
align-items: center;
gap: 7.77px;
padding-top: 7.77px;
box-sizing: border-box;
@media(min-width: 700px){
max-height: 54vh;
}
@media(min-width: 1300px){
max-height: 46.5vh;
}
.eventEntry{
width: 90%;
height: auto;
display: flex;
flex-direction: column;
justify-content: flex-start;
border-color: var(--back-color);
border-style: solid;
border-width: thin;
border-radius: 16.1px;
flex-shrink: 0;
gap: 0;
mix-blend-mode: exclusion;
filter: contrast(200%);
.titleSection{
width: 100%;
height: 44px;
display: flex;
flex-direction: column;
justify-content: flex-start;
align-items: center;
box-sizing: border-box;
padding-top: 7.77px;
pointer-events: none;
p{
font-family: 'velvelyne';
font-size: 16.1px;
font-weight: bold;
color: var(--back-color);
height: 50%;
margin: 0;
padding: 0;
text-transform: uppercase;
}
p.date{
font-family: 'karrik';
font-weight: normal;
font-size: 9px;
text-transform: none;
}
}
.subtitleSection{
width: 100%;
height: auto;
padding-right: 16.1px;
padding-left: 16.1px;
box-sizing: border-box;
position: relative;
margin-top: 0;
padding-top: 0;
pointer-events: none;
p{
font-family: 'velvelyne';
font-size: 13.12px;
font-weight: normal;
color: var(--back-color);
white-space: pre-line;
}
}
}
.eventEntry:hover{
background-color: var(--back-color);
color: var(--main-color);
mix-blend-mode: normal;
p{
color: var(--main-color);
}
}
}
</style>
<script>
import { watch } from 'vue'
import { lolEventsList } from '../lolEvents.js'
import { dataStorage } from '../dataExchange.js'
export default {
name : 'EventContent',
methods: {
openEvent(obj){
console.log('updating...')
dataStorage.selectedEvent = obj;
if (dataStorage.activePannels.includes('event')){
dataStorage.focus = 'event'
} else {
dataStorage.activePannels.push('event')
dataStorage.focus = 'event'
}
}
},
computed: {
displayedEvents(){
return lolEventsList
}
},
mounted(){
console.log("Event list is loaded!");
}
};
</script>
+115
View File
@@ -0,0 +1,115 @@
<script setup>
import CloseIcon from '../assets/icons/close.svg'
</script>
<template>
<div id="eventPannel" class="windowStyle" ref="eventPannel" @mousedown="$emit('focus')" @touchstart="$emit('focus')">
<Moveable
className="moveable"
:target="target"
:draggable="true"
@drag="onDrag"
/>
<div class="windowTitle">
<p>
{{displayedEvent.title}}
</p>
<button type="button" class="closeBtn" @mousedown.stop="closePannel" @touchstart.stop="closePannel">
<CloseIcon name="close" class="icon"/>
</button>
</div>
<div class="windowContent" id="eventContent">
<p class="date">
{{displayedEvent.date}} &rarr; {{displayedEvent.time}}
</p>
<p>{{displayedEvent.desc}}</p>
</div>
</div>
</template>
<style scoped>
#eventPannel{
position: fixed;
width: 250px;
height: auto;
max-height: 250px;
top: 161px;
left: 77px;
padding-bottom: 3.33px;
@media(min-width:650px){
left: 333px;
}
@media(min-width: 1300px){
width: 333px;
max-height: 333px;
top: 222px;
left: 1000px;
}
#eventContent{
padding: 7.77px;
align-items: flex-start;
justify-content: start;
overflow-y: scroll;
p{
font-family: 'velvelyne';
font-weight: normal;
font-size: 13.12;
color: var(--main-color);
margin: 0;
padding: 0;
margin-bottom: 3.33px;
margin-left: 7.77px;
margin-right: 13.12px;
white-space: pre-line;
}
p.date{
font-family: 'karrik';
}
}
}
</style>
<script>
import Moveable from 'vue3-moveable';
import { dataStorage } from '../dataExchange.js'
export default {
name : 'EventInfoPannel',
components:{
Moveable
},
data(){
return{
target: null
}
},
emits: ['close','focus'],
computed: {
displayedEvent(){
return dataStorage.selectedEvent
},
isActive(){
return dataStorage.eventInfoActive
}
},
methods:{
onDrag({ target, transform }) {
target.style.transform = transform;
},
closePannel(){
this.$emit('close')
}
},
mounted(){
this.target = this.$refs.eventPannel;
console.log("Event info pannel is loaded!");
}
};
</script>
+141
View File
@@ -0,0 +1,141 @@
<script setup>
import CloseIcon from '../assets/icons/close.svg'
</script>
<template>
<div id="linkPannel" class="windowStyle" ref="linkPannel" @mousedown="$emit('focus')" @touchstart="$emit('focus')">
<Moveable
className="moveable"
:target="target"
:draggable="true"
@drag="onDrag"
/>
<div class="windowTitle">
<p>
Liens utiles
</p>
<!-- touchstart.capture pour passer en prio sur déplacement fenêtre/ .stop si pas de method-->
<button type="button" class="closeBtn" @mousedown.capture="$emit('close')" @touchstart.capture="$emit('close')" data-tooltip="fermer">
<CloseIcon name="close" class="icon"/>
</button>
</div>
<div class="windowContent" id="linkContent">
<p id="info">Par ici on poste pleins de truc qu'on trouve utiles, n'hésite pas à fouiller </p>
<a id="linkItem" v-for="item of displayedLinks" :href="item.href" class="textBtnStyle">
<p><strong>{{item.title}}</strong><br>{{item.desc}}</p>
</a>
</div>
</div>
</template>
<style scoped>
/*================= Mise en page:
=> Mobile First : par défaut, moins de 500px
=> Tablette et PC format haut : de 500 à 1000px
=> PC large : à partir de 1000px
*/
/*+++++++++++++++++ COPYBOX
================ PC HAUT/IPAD
@media(min-width:650px){}
================ PC LARGE
@media(min-width:1300px){}
*/
#linkPannel{
position: fixed;
width: 222px;
height: 333px;
top: 222px;
left: 117px;
@media(min-width:650px){
left: 477px;
}
@media(min-width: 1300px){
width: 333px;
height: 444px;
top: 420px;
left: 555px;
}
}
#linkContent{
height: 100%;
overflow-y: scroll;
overflow-x: hidden;
p#info{
padding-right: 7.77px;
padding-left: 7.77px;
font-family: 'velvelyne';
font-weight: normal;
font-size: 13.12px;
color: var(--main-color);
border-width: 0 0 1.61px 0;
border-style: solid;
border-color: var(--main-color);
padding-bottom: 7.77px;
margin-bottom: 0;
}
}
#linkItem{
width: 100%;
padding-right: 13.12px;
padding-left: 13.12px;
font-family: 'velvelyne';
font-size: 13.12px;
border-radius: 0;
border-width: 0 0 1.61px 0;
text-align: left;
justify-content: flex-start;
box-sizing: border-box;
strong{
text-transform: uppercase;
font-family: 'karrik';
font-weight: normal;
font-size: 16.1px;
}
p{
border-width: 0;
padding-bottom: 0;
margin-bottom: 7.77px;;
}
}
</style>
<script>
import Moveable from 'vue3-moveable';
import { lolLinkList } from '../lolLinks.js'
export default {
name : 'LinkPannel',
components:{
Moveable
},
data(){
return{
target: null
}
},
emits: ['close','focus'],
computed: {
displayedLinks(){
return lolLinkList
}
},
methods:{
onDrag({ target, transform }) {
target.style.transform = transform;
}
},
mounted(){
this.target = this.$refs.linkPannel;
console.log("Link pannel is loaded!");
}
};
</script>
+204
View File
@@ -0,0 +1,204 @@
<script setup>
import CloseIcon from '../assets/icons/close.svg'
import PlayIcon from '../assets/icons/play.svg'
import PauseIcon from '../assets/icons/pause.svg'
import NextIcon from '../assets/icons/next.svg'
import PrevIcon from '../assets/icons/prev.svg'
</script>
<template>
<div id="playerPannel" class="windowStyle" ref="playerPannel" @mousedown="$emit('focus')" @touchstart="$emit('focus')">
<Moveable
className="moveable"
:target="target"
:draggable="true"
@drag="onDrag"
/>
<button type="button" class="closeBtn" @mousedown.capture="$emit('close')" @touchstart.capture="$emit('close')" data-tooltip="fermer">
<CloseIcon name="close" class="icon"/>
</button>
<div class="windowContent" id="playerContent">
<div id="credits">
<marquee direction="left" behavior="scroll" scrollamount="7" width="100%">{{selectedSong.track}} {{selectedSong.artist}}</marquee>
</div>
<div id="controls">
<button type="button" class="iconBtnStyle" @mousedown.stop @touchstart.stop @click="prevTrack" data-tooltip="précédente">
<PrevIcon name="prev" class="icon"/>
</button>
<button type="button" class="iconBtnStyle" @mousedown.stop @touchstart.stop @click="toggleAudio" data-tooltip="lancer">
<component :is="isPlaying? PauseIcon : PlayIcon" class="icon"/>
</button>
<button type="button" class="iconBtnStyle" @mousedown.stop @touchstart.stop @click="nextTrack" data-tooltip="suivante">
<NextIcon name="next" class="icon"/>
</button>
</div>
<audio ref="selectedAudio" @ended="nextTrack">
<source :src="audioFile" type="audio/mpeg">
</audio>
</div>
</div>
</template>
<style scoped>
/*================= Mise en page:
=> Mobile First : par défaut, moins de 500px
=> Tablette et PC format haut : de 500 à 1000px
=> PC large : à partir de 1000px
*/
/*+++++++++++++++++ COPYBOX
================ PC HAUT/IPAD
@media(min-width:650px){}
================ PC LARGE
@media(min-width:1300px){}
*/
#playerPannel{
position: fixed;
width: 222px;
height: auto;
top: 222px;
left: 117px;
box-sizing: border-box;
cursor: move;
@media(min-width:700px){
left: 477px;
}
@media(min-width: 1300px){
width: 333px;
top: 333px;
left: 333px;
}
.closeBtn{
position: absolute;
align-self: flex-end;
margin-right: 3.33px;
margin-top: 3.33px;
}
}
#playerContent{
margin-top: 40px;
#credits{
width: 100%;
height: 44px;
background-color: var(--main-color);
padding-left: 7.77px;
padding-right: 7.77px;
padding-top: 13.12px;
margin-bottom: 13.12px;
marquee{
color: var(--back-color);
font-family: 'pressStart2P';
font-size: 22px;
font-weight: normal;
}
}
#controls{
width: 100%;
height: auto;
display: flex;
flex-direction: row;
justify-content: space-around;
margin-bottom: 13.12px;
.iconBtnStyle{
width: 33px;
height: 33px;
}
}
}
</style>
<script>
import { loadAudioData } from '../data/audioData.js'
import Moveable from 'vue3-moveable';
export default {
name : 'PlayerPannel',
components:{
Moveable
},
data(){
return{
target: null,
audioTarget: null,
selectedSong:{
track: "",
artist: "",
src: ""
},
audioFile:"",
audioCredits:"",
trackCount: 0,
isPlaying: false
}
},
computed: {
audioData(){
return loadAudioData
}
},
emits: ['close','focus'],
methods: {
onDrag({ target, transform }) {
target.style.transform = transform;
},
loadAudio(){
//console.log(this.target);
this.audioTarget.pause();
this.selectedSong = this.audioData[this.trackCount];
this.audioFile = this.selectedSong.src;
this.audioCredits = ' ' + this.selectedSong.track +' - '+ this.selectedSong.artist;
this.audioTarget.volume = 1;
this.audioTarget.load();
if(this.isPlaying){
this.audioTarget.play();
}
},
toggleAudio(){
if(this.isPlaying){
this.audioTarget.pause();
}else{
this.audioTarget.play();
}
this.isPlaying = !this.isPlaying;
},
prevTrack(){
this.trackCount -= 1;
if (this.trackCount<0){
this.trackCount = this.audioData.length - 1;
}
//console.log('prev:', this.trackCount);
this.loadAudio();
},
nextTrack(){
this.trackCount += 1;
if (this.trackCount>=this.audioData.length){
this.trackCount = 0;
}
//console.log('next:', this.trackCount);
this.loadAudio();
}
},
async mounted(){
this.target = this.$refs.playerPannel;
this.audioTarget = this.$refs.selectedAudio;
console.log('AUDIO/', this.audioData);
this.loadAudio();
console.log("Player pannel is loaded!");
}
};
</script>
+82
View File
@@ -0,0 +1,82 @@
<template>
<div id="lolStatusContainer">
<p ref="lolStatus">{{statusText}}</p>
</div>
</template>
<style scoped>
#lolStatusContainer{
width: 161px;
height: 33px;
background-color: var(--main-color);
color: var(--back-color);
border-color: var(--main-color);
border-style: solid;
border-width: thin;
border-radius: 33px;
display: flex;
align-items: center;
justify-content: space-around;
padding-bottom: 7.77px;
margin-left: 1.61vw;
padding-left: 3.33px;
filter: contrast(200%) saturate(200%);
p{
font-family: 'pressStart2P';
font-size: 16.1px;
letter-spacing: 1.61px;
font-weight: normal;
}
}
#lolOpener #lolStatusContainer{
padding-top: 3.33px;
margin-left: 0;
width: 90%;
align-self: center;
@media(min-width: 700px){
width: 44%;
}
}
</style>
<script>
import { lolState } from '../lolStatus.js'
import { watch } from 'vue'
export default {
name : 'lolStatus',
data(){
return{
statusText: 'FERMÉ...'
}
},
methods: {
updateVisibleStatus(){
let currentTheme = this.lolCurrentStatus ? 'open' : 'closed';
let pageIcon = document.querySelector('link');
//console.log(currentTheme);
console.log(pageIcon.href);
this.statusText = this.lolCurrentStatus ? 'OUVERT !' : 'FERMÉ...';
document.documentElement.setAttribute('data-theme' , currentTheme);
document.querySelector('link').href = this.lolCurrentStatus ? './src/assets/favicon_open.svg' : './src/assets/favicon.svg'
this.$refs.lolStatus.style.animation = this.lolCurrentStatus ? 'blink 3.33s infinite' : 'none';
}
},
computed: {
lolCurrentStatus(){
return lolState.isOpen
}
},
onMounted(){
watch(() => this.lolCurrentStatus, () => this.updateVisibleStatus())
},
mounted(){
this.updateVisibleStatus();
console.log("LOL status is loaded!");
}
};
</script>
+25
View File
@@ -0,0 +1,25 @@
import { reactive } from 'vue'
import audio01 from './juste-tek.mp3'
import audio02 from './sinking-into-.mp3'
import audio03 from './technoloooogia.mp3'
export const loadAudioData = reactive (
[
{
track: 'the sink',
artist: '333',
src: audio02
},
{
track: 'just tek',
artist: '333',
src: audio01
},
{
track: 'Technolooooogia',
artist: '333',
src: audio03
}
]
)
Binary file not shown.
Binary file not shown.
Binary file not shown.
+13
View File
@@ -0,0 +1,13 @@
import { reactive } from 'vue'
export const dataStorage = reactive({
selectedEvent: {
title: '',
date: '',
time: '',
subtitle: '',
desc: ''
},
activePannels: [],
focus: ''
})
+34
View File
@@ -0,0 +1,34 @@
import { reactive } from 'vue'
export const lolEventsList = reactive(
[
{
title: 'test-01',
date: '13/12/26',
time: '13h12',
subtitle: 'test event 001',
desc: 'ça marche !'
},
{
title: 'test-02',
date: '13/12/26',
time: '13h12',
subtitle: 'test event 002',
desc: 'oui je crois bien'
},
{
title: 'test-333',
date: '13/12/26',
time: '13h12',
subtitle: 'test event 333 \n test event 333 \n test event 333 \n test event 333',
desc: 'super !'
},
{
title: 'test-004',
date: '13/12/26',
time: '13h12',
subtitle: 'test event 004',
desc: 'test de très longue description: \n Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.'
}
]
)
+31
View File
@@ -0,0 +1,31 @@
import { reactive } from 'vue'
export const lolLinkList = reactive(
[
{
title: 'test',
desc: 'blah blah description du truc test',
href: '#'
},
{
title: 'test 0002',
desc: 'blah blah description du truc test',
href: '#'
},
{
title: 'test 333',
desc: 'encore une autre description du truc test',
href: '#'
},
{
title: 'test 0002',
desc: 'blah blah description du truc test',
href: '#'
},
{
title: 'test 333',
desc: 'encore une autre description du truc test',
href: '#'
}
]
)
+7
View File
@@ -0,0 +1,7 @@
import { reactive } from 'vue'
export const lolState = reactive(
{
isOpen: false
}
)
+37
View File
@@ -0,0 +1,37 @@
import { createApp } from 'vue'
// import CSS global
import './style.css'
// import app vue racine
import App from './App.vue'
// import composants
import lolStatus from './components/lolStatus.vue'
import EventContent from './components/EventContent.vue'
import EventInfoPannel from './components/EventInfoPannel.vue'
import PlayerPannel from './components/PlayerPannel.vue'
import LinkPannel from './components/LinkPannel.vue'
// création app racine
const app = createApp(App);
//Composants
app.component('lolStatusDiv', lolStatus);
app.component('eventDiv', EventContent);
app.component('eventPannel', EventInfoPannel);
app.component('playerPannel', PlayerPannel);
app.component('linkPannel', LinkPannel);
//Démarrage dans div#app de index.html
app.mount('#app');
let menuActive = false;
document.documentElement.setAttribute('data-theme', 'closed');
document.querySelector('#menuBtn').addEventListener('click', () => {
let target = document.querySelector('#mainContainer .right');
let btnIcon = document.querySelector('#menuBtn .icon')
menuActive = !menuActive
target.style.display = menuActive ? 'flex' : 'none';
target.style.visibility = menuActive ? 'visible' : 'collapse';
btnIcon.classList.toggle('rotated');
})
+719
View File
@@ -0,0 +1,719 @@
:root[data-theme="closed"]{
--back-color: #FFFF4D;
--main-color: #000000;
}
:root[data-theme="open"]{
--back-color: #00FF44;
--main-color: #000000;
}
/*====================Typo*/
@font-face {
font-family: 'karrik';
src: url('./typo/Karrik-Italic.woff2').format('woff2');
font-style: italic;
}
@font-face {
font-family: 'karrik';
src: url('./typo/Karrik-Regular.woff2') format('woff2');
font-style: normal;
}
@font-face {
font-family: 'velvelyne';
src: url('./typo/Velvelyne-Book.ttf') format('truetype');
font-weight: normal;
}
@font-face {
font-family: 'avara';
src: url('./typo/Avara-Black.woff2') format('woff2');
}
@font-face {
font-family: 'pressStart2P';
src: url('./typo/PressStart2P-Regular.ttf') format('truetype');
}
@font-face {
font-family: 'velvelyne';
src:url('./typo/Velvelyne-Bold.ttf') format('truetype');
font-weight: bold;
}
/*===================Animation*/
@keyframes blink {
0% { color: var(--back-color);}
15% { color: var(--main-color);}
35% { color: var(--main-color);}
50% { color: var(--back-color);}
65% { color: var(--main-color);}
85% { color: var(--main-color);}
100% { color: var(--back-color);}
}
@keyframes blinkBack {
0% { background-color: var(--back-color);}
15% { background-color: var(--main-color);}
35% { background-color: var(--main-color);}
50% { background-color: var(--back-color);}
65% { background-color: var(--main-color);}
85% { background-color: var(--main-color);}
100% { background-color: var(--back-color);}
}
@keyframes blinkBorder {
0% { border-color: var(--main-color);}
15% { border-color: var(--accent-color);}
35% { border-color: var(--accent-color);}
50% { border-color: var(--main-color);}
65% { border-color: var(--accent-color);}
85% { border-color: var(--accent-color);}
100% { border-color: var(--main-color);}
}
@keyframes float {
0% { transform: translateY(0px); }
35% { transform: translateY(1px); }
50% { transform: translateY(-10px); }
65% { transform: translateY(1px); }
100% { transform: translateY(0px); }
}
/*=============Désact défault*/
input {
-webkit-appearance: none !important;
appearance: none !important;
}
a{
text-decoration: none;
color: inherit;
cursor: alias;
}
button{
cursor: cell;
}
a p{
cursor:inherit;
}
a button{
cursor: inherit;
}
p{
cursor: inherit;
pointer-events: none !important;
}
.dg{
display: none !important;
height: 0;
overflow: hidden;
}
/*==========================Moveable*/
.moveable-control-box {
display: none !important;
}
/*=============Body & background*/
html, body{
margin: 0;
padding: 0;
background-color: var(--main-color);
width: 100%;
height:100%;
position: fixed;
inset: 0;
overflow-x: hidden;
overflow-y: scroll;
display: block;
scrollbar-color: var(--back-color) var(--main-color);
scrollbar-width: thin;
z-index: -33;
}
#canvas{
position: fixed;
inset: 0;
width: 100%;
height: 100%;
pointer-events: none;
mix-blend-mode: screen;
z-index: -2;
opacity: .25;
filter: saturate(333%);
}
#background{
position: fixed;
right: 0;
bottom: 0;
width: auto;
height: 133%;
overflow: hidden;
pointer-events: none;
z-index: -1;
opacity: 1;
visibility: hidden;
filter: contrast(200%) saturate(33%) grayscale();
transform: rotate(180deg);
mix-blend-mode: difference;
@media(min-width: 700px){
height: 200%;
}
}
#mainContainer{
display: flex;
flex-direction: column;
align-items: flex-start;
justify-content: flex-start;
width: 100%;
height: auto;
gap: 0;
}
/*=====================BUTTONS*/
.textBtnStyle{
font-family: 'karrik';
font-size: 13.12px;
background-color: var(--back-color);
color: var(--main-color);
border-color: var(--main-color);
border-style: solid;
border-width: 1.75px;
border-radius: 16.1px;
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-around;
}
.textBtnStyle:hover{
background-color: var(--main-color);
color: var(--back-color);
font-weight: bold;
}
.iconBtnStyle{
background-color: var(--back-color);
color: var(--main-color);
border-color: var(--main-color);
border-style: solid;
border-width: thin;
border-radius: 0;
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-around;
}
.iconBtnStyle:hover{
background-color: var(--main-color);
color: var(--back-color);
}
/*==============FENETRES*/
.windowStyle{
display: flex;
flex-direction: column;
align-items: center;
justify-content: flex-start;
background-color: var(--back-color);
border-style: solid;
border-width: thin;
border-radius: 16.1px;
border-color: var(--main-color);
overflow: hidden;
}
.zBase{
z-index: 333;
}
.zFocus{
z-index: revert;
z-index: 1312;
}
.windowTitle{
width:100%;
height:50px;
background-color: var(--main-color);
border-radius: 0;
font-family: 'velvelyne';
font-weight: bold;
text-transform: uppercase;
font-size: 22px;
color: var(--back-color);
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-between;
box-sizing: border-box;
padding-left: 10px;
padding-right: 10px;
cursor: move;
}
.windowTitleLower{
font-family: 'velvelyne';
font-weight: bold;
font-size: 13.12px;
}
.closeBtn{
color: var(--back-color);
background-color: var(--main-color);
border-style: solid;
border-width: thin;
border-radius: 16.1px;
border-color: var(--back-color);
width: 33px;
height: 33px;
align-items: center;
}
.closeBtn:hover{
color: var(--main-color);
background-color: var(--back-color);
}
.windowContent{
height:77%;
width:100%;
display: flex;
flex-direction: column;
align-items: center;
justify-content: flex-start;
}
/*=============INTERFACE*/
.uiStyle{
background-color: var(--back-color);
border-color: var(--main-color);
border-style: solid;
border-width: thin;
}
.icon{
height: 16.1px;
width: auto;
fill: currentColor;
pointer-events: none;
}
#topBar{
position: relative;
top: 0;
left: 0;
width: 100vw;
height: 50px;
z-index: 333;
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-between;
color: var(--main-color);
padding-left: 7.77px;
padding-right: 16.1px;
gap: 7.77px;
box-sizing: border-box;
p{
font-family: 'velvelyne';
font-size: 40px;
font-weight: bold;
padding-top: 7.77px;
}
#mainLogo{
height: auto;
width: 50px;
}
.left{
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-around;
width: auto;
gap: 7.77px;
height: 100%;
}
.right{
display: none;
visibility: collapse;
flex-direction: column;
align-items: center;
justify-content: space-around;
width:33%;
height: 200px;
position: absolute;
top: 55px;
right: 3.33px;
z-index: 3;
.textBtnStyle{
width: 16.1%;
min-width: 93px;
height: 33px;
text-transform: uppercase;
}
.textBtnStyle:hover{
border-color: var(--back-color);
}
}
.iconBtnStyle{
width: 33px;
height: 33px;
}
#menuBtn{
.icon.rotated{
transform: rotate(0);
}
.icon{
transform: rotate(45deg);
}
}
@media(min-width: 700px){
#menuBtn{
display: none;
visibility: collapse;
}
.right{
display: flex;
visibility: visible;
flex-direction: row;
align-items: center;
justify-content: space-around;
width:70%;
height: 100%;
position: relative;
top: 0;
left: 0;
}
}
}
#mainInfo{
display: grid;
grid-template-columns: 1fr 1fr;
grid-template-rows: 1fr 2fr 1fr;
grid-template-areas:
"topL topR"
"midL midR"
"botL botR";
box-sizing: border-box;
width: 100vw;
height: auto;
align-items: stretch;
.uiStyle{
width:100%;
height: auto;
padding-left: 7.77px;
box-sizing: border-box;
font-family: 'velvelyne';
font-size: 13.12px;
font-weight: bold;
}
#planContainer{
width: 200%;
height: auto;
color: var(--back-color);
display: flex;
flex-direction: column;
align-items: center;
#plan{
position: relative;
width: 90%;
margin-bottom: 13.12px;
}
#fleche{
position: absolute;
width: 90%;
fill: currentColor;
z-index: -1;
}
@media(max-width: 700px){
grid-row: 2;
grid-column: 1 / 2;
}
}
#title{
grid-area: topL;
font-size: 22px;
line-height: .7;
height: 100%;
#desc{
font-family: 'velvelyne';
font-style: normal;
font-size: 13.12px;
line-height: 1em;
text-transform: uppercase;
}
}
#address{
grid-area: topR;
font-family: 'karrik';
color: var(--back-color);
font-style: normal;
font-size: 13.12px;
line-height: 1em;
text-transform: uppercase;
padding-left: 13.12px;
mix-blend-mode: exclusion;
#hackerLogo{
width: 77px;
height: 50px;
display:inline-block;
position: absolute;
right: 13.12px;
top: 117px;
z-index: 33;
img{
width: 77px;
height: auto;
pointer-events: none;
cursor: inherit;
}
}
}
#openingHours{
grid-area: botL;
text-align: right;
padding-right: 13.12px;
font-weight: normal;
line-height: 1em;
margin-top: -13.12px;
strong{
font-weight: bold;
}
}
#lolOpener{
grid-area: botR;
font-weight: normal;
padding-right: 7.77px;
line-height: 1em;
display: flex;
flex-direction: column;
align-items: flex-start;
position: relative;
gap: 0;
height: auto;
}
@media(min-width: 700px){
grid-template-columns: 1fr 2fr;
grid-template-rows: 161px 222px 77px;
height: auto;
.uiStyle{
font-size: 16.1px;
}
#planContainer{
height: 90%;
width: auto;
grid-row: 2;
grid-column: 2;
margin-left: 0;
margin-top: -100px;
#plan{
width:90%;
height: auto;
margin-bottom: 0;
max-height: 333px;
}
#fleche{
width:60%;
height: auto;
box-sizing: border-box;
max-height: 333px;
}
}
#openingHours{
grid-area: midL;
height: 60%
}
#lolOpener{
width: 300%;
grid-column: 1 / 2;
grid-row: 3;
flex-direction: row;
gap: 7.77px;
align-items: center;
justify-content: space-between;
padding-left: 16.1px;
height: 77px;
#desc{
width: 44%;
box-sizing: border-box;
}
}
#title{
margin-bottom: 3.33px;
font-size: 27px;
line-height: 0;
#desc{
font-size: 16.1px;
}
}
#address #hackerLogo{
grid-area: midL;
position: relative;
top: 0;
left: 7.77px;
right: unset;
}
}
@media(min-width: 1300px){
grid-template-rows: 222px 500px 77px;
.uiStyle{
font-size: 16.1px;
}
#lolOpener{
font-size: 22px;
}
#address{
font-size: 22px;
#hackerLogo{
width: 117px;
}
}
#openingHours{
font-size: 33px;
}
#title{
margin-bottom: 3.33px;
font-size: 44px;
line-height: 0;
#desc{
font-size: 22px;
}
}
#planContainer {
margin-top: -117px;
margin-bottom: 77px;
#fleche{
width: 60%;
max-height: 666px;
}
#plan{
max-height: 666px;
}
}
}
}
#aboutSection{
position: relative;
top: 0;
left: 0;
display: flex;
flex-direction: row;
align-items: flex-start;
justify-content: flex-start;
box-sizing: border-box;
height: 50vh;
#aboutText{
width: 60%;
height: auto;
padding-left: 13.12px;
padding-right: 13.12px;
padding-bottom: 13.12px;
overflow-y: scroll;
@media(min-width: 700px){
height: 60vh;
}
@media(min-width: 1300px){
height: 50vh;
padding-left: 33px;
}
p{
font-family: 'velvelyne';
font-weight: normal;
font-size: 13.12px;
color: var(--main-color);
@media(min-width: 1300px){
font-size: 20px;
}
}
}
#eventSection{
width: 40%;
height: 100%;
position: relative;
#title{
height: 44px;
padding-top: 7.77px;
padding-left: 7.77px;
box-sizing: border-box;
font-family: 'karrik';
font-style: italic;
font-size: 13.12px;
text-transform: uppercase;
color: var(--main-color);
pointer-events: none !important;
cursor: inherit;
}
}
}
-88
View File
@@ -1,88 +0,0 @@
:root {
--back-color: #FFFF4D;
--main-color: #000000;
}
/*======================= Page Statut LOL fermé ===*/
#lolIsClosed {
position: relative;
top: 0;
left: 0;
margin: 0;
width: 100vw;
height: 100vh;
background-color: var(--main-color);
#closedContainer {
padding: 15px;
box-sizing: border-box;
}
.cute-texture {
position: fixed;
left: 0;
top: 0;
width: 100%;
height: 100%;
z-index: -1;
}
}
#closedContainer{
width:100%;
height: 100%;
border-radius: 33px;
display:flex;
flex-direction: column;
justify-content: space-around;
align-items: center;
section{
width: 333px;
height: 117px;
background-color: var(--back-color);
display: flex;
flex-direction: column;
align-items: center;
justify-content: flex-start;
padding-top: 33px;
margin-top: -77px;
border-radius: 33px;
p{
padding: 0;
margin: 0;
text-transform: none;
font-size: 22px;
font-family: 'velvelyne';
font-weight: bold;
color: var(--main-color);
}
h3{
width: 277px;
height: 50px;
background-color: var(--main-color);
color: var(--back-color);
border-radius: 33px;
text-transform: uppercase;
text-align: center;
font-size: 33px;
font-family: 'karrik';
font-weight: normal;
padding: 0;
margin: 0;
padding-top: 7.77px;
}
}
}
-58
View File
@@ -1,58 +0,0 @@
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="icon" type="image/svg" href="../assets/favicon.svg" />
<link rel="stylesheet" href="/status/closedStyle.css">
<link rel="stylesheet" href="../style/animation.css">
<link rel="stylesheet" href="/style/typo.css">
<title>Le LOL est Fermé ...</title>
</head>
<body id="lolIsClosed">
<canvas data-cute-texture class="cute-texture"></canvas>
<main id="closedContainer">
<section>
<p>Le LOL est actuellement</p>
<h3 id="lolStatus">fermé ...</h3>
</section>
</main>
<script type="x-shader/glsl+fragment">
// Some random values computed for each frame
uniform highp vec4 uRandom;
// Size (in logical pixel) of current CuteTexture canvas
uniform highp vec2 uCanvasSize;
// Coordinates of current pixel being computed from [0,0] (top left) to [1,1] (bottom right)
varying highp vec2 vTextureCoord;
void main() {
highp float pixelSize = 50.0;
highp vec2 coords = floor((uCanvasSize.xy * vTextureCoord.xy) / pixelSize);
highp float lum = (noise1(uRandom.yz+coords) * 0.631372549);
lowp float opacity = 0.5;
highp vec4 baseColor = vec4(
0.0,
lum,
lum,
1.0
);
highp vec4 rotatedColor = hue_rotate(baseColor, 13.12);
gl_FragColor = vec4(
rotatedColor.x*opacity,
rotatedColor.y*opacity,
rotatedColor.z*opacity,
1.0
);
}
</script>
<script type="module">
import {initCuteTexture} from "../js/cuteTexture.js"
initCuteTexture()
</script>
</body>
</html>
-70
View File
@@ -1,70 +0,0 @@
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="icon" type="image/svg" href="../assets/favicon_open.svg" />
<!-- STYLE A IMPORTER EN 1ER -->
<link rel="stylesheet" href="/status/openStyle.css">
<link rel="stylesheet" href="../style/animation.css">
<title>Le LOL est Ouvert</title>
</head>
<body id="lolIsOpen">
<video data-cute-texture-video class="cute-texture-video" src="/assets/video/background.webm" autoplay muted loop ></video>
<canvas data-cute-texture class="cute-texture"></canvas>
<main id="openContainer">
<section>
<p>Le LOL est actuellement</p>
<h3 id="lolStatus">ouvert !</h3>
</section>
</main>
<script type="x-shader/glsl+fragment">
// Some random values computed for each frame
uniform highp vec4 uRandom;
// Size (in logical pixel) of current CuteTexture canvas
uniform highp vec2 uCanvasSize;
// Number of seconds since canvas was initialized
uniform lowp float uTime;
// Current frame of first video with [data-cute-texture-video] attribute
uniform sampler2D uVideo;
// Coordinates of current pixel being computed from [0,0] (top left) to [1,1] (bottom right)
varying highp vec2 vTextureCoord;
void main() {
highp float waveSize = 10.0;
highp vec2 coords = (uCanvasSize.xy * vTextureCoord.xy) / waveSize;
highp float lum = abs(sin(coords.y-uTime)) + 0.631372549;
lowp float opacity = 0.25;
gl_FragColor = vec4(
0.0,
lum,
0.0,
1.0
);
gl_FragColor = vec4(
gl_FragColor.rgb * opacity,
1.0
);
highp vec2 videoCoords = (vTextureCoord.xy / 1.5) + vec2(0, 0.25);
highp vec4 videoPix = clamp(( grayscale(texture2D(uVideo, videoCoords), 1.0) * 2.0 ), vec4(0), vec4(1));
videoPix *= 0.777;
gl_FragColor = abs( (videoPix*1.2) - gl_FragColor );
gl_FragColor.xyz *= 0.9;
gl_FragColor.a = 1.0;
}
</script>
<script type="module">
import {initCuteTexture} from "../js/cuteTexture.js"
initCuteTexture()
</script>
</body>
</html>
-118
View File
@@ -1,118 +0,0 @@
:root {
--back-color: #00FF44;
--main-color: #000000;
}
.closedBackground{
visibility: collapse;
}
.openBackground{
position: absolute;
visibility: visible;
opacity: 1;
z-index: -20
}
.openBackground#texture{
z-index: -30;
}
.openBackground#background{
mix-blend-mode: difference;
filter: brightness(133%) saturate(33%) grayscale();
transform: rotate(180deg);
position: absolute;
margin-top: -9%;
height: 120%;
opacity: .777;
}
/*======================= Page Statut LOL ouvert ===*/
#lolIsOpen {
position: relative;
top: 0;
left: 0;
margin: 0;
width: 100vw;
height: 100vh;
background-color: var(--main-color);
#openContainer {
padding: 15px;
box-sizing: border-box;
}
.cute-texture, .cute-texture-video {
position: fixed;
left: 0;
top: 0;
width: 100%;
height: 100%;
z-index: -1;
}
}
#openContainer{
width:100%;
height: 100%;
border-radius: 33px;
display:flex;
flex-direction: column;
justify-content: space-around;
align-items: center;
section{
width: 333px;
height: 117px;
background-color: var(--back-color);
display: flex;
flex-direction: column;
align-items: center;
justify-content: flex-start;
padding-top: 33px;
margin-top: -77px;
border-radius: 33px;
p{
padding: 0;
margin: 0;
text-transform: none;
font-size: 22px;
font-family: 'velvelyne';
font-weight: bold;
color: var(--main-color);
}
h3{
width: 277px;
height: 50px;
background-color: var(--main-color);
color: var(--back-color);
border-radius: 33px;
text-transform: uppercase;
text-align: center;
font-size: 33px;
font-family: 'karrik';
font-weight: normal;
padding: 0;
margin: 0;
padding-top: 7.77px;
}
}
}
#lolStatus{
animation: blink 3.33s infinite;
}
-23
View File
@@ -1,23 +0,0 @@
#!/bin/bash
if [ "$#" = "0" ]; then
echo "Usage set-status.sh [new-status]"
echo ""
echo "[new-status] can be \"opened\" or \"closed\""
echo ""
exit 1
fi
#SPACE_JSON=/var/www/html/spaceapi/space.json
if [ "$1" = "opened" ]; then
ln -sf "index.ouvert.html" "$(dirname $0)/index.html"
#jq "setpath([\"state\", \"open\"]; true) | setpath([\"state\", \"lastchange\"]; $(date +%s))" < $SPACE_JSON > $SPACE_JSON.new &&
#mv -f $SPACE_JSON.new $SPACE_JSON
fi
if [ "$1" = "closed" ]; then
ln -sf "index.fermé.html" "$(dirname $0)/index.html"
#jq "setpath([\"state\", \"open\"]; false) | setpath([\"state\", \"lastchange\"]; $(date +%s))" < $SPACE_JSON > $SPACE_JSON.new &&
#mv -f $SPACE_JSON.new $SPACE_JSON
fi
-37
View File
@@ -1,37 +0,0 @@
@keyframes blink {
0% { color: var(--main-color);}
15% { color: var(--back-color);}
35% { color: var(--back-color);}
50% { color: var(--main-color);}
65% { color: var(--back-color);}
85% { color: var(--back-color);}
100% { color: var(--main-color);}
}
@keyframes blinkBack {
0% { background-color: var(--back-color);}
15% { background-color: var(--main-color);}
35% { background-color: var(--main-color);}
50% { background-color: var(--back-color);}
65% { background-color: var(--main-color);}
85% { background-color: var(--main-color);}
100% { background-color: var(--back-color);}
}
@keyframes blinkBorder {
0% { border-color: var(--main-color);}
15% { border-color: var(--accent-color);}
35% { border-color: var(--accent-color);}
50% { border-color: var(--main-color);}
65% { border-color: var(--accent-color);}
85% { border-color: var(--accent-color);}
100% { border-color: var(--main-color);}
}
@keyframes float {
0% { transform: translateY(0px); }
35% { transform: translateY(1px); }
50% { transform: translateY(-10px); }
65% { transform: translateY(1px); }
100% { transform: translateY(0px); }
}
-187
View File
@@ -1,187 +0,0 @@
.textBtnStyle{
display: flex;
flex-direction: column;
justify-content: space-around;
align-items: center;
text-align: center;
border-radius: 16.1px;
border-style: solid;
border-width: thin;
padding: 3.33px;
padding-left: 7.77px;
font-family: 'karrik';
font-size: 16.1px;
text-transform: uppercase;
border-color: var(--main-color);
color: var(--main-color);
background-color: var(--back-color);
}
.textBtnStyle:hover{
color: var(--back-color);
background-color: var(--main-color);
border-color: var(--back-color);
}
.iconBtnStyle{
display: flex;
flex-direction: column;
align-items: center;
justify-content: space-around;
text-align: center;
border-radius: 16.1px;
border-style: solid;
border-width: thin;
border-color: var(--main-color);
color: var(--main-color);
background-color: var(--back-color);
}
.icon{
height: 16.1px;
width: auto;
fill: currentColor;
pointer-events: none;
}
.iconBtnStyle:hover{
color: var(--back-color);
background-color: var(--main-color);
border-color: var(--back-color);
animation: none;
}
@media(min-width: 1300px){
.textBtnStyle{
font-size: 19px;
}
.iconBtnStyle{
font-size: 19px;
}
}
.solidBox{
width: 100%;
height: 100%;
position: relative;
z-index: 0;
border-radius: 0;
border-style: solid;
border-width: thin;
padding: 7.77px;
border-color: var(--main-color);
color: var(--main-color);
background-color: var(--back-color);
font-family: 'velvelyne';
font-weight: bold;
font-size: 16.1px;
box-sizing: border-box;
}
.transparentBox{
width: 100%;
height: 100%;
position: relative;
z-index: 0;
padding: 7.77px;
color: var(--back-color);
background-color: transparent;
font-family: 'karrik';
text-transform: uppercase;
font-size: 16.1px;
box-sizing: border-box;
}
.borderBox{
width: 95%;
height: 95%;
position: relative;
z-index: 0;
border-radius: 0;
border-style: solid;
border-width: medium;
padding: 7.77px;
padding-right: 13.12px;
border-color: var(--main-color);
color: var(--back-color);
background-color: transparent;
box-sizing: border-box;
}
.floatingWindow{
position: relative;
z-index: 3333;
width: auto;
height: auto;
background-color: var(--back-color);
border-color: var(--main-color);
border-radius: 16.1px;
border-style: solid;
border-width: thin;
overflow: hidden;
box-sizing: content-box;
display: flex;
flex-direction: column;
justify-content: flex-start;
align-items: center;
.title{
position: relative;
top: 0;
width: 100%;
height: 44px;
background-color: var(--main-color);
color: var(--back-color);
text-transform: none;
font-size: 15px;
font-family: 'velvelyne';
font-weight: bold;
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-between;
padding-left: 16.1px;
padding-right: 7.77px;
box-sizing: border-box;
cursor: move;
h4{
pointer-events: none;
}
.iconBtnStyle{
width: 27px;
height: 27px;
.icon{
height: 13.12px;
width: auto;
}
}
}
}
-39
View File
@@ -1,39 +0,0 @@
input {
-webkit-appearance: none !important;
appearance: none !important;
}
a{
text-decoration: none;
color: inherit;
cursor: alias;
}
button{
cursor: cell;
}
a p{
cursor:inherit;
}
a button{
cursor: inherit;
}
p,h1,h2,h3,h4{
cursor: inherit;
pointer-events: none !important;
padding: 0;
margin: 0;
}
ul,ol {
padding: 0;
margin: 0;
list-style-type: none;
}
dialog{
padding: 0;
}
-594
View File
@@ -1,594 +0,0 @@
/*================ GAMME COLOR ======================*/
:root{
--back-color: #FFFF4D;
--main-color: #000000;
}
/*================ BODY ======================*/
html{
margin: 0;
padding: 0;
scrollbar-color: var(--back-color) var(--main-color);
background-color: var(--main-color);
height: 100%;
width: 100%;
overflow-x: hidden;
overflow-y: scroll;
position: relative;
z-index: -33;
}
body{
margin: 0;
padding: 0;
width: 100%;
height: auto;
overflow-y: hidden;
position: relative;
z-index: -33;
box-sizing: border-box;
}
/*================ STRUCTURE ======================*/
header{
width: 100%;
height: 93px;
margin: 0;
position: relative;
top:0;
z-index: 0;
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: center;
border-style: solid;
border-width: 0 0 1.61px 0;
border-color: var(--main-color);
background-color: var(--back-color);
h1{
display: flex;
flex-direction: row;
justify-content: flex-start;
align-items: center;
gap: 13.12px;
padding-left: 13.12px;
margin-bottom: 13.12px;
img{
height: 50px;
width: auto;
}
.cool-name{
font-family: 'karrik';
font-size: 50px;
padding-top: 13.12px;
.trans-symbol{
font-family: 'velvelyne';
font-weight: bold;
}
}
.plain-name{
position: relative;
z-index: -33;
opacity: 0;
width: 0;
}
}
nav > ul{
width: auto;
height: 100%;
margin: 0;
display: flex;
flex-direction: column;
justify-content: space-between;
align-items: center;
margin-right: 7.77px;
margin-top: 13.12px;
.textBtnStyle{
border-radius: 0;
width: 117px;
}
}
}
noscript > video{
height: 110%;
width: auto;
position: absolute;
inset: 0;
z-index: -32;
}
.cute-texture-video{
opacity: 0;
position: absolute;
top: 0;
left: 0;
z-index: -33;
}
.cute-texture{
position: absolute;
width: 100%;
height: 110%;
top: 0;
left: 0;
z-index: -33;
}
.openBackground{
visibility: collapse;
}
main{
position: relative;
z-index: -33;
overflow: hidden;
#homeContent{
height: 66vh;
width: 100%;
position:relative;
z-index: 0;
display: grid;
grid-template-columns: 2.5fr 2fr 1fr;
grid-template-rows: 1fr 1.5fr;
aside{
grid-row: 2;
grid-column: 2;
align-self: end;
justify-self: end;
color: var(--main-color);
position: relative;
z-index: 33;
margin-bottom: 13.12px;
margin-right: 13.12px;
#openMsg{
width: 33px;
height: 33px;
animation: float 1.61s infinite;
box-sizing: border-box;
border-radius: 13.12px;
}
#openMsg:hover{
animation: none;
}
#msgWindow{
border-style: none;
background-color: transparent;
position: fixed;
top: 117px;
left: 33px;
animation: none;
z-index: 1312;
margin: 0;
.floatingWindow{
width: 277px;
height: auto;
margin-top: 33px;
text-transform: none;
font-size: 15px;
font-family: 'velvelyne';
font-weight: bold;
padding-bottom: 13.12px;
border-width: 3.33px;
border-style: double solid solid;
p{
padding: 7.77px;
padding-right: 16.1px;
strong{
font-family: 'karrik';
font-weight: normal;
text-transform: uppercase;
font-size: 16.1px;
}
}
}
}
#msgWindow::backdrop{
background-color: var(--back-color);
opacity: .333;
width: 100vw;
height: 100vh;
box-sizing: border-box;
}
}
#titleSection{
grid-column: 1;
grid-row: 1;
width: 100%;
height: 100%;
h2{
text-transform: uppercase;
font-family: 'karrik';
font-size: 22px;
line-height: 1em;
small{
text-transform: none;
font-size: 15px;
font-family: 'velvelyne';
font-weight: bold;
line-height: 0.3em;
padding-left: 7.77px;
}
}
}
#hourSection{
grid-column: 3;
grid-row: 2;
width: 100%;
height: 77%;
align-self: end;
justify-self: end;
padding: 0;
h3{
width: 100%;
margin-bottom: 16.1px;
font-family: 'karrik';
text-transform: uppercase;
font-weight: normal;
font-size: 14px;
border-radius: 0;
border-style: solid;
border-width: thin;
padding: 3.33px;
margin-bottom: 3.33px;
box-sizing: border-box;
border-color: var(--main-color);
}
ol{
padding-left: 3.33px;
font-family: 'karrik';
text-transform: uppercase;
font-weight: normal;
font-size: 11px;
strong{
font-family: 'velvelyne';
font-weight: bold;
font-size: 16.1px;
}
li{
margin-top: 16.1px;
}
}
}
address{
grid-column: 2;
grid-row: 1;
width: 150%;
font-size: 15px;
padding-top: 33px;
}
#planSection{
grid-column: 1 / 3;
grid-row: 2;
color: var(--back-color);
justify-self: end;
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
#planContainer{
width: 100%;
height: max-content;
margin-left: 13.12px;
margin-top: 0;
}
img{
position: relative;
z-index: 0;
width: 90%;
height: auto;
}
svg{
fill: currentColor;
position: absolute;
z-index: -1;
width: 90%;
height: auto;
top: 4.44px;
left: -1.61px;
}
}
#extLinkSection{
grid-column: 3;
grid-row: 1;
width: 77%;
height: 133%;
justify-self: end;
display: flex;
flex-direction: column;
align-items: center;
justify-content: flex-end;
margin-right: 16.1px;
margin-top: 7.77px;
gap: 13.12px;
a{
cursor: alias;
img{
width: auto;
height: 55px;
pointer-events: none;
}
}
}
#adhesionSection{
visibility: collapse;
grid-column: 1;
grid-row: 2;
display: flex;
flex-direction: column;
align-items: center;
justify-content: flex-start;
.textBtnStyle{
position: relative;
z-index: 33;
width: 90%;
height: 33px;
font-size: 13.12px;
margin-top: 13.12px;
}
#addUserWindow{
border-style: none;
background-color: transparent;
position: fixed;
top: 77px;
left: 16.1px;
animation: none;
z-index: 1312;
margin: 0;
.floatingWindow{
width: 333px;
height: auto;
margin-top: 33px;
text-transform: none;
font-size: 15px;
font-family: 'velvelyne';
font-weight: bold;
padding-bottom: 13.12px;
border-width: 3.33px;
border-style: double solid solid;
p{
padding: 7.77px;
padding-right: 16.1px;
strong{
font-family: 'karrik';
font-weight: normal;
text-transform: uppercase;
font-size: 16.1px;
}
}
}
}
#addUserWindow::backdrop{
background-color: var(--back-color);
opacity: .333;
width: 100vw;
height: 100vh;
box-sizing: border-box;
}
}
}
#statuSection{
display: flex;
flex-direction: row;
align-items: center;
justify-content: flex-start;
padding: 0;
height: 20vh;
.textBtnStyle{
width: 66px;
font-size: 11px;
margin-right: 7.77px;
}
#statusDesc{
width: 77%;
padding: 7.77px;
padding-right: 33px;
font-size: 16.1px;
line-height: 1.1em;
small{
font-size: 13.12px;
line-height: 0.333em;
}
}
#lolStatus{
position: relative;
z-index: 33;
width: 40%;
height: 50px;
display: flex;
flex-direction: row;
align-items: center;
font-family: 'karrik';
text-transform: uppercase;
font-size: 22px;
line-height: 1em;
padding-left: 16.1px;
box-sizing: border-box;
border-radius: 22px 0 0 22px;
background-color: var(--main-color);
color: var(--back-color);
small{
font-size: 1px;
opacity: 0;
}
}
}
#extraContent{
width: 100%;
height:auto;
position: relative;
z-index: 0;
display: flex;
flex-direction: column;
justify-content: flex-start;
align-items: flex-start;
#aboutSection{
padding: 13.12px;
padding-right: 33px;
font-size: 16.1px;
line-height: 1.333em;
}
#eventSection{
position: relative;
z-index: -1;
height: auto;
width: 100%;
overflow: hidden;
display: flex;
flex-direction: column;
justify-content: flex-start;
align-items: flex-start;
gap: 0;
padding-bottom: 16.1px;
padding-right: 16.1px;
h3{
position: relative;
margin-bottom: 7.77px;
}
article{
h4{
padding: 16.1px;
}
a{
margin-right: 33px;
}
.date{
padding: 16.1px;
}
}
.solidBox{
width: 100%;
height: auto;
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: center;
padding: 0;
box-sizing: border-box;
}
.solidBox:has(details[open]){
color: var(--back-color);
background-color: var(--main-color);
border-color: var(--back-color);
border-radius: 16.1px;
margin-top: 7.77px;
overflow: hidden;
margin-bottom: 7.77px;
details{
cursor: default;
}
}
.iconBtnStyle{
width: 33px;
height: 33px;
.icon{
transform: rotate(45deg);
}
}
details{
width: 100%;
height: 100%;
cursor: copy;
overflow: hidden;
summary{
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-between;
width: 100%;
box-sizing: border-box;
list-style-type: none;
padding: 16.1px;
}
article{
width: 100%;
cursor: default;
text-transform: none;
}
}
}
}
}
-12
View File
@@ -1,12 +0,0 @@
@media (prefers-reduced-motion: reduce){
noscript > video,
.cute-texture,
.cute-texture-video{
visibility: collapse !important;
display: none !important;
}
main aside #openMsg{
animation: none !important;
}
}
-314
View File
@@ -1,314 +0,0 @@
/*===========================Moyen format : Tablette et petite fenêtres PC ===*/
@media(min-width: 650px){
header{
height: 60px;
h1{
margin-bottom: 5px;
img{
height: 40px;
}
}
nav > ul{
display: flex;
flex-direction: row;
justify-content: flex-end;
align-items: center;
height: 44px;
margin-top: 16.1px;
margin-right: 13.12px;
min-width: 444px;
box-sizing: border-box;
li{
height: 100%;
}
.textBtnStyle{
border-radius: 0;
width: 93px;
height: 100%;
}
}
}
main{
#homeContent{
height: 77vh;
grid-template-columns: 2fr 2fr 1fr;
grid-template-rows: 0.7fr 2fr;
aside{
grid-column: 3;
margin-bottom: 33px;
margin-right: 33px;
#msgWindow{
left: unset;
right: 77px;
top: 161px;
}
}
#titleSection{
height: 110%;
h2{
font-size: 27px;
small{
font-size: 20px;
}
}
}
#hourSection{
grid-column: 1;
width: 50%;
height: 100%;
justify-self: start;
}
address{
padding-top: 16.1px;
}
#planSection{
grid-column: 2 / 4;
#planContainer{
width: 110%;
height: auto;
margin-left: -88px;
margin-top: -50px;
@media(min-width: 800px){
margin-top: -88px;
}
}
}
#extLinkSection{
justify-content: flex-start;
padding-top: 33px;
}
#adhesionSection{
justify-content: flex-end;
margin-top: 0;
margin-bottom: 33px;
width: 77%;
}
}
#statuSection{
.textBtnStyle{
font-size: 16.1px;
width: 117px;
margin-right: 33px;
}
#statusDesc{
font-size: 16.1px;
padding-left: 33px;
}
}
#extraContent{
#aboutSection{
}
#eventSection{
#eventContent{
li{
.iconBtnStyle{
right: 3.33%;
}
}
}
}
}
}
}
/*===========================Grand format : écrans larges et grands ===*/
@media(min-width: 1300px){
header{
nav > ul{
font-size: 27px;
li{
height: 100%;
}
.textBtnStyle{
padding-left: 16.1px;
width: 133px;
}
}
}
main{
#homeContent{
aside{
margin-bottom: 77px;
margin-right: 77px;
#msgWindow{
left: unset;
right: 33px;
top: 33vh;
}
#openMsg{
width: 44px;
height: 44px;
}
.icon{
height: 22px;
width: auto;
}
dialog{
.title{
font-size: 22px;
height: 50px;
.iconBtnStyle{
width: 36px;
height: 36px;
border-radius: 22px;
}
}
}
}
#titleSection{
width: 90%;
}
#hourSection{
height: 77%;
width: 44%;
h3{
font-size: 20px;
}
ol{
font-size: 16.1px;
padding-left: 16.1px;
strong{
font-size: 22px;
}
}
}
address{
font-size: 22px;
margin-top: 13.12px;
}
#planSection{
#planContainer{
width: 100%;
height: auto;
margin-left: -88px;
margin-top: -133px;
}
}
#extLinkSection{
a img{
height: 77px;
}
}
#adhesionSection{
width: 50%;
margin-left: 16.1px;
margin-bottom: 77px;
.textBtnStyle{
height: 44px;
font-size: 20px;
}
}
}
#statuSection{
#statusDesc{
padding-left: 77px;
font-size: 20px;
}
#lolStatus{
font-size: 33px;
height: 77px;
width: 50%;
border-radius: 33px 0 0 33px;
}
.textBtnStyle{
font-size: 22px;
margin-right: 33px;
padding-left: 16.1px;
}
}
#extraContent{
height: 90vh;
flex-direction: row;
overflow: hidden;
#aboutSection{
font-size: 22px;
}
#eventSection{
#eventContent{
li{
.iconBtnStyle{
width: 44px;
height: 44px;
border-radius: 22px;
right: 1.61%;
}
.icon{
height: 22px;
}
}
details{
summary{
.title{
font-size: 22px;
h4{
font-size: 27px;
}
}
.resume{
font-size: 16.1px;
}
}
.description{
font-size: 16.1px;
}
}
}
}
}
}
}
-33
View File
@@ -1,33 +0,0 @@
@font-face {
font-family: 'karrik';
src: url('typo/Karrik-Italic.woff2') format('woff2');
font-style: italic;
}
@font-face {
font-family: 'karrik';
src: url('typo/Karrik-Regular.woff2') format('woff2');
font-style: normal;
}
@font-face {
font-family: 'velvelyne';
src: url('typo/Velvelyne-Book.ttf') format('truetype');
font-weight: normal;
}
@font-face {
font-family: 'avara';
src: url('typo/Avara-Black.woff2') format('woff2');
}
@font-face {
font-family: 'pressStart';
src: url('typo/PressStart2P-Regular.ttf');
}
@font-face {
font-family: 'velvelyne';
src:url('typo/Velvelyne-Bold.ttf') format('truetype');
font-weight: bold;
}
+26
View File
@@ -0,0 +1,26 @@
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import path from 'path'
import svgLoader from 'vite-svg-loader'
// https://vite.dev/config/
export default defineConfig({
plugins: [vue(), svgLoader()],
server: {
host: '0.0.0.0',
port: 8080
},
resolve: {
alias: {
'@': path.resolve(__dirname, './src')
}
},
build: {
rollupOptions: {
input: {
main: path.resolve(import.meta.dirname, 'index.html'),
admin: path.resolve(import.meta.dirname, 'admin/index.html'),
},
},
}
})