Hexagon with changing pictures on click in CSS HTML JavaScript - javascript

I am new to CSS HTML and JavaScrip.
I found this code to create a pattern of hexagons with pictures (see first code). When I press on a hexagon, I want it's picture to change to another picture (see second code).
First Code: Below is the JavaScript, CSS, and HTML.
//I don't know how my java script is going to be
/**
* Generate repeating hexagonal pattern with CSS3 (SO) - 1 element/ hexagon !!!
* http://stackoverflow.com/q/10062887/1397351
*/
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
.row {
margin: -18% 0;
text-align: center;
}
.row:first-child {
margin-top: -20%;
}
.hexagon {
position: relative;
display: inline-block;
overflow: hidden;
margin: 0 8.5%;
padding: 16%;
transform: rotate(30deg) skewY(30deg) scaleX(.866);
/* .866 = sqrt(3)/2 */
}
.hexagon:before,
.content:after {
display: block;
position: absolute;
/* 86.6% = (sqrt(3)/2)*100% = .866*100% */
top: 6.7%;
right: 0;
bottom: 6.7%;
left: 0;
/* 6.7% = (100% -86.6%)/2 */
transform: scaleX(1.155) skewY(-30deg) rotate(-30deg);
/* 1.155 = 2/sqrt(3) */
background-color: rgba(30, 144, 255, .56);
background-size: cover;
content: '';
}
t:after {
content: attr(data-content);
}
.row:first-child .hexagon:first-child:before {
background-image: url(http://s10.postimg.org/o0vmcz3hl/Untitled_2_0.jpg);
}
.row:nth-child(2) .hexagon:nth-child(2):before {
background-image: url(http://s10.postimg.org/n7j0kcxgp/Untitled_2_0.jpg);
}
.row:nth-child(3) .hexagon:first-child:before {
background-image: url(http://s10.postimg.org/pen98a2qx/Untitled_2_0.jpg);
}
.row:nth-child(4) .hexagon:nth-child(2):before {
background-image: url(http://s10.postimg.org/ivuevcqjt/Untitled_2_0.jpg);
}
.row:nth-child(2) .hexagon:first-child:before {
background-image: url(http://s10.postimg.org/dvwynekx5/Untitled_2_0.jpg);
}
.row:nth-child(4) .hexagon:first-child:before {
background-image: url(http://s10.postimg.org/7ak8nn52h/Untitled_2_0.jpg);
}
.row:nth-child(5) .hexagon:first-child:before {
background-image: url(http://s10.postimg.org/i7lkceru1/Untitled_2_0.jpg);
}
<!-- content to be placed inside <body>…</body> -->
<div class='row'>
<div class='hexagon'></div>
</div>
<div class='row'>
<div class='hexagon'></div>
<div class='hexagon'></div>
</div>
<div class='row'>
<div class='hexagon'></div>
</div>
<div class='row'>
<div class='hexagon'></div>
<div class='hexagon'></div>
</div>
<div class='row'>
<div class='hexagon'></div>
</div>
Second Code: Below is the JavaScript, CSS, and HTML.
var bodyObj, className, index;
bodyObj = document.getElementById('body');
index = 1;
className = [
'imageOne',
'imageTwo'
];
function updateIndex() {
if (index === 0) {
index = 1;
} else {
index = 0;
}
}
bodyObj.onclick = function(e) {
e.currentTarget.className = className[index];
updateIndex();
}
html,
body,
#body {
height: 100%;
width: 100%;
}
#body.imageOne {
background-image: url("http://s10.postimg.org/7ak8nn52h/Untitled_2_0.jpg");
}
#body.imageTwo {
background-image: url("http://s27.postimg.org/qqz5ww52r/red_4.jpg");
}
<div id="body" class="imageOne"></div>

Result: jsfiddle
I added a new class .hexagon-hide (identical to .hexagon but with different background images), then I added the JQuery function to switch between .hexagon and .hexagon-hide with a click in the hexagon div.
$( ".hexagon" ).click(function() {
$( this ).toggleClass('hexagon hexagon-hide');
});
/**
* Generate repeating hexagonal pattern with CSS3 (SO) - 1 element/ hexagon !!!
* http://stackoverflow.com/q/10062887/1397351
*/
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
.row {
margin: -18% 0;
text-align: center;
}
.row:first-child {
margin-top: -20%;
}
.hexagon, .hexagon-hide {
position: relative;
display: inline-block;
overflow: hidden;
margin: 0 8.5%;
padding: 16%;
transform: rotate(30deg) skewY(30deg) scaleX(.866);
/* .866 = sqrt(3)/2 */
}
.hexagon:before, .hexagon-hide:before,
.content:after {
display: block;
position: absolute;
/* 86.6% = (sqrt(3)/2)*100% = .866*100% */
top: 6.7%;
right: 0;
bottom: 6.7%;
left: 0;
/* 6.7% = (100% -86.6%)/2 */
transform: scaleX(1.155) skewY(-30deg) rotate(-30deg);
/* 1.155 = 2/sqrt(3) */
background-color: rgba(30, 144, 255, .56);
background-size: cover;
content: '';
}
t:after {
content: attr(data-content);
}
.row:first-child .hexagon:first-child:before {
background-image: url(http://s10.postimg.org/o0vmcz3hl/Untitled_2_0.jpg);
}
.row:nth-child(2) .hexagon:nth-child(2):before {
background-image: url(http://s10.postimg.org/n7j0kcxgp/Untitled_2_0.jpg);
}
.row:nth-child(3) .hexagon:first-child:before {
background-image: url(http://s10.postimg.org/pen98a2qx/Untitled_2_0.jpg);
}
.row:nth-child(4) .hexagon:nth-child(2):before {
background-image: url(http://s10.postimg.org/ivuevcqjt/Untitled_2_0.jpg);
}
.row:nth-child(2) .hexagon:first-child:before {
background-image: url(http://s10.postimg.org/dvwynekx5/Untitled_2_0.jpg);
}
.row:nth-child(4) .hexagon:first-child:before {
background-image: url(http://s10.postimg.org/7ak8nn52h/Untitled_2_0.jpg);
}
.row:nth-child(5) .hexagon:first-child:before {
background-image: url(http://s10.postimg.org/i7lkceru1/Untitled_2_0.jpg);
}
.row:first-child .hexagon-hide:first-child:before {
background-image: url("http://s27.postimg.org/qqz5ww52r/red_4.jpg");}
.row:nth-child(2) .hexagon-hide:nth-child(2):before {
background-image: url("http://s27.postimg.org/qqz5ww52r/red_4.jpg");}
.row:nth-child(3) .hexagon-hide:first-child:before {
background-image: url("http://s27.postimg.org/qqz5ww52r/red_4.jpg");}
.row:nth-child(4) .hexagon-hide:nth-child(2):before {
background-image: url("http://s27.postimg.org/qqz5ww52r/red_4.jpg");}
.row:nth-child(2) .hexagon-hide:first-child:before {
background-image: url("http://s27.postimg.org/qqz5ww52r/red_4.jpg");}
.row:nth-child(4) .hexagon-hide:first-child:before {
background-image: url("http://s27.postimg.org/qqz5ww52r/red_4.jpg");}
.row:nth-child(5) .hexagon-hide:first-child:before {
background-image: url("http://s27.postimg.org/qqz5ww52r/red_4.jpg");}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<!-- content to be placed inside <body>…</body> -->
<div class='row'>
<div class='hexagon'></div>
</div>
<div class='row'>
<div class='hexagon'></div>
<div class='hexagon'></div>
</div>
<div class='row'>
<div class='hexagon'></div>
</div>
<div class='row'>
<div class='hexagon'></div>
<div class='hexagon'></div>
</div>
<div class='row'>
<div class='hexagon'></div>
</div>

Related

How to create a slide of background images using Pure Javascript or a pure Javascript library

I'd like to make the below in a way that I can have two images slide in the background but have I'm stuck on how to implement a slide of background images. Kindly assist, any assistance will be highly appreciated.
#header-image {
background-image: url('/images/photography1.jpg');
width: 100%;
border: none;
padding: 0;
margin: 0;
background-position: bottom center;
background-repeat: no-repeat;
background-size: cover;
height: 100vh;
position: relative;
}
<div id="header-image">
<div class="overlay" data-aos="fade-down-right">
<h1>Photography Logo</h1>
</div>
</div>
I made an example for you using javascript, as well as modified your html and css. Was such a result necessary? If you have any questions, please let me know.
let anime = document.querySelector('#header-image');
var step = 0;
function animate() {
if (step > -200) {
anime.style.transform = 'translateX('+ step +'vw)';
} else {
anime.style.transform = 'transformX(100vw)';
step = 100;
}
}
setInterval(function () {
step = step - 100;
animate();
}, 5000);
body {
padding: 0;
margin: 0;
}
#header {
overflow: hidden;
}
#header-image {
border: none;
width: 200vw;
height: 100vh;
transition: 1s;
display: flex;
}
#photo_section_one {
background-image: url('https://img.desktopwallpapers.ru/newyear/pics/wide/1920x1200/5f7ff83acdb7b743fb61468954e9c511.jpg');
width: 100vw;
background-position: bottom center;
background-repeat: no-repeat;
background-size: cover;
height: 100%;
}
#photo_section_two {
background-image: url('https://lh3.googleusercontent.com/proxy/N_97o7XR3tJd8Thp4vFQxXqqQVMSgBNhjGlvvHa9bDnpW-i4v6J9EElWWMSC8qumCbDAfvAjroBDWBu8F1HPl-hZX1BsYOk-wDNO26pT19W90o8n22aABvQ');
width: 100vw;
background-position: bottom center;
background-repeat: no-repeat;
background-size: cover;
height: 100%;
}
<div id="header">
<div id="header-image">
<div id="photo_section_one">
<div class="overlay" data-aos="fade-down-right">
<h1>Photography Logo</h1>
</div>
</div>
<div id="photo_section_two">
<div class="overlay" data-aos="fade-down-right">
<h1>Photography Logo</h1>
</div>
</div>
</div>
</div>
Second solution using an array of images. The images change as on the site you showed.
let anime = document.querySelector('#header-image');
let images = ['https://vjoy.cc/wp-content/uploads/2019/08/1-39.jpg', 'https://img.desktopwallpapers.ru/newyear/pics/wide/1920x1200/5f7ff83acdb7b743fb61468954e9c511.jpg'];
let index = 0;
setInterval(function(){
anime.style.backgroundImage = 'url(' + images[index] + ')';
index++;
if (index >= images.length) {
index = 0;
}
}, 5000);
* {
padding: 0;
margin: 0;
}
#header {
overflow: hidden;
}
#header-image {
border: none;
height: 100vh;
transition: 1s;
background-image: url('https://img.desktopwallpapers.ru/newyear/pics/wide/1920x1200/5f7ff83acdb7b743fb61468954e9c511.jpg');
width: 100%;
background-position: bottom center;
background-repeat: no-repeat;
background-size: cover;
}
<div id="header">
<div id="header-image">
<div id="photo_section_one">
<div class="overlay" data-aos="fade-down-right">
<h1>Photography Logo</h1>
</div>
</div>
</div>
</div>
As far as I'm aware you cannot do exactly what you are asking for. But, you can create something similar though z-index and absolute positioning, some css, and some js. You would have to create a div behind the text and animate it using css, while using some js to make it continuously loop.
setInterval(function() {
if (document.getElementsByClassName("slide-pos-1")[0] != undefined) {
document.getElementsByClassName("background-slide")[0].classList.add("slide-pos-2")
setTimeout(function() {
document.getElementsByClassName("background-slide")[0].classList.remove("slide-pos-1")
document.getElementsByClassName("background-slide")[0].classList.remove("slide-pos-2")
}, 1500)
} else {
document.getElementsByClassName("background-slide")[0].classList.add("slide-pos-1")
}
}, 6000)
html,
body {
margin: 0;
width: 100%;
height: 100%;
overflow: hidden;
}
.background-slide {
position: absolute;
top: 0;
left: 0;
width: 300%;
height: 100%;
display:flex;
transform:translate(0,0);
transition: transform 0s ease-out;
}
.slide-pos-1{
transform:translate(calc(-100% / 3),0);
transition: transform 1s ease-out;
}
.slide-pos-2{
transform:translate(calc(-200% / 3),0);
transition: transform 1s ease-out;
}
.header-image {
width: 100%;
height: 100%;
}
.overlay{
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
.image {
flex:1;
}
img {
object-fit: cover;
width:100%;
height:100%;
margin:0;
}
<div class="header-image">
<div class="background-slide slide-pos-1">
<div class="image"><img src="https://upload.wikimedia.org/wikipedia/commons/thumb/b/b6/Image_created_with_a_mobile_phone.png/1200px-Image_created_with_a_mobile_phone.png" /></div>
<div class="image"><img src="https://miro.medium.com/max/1200/1*mk1-6aYaf_Bes1E3Imhc0A.jpeg" /></div>
<div class="image"><img src="https://upload.wikimedia.org/wikipedia/commons/thumb/b/b6/Image_created_with_a_mobile_phone.png/1200px-Image_created_with_a_mobile_phone.png" /></div>
</div>
<div class="overlay">
<h1>Photography Logo</h1>
</div>
</div>
Also, this one doesn't slide the text along with the image, and the slide direction is the same. Credit of s.kuznetsov for making me realize that and revise my answer.

How to rotate 4 children within a circle 90 degrees every 3 seconds using CSS custom properties and transform?

I'm trying to rotate 4 children (.feat) elements within a circle 90 degrees every 3 seconds using a CSS custom property called --angle, but it doesn't seem to work as expected:
function rotation() {
let inner = document.querySelector('[inn]');
let rota = inner.style.transform;
}
setInterval(rotation, 3000);
.feat-cont {
width: 60vmax;
height: 60vmax;
}
.feat-cont p {
display: inline-block;
}
.inner {
--angle: 0;
position: relative;
background-color: yellow;
transform: rotate(var(--angle) * 1deg);
width: 100%;
height: 100%;
border-radius: 50%;
}
.feat {
position: absolute;
}
.feat1 {
left: 25vmax;
}
.feat2 {
left: 50vmax;
top: 25vmax;
}
.feat3 {
left: 25vmax;
top: 50vmax;
}
.feat4 {
top: 25vmax;
}
<div class='feat-cont'>
<div class='inner' inn>
<div class='feat feat1' f1>
<img src="https://img.icons8.com/nolan/64/fast-forward.png"/>
<p>Fast Performance</p>
</div>
<div class='feat feat2' f2>
<img src="https://img.icons8.com/color/48/000000/memory-slot.png"/>
<p>64 GBs of memory</p>
</div>
<div class='feat feat3' f3>
<img src="https://img.icons8.com/nolan/64/camera.png"/>
<p>3K MP camera</p>
</div>
<div class='feat feat4' f4>
<img src="https://img.icons8.com/dusk/64/000000/branding.png"/>
<p>Trusted brand</p>
</div>
</div>
</div>
You can change the angle CSS custom property using CSSStyleDeclaration.setProperty():
circle.style.setProperty('--angle', `${ angle }deg`);
Also, note you use it as transform: rotate(var(--angle)), not as rotate(var(--angle) * 1deg), so the unit should already be included in the CSS property.
If you don't want to use CSS properties, you can change the style attribute directly:
circle.style.transform = `rotate(${ angle }deg)`;
However, I guess you need to rotate the circle in one direction while rotating all the children (.feat) in the opposite direction to keep them straight, so using CSS properties is probably more convenient, as otherwise, you would have to change the style attribute in all 4 children:
const circle = document.querySelector('.circle');
const prev = document.querySelector('.prev');
const next = document.querySelector('.next');
const step = 90;
let angle = 0;
let intervalID = null;
function updateRotation() {
circle.style.setProperty('--angle', `${ angle }deg`);
circle.style.setProperty('--angle-inverse', `${ -angle }deg`);
}
function autoRotate() {
intervalID = setInterval(() => {
angle += step;
updateRotation();
}, 3000);
}
prev.onclick = () => {
clearInterval(intervalID);
angle -= step;
updateRotation();
autoRotate();
};
next.onclick = () => {
clearInterval(intervalID);
angle += step;
updateRotation();
autoRotate();
};
autoRotate();
body {
font-family: monospace;
}
.container {
width: 60vmax;
height: 60vmax;
margin: 0 auto;
overflow: hidden;
}
.circle {
--angle: 0;
--angle-inverse: 0;
position: relative;
background-color: yellow;
width: 100%;
height: 100%;
border-radius: 50%;
transition: transform linear 1s;
transform: rotate(var(--angle));
}
.feat {
position: absolute;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
width: 20vmax;
height: 20vmax;
text-align: center;
transition: transform linear 1s;
}
.feat > img {
width: 10vmax;
height: 10vmax;
}
.feat > p {
margin: 8px 0 0;
}
.feat1 {
top: 0;
left: 50%;
transform: translate(-50%, 0) rotate(var(--angle-inverse));
}
.feat2 {
right: 0;
top: 50%;
transform: translate(0, -50%) rotate(var(--angle-inverse));
}
.feat3 {
bottom: 0;
left: 50%;
transform: translate(-50%, 0) rotate(var(--angle-inverse));
}
.feat4 {
left: 0;
top: 50%;
transform: translate(0, -50%) rotate(var(--angle-inverse));
}
.button {
position: fixed;
top: 0;
bottom: 0;
background: transparent;
border: 0;
padding: 32px;
outline: none;
font-family: monospace;
font-size: 32px;
}
.button:hover {
background: rgba(0, 0, 0, .0625);
}
.prev {
left: 0;
}
.next {
right: 0;
}
<div class="container">
<button class="button prev">‹</button>
<div class="circle">
<div class="feat feat1">
<img src="https://img.icons8.com/nolan/64/fast-forward.png"/>
<p>Fast Performance</p>
</div>
<div class="feat feat2">
<img src="https://img.icons8.com/color/48/000000/memory-slot.png"/>
<p>64 GBs of memory</p>
</div>
<div class="feat feat3">
<img src="https://img.icons8.com/nolan/64/camera.png"/>
<p>3K MP camera</p>
</div>
<div class="feat feat4">
<img src="https://img.icons8.com/dusk/64/000000/branding.png"/>
<p>Trusted brand</p>
</div>
</div>
<button class="button next">›</button>
</div>
I have added a pure CSS solution, You might not need javascript manipulations at all, it's lightweight too.
Just use CSS inbuilt Animation property.
.inner{animation: rotate 12s infinite;}
#keyframes rotate{
0%{transform: rotate(0deg);}
25%{transform: rotate(90deg);}
50%{transform: rotate(180deg);}
75%{transform: rotate(270deg);}
100%{transform: rotate(360deg);}
}
Find the codepen here
.feat-cont {
width: 60vmax;
height: 60vmax;
}
.feat-cont p {
display: inline-block;
}
.inner {
position: relative;
background-color: yellow;
width: 100%;
height: 100%;
border-radius: 50%;
}
.feat {
position: absolute;
}
.feat1 {
left: 25vmax;
}
.feat2 {
left: 50vmax;
top: 25vmax;
}
.feat3 {
left: 25vmax;
top: 50vmax;
}
.feat4 {
top: 25vmax;
}
.inner {
animation: rotate 12s infinite;
}
#keyframes rotate{
0%{transform: rotate(0deg);}
25%{transform: rotate(90deg);}
50%{transform: rotate(180deg);}
75%{transform: rotate(270deg);}
100%{transform: rotate(360deg);}
}
#keyframes r-rotate{
0%{transform: rotate(0deg);}
25%{transform: rotate(-90deg);}
50%{transform: rotate(-180deg);}
75%{transform: rotate(-270deg);}
100%{transform: rotate(-360deg);}
}
.feat {
animation: r-rotate 12s infinite;
}
<nav></nav>
<main>
<section>
<div class='feat-cont'>
<div class='inner' inn>
<div class='feat feat1' f1>
<img src="https://img.icons8.com/nolan/64/fast-forward.png"/><br><p>Fast Performance</p>
</div>
<div class='feat feat2' f2>
<img src="https://img.icons8.com/color/48/000000/memory-slot.png"/><br><p>64 GBs of memory</p>
</div>
<div class='feat feat3' f3>
<img src="https://img.icons8.com/nolan/64/camera.png"/><br><p>3K MP camera</p>
</div>
<div class='feat feat4' f4>
<img src="https://img.icons8.com/dusk/64/000000/branding.png"/><br><p>Trusted brand</p>
</div>
</div>
</div>
</section>
<section class='ndsection'>
</main>
Update Your javascript Code
setInterval(rotation, 3000);
var deg = 90;
let inner = document.querySelector('.inner');
function rotation() {
inner.style.transform='rotate('+deg+'deg)';
}

using same button for back

I have some javascript/CSS that hid/show content and some animation. It all works marvelously with no issues as far as functionality, however, I want to add a feature where the same picture/button that I click to run the script can again be used to run the same script in reverse to go back to the original state. See code below.
/* Portfolio */
.portfolio {
grid-area: portfolio;
width: 100%;
}
.portfolio {
display: grid;
background: #F1F1F1;
grid-template-rows: repeat(1, 100%);
grid-gap: 10px;
grid-template-areas: "portfolio-header";
align-items: start;
text-align: center;
min-height: 1000px;
}
.portfolio-header {
width: 100%;
text-align: center;
margin-top: 64px;
margin-bottom: -300px;
}
.portfolio-container {
min-height: 500px; /* temporary */
padding: 0 20px;
position: relative;
}
.portfolio-container .portfolio-picture {
left: 0;
position: absolute;
transition: all ease-in .3s; /* MAGIC */
top: 0;
width: 25%;
}
.portfolio-container .portfolio-picture img {
max-width: 100%;
}
.portfolio-container .portfolio-picture.portfolio-picture-1 {}
.portfolio-container.portfolio-active-2 .portfolio-picture-1,
.portfolio-container.portfolio-active-3 .portfolio-picture-1,
.portfolio-container.portfolio-active-4 .portfolio-picture-1,
.portfolio-container.portfolio-active-1 .portfolio-picture-2,
.portfolio-container.portfolio-active-3 .portfolio-picture-2,
.portfolio-container.portfolio-active-4 .portfolio-picture-2,
.portfolio-container.portfolio-active-1 .portfolio-picture-3,
.portfolio-container.portfolio-active-2 .portfolio-picture-3,
.portfolio-container.portfolio-active-4 .portfolio-picture-3,
.portfolio-container.portfolio-active-1 .portfolio-picture-4,
.portfolio-container.portfolio-active-2 .portfolio-picture-4,
.portfolio-container.portfolio-active-3 .portfolio-picture-4 {
opacity: 0;
pointer-events: none;
}
.portfolio-container .portfolio-picture.portfolio-picture-2 { transform: translate(100%,0); }
.portfolio-container .portfolio-picture.portfolio-picture-3 { transform: translate(200%,0); }
.portfolio-container .portfolio-picture.portfolio-picture-4 { transform: translate(300%,0); }
.portfolio-container .portfolio-content {
box-sizing: border-box;
opacity: 0;
padding-left: 30px;
position: absolute;
right: 0;
top: 0;
transform: translate(0,100%);
transition: all ease-in .3s; /* MAGIC */
width: 75%;
}
.portfolio-container.portfolio-active-2 .portfolio-picture.portfolio-picture-2,
.portfolio-container.portfolio-active-3 .portfolio-picture.portfolio-picture-3,
.portfolio-container.portfolio-active-4 .portfolio-picture.portfolio-picture-4 {
transform: translate(0,0);
}
.portfolio-container.portfolio-active-1 .portfolio-content.portfolio-content-1,
.portfolio-container.portfolio-active-2 .portfolio-content.portfolio-content-2,
.portfolio-container.portfolio-active-3 .portfolio-content.portfolio-content-3,
.portfolio-container.portfolio-active-4 .portfolio-content.portfolio-content-4 {
opacity: 1;
pointer-events: auto;
transform: translate(0,0);
}
.portfolio-back-button {
display: none;
}
.portfolio-back-button.portfolio-back-button-visible {
display: inline-block;
}
.port-content {
text-align: center;
}
.port-cont {
max-width: 35%;
text-align: justify;
background-image: url("assets/img/pattern.png");
color: #808080;
font-weight: bold;
text-transform: uppercase;
margin-right: 40%;
padding: 10px;
margin-bottom: 50px;
box-sizing: border-box;
}
function clearSelection() {
document.querySelector('.portfolio-container').classList.remove('portfolio-active-1', 'portfolio-active-2', 'portfolio-active-3', 'portfolio-active-4');
document.querySelector('.portfolio-back-button').classList.remove('portfolio-back-button-visible');
}
function selectPortfolio(which) {
clearSelection();
document.querySelector('.portfolio-container').classList.add('portfolio-active-' + which);
document.querySelector('.portfolio-back-button').classList.add('portfolio-back-button-visible');
}
<div class="portfolio-container">
<div class="portfolio-content portfolio-content-1 port-cont">
<p>some text</p>
</div>
<div class="portfolio-content portfolio-content-2 port-cont">
<p>some text</p>
</div>
<div class="portfolio-content portfolio-content-3 port-cont">
<p>some text</p>
</div>
<div class="portfolio-content portfolio-content-4 port-cont">
<p>some text</p>
</div>
<div class="portfolio-picture portfolio-picture-1">
<img src="assets/img/portfolio/corinthmc/corinthmc_small.png" alt="Corinth Designs">
</div>
<div class="portfolio-picture portfolio-picture-2">
<img src="assets/img/portfolio/beardedrazorback/beardedrazorback_small.png" alt="Corinth Designs">
</div>
<div class="portfolio-picture portfolio-picture-3">
<img src="assets/img/portfolio/theord/theord_small.png" alt="Corinth Designs">
</div>
<div class="portfolio-picture portfolio-picture-4">
<img src="assets/img/portfolio/21divine/21divine_small.png" alt="Corinth Designs">
</div>
<div class="port-back portfolio-back-button">
Back <i class="fas fa-angle-double-right"></i>
</div><!-- back button -->
If you modify the selectPortfolio function to the following, you can use a closure and an internal state variable to switch back and forth.
https://codepen.io/anon/pen/gKbjQj?editors=0010
const selectPortfolio = (() => {
let back = false;
return (which) => {
// clearSelection();
if (back) {
// document.querySelector('.portfolio-back-button').classList.add('portfolio-back-button-visible');
console.log(back, 'portfolio-back-button-visible');
} else {
// document.querySelector('.portfolio-container').classList.add('portfolio-active-' + which);
console.log(back, 'portfolio-active-');
}
back = !back;
}
return back;
})();
selectPortfolio();
selectPortfolio();
selectPortfolio();
selectPortfolio();
// true "portfolio-back-button-visible"
// false "portfolio-active-"
// true "portfolio-back-button-visible"
// false "portfolio-active-"

How to keep user's scrolling place when resizing div

I wanted to do a cool menu effect for a website I'm working on. I'm having a div act as the the section for the main content. When the user opens the menu, the main content div will resize and move out of the way, revealing the menu. However, when I do this with the code I have written, it always loses my scrolling place on the page. Is there any way to keep my place on the page when it shrinks and also when it expands back again? Below is what I have. Thank you in advance!
function shrinkPage() {
var element = document.getElementById("mock-body");
element.classList.toggle("mock-body-on-burger");
var z = document.getElementById("mock-body-container");
z.classList.toggle("mock-body-container-on-burger");
var x = document.getElementById("body");
x.classList.toggle("body-on-burger");
};
body {
margin: 0;
background:#000;
}
.body-on-burger {
max-width: 100%;
overflow-x:hidden;
}
.mock-body-container{
height:100vh;
}
.mock-body-container-on-burger {
height:100vh;
transform: scale(0.4) translate(130%);
overflow: hidden;
}
.mock-body-size-change{
overflow: scroll;
}
.mock-body {
position:relative;
background: #fff;
margin-left: 50px;
}
.container {
position: fixed;
height:50px;
width:50px;
cursor: pointer;
}
.container #icon {
width: 16px;
height: 8px;
position: relative;
margin: 0px auto 0;
top: 40%;
}
.container #icon .bars {
height: 1px;
background: #fff;
}
.myDiv {
height:500px;
}
.one {
background:red;
}
.two {
background:green;
}
.three {
background:blue;
}
<body id="body">
<div class="menu-activator" onclick="shrinkPage()">
<div class="container usd">
<div id="icon">
<div class="bars first"></div>
</div>
</div>
</div>
<div id="mock-body-container" class="mock-body-container">
<div id="mock-body" class="mock-body">
<div class="myDiv one"></div>
<div class="myDiv two"></div>
<div class="myDiv three"></div>
</div>
</div>
</body>
Please take a look at the snippet below. Notice how the overflow property is used.
You have to scroll mock-body-container to keep its scrolling position.
You're scrolling body instead, so when you scale mock-body-container there is nothing to scroll in body and you loose the scrolling position.
function shrinkPage() {
var element = document.getElementById("mock-body");
element.classList.toggle("mock-body-on-burger");
var z = document.getElementById("mock-body-container");
z.classList.toggle("mock-body-container-on-burger");
var x = document.getElementById("body");
x.classList.toggle("body-on-burger");
};
body {
margin: 0;
background:#000;
}
.body-on-burger {
max-width: 100%;
overflow-x:hidden;
}
.mock-body-container{
height:100vh;
overflow:auto;
}
.mock-body-container-on-burger {
height:100vh;
transform: scale(0.4) translate(130%);
}
.mock-body-size-change{
overflow: scroll;
}
.mock-body {
position:relative;
background: #fff;
margin-left: 50px;
}
.container {
position: fixed;
height:50px;
width:50px;
cursor: pointer;
}
.container #icon {
width: 16px;
height: 8px;
position: relative;
margin: 0px auto 0;
top: 40%;
}
.container #icon .bars {
height: 1px;
background: #fff;
}
.myDiv {
height:500px;
}
.one {
background:red;
}
.two {
background:green;
}
.three {
background:blue;
}
<body id="body">
<div class="menu-activator" onclick="shrinkPage()">
<div class="container usd">
<div id="icon">
<div class="bars first"></div>
</div>
</div>
</div>
<div id="mock-body-container" class="mock-body-container">
<div id="mock-body" class="mock-body">
<div class="myDiv one"></div>
<div class="myDiv two"></div>
<div class="myDiv three"></div>
</div>
</div>
</body>
Once you know the element that was in focus it should be relatively easy. If you need to find which element was last in focus, you can do that with a scroll function. If you need this as well let me know and I will update my answer.
If you know that #mock-body is the last element in focus, just scroll back to it after the resize.
In this example I've used jQuery as it makes this interaction easier, but this can be done (albeit more verbosely) with vanilla JS as well.
$('html, body').animate({
scrollTop: $('#mock-body').offset().top
}, 0); // If you want the animation to be smoother you can increase 0 to a higher number
A simple way to do it is to remember the position of the document scroll and reapply it when you getting back to "normal" view:
let savedScroll;
function shrinkPage() {
let _s = (el) => document.querySelector(el),
s_ = (d) => !d.classList.contains('body-on-burger'),
x = _s('#body'),
element = _s('#mock-body'),
z = _s('#mock-body-container');
if (s_(x)) {
savedScroll = document.documentElement.scrollTop;
}
element.classList.toggle("mock-body-on-burger");
z.classList.toggle("mock-body-container-on-burger");
x.classList.toggle("body-on-burger");
if (s_(x)) {
document.documentElement.scrollTop = savedScroll;
}
};
Check it out:
let savedScroll;
function shrinkPage() {
let _s = (el) => document.querySelector(el),
s_ = (d) => !d.classList.contains('body-on-burger'),
x = _s('#body'),
element = _s('#mock-body'),
z = _s('#mock-body-container');
if (s_(x)) {
savedScroll = document.documentElement.scrollTop;
}
element.classList.toggle("mock-body-on-burger");
z.classList.toggle("mock-body-container-on-burger");
x.classList.toggle("body-on-burger");
if (s_(x)) {
document.documentElement.scrollTop = savedScroll;
}
};
body {
margin: 0;
background: #000;
}
.body-on-burger {
max-width: 100%;
overflow-x: hidden;
}
.mock-body-container {
height: 100vh;
}
.mock-body-container-on-burger {
height: 100vh;
transform: scale(0.4) translate(130%);
overflow: hidden;
}
.mock-body-size-change {
overflow: scroll;
}
.mock-body {
position: relative;
background: #fff;
margin-left: 50px;
}
.container {
position: fixed;
height: 50px;
width: 50px;
cursor: pointer;
}
.container #icon {
width: 16px;
height: 8px;
position: relative;
margin: 0px auto 0;
top: 40%;
}
.container #icon .bars {
height: 1px;
background: #fff;
}
.myDiv {
height: 500px;
}
.one {
background: red;
}
.two {
background: green;
}
.three {
background: blue;
}
<body id="body">
<div class="menu-activator" onclick="shrinkPage()">
<div class="container usd">
<div id="icon">
<div class="bars first"></div>
</div>
</div>
</div>
<div id="mock-body-container" class="mock-body-container">
<div id="mock-body" class="mock-body">
<div class="myDiv one"></div>
<div class="myDiv two"></div>
<div class="myDiv three"></div>
</div>
</div>
</body>
Legend: _s(el) returns first match of el and s_(d) checks if d has class body-on-burger.
The simple way to do this is to determine the change in height during the resize, and scroll that much.
const heightChange = newHeight - initialHeight;
scrollableDiv.scrollTop = scrollableDiv.scrollTop - heightChange;
In my case I am using a resize method I wrote, so I do this work inside of a window.addEventListener("mousemove", handleResize); when I know the div in actively being resized by the user.
This will still work fine with native html resizable elements, you just need to figure out how/when to listen for resize/drag events accordingly.

