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 Projects from './components/Projects/Projects'
|
||||
import ContactForm from './components/ContactForm'
|
||||
@@ -13,7 +13,7 @@ const App: Component = () => {
|
||||
<Projects />
|
||||
<ContactForm />
|
||||
</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 type { Store } from '../store/index';
|
||||
import styles from './Controls.module.css';
|
||||
import LanguageSelector from './LanguageSelector';
|
||||
import { useStore } from '../store/index'
|
||||
import type { Store } from '../store/index'
|
||||
import styles from './Controls.module.css'
|
||||
import LanguageSelector from './LanguageSelector'
|
||||
import homeIcon from '../assets/icons/home.svg'
|
||||
import gridIcon from '../assets/icons/grid.svg'
|
||||
import mailIcon from '../assets/icons/mail.svg'
|
||||
|
||||
export default () => {
|
||||
const [state, { setVisibleChapter, setScrolling }] = useStore() as Store;
|
||||
const [selected, setSelected] = createSignal('home');
|
||||
const [blobby, setBlobby] = createSignal(['home']);
|
||||
const [state, { setVisibleChapter, setScrolling }] = useStore() as Store
|
||||
const [selected, setSelected] = createSignal('home')
|
||||
const [blobby, setBlobby] = createSignal(['home'])
|
||||
const chapters = [
|
||||
{ name: 'home', icon: homeIcon },
|
||||
{ name: 'projects', icon: gridIcon },
|
||||
@@ -20,23 +20,23 @@ export default () => {
|
||||
|
||||
const selectChapter = (chapterName: string) => {
|
||||
if (chapterName !== selected()) {
|
||||
setSelected(chapterName);
|
||||
setVisibleChapter(chapterName);
|
||||
setBlobby(b => [chapterName, ...b]);
|
||||
setSelected(chapterName)
|
||||
setVisibleChapter(chapterName)
|
||||
setBlobby(b => [chapterName, ...b])
|
||||
setTimeout(() => {
|
||||
setBlobby(b => [chapterName]);
|
||||
setBlobby(b => [chapterName])
|
||||
}, 500);
|
||||
}
|
||||
}
|
||||
|
||||
const isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent);
|
||||
const gooey = !isSafari;
|
||||
const isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent)
|
||||
const gooey = !isSafari
|
||||
|
||||
createEffect((prev) => {
|
||||
if (prev !== state.visibleChapter()) {
|
||||
selectChapter(state.visibleChapter());
|
||||
selectChapter(state.visibleChapter())
|
||||
}
|
||||
return state.visibleChapter();
|
||||
return state.visibleChapter()
|
||||
});
|
||||
|
||||
return (
|
||||
|
||||
@@ -23,11 +23,17 @@ export default (props: { project: Project, odd: boolean }) => {
|
||||
[styles.Project_halfWidth]: props.project.halfWidth
|
||||
}}
|
||||
>
|
||||
{
|
||||
typeof props.project.preview === 'string'
|
||||
?
|
||||
<img
|
||||
class={styles.preview}
|
||||
src={props.project.preview}
|
||||
src={props.project.preview as string}
|
||||
style={props.project.previewStyle}
|
||||
/>
|
||||
:
|
||||
<props.project.preview />
|
||||
}
|
||||
<div
|
||||
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 gamesPreview from '../../assets/projects/gamesPreview.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 vkmutePreview from '../../assets/projects/vkmutePreview.png';
|
||||
import musanthropePreview from '../../assets/projects/musanthropePreview.png';
|
||||
import RecursivePreview from './RecursivePreview';
|
||||
|
||||
import {
|
||||
Icon, npm, extension, pwa, github
|
||||
@@ -13,7 +15,7 @@ import {
|
||||
|
||||
export class Project {
|
||||
name: string;
|
||||
preview: string;
|
||||
preview: string | (() => JSXElement);
|
||||
link: string;
|
||||
repo?: string;
|
||||
npm?: string;
|
||||
@@ -50,6 +52,12 @@ export default [
|
||||
descriptionSlug: 'worktime_desc',
|
||||
icons: [ pwa, github ]
|
||||
}),
|
||||
new Project({
|
||||
name: 'This website',
|
||||
preview: RecursivePreview,
|
||||
link: 'https://kopyl.dev',
|
||||
descriptionSlug: 'this_desc'
|
||||
}),
|
||||
new Project({
|
||||
name: 'VK Mute',
|
||||
preview: vkmutePreview,
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
"lang": "en",
|
||||
"my_name": "Anatoly Kopyl",
|
||||
"tagline": "Fullstack developer",
|
||||
"this_desc": "This website",
|
||||
"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.",
|
||||
"warframe_desc": "A service that monitors prices of items on warframe.market and calculates profitable gaps between them.",
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
"lang": "ru",
|
||||
"my_name": "Анатолий Копыл",
|
||||
"tagline": "Fullstack разработчик",
|
||||
"this_desc": "Этот вебсайт",
|
||||
"flexpatrol_desc": "Лендинг для сквада геймеров, с информацией об их серверах и их статусе.",
|
||||
"games_desc": "Страница со ссылками на мои игры.",
|
||||
"warframe_desc": "Сервис, который считает разницу в цене между позициями на warframe.market.",
|
||||
|
||||
@@ -9,7 +9,7 @@ export type Store = [
|
||||
{
|
||||
setVisibleChapter: Setter<string>,
|
||||
setScrolling: Setter<boolean>,
|
||||
}
|
||||
},
|
||||
]
|
||||
|
||||
const StoreContext = createContext<Store>();
|
||||
@@ -25,7 +25,7 @@ export function StoreProvider(props: any) {
|
||||
},
|
||||
{
|
||||
setVisibleChapter,
|
||||
setScrolling
|
||||
setScrolling,
|
||||
}
|
||||
];
|
||||
|
||||
|
||||
@@ -6,5 +6,5 @@ export default defineConfig({
|
||||
build: {
|
||||
target: 'esnext',
|
||||
polyfillDynamicImport: false,
|
||||
},
|
||||
}
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user