start creating home page
This commit is contained in:
3
.gitignore
vendored
3
.gitignore
vendored
@@ -1 +1,2 @@
|
|||||||
node_modules
|
node_modules
|
||||||
|
dist
|
||||||
@@ -62,7 +62,7 @@ function sliderGoToIndex ( index: number ) {
|
|||||||
currentSlideIndex = index;
|
currentSlideIndex = index;
|
||||||
setTimeout( () => {
|
setTimeout( () => {
|
||||||
okToMove = true;
|
okToMove = true;
|
||||||
}, 750 );
|
}, 500 );
|
||||||
}, 1000 );
|
}, 1000 );
|
||||||
} else if ( index < 0 ) {
|
} else if ( index < 0 ) {
|
||||||
sliderGoToIndex( sliderElements.length - 1 );
|
sliderGoToIndex( sliderElements.length - 1 );
|
||||||
|
|||||||
79
site/build.js
Normal file
79
site/build.js
Normal file
@@ -0,0 +1,79 @@
|
|||||||
|
const fs = require( 'fs' );
|
||||||
|
const navMenu = '' + fs.readFileSync( './src/nav.html' );
|
||||||
|
const footer = '' + fs.readFileSync( './src/footer.html' );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Recursively find all HTML files in a directory
|
||||||
|
* @param {string} dir The directory to search. Either absolute or relative path
|
||||||
|
* @param {string} extension The file extension to look for
|
||||||
|
* @returns {string[]} returns a list of html files with their full path
|
||||||
|
*/
|
||||||
|
const treeWalker = ( dir, extension ) => {
|
||||||
|
const ls = fs.readdirSync( dir );
|
||||||
|
const fileList = [];
|
||||||
|
for ( let file in ls ) {
|
||||||
|
if ( !ls[ file ].includes( '.' ) ) {
|
||||||
|
const newFiles = treeWalker( dir + '/' + ls[ file ], extension );
|
||||||
|
for ( let file in newFiles ) {
|
||||||
|
fileList.push( newFiles[ file ] );
|
||||||
|
}
|
||||||
|
} else if ( ls[ file ].includes( extension ) ) {
|
||||||
|
fileList.push( dir + '/' + ls[ file ] );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return fileList;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const addNavAndFooterToFile = ( file ) => {
|
||||||
|
const f = '' + fs.readFileSync( file );
|
||||||
|
const navIndex = f.indexOf( '<nav>' ) + 5;
|
||||||
|
const footerIndex = f.indexOf( '<footer>' ) + 8;
|
||||||
|
return f.slice( 0, navIndex ) + navMenu + f.slice( navIndex, footerIndex ) + footer + f.substring( footerIndex );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Save a file to a path. All occurrences of "src" will be replaced by "dist"
|
||||||
|
* @param {string} filePath
|
||||||
|
* @param {string} data
|
||||||
|
* @returns {void}
|
||||||
|
*/
|
||||||
|
const saveFile = ( filePath, data ) => {
|
||||||
|
const nPath = filePath.replace( 'src', 'dist' );
|
||||||
|
const dirSplit = nPath.split( '/' );
|
||||||
|
let currDir = nPath.slice( 0, nPath.indexOf( '/' ) + 1 );
|
||||||
|
for ( let dir in dirSplit ) {
|
||||||
|
if ( dirSplit[ dir ] !== '.' && !dirSplit[ dir ].includes( '.' ) ) {
|
||||||
|
currDir += dirSplit[ dir ] + '/';
|
||||||
|
try {
|
||||||
|
fs.readdirSync( currDir );
|
||||||
|
} catch ( e ) {
|
||||||
|
fs.mkdirSync( currDir );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fs.writeFileSync( nPath, data );
|
||||||
|
}
|
||||||
|
|
||||||
|
const copyFiles = ( dir, extension ) => {
|
||||||
|
const files = treeWalker( dir, extension );
|
||||||
|
|
||||||
|
for ( let file in files ) {
|
||||||
|
saveFile( files[ file ], '' + fs.readFileSync( files[ file ] ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const filesToParse = treeWalker( './src', '.html' );
|
||||||
|
|
||||||
|
for ( let file in filesToParse ) {
|
||||||
|
if ( !filesToParse[ file ].includes( 'footer.html' ) && !filesToParse[ file ].includes( 'nav.html' ) ) {
|
||||||
|
saveFile( filesToParse[ file ], addNavAndFooterToFile( filesToParse[ file ] ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Copy all JS, CSS and jpg files
|
||||||
|
copyFiles( './src', '.js' );
|
||||||
|
copyFiles( './src', '.css' );
|
||||||
|
|
||||||
|
console.log( '\n==> DONE\n\n' );
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html lang="en">
|
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8">
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
||||||
<title>janishutz.com - Solving your software needs with passion</title>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
3
site/src/css/nav.css
Normal file
3
site/src/css/nav.css
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
nav .logo {
|
||||||
|
height: 10vh;
|
||||||
|
}
|
||||||
4
site/src/css/pages/index.css
Normal file
4
site/src/css/pages/index.css
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
.title-video {
|
||||||
|
width: 100vw;
|
||||||
|
height: 90vh;
|
||||||
|
}
|
||||||
72
site/src/css/slider.css
Normal file
72
site/src/css/slider.css
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
.slider {
|
||||||
|
overflow: hidden;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.slider-container {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.slider-controls {
|
||||||
|
position: absolute;
|
||||||
|
font-size: 3rem;
|
||||||
|
top: calc( 50% - 1.5rem );
|
||||||
|
cursor: pointer;
|
||||||
|
user-select: none;
|
||||||
|
padding: 0.5rem 1rem;
|
||||||
|
background-color: white;
|
||||||
|
text-align: center;
|
||||||
|
text-indent: 0;
|
||||||
|
line-height: 1;
|
||||||
|
transform: scale( 1 );
|
||||||
|
transition: all 0.5s;
|
||||||
|
z-index: 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
.slider-controls:hover {
|
||||||
|
transform: scale( 1.1 );
|
||||||
|
}
|
||||||
|
|
||||||
|
.slider-control-left {
|
||||||
|
left: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.slider-control-right {
|
||||||
|
right: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.slider-element {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
background-size: cover;
|
||||||
|
background-position: center;
|
||||||
|
transition: left 1s;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
.slider-element.past {
|
||||||
|
z-index: 3;
|
||||||
|
left: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.slider-element.current {
|
||||||
|
z-index: 4;
|
||||||
|
left: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.slider-element.future {
|
||||||
|
z-index: -1;
|
||||||
|
left: 110%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.slider-element.next {
|
||||||
|
z-index: 5;
|
||||||
|
left: 150%;
|
||||||
|
}
|
||||||
6
site/src/css/style.css
Normal file
6
site/src/css/style.css
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
body, html {
|
||||||
|
height: 100%;
|
||||||
|
width: 100%;
|
||||||
|
padding: 0;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
6
site/src/footer.html
Normal file
6
site/src/footer.html
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
<div>
|
||||||
|
<img src="https://static.janishutz.com/logo.jpg" alt="janishutz.com logo" class="logo">
|
||||||
|
<div class="text-container">
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
41
site/src/index.html
Normal file
41
site/src/index.html
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>janishutz.com - Solving your software needs with passion</title>
|
||||||
|
<link rel="stylesheet" href="/css/slider.css">
|
||||||
|
<link rel="stylesheet" href="/css/style.css">
|
||||||
|
<link rel="stylesheet" href="/css/nav.css">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<nav></nav>
|
||||||
|
<!-- <video src="https://static.janishutz.com/assets/video-home.mp4" autoplay class="title-video"></video> -->
|
||||||
|
<div class="slider" style="width: 100vw; height: 80vh;">
|
||||||
|
<div class="slider-container">
|
||||||
|
<div class="slider-element" style="background-image: url( 'https://store-cdn.janishutz.com/assets/promo-images/math-summaries-desktop.jpg' );">
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div class="slider-element" style="background-image: url( 'https://store-cdn.janishutz.com/assets/promo-images/libreevent-desktop.jpg' );">
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div class="slider-element" style="background-image: url( 'https://store-cdn.janishutz.com/assets/promo-images/donate-desktop.jpg' );">
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="slider-controls slider-control-left" onclick="sliderControl( 'previous' )">⮜</div>
|
||||||
|
<div class="slider-controls slider-control-right" onclick="sliderControl( 'next' )">⮞</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="content">
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<footer></footer>
|
||||||
|
|
||||||
|
|
||||||
|
<script src="/js/slider.js"></script>
|
||||||
|
<script>activateSlider( 7500 )</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
118
site/src/js/slider.js
Normal file
118
site/src/js/slider.js
Normal file
@@ -0,0 +1,118 @@
|
|||||||
|
const fetchedElements = document.getElementsByClassName('slider-element');
|
||||||
|
const sliderElements = [];
|
||||||
|
let okToMove = true;
|
||||||
|
let currentSlideIndex = 0;
|
||||||
|
const sliderContainer = document.getElementsByClassName('slider-container')[0];
|
||||||
|
function sliderGoToIndex(index) {
|
||||||
|
if (okToMove) {
|
||||||
|
if (index < sliderElements.length && index >= 0) {
|
||||||
|
okToMove = false;
|
||||||
|
// Determine next and previous elements
|
||||||
|
let previousElement = 0;
|
||||||
|
let nextElement = 0;
|
||||||
|
if (index < sliderElements.length - 1) {
|
||||||
|
nextElement = index + 1;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
nextElement = 0;
|
||||||
|
}
|
||||||
|
if (index === 0) {
|
||||||
|
previousElement = sliderElements.length - 1;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
previousElement = index - 1;
|
||||||
|
}
|
||||||
|
// Determine move direction:
|
||||||
|
// true = next, false = previous
|
||||||
|
let moveDirection = true;
|
||||||
|
if ((index < currentSlideIndex || (index === sliderElements.length - 1 && currentSlideIndex === 0)) && !(index === 0 && currentSlideIndex === sliderElements.length - 1)) {
|
||||||
|
moveDirection = false;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
Add correct classes to all elements
|
||||||
|
*/
|
||||||
|
// New current element
|
||||||
|
sliderElements[index].classList.add('current');
|
||||||
|
sliderElements[index].classList.remove('next');
|
||||||
|
sliderElements[index].classList.remove('past');
|
||||||
|
// New next element
|
||||||
|
if (moveDirection) {
|
||||||
|
sliderElements[nextElement].classList.add('future');
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
sliderElements[nextElement].classList.add('next');
|
||||||
|
}
|
||||||
|
sliderElements[nextElement].classList.remove('current');
|
||||||
|
sliderElements[nextElement].classList.remove('past');
|
||||||
|
// new past element
|
||||||
|
sliderElements[previousElement].classList.add('past');
|
||||||
|
sliderElements[previousElement].classList.remove('current');
|
||||||
|
sliderElements[previousElement].classList.remove('next');
|
||||||
|
// Glitch fixes
|
||||||
|
setTimeout(() => {
|
||||||
|
if (moveDirection) {
|
||||||
|
sliderElements[nextElement].classList.add('next');
|
||||||
|
sliderElements[nextElement].classList.remove('future');
|
||||||
|
}
|
||||||
|
currentSlideIndex = index;
|
||||||
|
setTimeout(() => {
|
||||||
|
okToMove = true;
|
||||||
|
}, 500);
|
||||||
|
}, 1000);
|
||||||
|
}
|
||||||
|
else if (index < 0) {
|
||||||
|
sliderGoToIndex(sliderElements.length - 1);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
sliderGoToIndex(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function sliderControl(action) {
|
||||||
|
if (action === 'next') {
|
||||||
|
sliderGoToIndex(currentSlideIndex + 1);
|
||||||
|
}
|
||||||
|
else if (action === 'previous') {
|
||||||
|
sliderGoToIndex(currentSlideIndex - 1);
|
||||||
|
}
|
||||||
|
sliderAutoAdvance();
|
||||||
|
}
|
||||||
|
let sliderAutoAdvanceInterval = 0;
|
||||||
|
let sliderInterval = 0;
|
||||||
|
function activateSlider(interval) {
|
||||||
|
sliderAutoAdvanceInterval = interval;
|
||||||
|
sliderContainer.addEventListener('mouseenter', () => {
|
||||||
|
stopSliderAutoAdvance();
|
||||||
|
});
|
||||||
|
sliderContainer.addEventListener('mouseleave', () => {
|
||||||
|
sliderAutoAdvance();
|
||||||
|
});
|
||||||
|
document.addEventListener('blur', () => {
|
||||||
|
stopSliderAutoAdvance();
|
||||||
|
});
|
||||||
|
window.addEventListener('focus', () => {
|
||||||
|
sliderAutoAdvance();
|
||||||
|
});
|
||||||
|
sliderAutoAdvance();
|
||||||
|
}
|
||||||
|
const sliderAutoAdvance = () => {
|
||||||
|
if (sliderAutoAdvanceInterval > 0) {
|
||||||
|
stopSliderAutoAdvance();
|
||||||
|
sliderInterval = setInterval(() => {
|
||||||
|
sliderGoToIndex(currentSlideIndex + 1);
|
||||||
|
}, sliderAutoAdvanceInterval);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const stopSliderAutoAdvance = () => {
|
||||||
|
try {
|
||||||
|
clearInterval(sliderInterval);
|
||||||
|
}
|
||||||
|
catch (e) { }
|
||||||
|
;
|
||||||
|
};
|
||||||
|
for (let el in fetchedElements) {
|
||||||
|
if (fetchedElements[el].className) {
|
||||||
|
sliderElements.push(fetchedElements[el]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sliderGoToIndex(0);
|
||||||
2
site/src/nav.html
Normal file
2
site/src/nav.html
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
<img src="https://static.janishutz.com/logo.jpg" alt="janishutz.com logo" class="logo">
|
||||||
|
<div>nav</div>
|
||||||
Reference in New Issue
Block a user