Skip to content

Commit 9cd29b7

Browse files
authored
Merge pull request #4 from LoupesDEV/dev
Dev
2 parents 3f4324c + 98b1ef9 commit 9cd29b7

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

52 files changed

+5924
-20009
lines changed

.gitignore

Lines changed: 21 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,24 @@
1-
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2-
3-
# dependencies
4-
/node_modules
5-
/.pnp
6-
.pnp.js
7-
8-
# testing
9-
/coverage
1+
# Logs
2+
logs
3+
*.log
4+
npm-debug.log*
5+
yarn-debug.log*
6+
yarn-error.log*
7+
pnpm-debug.log*
8+
lerna-debug.log*
109

11-
# production
12-
/build
10+
node_modules
11+
dist
12+
dist-ssr
13+
*.local
1314

14-
# misc
15+
# Editor directories and files
16+
.vscode/*
17+
!.vscode/extensions.json
18+
.idea
1519
.DS_Store
16-
.env.local
17-
.env.development.local
18-
.env.test.local
19-
.env.production.local
20-
21-
npm-debug.log*
22-
yarn-debug.log*
23-
yarn-error.log*
20+
*.suo
21+
*.ntvs*
22+
*.njsproj
23+
*.sln
24+
*.sw?

LICENSE

Lines changed: 21 additions & 674 deletions
Large diffs are not rendered by default.

README.md

Lines changed: 3 additions & 103 deletions
Original file line numberDiff line numberDiff line change
@@ -1,105 +1,5 @@
1-
# Portfolio - Mathéo PICHOT-MOÏSE
1+
# 🚀 PORTFOLIO
22

3-
Bienvenue sur mon portfolio ! Ce projet met en avant mes compétences, mes réalisations et mes services en tant que développeur passionné par les expériences interactives et le design innovant.
3+
## 🌐 Site Web
44

5-
## 🎯 Objectif
6-
7-
Ce site a pour but de :
8-
9-
- Présenter mon parcours et mes compétences techniques.
10-
- Mettre en avant mes projets en développement web, logiciels et intelligence artificielle.
11-
- Offrir un accès simple à mes services et à mon expertise.
12-
- Faciliter la prise de contact avec moi.
13-
14-
## 🌐 Démo
15-
16-
Vous pouvez consulter une démo en ligne de mon portfolio [ici](https://www.matheo-pichotmoise.fr)
17-
18-
## 🛠 Technologies Utilisées
19-
20-
Ce projet a été développé avec les technologies suivantes :
21-
22-
- **React.js** - Bibliothèque JavaScript pour la construction d'interfaces utilisateur dynamiques
23-
- **Material UI** - Composants React pour une interface utilisateur moderne
24-
- **CSS3 & Tailwind CSS** - Style et mise en page
25-
- **JavaScript (ES6+)** - Fonctionnalités interactives et animations avancées
26-
- **Framer Motion & GSAP** - Animations fluides et effets interactifs
27-
- **EmailJS** - Gestion de l'envoi des emails depuis le formulaire de contact
28-
29-
## 📌 Fonctionnalités
30-
31-
- **Interface immersive** avec animations modernes et interactions avancées.
32-
- **Sections dynamiques** : Accueil, À propos, Projets, Parcours, et Contact.
33-
- **Affichage interactif des projets** avec détails et animations.
34-
- **Formulaire de contact fonctionnel** avec envoi d'email via EmailJS.
35-
- **Optimisation mobile** pour une expérience fluide sur tous les supports.
36-
- **Navigation interactive** avec un menu fixe en version desktop et un menu bottom pour mobile.
37-
38-
## 📂 Structure du projet
39-
40-
```
41-
portfolio/
42-
├── public/
43-
│ ├── index.html # Fichier HTML principal
44-
├── src/
45-
│ ├── Components/ # Composants
46-
│ ├── Images/ # Ressources
47-
│ ├── Styles/ # Feuilles de style CSS
48-
│ ├── App.js # Composant principal
49-
│ ├── index.js # Point d'entrée de l'application React
50-
│ ├── data.js # Données des projets et informations personnelles
51-
│ ├── ScrollToTop.jsx # Gestion du scrolling dynamique
52-
├── .gitignore # Fichiers à ignorer par Git
53-
├── CNAME # Configuration du domaine personnalisé
54-
├── CODE_OF_CONDUCT.md # Code de conduite du projet
55-
├── CONTRIBUTING.md # Guide de contribution
56-
├── LICENSE # Licence du projet
57-
├── package-lock.json # Dépendances verrouillées
58-
├── package.json # Dépendances et scripts
59-
└── README.md # Documentation du projet
60-
```
61-
62-
## 🚀 Installation et Exécution
63-
64-
1. Cloner ce dépôt :
65-
```bash
66-
git clone https://github.com/KucoDEV/portfolio.git
67-
```
68-
2. Installer les dépendances :
69-
```bash
70-
cd portfolio
71-
npm install
72-
```
73-
3. Lancer l'application en local :
74-
```bash
75-
npm start
76-
```
77-
4. Accéder à (`http://localhost:3000`)[http://localhost:3000] dans votre navigateur.
78-
79-
## 🚢 Déploiement sur GitHub Pages
80-
81-
1. Assurez-vous que `gh-pages` est bien installé et que les scripts suivants sont déjà ajoutés dans `package.json` :
82-
```json
83-
"scripts": {
84-
"predeploy": "npm run build",
85-
"deploy": "gh-pages -d build"
86-
}
87-
```
88-
89-
2. Déployer le projet avec la commande :
90-
```bash
91-
npm run deploy
92-
```
93-
94-
3. Configurer GitHub Pages :
95-
- Aller dans les paramètres du dépôt GitHub.
96-
- Accéder à la section **Pages**.
97-
- Vérifier que la branche `gh-pages` est bien sélectionnée comme source de déploiement.
98-
99-
## 📜 Licence
100-
101-
Ce projet est sous licence **GNU General Public License v3.0 (GPL-3.0)**.
102-
Vous êtes libre d'utiliser, modifier et distribuer ce projet tant que vous respectez les termes de la licence.
103-
Cela inclut notamment l'obligation de **rendre publiques les modifications** si vous redistribuez le projet.
104-
105-
Pour plus d’informations, consultez la licence complète ici : [GPL-3.0 License](https://www.gnu.org/licenses/gpl-3.0.html).
5+
📍 [**Lien**](https://www.matheo-pichotmoise.fr)

assets/background.mp3

2.38 MB
Binary file not shown.

assets/fonts/ROF.ttf

35.8 KB
Binary file not shown.

assets/github.png

778 Bytes
Loading

assets/scripts.js

Lines changed: 173 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,173 @@
1+
/* =========================
2+
MEDIA
3+
========================= */
4+
const overlay = document.getElementById("overlay");
5+
const audio = document.getElementById("background-audio");
6+
const volumeIcon = document.getElementById("volume-icon");
7+
const volumeSlider = document.getElementById("volume");
8+
9+
function startMedia() {
10+
overlay.classList.add("hidden");
11+
audio?.play?.();
12+
}
13+
function setVolume(v) {
14+
v = Math.max(0, Math.min(1, Number(v)));
15+
if (audio) audio.volume = v;
16+
if (volumeIcon)
17+
volumeIcon.src = v > 0 ? "assets/vol_on.png" : "assets/vol_off.png";
18+
}
19+
function toggleMute() {
20+
setVolume((audio?.volume || 0) > 0 ? 0 : 1);
21+
if (volumeSlider) volumeSlider.value = audio?.volume || 0;
22+
}
23+
window.addEventListener("load", () => {
24+
const v = Number(localStorage.getItem("vol") || 0.5);
25+
setVolume(v);
26+
if (volumeSlider) volumeSlider.value = v;
27+
});
28+
if (volumeSlider)
29+
volumeSlider.addEventListener("input", (e) => {
30+
setVolume(e.target.value);
31+
localStorage.setItem("vol", e.target.value);
32+
});
33+
34+
// Gestion du volume sur mobile
35+
const volumeControl = document.querySelector('.volume-control');
36+
if (volumeControl && 'ontouchstart' in window) {
37+
volumeControl.addEventListener('click', (e) => {
38+
if (e.target === volumeControl || e.target === volumeIcon) {
39+
volumeControl.classList.toggle('active');
40+
}
41+
});
42+
}
43+
44+
/* =========================
45+
MAP / ZOOM
46+
========================= */
47+
const svg = document.getElementById("got-map");
48+
const panzoom = document.getElementById("panzoom");
49+
const backBtn = document.getElementById("back-btn");
50+
51+
let activeRegion = null;
52+
53+
function computeZoomToBBox(bbox, factor = 0.82) {
54+
const viewW = svg.clientWidth;
55+
const viewH = svg.clientHeight;
56+
const scale = Math.min(
57+
(viewW * factor) / bbox.width,
58+
(viewH * factor) / bbox.height
59+
);
60+
const cx = bbox.x + bbox.width / 2;
61+
const cy = bbox.y + bbox.height / 2;
62+
const tx = viewW / 2 - cx * scale;
63+
const ty = viewH / 2 - cy * scale;
64+
return { scale, tx, ty };
65+
}
66+
67+
function zoomToRegion(regionEl) {
68+
const bbox = regionEl.getBBox();
69+
const { scale, tx, ty } = computeZoomToBBox(bbox);
70+
panzoom.style.transform = `translate(${tx}px, ${ty}px) scale(${scale})`;
71+
setTimeout(() => {
72+
regionEl.classList.add("active");
73+
activeRegion = regionEl;
74+
backBtn.classList.add("show");
75+
}, 650);
76+
}
77+
78+
function resetZoom() {
79+
panzoom.style.transform = `translate(0px, 0px) scale(1)`;
80+
if (activeRegion) activeRegion.classList.remove("active");
81+
activeRegion = null;
82+
backBtn.classList.remove("show");
83+
closeInfoPanel();
84+
}
85+
86+
const infoPanel = document.getElementById("info-panel");
87+
const panelTitle = document.getElementById("panel-title");
88+
const panelClose = document.getElementById("panel-close");
89+
const aboutContent = document.getElementById("about-content");
90+
const contactContent = document.getElementById("contact-content");
91+
92+
function openInfoPanel(regionKey, title) {
93+
panelTitle.textContent = title;
94+
95+
aboutContent.style.display = "none";
96+
contactContent.style.display = "none";
97+
98+
if (regionKey === "about") {
99+
aboutContent.style.display = "block";
100+
} else if (regionKey === "contact") {
101+
contactContent.style.display = "block";
102+
}
103+
104+
infoPanel.classList.add("open");
105+
}
106+
107+
function closeInfoPanel() {
108+
infoPanel.classList.remove("open");
109+
}
110+
111+
panelClose.addEventListener("click", closeInfoPanel);
112+
113+
document.querySelectorAll(".region").forEach((region) => {
114+
region.addEventListener("click", () => {
115+
if (activeRegion === region) return;
116+
if (activeRegion) {
117+
activeRegion.classList.remove("active");
118+
}
119+
120+
closeInfoPanel();
121+
closeModal();
122+
123+
zoomToRegion(region);
124+
125+
if (region.classList.contains("panel-region")) {
126+
setTimeout(() => {
127+
openInfoPanel(region.dataset.key, region.dataset.title);
128+
}, 700);
129+
}
130+
});
131+
});
132+
133+
const modal = document.getElementById("modal");
134+
const modalTitle = document.getElementById("modal-title");
135+
const modalBody = document.getElementById("modal-body");
136+
const modalClose = document.getElementById("modal-close");
137+
138+
function openModal(title, content) {
139+
modalTitle.textContent = title;
140+
modalBody.innerHTML = content;
141+
modal.classList.add("open");
142+
}
143+
function closeModal() {
144+
modal.classList.remove("open");
145+
}
146+
147+
document.querySelectorAll(".city").forEach((city) => {
148+
city.addEventListener("click", (e) => {
149+
e.stopPropagation();
150+
if (!activeRegion || activeRegion.dataset.key !== "projects") return;
151+
openModal(city.dataset.title, city.dataset.content);
152+
});
153+
});
154+
155+
modalClose.addEventListener("click", closeModal);
156+
157+
backBtn.addEventListener("click", () => {
158+
closeModal();
159+
resetZoom();
160+
});
161+
window.addEventListener("keydown", (e) => {
162+
if (e.key === "Escape") {
163+
closeModal();
164+
resetZoom();
165+
}
166+
});
167+
window.addEventListener("resize", () => {
168+
if (activeRegion) {
169+
const b = activeRegion.getBBox();
170+
const { scale, tx, ty } = computeZoomToBBox(b);
171+
panzoom.style.transform = `translate(${tx}px, ${ty}px) scale(${scale})`;
172+
}
173+
});

0 commit comments

Comments
 (0)