Recursive preview
This commit is contained in:
10
src/App.tsx
10
src/App.tsx
@@ -1,6 +1,6 @@
|
|||||||
import type { Component } from 'solid-js';
|
import type { Component } from 'solid-js'
|
||||||
|
|
||||||
import Controls from './components/Controls';
|
import Controls from './components/Controls'
|
||||||
import Hero from './components/Hero'
|
import Hero from './components/Hero'
|
||||||
import Projects from './components/Projects/Projects'
|
import Projects from './components/Projects/Projects'
|
||||||
import ContactForm from './components/ContactForm'
|
import ContactForm from './components/ContactForm'
|
||||||
@@ -13,7 +13,7 @@ const App: Component = () => {
|
|||||||
<Projects />
|
<Projects />
|
||||||
<ContactForm />
|
<ContactForm />
|
||||||
</div>
|
</div>
|
||||||
);
|
)
|
||||||
};
|
}
|
||||||
|
|
||||||
export default App;
|
export default App
|
||||||
|
|||||||
BIN
src/assets/laptop_front.png
Normal file
BIN
src/assets/laptop_front.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 351 KiB |
@@ -1,17 +1,17 @@
|
|||||||
import { For, createSignal, createEffect } from 'solid-js';
|
import { For, createSignal, createEffect } from 'solid-js'
|
||||||
|
|
||||||
import { useStore } from '../store/index';
|
import { useStore } from '../store/index'
|
||||||
import type { Store } from '../store/index';
|
import type { Store } from '../store/index'
|
||||||
import styles from './Controls.module.css';
|
import styles from './Controls.module.css'
|
||||||
import LanguageSelector from './LanguageSelector';
|
import LanguageSelector from './LanguageSelector'
|
||||||
import homeIcon from '../assets/icons/home.svg'
|
import homeIcon from '../assets/icons/home.svg'
|
||||||
import gridIcon from '../assets/icons/grid.svg'
|
import gridIcon from '../assets/icons/grid.svg'
|
||||||
import mailIcon from '../assets/icons/mail.svg'
|
import mailIcon from '../assets/icons/mail.svg'
|
||||||
|
|
||||||
export default () => {
|
export default () => {
|
||||||
const [state, { setVisibleChapter, setScrolling }] = useStore() as Store;
|
const [state, { setVisibleChapter, setScrolling }] = useStore() as Store
|
||||||
const [selected, setSelected] = createSignal('home');
|
const [selected, setSelected] = createSignal('home')
|
||||||
const [blobby, setBlobby] = createSignal(['home']);
|
const [blobby, setBlobby] = createSignal(['home'])
|
||||||
const chapters = [
|
const chapters = [
|
||||||
{ name: 'home', icon: homeIcon },
|
{ name: 'home', icon: homeIcon },
|
||||||
{ name: 'projects', icon: gridIcon },
|
{ name: 'projects', icon: gridIcon },
|
||||||
@@ -20,23 +20,23 @@ export default () => {
|
|||||||
|
|
||||||
const selectChapter = (chapterName: string) => {
|
const selectChapter = (chapterName: string) => {
|
||||||
if (chapterName !== selected()) {
|
if (chapterName !== selected()) {
|
||||||
setSelected(chapterName);
|
setSelected(chapterName)
|
||||||
setVisibleChapter(chapterName);
|
setVisibleChapter(chapterName)
|
||||||
setBlobby(b => [chapterName, ...b]);
|
setBlobby(b => [chapterName, ...b])
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
setBlobby(b => [chapterName]);
|
setBlobby(b => [chapterName])
|
||||||
}, 500);
|
}, 500);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent);
|
const isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent)
|
||||||
const gooey = !isSafari;
|
const gooey = !isSafari
|
||||||
|
|
||||||
createEffect((prev) => {
|
createEffect((prev) => {
|
||||||
if (prev !== state.visibleChapter()) {
|
if (prev !== state.visibleChapter()) {
|
||||||
selectChapter(state.visibleChapter());
|
selectChapter(state.visibleChapter())
|
||||||
}
|
}
|
||||||
return state.visibleChapter();
|
return state.visibleChapter()
|
||||||
});
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -23,11 +23,17 @@ export default (props: { project: Project, odd: boolean }) => {
|
|||||||
[styles.Project_halfWidth]: props.project.halfWidth
|
[styles.Project_halfWidth]: props.project.halfWidth
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<img
|
{
|
||||||
class={styles.preview}
|
typeof props.project.preview === 'string'
|
||||||
src={props.project.preview}
|
?
|
||||||
style={props.project.previewStyle}
|
<img
|
||||||
/>
|
class={styles.preview}
|
||||||
|
src={props.project.preview as string}
|
||||||
|
style={props.project.previewStyle}
|
||||||
|
/>
|
||||||
|
:
|
||||||
|
<props.project.preview />
|
||||||
|
}
|
||||||
<div
|
<div
|
||||||
class={styles.body}
|
class={styles.body}
|
||||||
>
|
>
|
||||||
|
|||||||
21
src/components/Projects/RecursivePreview.module.css
Normal file
21
src/components/Projects/RecursivePreview.module.css
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
.laptop {
|
||||||
|
position: relative;
|
||||||
|
background-image: url('/src/assets/laptop_front.png');
|
||||||
|
background-size: contain;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-position: center;
|
||||||
|
min-width: 50%;
|
||||||
|
box-sizing: border-box;
|
||||||
|
overflow: hidden;
|
||||||
|
padding: 40px 39px 50px 44px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.screen {
|
||||||
|
position: relative;
|
||||||
|
width: 300%;
|
||||||
|
height: 300%;
|
||||||
|
border: none;
|
||||||
|
transform: scale(0.33);
|
||||||
|
transform-origin: 0 0;
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
13
src/components/Projects/RecursivePreview.tsx
Normal file
13
src/components/Projects/RecursivePreview.tsx
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
import styles from './RecursivePreview.module.css'
|
||||||
|
|
||||||
|
export default () => {
|
||||||
|
return (
|
||||||
|
<div class={styles.laptop} >
|
||||||
|
<iframe
|
||||||
|
src='https://kopyl.dev'
|
||||||
|
class={styles.screen}
|
||||||
|
>
|
||||||
|
</iframe>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import type { JSXElement } from 'solid-js';
|
||||||
import flexpatrolPreview from '../../assets/projects/flexpatrolPreview.png';
|
import flexpatrolPreview from '../../assets/projects/flexpatrolPreview.png';
|
||||||
import gamesPreview from '../../assets/projects/gamesPreview.png';
|
import gamesPreview from '../../assets/projects/gamesPreview.png';
|
||||||
import warframePreview from '../../assets/projects/warframePreview.png';
|
import warframePreview from '../../assets/projects/warframePreview.png';
|
||||||
@@ -6,6 +7,7 @@ import studybuddyPreview from '../../assets/projects/studybuddyPreview.png';
|
|||||||
import mockupPreview from '../../assets/projects/mockupPreview.png';
|
import mockupPreview from '../../assets/projects/mockupPreview.png';
|
||||||
import vkmutePreview from '../../assets/projects/vkmutePreview.png';
|
import vkmutePreview from '../../assets/projects/vkmutePreview.png';
|
||||||
import musanthropePreview from '../../assets/projects/musanthropePreview.png';
|
import musanthropePreview from '../../assets/projects/musanthropePreview.png';
|
||||||
|
import RecursivePreview from './RecursivePreview';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
Icon, npm, extension, pwa, github
|
Icon, npm, extension, pwa, github
|
||||||
@@ -13,7 +15,7 @@ import {
|
|||||||
|
|
||||||
export class Project {
|
export class Project {
|
||||||
name: string;
|
name: string;
|
||||||
preview: string;
|
preview: string | (() => JSXElement);
|
||||||
link: string;
|
link: string;
|
||||||
repo?: string;
|
repo?: string;
|
||||||
npm?: string;
|
npm?: string;
|
||||||
@@ -50,6 +52,12 @@ export default [
|
|||||||
descriptionSlug: 'worktime_desc',
|
descriptionSlug: 'worktime_desc',
|
||||||
icons: [ pwa, github ]
|
icons: [ pwa, github ]
|
||||||
}),
|
}),
|
||||||
|
new Project({
|
||||||
|
name: 'This website',
|
||||||
|
preview: RecursivePreview,
|
||||||
|
link: 'https://kopyl.dev',
|
||||||
|
descriptionSlug: 'this_desc'
|
||||||
|
}),
|
||||||
new Project({
|
new Project({
|
||||||
name: 'VK Mute',
|
name: 'VK Mute',
|
||||||
preview: vkmutePreview,
|
preview: vkmutePreview,
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
"lang": "en",
|
"lang": "en",
|
||||||
"my_name": "Anatoly Kopyl",
|
"my_name": "Anatoly Kopyl",
|
||||||
"tagline": "Fullstack developer",
|
"tagline": "Fullstack developer",
|
||||||
|
"this_desc": "This website",
|
||||||
"flexpatrol_desc": "A landing page for a gaming squad with info on their servers and their status.",
|
"flexpatrol_desc": "A landing page for a gaming squad with info on their servers and their status.",
|
||||||
"games_desc": "A page with a list of my games avaliable to play.",
|
"games_desc": "A page with a list of my games avaliable to play.",
|
||||||
"warframe_desc": "A service that monitors prices of items on warframe.market and calculates profitable gaps between them.",
|
"warframe_desc": "A service that monitors prices of items on warframe.market and calculates profitable gaps between them.",
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
"lang": "ru",
|
"lang": "ru",
|
||||||
"my_name": "Анатолий Копыл",
|
"my_name": "Анатолий Копыл",
|
||||||
"tagline": "Fullstack разработчик",
|
"tagline": "Fullstack разработчик",
|
||||||
|
"this_desc": "Этот вебсайт",
|
||||||
"flexpatrol_desc": "Лендинг для сквада геймеров, с информацией об их серверах и их статусе.",
|
"flexpatrol_desc": "Лендинг для сквада геймеров, с информацией об их серверах и их статусе.",
|
||||||
"games_desc": "Страница со ссылками на мои игры.",
|
"games_desc": "Страница со ссылками на мои игры.",
|
||||||
"warframe_desc": "Сервис, который считает разницу в цене между позициями на warframe.market.",
|
"warframe_desc": "Сервис, который считает разницу в цене между позициями на warframe.market.",
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ export type Store = [
|
|||||||
{
|
{
|
||||||
setVisibleChapter: Setter<string>,
|
setVisibleChapter: Setter<string>,
|
||||||
setScrolling: Setter<boolean>,
|
setScrolling: Setter<boolean>,
|
||||||
}
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
const StoreContext = createContext<Store>();
|
const StoreContext = createContext<Store>();
|
||||||
@@ -25,7 +25,7 @@ export function StoreProvider(props: any) {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
setVisibleChapter,
|
setVisibleChapter,
|
||||||
setScrolling
|
setScrolling,
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|||||||
@@ -6,5 +6,5 @@ export default defineConfig({
|
|||||||
build: {
|
build: {
|
||||||
target: 'esnext',
|
target: 'esnext',
|
||||||
polyfillDynamicImport: false,
|
polyfillDynamicImport: false,
|
||||||
},
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user