I'm working on this script since 9 days, I found the script online, and from there I tried to add some code.
The point of the script is to rotate the Div dynamically based on the distance they have between each other.
In a way it works, if you resize the page at some point the divs turn their Y axes.
I have mainly 2 problems, the first one is that if I add new divs they just are shown in a new line.
The second problem is that those divs position should change, they need to get closer and they should move to the left side of the div.
I hope somebody can help because I spent already 10 days on this and I can't find a solution.
Thank you so much
function myFunction(distance) {
//add browser check currently it set for safari
// Code for Safari
var degree = 0;
if (distance <= -1 && distance >= -5) {
degree = 15;
} else if (distance < -5 && distance >= -10) {
degree = 25;
} else if (distance < -10 && distance >= -15) {
degree = 30;
} else if (distance < -15 && distance >= -20) {
degree = 35;
} else if (distance < -20) {
degree = 45;
}
document.getElementById("panel").style.WebkitTransform = "rotateY(" + degree + "deg)";
document.getElementById("panel2").style.WebkitTransform = "rotateY(" + degree + "deg)";
document.getElementById("panel3").style.WebkitTransform = "rotateY(" + degree + "deg)";
document.getElementById("panel4").style.WebkitTransform = "rotateY(" + degree + "deg)";
// document.getElementById("panel").style.marginRight= "100px";
document.getElementById("panel2").style.marginRight = "300px";
document.getElementById("panel3").style.marginRight = "30px";
document.getElementById("panel4").style.marginRight = "30px";
// document.getElementById("panel5").style.WebkitTransform = "rotateY(45deg)";
// document.getElementById("panel6").style.WebkitTransform = "rotateY(45deg)";
// Code for IE9
// document.getElementById("asd").style.msTransform = "rotateY(20deg)";
// Standard syntax
// document.getElementById("asd").style.transform = "rotateY(20deg)";
}
function myFunctionb() {
document.getElementById("panel").style.WebkitTransform = "rotateY(0deg)";
document.getElementById("panel2").style.WebkitTransform = "rotateY(0deg)";
document.getElementById("panel3").style.WebkitTransform = "rotateY(0deg)";
document.getElementById("panel4").style.WebkitTransform = "rotateY(0deg)";
// document.getElementById("panel5").style.WebkitTransform = "rotateY(0deg)";
// document.getElementById("panel6").style.WebkitTransform = "rotateY(0deg)";
}
// need to find a better solution
var first = document.getElementById("panel");
var second = document.getElementById("panel2");
var lastpanel = document.getElementById("panel4");
var lastbox = document.getElementById("last");
var container = document.getElementById("wrapper");
var notcongainer = container.offsetLeft;
var distance = container.offsetWidth - (lastpanel.offsetWidth + lastbox.offsetLeft + 4) + notcongainer;
console.log(distance);
var myVar;
var minDistance = 10;
function check() {
myVar = setInterval(testcheck, 100);
}
// First I check that the boxes lenght are as much as the container
// Then I check the distance between 2 boxes
function testcheck() {
if (distance < minDistance) {
myFunction(distance);
} else {
myFunctionb();
}
distance = container.offsetWidth - (lastpanel.offsetWidth + lastbox.offsetLeft + 4) + notcongainer;
/*console.log(distance)*/
}
//ADD NEW DIV
function addDiv() {
var div = document.createElement('div');
div.className = "col-box";
div.id = "newId";
div.innerHTML = '<div class="hover panel"><div id= "panel3" class="front"><div class="box1"><p>New Div</p></div></div></div>';
document.getElementById('wrapper').appendChild(div);
}
body {
background-color: #ecf0f1;
margin: 20px;
font-family: Arial, Tahoma;
font-size: 20px;
color: #666666;
text-align: center;
}
p {
color: #ffffff;
}
.col-box {
width: 22%;
position: relative;
display: inline;
display: inline-block;
margin-bottom: 20px;
z-index: 1;
}
.end {
margin-right: 0 !important;
}
/*-=-=-=-=-=-=-=-=-=-=- */
/* Flip Panel */
/*-=-=-=-=-=-=-=-=-=-=- */
.wrapper {
width: 80%;
height: 200px;
margin: 0 auto;
background-color: #bdd3de;
hoverflow: hidden;
border: 1px;
}
.panel {
margin: 0 auto;
height: 130px;
position: relative;
-webkit-perspective: 600px;
-moz-perspective: 600px;
}
.panel .front {
text-align: center;
}
.panel .front {
height: inherit;
position: absolute;
top: 0;
z-index: 900;
text-align: center;
-webkit-transform: rotateX(0deg) rotateY(0deg);
-moz-transform: rotateX(0deg) rotateY(0deg);
-webkit-transform-style: preserve-3d;
-moz-transform-style: preserve-3d;
-webkit-backface-visibility: hidden;
-moz-backface-visibility: hidden;
-webkit-transition: all .4s ease-in-out;
-moz-transition: all .4s ease-in-out;
-ms-transition: all .4s ease-in-out;
-o-transition: all .4s ease-in-out;
transition: all .4s ease-in-out;
}
.panel.flip .front {
-webkit-transform: rotateY(45deg);
-moz-transform: rotateY(180deg);
}
.col-box:hover {
z-index: 1000;
}
.box1 {
background-color: #14bcc8;
width: 160px;
height: 60px;
margin-left: 5px;
padding: 20px;
border-radius: 10px;
-moz-border-radius: 10px;
-webkit-border-radius: 10px;
}
<body onload="check()">
<div id="wrapper" class="wrapper">
<div id="first" class="col-box">
<div class="hover panel">
<div id="panel" class="front">
<div class="box1">
<p>Div 1</p>
</div>
</div>
</div>
</div>
<div id="second" class="col-box">
<div class="hover panel">
<div id="panel2" class="front">
<div class="box1">
<p>Div 2</p>
</div>
</div>
</div>
</div>
<div id="third" class="col-box">
<div class="hover panel">
<div id="panel3" class="front">
<div class="box1">
<p>Div 3</p>
</div>
</div>
</div>
</div>
<div id="last" class="col-box">
<div class="hover panel">
<div id="panel4" class="front">
<div class="box1">
<p>Last Div</p>
</div>
</div>
</div>
</div>
<button onclick="addDiv()">Add New Div</button>
</div>
9 days... that's too long. Time to step back and break this up into smaller things.
This isn't an 'answer' yet... but I need to post an image for you. Your question wasn't that clear, but it's not an easy thing to explain. In your case, I would show an image.
Now that I can see what you're doing - it doesn't sound like an arbitrary and completely silly task.
You have a list of 'things' or 'cards' or whatever... so, first things first... how do you insert new DOM into the page - and / into that list - and have the list all on one line. A few ways - but most likely you can just use flexbox -
https://jsfiddle.net/sheriffderek/8eLggama -> https://jsfiddle.net/sheriffderek/pztvhn3L (this is an example - but it's pretty naive - and the further you take this, the closer you'll get to building what most frameworks - like Vue could do way better... but good for learning! Start with something small - to just do that.
// will take an object with the list name and the card id
// eventuallly - you'd want the card to have more info sent in...
function addCard(infoObject) {
var targetList = document.getElementById(infoObject.list);
var li = document.createElement('li');
li.classList.add('item');
// ug! why aren't I using jQuery...
var component = document.createElement('aside');
component.classList.add('card');
var title = document.createElement('h2');
var uniqueId = idMaker.create();
var id = document.createTextNode(uniqueId);
title.appendChild(id);
component.appendChild(title)
li.appendChild(component);
targetList.appendChild(li);
// woah... this part is really boring...
// this is why templating engines and JSON are so popular
// you could also add 'remove' button etc... right?
var removeButton = document.createElement('button');
var removeText = document.createTextNode('x');
removeButton.appendChild(removeText);
removeButton.classList.add('remove-card');
component.appendChild(removeButton);
//
removeButton.addEventListener('click', function() {
var parent = document.getElementById(infoObject.list);
idMaker.removed.push(uniqueId);
parent.removeChild(li);
idMaker.read();
});
}
// start out with a few?
addCard({list: 'exampleTarget'});
addCard({list: 'exampleTarget'});
addCard({list: 'exampleTarget'});
// start a UI to add cards
var addCardButton = document.querySelector('[data-trigger="add-card"]');
addCardButton.addEventListener('click', function() {
addCard({list: 'exampleTarget'});
});
...and then you maybe absolute position the card inside of that list item? It's certainly a unique thing to do, and wont be easy. Then, you can check the number of items - of the width of each item - and make a calculation for transform based on that? Good luck!
Related
Hey I'm trying to make a function that fills an empty container of a slideshow with images, with each image being contained in it's own div.
My webpage have an undetermined amount of modal images which , when clicked, open a slideshow album of images. I got this working for 1 image then realized that to have it work for an undetermined amount of slideshows of undetermined size I should make a function that fills the slideshow div. I planned to have each modal image to have a data attribute of "1,2,3...etc" and have a bunch an array with multiple objects each named similarly "1,2,3...etc" then I'd use this information to create and append the correct divs and images to the slideshow container. I will post what I want the slideshow container div to look like, my existing code, and a fiddle of what is supposed to happen. I am new to javascript and appreciate the help. I'm not certain what I've done incorrectly here, and If I haven't explained well enough then I will add more.
Edit:
I have noticed that in my modal image, if in the onClick I put fillSlides first, the other two functions won't work (or won't be called), but if I put it at the end it opens an empty slideshow. I don't get why.
https://jsfiddle.net/nhk3o0m1/26/
Current HTML:
<body >
<h2 id="title" style="text-align:center">hellkkko</h2>
<div class="row">
<div class="column">
<img id="modal-1" src="https://www.yosemitehikes.com/images/wallpaper/yosemitehikes.com-bridalveil-winter-1200x800.jpg" style="max-width:100%" data-modal="1" onclick="openModal();currentSlide(1); fillSlides(this);" class="hover-shadow cursor">
</div>
</div>
<div id="myModal" class="modal">
<span class="close cursor" onclick="closeModal()">×</span>
<div class="modal-content">
<a class="prev" onclick="plusSlides(-1)">❮</a>
<a class="next" onclick="plusSlides(1)">❯</a>
</div>
</div>
What I want my .modal-content div to look like after the function runs:
<div class="modal-content">
<div class="mySlides">
<img src="Images/LS_01.jpg" class="img">
</div>
<div class="mySlides">
<img src="Images/LS_02.jpg" class="img">
</div>
<div class="mySlides">
<img src="Images/LS_03.jpg" class="img">
</div>
<div class="mySlides">
<img src="Images/LS_04.jpg" class="img">
</div>
<a class="prev" onclick="plusSlides(-1)">❮</a>
<a class="next" onclick="plusSlides(1)">❯</a>
</div>
Javascript:
function fillSlides(modalID) {
var container = document.getElementsByClassName("modal-content");
var slides = {
"1": ["Images/LS_01.jpg", "Images/LS_02.jpg", "Images/LS_03.jpg", "Images/LS_04.jpg"],
"2": ["Images/LS_05.jpg", "Images/LS_06.jpg", "Images/LS_07.jpg", "Images/LS_08.jpg"],
"3": ["Images/LS_09.jpg", "Images/LS_10.jpg", "Images/LS_11.jpg", "Images/LS_12.jpg"]
};
var modal_num = modalID.getAttribute('data-modal');
for (var i = slides[modal_num].length; i > 0; i--) {
var the_divs = document.createElement('div');
var s_img = document.createElement('img');
the_divs.className = 'mySlides';
s_img.src = slides[modal_num][i];
the_divs.appendChild(s_img);
container.appendChild(the_divs);
}
}
<h2 id="title" style="text-align:center">hellkkko</h2>
<div class="row">
<div class="column">
<img id="modal-1" src="https://www.yosemitehikes.com/images/wallpaper/yosemitehikes.com-bridalveil-winter-1200x800.jpg" style="max-width:100%" data-modal="1" onclick="openModal();currentSlide(1); fillSlides(this);" class="hover-shadow cursor">
</div>
</div>
<div id="myModal" class="modal">
<span class="close cursor" onclick="closeModal()">×</span>
<div class="modal-content">
<a class="prev" onclick="plusSlides(-1)">❮</a>
<a class="next" onclick="plusSlides(1)">❯</a>
</div>
</div>
Added a function that generates slides on the fly. There are no slides in HTML and arrow controls are in #content. You gave no details on how album exists so I made a thumbnail for 2 extra albums. Also, there's a solution to your problem concerning the removal of everything with the arrows being the exception. The CSS is a little wonky but I'm sure you can rectify it easily enough.
Details commented in demo
Demo
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1, user-scalable=no">
<title></title>
<style>
html,
body {
height: 100%;
width: 100%
}
body {
font-family: Verdana, sans-serif;
margin: 0;
}
* {
box-sizing: border-box;
}
.img {
max-width: 100%;
max-height: 100%;
width: auto;
height: auto;
object-fit: contain;
}
.row {
display:flex;
justify-content:space-between;
}
.column {
width: 25%;
padding: 0 8px;
}
/* The Modal (background) */
.modal {
display: none;
position: fixed;
z-index: 1;
padding-top: 100px;
left: 0;
top: 0;
width: 100%;
height: 100%;
overflow-x: hidden;
overflow-y: scroll;
background: rgba(0, 0, 0, 0.9);
}
/* Modal Content */
.modal-content {
position: relative;
background-color: rgba(0, 0, 0, 0.9);
margin: auto;
padding: 0;
width: 100%;
max-width: 1200px;
}
/* The Close Button */
.close {
color: white;
position: absolute;
top: 10px;
right: 25px;
font-size: 35px;
font-weight: bold;
}
.close:hover,
.close:focus {
color: #999;
text-decoration: none;
cursor: pointer;
}
/* Next & previous buttons */
.prev,
.next {
cursor: pointer;
position: absolute;
top: 50%;
width: auto;
padding: 16px;
margin-top: -50px;
color: white;
font-weight: bold;
font-size: 20px;
transition: 0.6s ease;
border-radius: 0 3px 3px 0;
user-select: none;
-webkit-user-select: none;
}
/* Position the "next button" to the right */
.next {
right: 0;
border-radius: 3px 0 0 3px;
}
/* On hover, add a black background color with a little bit see-through */
.prev:hover,
.next:hover {
background-color: rgba(0, 0, 0, 0.8);
text-decoration: none;
}
/* Number text (1/3 etc) */
.nth {
color: #f2f2f2;
font-size: 12px;
padding: 8px 12px;
position: absolute;
right: 0;
}
img {
margin-bottom: -4px;
cursor: pointer
}
img.hover-shadow {
transition: all .2s ease-in-out;
}
.hover-shadow:hover {
transform: scale(1.1);
}
.modal-content {
-webkit-animation-name: zoom;
-webkit-animation-duration: 0.6s;
animation-name: zoom;
animation-duration: 0.6s;
}
#-webkit-keyframes zoom {
from {
-webkit-transform: scale(0)
}
to {
-webkit-transform: scale(1)
}
}
#keyframes zoom {
from {
transform: scale(0)
}
to {
transform: scale(1)
}
}
.slide img {
display: block;
height: 100%;
margin: 0 auto;
margin-bottom: 50px;
}
.slide {
text-align: center;
height: 80vh;
display: none;
}
.cap {
font-size: 1.5em;
background: rgba(0, 0, 0, .4);
position: absolute;
z-index: 2;
left: 0;
top: 0;
right: 0;
text-align: center;
color: #fff
}
.act {
display: block
}
</style>
</head>
<body>
<header>
<div class="row">
<div class="column"> <img src="https://www.yosemitehikes.com/images/wallpaper/yosemitehikes.com-bridalveil-winter-1200x800.jpg"
style="max-width:100%" onclick="album(img0, cap0);openModal();"
class="hover-shadow"> </div>
<div class="column"> <img src="https://www.yosemitehikes.com/images/wallpaper/yosemitehikes.com-bridalveil-winter-1200x800.jpg"
style="max-width:100%" onclick="album(img1, cap1);openModal();"
class="hover-shadow"> </div>
<div class="column"> <img src="https://www.yosemitehikes.com/images/wallpaper/yosemitehikes.com-bridalveil-winter-1200x800.jpg"
style="max-width:100%" onclick="album(img2, cap2);openModal();"
class="hover-shadow"> </div>
</div>
</header>
<section id="box">
<div id="xModal" class="modal"> <span class="close cursor" onclick="closeModal()">×</span>
<div class="modal-content" id='content'> <a class="prev" onclick="plusSlides(-1)">❮</a> <a class="next"
onclick="plusSlides(1)">❯</a> </div>
</div>
</section>
<footer> </footer>
<script>
/* 3 arrays are required:
|= 1. An array of strings.
|| Each represents a src of an image
|= 2. An array of strings. Each represents the
|| text of a figcaption
|= 3. An empty array
|| For each additional album add #1 and #2, #3
|| is emptied and reused at the beginning of
|| a new cycle.
*/
// Album 0
var img0 = [
"http://www.catholicevangelism.org/wp-content/uploads/2013/06/1200x800.gif",
"http://chasingseals.com/wp-content/uploads/2014/02/greenlandBanner2000x800.jpg",
"http://www.a1carpet-to.com/wp-content/uploads/2015/08/600x400.png",
"https://support.kickofflabs.com/wp-content/uploads/2016/06/800x1200.png"
];
var cap0 = ['caption1', 'caption2', 'caption3', 'caption4'];
// Album 1
var img1 = [
'https://d3i6fh83elv35t.cloudfront.net/newshour/app/uploads/2016/05/729665main_A-BlackHoleArt-pia16695_full-1024x576.jpg',
'http://cdn.newsapi.com.au/image/v1/85fb305132eb20ebbb01af386983c8a1',
'http://science.nationalgeographic.com/staticfiles/NGS/Shared/StaticFiles/Science/Images/Content/neptune-pia01492-ga.jpg',
'https://cdn.spacetelescope.org/archives/images/wallpaper1/heic1509a.jpg',
'https://i.giphy.com/media/JCUyexH8Zaf8k/giphy.webp'
];
var cap1 = ['Title I', 'Title II', 'Title III', 'Title IV',
'Title V'
];
// Album 2
var img2 = [
'https://i.ytimg.com/vi/YeQnLnRvZ9Y/maxresdefault.jpg',
'https://www.thesun.co.uk/wp-content/uploads/2017/08/nintchdbpict000319076839.jpg?strip=all&w=960',
'https://i0.wp.com/www.sketchysloth.com/wp-content/uploads/2016/07/Legendary-Hanging-Garden-Of-Babylon.jpg?fit=710%2C495&ssl=1',
'https://i.ytimg.com/vi/YoRvJcgSDE4/maxresdefault.jpg',
'https://www.realmofhistory.com/wp-content/uploads/2017/01/mausoleum-at-halicarnassus-restored_1.jpg',
'http://www.ancient-origins.net/sites/default/files/field/image/statue-of-Zeus-Olympia.jpg',
'https://i.ytimg.com/vi/F2yYkbinGnc/maxresdefault.jpg'
];
var cap2 = ['Colossus of Rhodes', 'Great Pyramid of Giza',
'Hanging Gardens of Babylon', 'Lighthouse of Alexandria',
'Mausoleum at Halicarnassus', 'Statue of Zeus at Olympia',
'Temple of Artemis at Ephesus'
];
// Declare a empty array
var data = [];
// Declare some counters outside of loop (or inside of loop using let)
var i, b, x;
// Reference the node that will contain the slides
var con = document.getElementById('content');
/* On each iteration...
|= Empty the data array
|= Create an object...
|| add a value from img[] to the src property
|| add a value from cap[] to the cap property
|| add the current value of index +1 to pos property
|| push the object into data array
*/
// Get the total length of data array
// Call genSlides()
function album(img, cap) {
data.length = 0;
for (i = 0; i < img.length; i++) {
var ele = new Object;
ele.src = img[i];
ele.cap = cap[i];
ele.pos = i + 1;
data.push(ele);
}
var qty = data.length;
genSlides(qty)
}
console.log(data);
/* Pass qty through...
|= On each iteration...
|= Create a documentFragment
|| it will allow us to append new elements to
|| it while still not in the DOM
|| which is faster because tasks within the DOM
|| are slow for the browser in comparison.
|= Notice that the data array is being used
|| to assign unique values.
*/
function genSlides(qty) {
for (b = 0; b < qty; b++) {
var frag = document.createDocumentFragment();
var slide = document.createElement('figure');
slide.id = 's' + b;
slide.className = 'slide';
var cap = document.createElement('figcaption');
cap.className = 'cap';
cap.textContent = data[b].cap;
var img = document.createElement('img');
img.classsName = 'img';
img.src = data[b].src;
var nth = document.createElement('b');
nth.className = 'nth';
nth.textContent = data[b].pos + '/' + data.length;
slide.appendChild(cap);
cap.appendChild(nth);
slide.appendChild(img);
frag.appendChild(slide);
con.appendChild(frag);
}
return false;
}
/* To avoid redundancy call sub functions within an initiating function
|| currentSlide() should start at 0, remember that all indexes by
|| default start at 0 and that the last index is .length - 1
|| showSlides() has ben corrected.
*/
function openModal() {
document.getElementById('xModal').style.display = "block";
showSlides(slideIndex);
currentSlide(0);
}
/* To remove what's in #content with the exception of the arrows we
|| gather all .slides in a NodeList and use a loop to remove them.
*/
function closeModal() {
document.getElementById('xModal').style.display = "none";
var slides = document.querySelectorAll(".slide");
for (x = 0; x < slides.length; x++) {
con.removeChild(slides[x]);
}
}
var slideIndex = 0;
function plusSlides(n) {
showSlides(slideIndex += n);
}
function currentSlide(n) {
showSlides(slideIndex = n);
}
function showSlides(n) {
var i;
var slides = document.querySelectorAll(".slide");
if (n > slides.length - 1) {
slideIndex = 0
}
if (n < 0) {
slideIndex = slides.length - 1
}
// Flipping a class is much cleaner than relying on style
for (i = 0; i < slides.length; i++) {
slides[i].classList.remove('act');
}
slides[slideIndex].classList.add('act');
}
</script>
</body>
</html>
I made a little 15 puzzle which I want to be shuffled in the beginning. I start from the completed state and do 1000 random "fakeClicks" on tiles of which some are valid according to my code and most are not. The valid "fakeClicks" cause the emptyTile and the selectedTile to swap their positions by swaping their top and left values.
Everything (except the checkCompleteness() method which does not exist yet) seems to work - until one actually tries to solve the puzzle. With a small n, I reached the unsolvable game situation more than 50 percent of the time.
How is this possible when during shuffling I do valid moves only? Obviously it must be something about my code checking if a move is valid or not:
if ((Math.abs(selectedX - emptyX) === tileSize) ^ (Math.abs(selectedY - emptyY) === tileSize)) {
(The ^ (xor) is to prevent diagonal moves.)
Does anyone see where the problem is to be found? Or does anyone have a suggestion for a good debugging strategy? After more than an hour of debugging, I am kind of clueless.
var idList = ["t1", "t2", "t3", "t4", "t5", "t6", "t7", "t8", "t9", "t10", "t11", "t12", "t13", "t14", "t15", "t0"];
var tileSize = 100;
var init = function() {
// place tiles on the board and add listener
for (var column = 0; column < 4; column++) {
for (var row = 0; row < 4; row++) {
var div = document.querySelector("." + idList[row * 4 + column]);
div.style.top = row * tileSize + "px";
div.style.left = column * tileSize + "px";
if (idList[row * 4 + column] !== "t0") {
div.addEventListener("click", clickListener);
}
}
}
// shuffle tiles
for (i = 0; i < 1000; i++) {
var fakeClick = parseInt(Math.random() * 15);
swapTiles(idList[fakeClick]);
}
};
var clickListener = function(e) {
var selectedTileClass = e.target.classList[1];
swapTiles(selectedTileClass);
//checkCompleteness(); // to be done later
};
var swapTiles = function(selectedTileClass) {
// get empty tile and selected tile
var selectedTile = document.querySelector("." + selectedTileClass);
var selectedX = parseInt(selectedTile.style.left);
var selectedY = parseInt(selectedTile.style.top);
var emptyTile = document.querySelector(".t0");
var emptyX = parseInt(emptyTile.style.left);
var emptyY = parseInt(emptyTile.style.top);
// only swap tiles if selected tile "next to" empty tile
if ((Math.abs(selectedX - emptyX) === tileSize) ^ (Math.abs(selectedY - emptyY) === tileSize)) {
selectedTile.style.left = emptyX + "px";
selectedTile.style.top = emptyY + "px";
emptyTile.style.left = selectedX + "px";
emptyTile.style.top = selectedY + "px";
}
};
.board {
position: relative;
width: 400px;
height: 400px;
margin: auto;
background-color: firebrick;
border: 2px firebrick solid;
}
.tile {
position: absolute;
width: 100px;
height: 100px;
border: 2px firebrick solid;
box-sizing: border-box;
background-color: orange;
line-height: 100px;
font-size: 2rem;
font-weight: bold;
font-family: Arial, sans-serif;
color: firebrick;
text-align: center;
transition: all .25s linear;
cursor: pointer;
}
.t0 {
position: absolute;
width: 96px;
height: 96px;
margin: 2px;
border: 2px orange solid;
box-sizing: border-box;
pointer-events: none;
transition: all .25s linear;
}
<html>
<meta charset="utf-8">
<head>
<script type="text/javascript" src="js.js"></script>
<link rel="stylesheet" type="text/css" href="style.css">
</head>
<body onload="init();">
<div class="wrapper">
<div class="center">
<div class="board">
<div class="tile t1">1</div>
<div class="tile t2">2</div>
<div class="tile t3">3</div>
<div class="tile t4">4</div>
<div class="tile t5">5</div>
<div class="tile t6">6</div>
<div class="tile t7">7</div>
<div class="tile t8">8</div>
<div class="tile t9">9</div>
<div class="tile t10">10</div>
<div class="tile t11">11</div>
<div class="tile t12">12</div>
<div class="tile t13">13</div>
<div class="tile t14">14</div>
<div class="tile t15">15</div>
<div class="t0"></div>
</div>
</div>
</div>
</body>
</html>
You are right, your test is wrong.
Imagine a small board with the selected tile in the center
ooooo
ooooo
ooxoo
ooooo
ooooo
and now look at what the two truth tables of the 2 predicates give depending on where the empty tile is.
ftftf
ftftf
ftxtf
ftftf
ftftf
and
fffff
ttttt
ffxff
ttttt
fffff
mix them with an xor and you get
ftftf
tftft
ftxtf
tftft
ftftf
which means you get the correct response on the "first circle" around the tile, but you get incorrect responses farther from the tile.
So I have a set of elements called .project-slide, one after the other. Some of these will have the .colour-change class, IF they do have this class they will change the background colour of the .background element when they come into view. This is what I've got so far: https://codepen.io/neal_fletcher/pen/eGmmvJ
But I'm looking to achieve something like this: http://studio.institute/clients/nike/
Scroll through the page to see the background change. So in my case what I'd want is that when a .colour-change was coming into view it would slowly animate the opacity in of the .background element, then slowly animate the opacity out as I scroll past it (animating on scroll that is).
Any suggestions on how I could achieve that would be greatly appreciated!
HTML:
<div class="project-slide fullscreen">
SLIDE ONE
</div>
<div class="project-slide fullscreen">
SLIDE TWO
</div>
<div class="project-slide fullscreen colour-change" data-bg="#EA8D02">
SLIDE THREE
</div>
<div class="project-slide fullscreen">
SLIDE TWO
</div>
<div class="project-slide fullscreen colour-change" data-bg="#cccccc">
SLIDE THREE
</div>
</div>
jQuery:
$(window).on('scroll', function () {
$('.project-slide').each(function() {
if ($(window).scrollTop() >= $(this).offset().top - ($(window).height() / 2)) {
if($(this).hasClass('colour-change')) {
var bgCol = $(this).attr('data-bg');
$('.background').css('background-color', bgCol);
} else {
}
} else {
}
});
});
Set some data-gb-color with RGB values like 255,0,0…
Calculate the currently tracked element in-viewport-height.
than get the 0..1 value of the inViewport element height and use it as the Alpha channel for the RGB color:
/**
* inViewport jQuery plugin by Roko C.B.
* http://stackoverflow.com/a/26831113/383904
* Returns a callback function with an argument holding
* the current amount of px an element is visible in viewport
* (The min returned value is 0 (element outside of viewport)
*/
;
(function($, win) {
$.fn.inViewport = function(cb) {
return this.each(function(i, el) {
function visPx() {
var elH = $(el).outerHeight(),
H = $(win).height(),
r = el.getBoundingClientRect(),
t = r.top,
b = r.bottom;
return cb.call(el, Math.max(0, t > 0 ? Math.min(elH, H - t) : (b < H ? b : H)), H);
}
visPx();
$(win).on("resize scroll", visPx);
});
};
}(jQuery, window));
// OK. Let's do it
var $wrap = $(".background");
$("[data-bg-color]").inViewport(function(px, winH) {
var opacity = (px - winH) / winH + 1;
if (opacity <= 0) return; // Ignore if value is 0
$wrap.css({background: "rgba(" + this.dataset.bgColor + ", " + opacity + ")"});
});
/*QuickReset*/*{margin:0;box-sizing:border-box;}html,body{height:100%;font:14px/1.4 sans-serif;}
.project-slide {
height: 100vh;
display: flex;
align-items: center;
justify-content: center;
}
.project-slide h2 {
font-weight: 100;
font-size: 10vw;
}
<div class="project-slides-wrap background">
<div class="project-slide">
<h2>when in trouble...</h2>
</div>
<div class="project-slide" data-bg-color="0,200,255">
<h2>real trouble...</h2>
</div>
<div class="project-slide">
<h2>ask...</h2>
</div>
<div class="project-slide" data-bg-color="244,128,36">
<h2>stack<b>overflow</b></h2>
</div>
</div>
<script src="//code.jquery.com/jquery-3.1.0.js"></script>
Looks like that effect is using two fixed divs so if you need something simple like that you can do it like this:
But if you need something more complicated use #Roko's answer.
var fixed = $(".fixed");
var fixed2 = $(".fixed2");
$( window ).scroll(function() {
var top = $( window ).scrollTop();
var opacity = (top)/300;
if( opacity > 1 )
opacity = 1;
fixed.css("opacity",opacity);
if( fixed.css('opacity') == 1 ) {
top = 0;
opacity = (top += $( window ).scrollTop()-400)/300;
if( opacity > 1 )
opacity = 1;
fixed2.css("opacity",opacity);
}
});
.fixed{
display: block;
width: 100%;
height: 200px;
background: blue;
position: fixed;
top: 0px;
left: 0px;
color: #FFF;
padding: 0px;
margin: 0px;
opacity: 0;
}
.fixed2{
display: block;
width: 100%;
height: 200px;
background: red;
position: fixed;
top: 0px;
left: 0px;
color: #FFF;
padding: 0px;
margin: 0px;
opacity: 0;
}
.container{
display: inline-block;
width: 100%;
height: 2000px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container">
Scroll me!!
</div>
<div class="fixed">
</div>
<div class="fixed2">
</div>
I'm struggling to find a solution to this and wonder if anyone can help.
I'd like to make a page where an image would disappear over time revealing another image. I'm hoping to achieve this by using the updatesecond/getseconds function. So essentially it would act as a clock, the more minutes/seconds have passed the more it disappears, and have it cycle. For example at the beginning of the day it would be a full image, at 12 it would be half, and at 24hours it would be gone, and repeat. I figure it would be an if else function about the percentage of the page that's left, I just can't figure out how to word it.
Is this possible at all? Any help would be greatly appreciated. Thanks!
Here is the code I'm working with so far. Thank you in advance.
body
{
background-color: #FFF;
padding: 2%;
color: #ccc;
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
font-size: 1em;
}
a
{
color: #FFF;
text-decoration: none;
}
a:hover
{
color: #DCE808;
text-decoration: underline;
}
#mosaic
{
/* background-color: yellow;
font-size: 500px;
color: black;
height: 1310px;
width: 2000px; */
background-image: url('tomorrow4.png');
}
#mosaic span.hover
{
/* background-color: blue;
font-size: 500px;
color: white;
height: 1310px;
width: 2000px;
left: 100px;*/
float: left;
background-image: url('today4.png');
}
and javascript
$(document).ready(function() {
var width = 1400;
var height = 724;
count = 0;
elements = new Array();
var el = $('#mosaic');
el.width(width).height(height);
var horizontal_pieces = 100;
var vertical_pieces = 100;
total_pieces = horizontal_pieces * vertical_pieces;
var box_width = width / horizontal_pieces;
var box_height = height / vertical_pieces;
var vertical_position = 0;
for (i=0; i<total_pieces; i++)
{
var tempEl = $('<span class="hover" id="hover-' + i + '">
</span>');
var horizontal_position = (i % horizontal_pieces) * box_width;
if(i > 0 && i % horizontal_pieces == 0)
{
vertical_position += box_height;
}
tempEl.css('background-position', '-' + horizontal_position + 'px
-' + vertical_position + 'px');
el.append(tempEl);
elements.push(tempEl);
}
elements = shuffleArray(elements);
$('#mosaic .hover').width(box_width).height(box_height);
setInterval(toggleDisplay, 100);
});
function toggleDisplay()
{
var tempEl = elements[count];
var opacity = tempEl.css('opacity');
if(opacity == 0)
{
tempEl.animate({ opacity: 1 })
}
else
{
tempEl.animate({ opacity: 0 })
}
count = (count + 1) % total_pieces;
}
/* shuffleArray source:
http://stackoverflow.com/questions/2450954/how-to-randomize-a-
javascript-array#12646864 */
function shuffleArray(array) {
for (var i = array.length - 1; i > 0; i--) {
var j = Math.floor() * (i + 1);
var temp = array[i];
array[i] = array[j];
array[j] = temp;
}
return array;
}
Do you mean something like this? http://jsfiddle.net/1r5qer56/
I used 4 sectors (as skewY tends to screw up over 90 degrees) and had them set to a size relative to the amount of minutes that have passed since midnight.
If you want to test it, just put a custom number in for time.
My code is below:
HTML
<ul class='pie'>
<li class='slice tr'><div class='slice-contents'></div></li>
<li class='slice br'><div class='slice-contents'></div></li>
<li class='slice bl'><div class='slice-contents'></div></li>
<li class='slice tl'><div class='slice-contents'></div></li>
<ul>
CSS
.pie {
position: relative;
margin: 1em auto;
border: dashed 1px;
padding: 0;
width: 32em; height: 32em;
border-radius: 50%;
list-style: none;
background-image: url('http://lorempixel.com/output/animals-q-c-512-512-4.jpg');
}
.slice {
overflow: hidden;
position: absolute;
top: 0; right: 0;
width: 50%; height: 50%;
transform-origin: 0% 100%;
}
.slice.tr {
transform: rotate(0deg) skewY(-0deg);
}
.slice.br {
transform: rotate(90deg) skewY(0deg);
}
.slice.bl {
transform: rotate(180deg) skewY(0deg);
}
.slice.tl {
transform: rotate(270deg) skewY(0deg);
}
.slice-contents {
position: absolute;
left: -100%;
width: 200%; height: 200%;
border-radius: 50%;
background: lightblue;
}
.slice.tr .slice-contents {
transform: skewY(0deg); /* unskew slice contents */
}
.slice.br .slice-contents {
transform: skewY(0deg); /* unskew slice contents */
}
.slice.bl .slice-contents {
transform: skewY(0deg); /* unskew slice contents */
}
.slice.tl .slice-contents {
transform: skewY(0deg); /* unskew slice contents */
}
JS+jQuery
updateClock();
setInterval(function(){updateClock();}, 60000);//check for updates once per minute
function updateClock(){
var dt = new Date();
var time = (dt.getHours() * 60) + dt.getMinutes();//number of minutes since 00.00
var timeToDegrees = time / 4;//1440 minutes in 24hours, 360 degrees in a circle. 1440 / 4 = 360
if(timeToDegrees < 90){//deal with top right sector
$('.slice.tr').css('transform', 'rotate('+timeToDegrees+'deg) skewY(-'+timeToDegrees+'deg)');
$('.slice.tr .slice-contents').css('transform', 'skewY('+timeToDegrees+'deg)');
}
else if(timeToDegrees < 180){//deal with bottom right sector
var localDeg = timeToDegrees - 90;
$('.slice.tr').eq(0).css('transform', 'rotate(90deg) skewY(-90deg)');
$('.slice.tr .slice-contents').css('transform', 'skewY(90deg)');
$('.slice.br').css('transform', 'rotate('+(90+localDeg)+'deg) skewY(-'+localDeg+'deg)');
$('.slice.br .slice-contents').css('transform', 'skewY('+localDeg+'deg)');
}
else if(timeToDegrees < 270){//deal with bottom left sector
var localDeg = timeToDegrees - 180;
$('.slice.tr').css('transform', 'rotate(90deg) skewY(-90deg)');
$('.slice.tr .slice-contents').css('transform', 'skewY(90deg)');
$('.slice.br').css('transform', 'rotate(180deg) skewY(-90deg)');
$('.slice.br .slice-contents').css('transform', 'skewY(90deg)');
$('.slice.bl').css('transform', 'rotate('+(180+localDeg)+'deg) skewY(-'+localDeg+'deg)');
$('.slice.bl .slice-contents').css('transform', 'skewY('+localDeg+'deg)');
}
else if(timeToDegrees <= 360){//deal with top left sector
var localDeg = timeToDegrees - 270;
$('.slice.tr').css('transform', 'rotate(90deg) skewY(-90deg)');
$('.slice.tr .slice-contents').css('transform', 'skewY(90deg)');
$('.slice.br').css('transform', 'rotate(90deg) skewY(-90deg)');
$('.slice.br .slice-contents').css('transform', 'skewY(90deg)');
$('.slice.bl').css('transform', 'rotate(270deg) skewY(-90deg)');
$('.slice.bl .slice-contents').css('transform', 'skewY(90deg)');
$('.slice.tl').css('transform', 'rotate('+(270+localDeg)+'deg) skewY(-'+localDeg+'deg)');
$('.slice.tl .slice-contents').css('transform', 'skewY('+localDeg+'deg)');
}
}
Taking a look at the code, from what I gather, you're looking for a picture that is covered with another picture, proportional to the length of the day in seconds. Like one picture sliding over another? Like this picture:
Take a look at the jsBin I've created here http://jsbin.com/xevinakihe/edit?html,css,js,output
The meat of the code is the timing and height adjustment:
function setCoverHeight() {
var d = new Date();
var curSecs = d.getHours() * 3600 + d.getMinutes() * 60 + d.getSeconds();
var coverHeight = curSecs * 100 / (24 * 3600);
$('.cover').height(coverHeight + '%');
if (curSecs < 24 * 3600) {
setTimeout(setCoverHeight, 1000);
console.log(coverHeight);
} else {
// reset the cover height to 0%
$('.cover').height(0);
// swap the cover image to the bottom
$('.bottom').css('backround-image', $('.cover').css('background-image'));
// set a new cover image
// ... get from Ajax, array, etc
}
}
setCoverHeight();
That is adjusting the HTML:
<div class="wrapper">
<div class="cover"></div>
<div class="bottom"></div>
</div>
Eventually the day will run out and the cover should be swapped with the bottom image, so that you can cycle through individual daily pictures (ex. 'today.jpg' and 'tomorrow.jpg')
Hope that helps!
I like to know the cleanest method to distribute elements vertically with jQuery. I nailed it but it's not very clean right >< ? I would like to get to do it without plugin... Thank you in advance ;-)
Here my JSFiddle
jQuery(document).ready(function($) {
var gap = 10;
var firstElem = $('#lorem');
if(firstElem.length){
var heightCall = (firstElem.offset().top)+(firstElem.outerHeight())+(gap);
var middleElem = $('#dolore');
middleElem.offset({top : heightCall});
var lastElem = $('#amet');
var NewHeightCall = (middleElem.offset().top)+(middleElem.outerHeight())+(gap);
lastElem.offset({top : NewHeightCall});
/* Animation */
$('#lorem, #dolore, #amet').hover(
function(){
$(this).stop().animate({left: (($(this).offset().left)-(20))+'px',opacity:'0.5'},'slow')
},
function(){
$(this).stop().animate({left: (($(this).offset().left)+(20))+'px',opacity:'1'},'slow')
});
}
});
I have fiddled around with your code:
This is a simplified version:
HTML:
<div id="lorem" class="vertical-block">My first ID div</div>
<div id="dolore" class="vertical-block">My second ID div.<br>My second ID div. My second ID div.</div>
<div id="amet" class="vertical-block">My third ID div</div>
CSS:
.vertical-block {
position: absolute;
padding:15px;
}
#lorem{
top:20%;
right:40px;
background:#f79673;
}
#dolore{
right:80px;
background:#cd7454;
}
#amet{
right:40px;
background:#a15338;
}
.vertical-block:hover {
opacity: 0.5;
padding-right: 30px;
-webkit-transition: all 2s;
transition: all 0.4s;
}
Javascript:
jQuery(document).ready(function($) {
var gap = 10;
var firstElem = $('#lorem');
var top = 0;
$('.vertical-block').each(function(element){
var $currentElement = $(this);
if (top === 0) {
top = $currentElement.offset().top + $currentElement.outerHeight() + gap;
} else {
$currentElement.offset({top: top});
top = top + $currentElement.outerHeight() + gap;
}
});
});
https://jsfiddle.net/rae2x4e0/1/
Now if you want to go for a purely css solution, then:
HTML:
<div class="container">
<div id="lorem" class="vertical-block">My first ID div</div>
<br />
<div id="dolore" class="vertical-block">My second ID div.<br>My second ID div. My second ID div.</div>
<br />
<div id="amet" class="vertical-block">My third ID div</div>
</div>
CSS:
.container {
position-relative;
text-align: right;
padding-top: 10%;
}
.vertical-block {
padding:15px;
display: inline-block;
margin-top: 20px;
}
#lorem{
right:40px;
background:#f79673;
}
#dolore{
right:80px;
background:#cd7454;
}
#amet{
right:40px;
background:#a15338;
}
.vertical-block:hover {
opacity: 0.5;
padding-right: 30px;
-webkit-transition: all 2s;
transition: all 0.4s;
}
https://jsfiddle.net/ycdwpjxw/1/