How to make dice not overlap when being thrown?

I'm making a mobile app, and a part of it is being able to throw dice.
I'm working with Ionic as mobile framework and using angular and jquery to make the dice roll. The problem is when i roll multiple dice, that these dice can appear on the same spot, so basicly overlap eachother. I tried working with the jquery offset() and position() and then saying the left value of the dice can never be the same, that way the dice will always appear in another 'column'.
but somehow this didn't work because it registered the position before rolling, and not after rolling.
Here is my code:
dice.html
<ion-view view-title="dice" id="dice">
<ion-nav-bar class="bar-stable">
<ion-nav-back-button>
</ion-nav-back-button>
</ion-nav-bar>
<ion-content id="dice" scroll="true">
<button class="btn orange" id="addDie1" type="button"><span>Add second die</span></button>
<button class="btn red" id="addDie2" type="button"><span>Add third die</span></button>
<section id="roll-wrap">
<div id="die" style="transform: rotateX(0deg) rotateY(0deg);">
<div class="sf f1">1</div>
<div class="sf f2">2</div>
<div class="sf f3">3</div>
<div class="sf f4">4</div>
<div class="sf f5">5</div>
<div class="sf f6">6</div>
</div>
<div id="die2" style="transform: rotateX(0deg) rotateY(90deg);">
<div class="sf f1">1</div>
<div class="sf f2">2</div>
<div class="sf f3">3</div>
<div class="sf f4">4</div>
<div class="sf f5">5</div>
<div class="sf f6">6</div>
</div>
<div id="die3" style="transform: rotateX(0deg) rotateY(180deg);">
<div class="sf f1">1</div>
<div class="sf f2">2</div>
<div class="sf f3">3</div>
<div class="sf f4">4</div>
<div class="sf f5">5</div>
<div class="sf f6">6</div>
</div>
</section>
<button class="btn orange" id="play" type="button"><span>Roll it</span></button>
</ion-content>
</ion-view>
controllers.js
.controller('DiceCtrl', function($scope) {
(function($, self){
if(!$ || !self) {
return;
}
for(var i=0; i<self.properties.length; i++) {
var property = self.properties[i],
camelCased = StyleFix.camelCase(property),
PrefixCamelCased = self.prefixProperty(property, true);
$.cssProps[camelCased] = PrefixCamelCased;
}
})(window.jQuery, window.PrefixFree);
//Actual code for Play Action , still buggy for 2 dice stacking on top of eachother
$(function(){
$("#addDie1").click(function(e){
e.preventDefault();
$("#die2").css("display","block");
});
$("#addDie2").click(function(e){
e.preventDefault();
$("#die3").css("display","block");
});
$()
var x=[0,90,180,270];
$("#play").click(function(e){
var position = $(".sf").offset();
var position2 = $("#die2 .sf").offset();
var position3 = $("#die3 .sf").offset();
console.log(position);
console.log(position2);
console.log(position3);
e.preventDefault();
do {
var rand1=Math.floor(Math.random()*4);
var rand2=Math.floor(Math.random()*4);
var rand3=Math.floor(Math.random()*4);
var rand4=Math.floor(Math.random()*4);
var rand5=Math.floor(Math.random()*4);
var rand6=Math.floor(Math.random()*4);
} while((x[rand1] == x[rand3] && x[rand2] == x[rand4]) || (x[rand1] == x[rand5] && x[rand2] == x[rand6]) || (x[rand3] == x[rand5] && x[rand4] == x[rand6]))
console.log(x[rand1] + "\n" + x[rand2] + "\n" + x[rand3] + "\n" + x[rand4] + "\n" + x[rand5] + "\n" + x[rand6] + "\n")
$("#die").css("transform","rotateX("+x[rand1]+"deg) rotateY("+x[rand2]+"deg)");
$("#die2").css("transform","rotateX("+x[rand3]+"deg) rotateY("+x[rand4]+"deg)");
$("#die3").css("transform","rotateX("+x[rand5]+"deg) rotateY("+x[rand6]+"deg)");
});
});
})
style.css
#dice {
background: url("../img/dice_bg.jpg") no-repeat;
background-position: center;
background-size: cover;
}
#roll-wrap {
perspective: 800;
perspective-origin: 50% 200px;
}
#addDie1, #addDie2{
width: 50%;
}
#addDie2 {
float:right;
}
#play {
width: 50%;
margin-left: 25%;
margin-top: 10px;
}
.btn {
position: relative;
display: inline-block;
margin: 0px auto;
padding: 0;
overflow: hidden;
border-width: 0;
outline: none;
background-color: #2ecc71;
color: #ecf0f1;
transition: background-color .3s;
}
.btn > * {
position: relative;
}
.btn span {
display: block;
padding: 12px 24px;
}
.btn.orange {
background-color: #e67e22;
}
.btn.orange:hover, .btn.orange:focus {
background-color: #d35400;
}
.btn.red {
background-color: #e74c3c;
}
.btn.red:hover, .btn.red:focus {
background-color: #c0392b;
}
#die {
position: relative;
margin: 40px auto 0;
height: 400px;
width: 90%;
transition: transform 1.5s linear;
transform-style: preserve-3d;
}
#die2 {
position: relative;
margin: -400px auto 0;
height: 400px;
width: 90%;
transition: transform 1.5s linear;
transform-style: preserve-3d;
}
#die3 {
position: relative;
margin: -400px auto 0;
height: 400px;
width: 90%;
transition: transform 1.5s linear;
transform-style: preserve-3d;
}
.sf {
position: absolute;
height: 62px;
width: 62px;
padding: 20px;
background-color:white;;
font-size: 30px;
color: black;;
border: 1px solid white;
border-radius: 3px;
text-align: center;
}
/* TranslateZ = hoever elk vlak vaneen moet staan. rotateX waar het moet staan */
#die .f1, #die2 .f1, #die3 .f1 {
transform: rotateX(90deg) translateZ(30px);
}
#die .f2, #die2 .f2, #die3 .f2 {
transform: translateZ(30px);
}
#die .f3, #die2 .f3, #die3 .f1 {
transform: rotateY(90deg) translateZ(30px);
}
#die .f4, #die2 .f4, #die3 .f4 {
transform: rotateY(180deg) translateZ(30px);
}
#die .f5, #die2 .f5, #die3 .f5 {
transform: rotateY(-90deg) translateZ(30px);
}
#die .f6, #die2 .f6, #die3 .f6 {
transform: rotateX(-90deg) rotate(180deg) translateZ(30px);
}

Categories

Resources