I am trying to save divs like the following one either as PDF or image file. The problem so far with solutions I found online are the clip-path attributes...
<link href="https://cdn.jsdelivr.net/npm/bootstrap#5.1.3/dist/css/bootstrap.min.css" rel="stylesheet" />
<div class="m-2">
<div class="border border-5 d-flex" style="width: 1000px; height: 500px;">
<div class="position-relative w-100 h-100">
<div class="position-absolute start-0 bottom-0" style="width: 0;height: 0;border-style: solid;border-width: 400px 0 0 250px; border-color: transparent transparent transparent #ffa447;"></div>
<div class="position-absolute start-0 top-0 h-100" style="background-color:blueviolet; width: 350px; clip-path: polygon(0 0, 100% 0, 40% 100%, 0% 100%); background-image: url('https://images.pexels.com/photos/842571/pexels-photo-842571.jpeg?auto=compress&cs=tinysrgb&h=750&w=1260'); background-repeat: no-repeat; background-size: cover;"></div>
<div class="m-4 position-absolute start-0" style="height: 200px; width: 200px; background-color: black; color: white; background-image: url('https://upload.wikimedia.org/wikipedia/commons/thumb/6/61/QR_deWP.svg/1200px-QR_deWP.svg.png'); background-repeat: no-repeat; background-size: cover;">
QR
</div>
<div class="position-absolute top-50 start-50 translate-middle">
<div class="d-flex justify-content-center text-center">
<h1 class="mb-0 text-uppercase" style="font-size: 40pt;">Lorem ipsum</h1>
</div>
<div class="d-flex justify-content-center text-center">
<div class="" style="width: 300px;">
<h1>Lorem ipsum</h1>
</div>
</div>
<div class="d-flex justify-content-center text-center">
<div class="row" style="width: 350px;">
<div class="col-2">
<h4>Lorem</h4>
</div>
<div class="col-10">
<h4>ipsum</h4>
</div>
<div class="col-2">
<h4>Lorem</h4>
</div>
<div class="col-10">
<h4>ipsum</h4>
</div>
</div>
</div>
<div class="d-flex justify-content-center text-center">
<p class="text-justify" style="width: 400px;">Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum.</p>
</div>
<div class="d-flex justify-content-center text-center mt-3">
<p class="mb-0 text-justify small" style="width: 450px; padding-right: 110px;color: grey;">Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum.</p>
</div>
</div>
<div class="position-absolute end-0 bottom-0 h-100" style="background-color:blueviolet; width: 350px; clip-path: polygon(60% 0, 100% 0, 100% 100%, 0% 100%); background-image: url('https://images.pexels.com/photos/3338497/pexels-photo-3338497.jpeg?auto=compress&cs=tinysrgb&h=750&w=1260'); background-repeat: no-repeat; background-size: cover;">
<div class="mb-4 p-2 position-absolute bottom-0 start-50 translate-middle-x small" style="width: auto; max-width: 200px; background-color: rgba(255, 255, 255, 0.6);">
<p class="mb-0">Lorem ipsum</p>
<p class="mb-0">dolor sit</p>
<div class="d-flex">
<p class="mb-0 me-1">amet, </p><p class="mb-0">consetetur</p>
</div>
<p class="mb-0">sadipscing</p>
<p class="mb-0">elitr</p>
</div>
</div>
<div class="position-absolute end-0 top-0" style="width: 0;height: 0;border-style: solid;border-width: 0 250px 400px 0;border-color: transparent #ffa447 transparent transparent;"></div>
<div class="m-3 position-absolute end-0 top-0" style="height: 125px; width: 125px; background-color: black; color: white; background-image: url('https://png.pngtree.com/png-clipart/20190515/original/pngtree-coffee-time-png-image_3626459.jpg'); background-repeat: no-repeat; background-size: cover;">
logo
</div>
</div>
</div>
</div>
I tried different approaches with PHP or JS like html2canvas or jsPDF so far, but nothing saved the div the way it is displayed inside the browser.
The simplest method for HTML to PDF is to use the browser output e.g. Chrome
And this can be run as a headless print, here I use Windows Edge but you can of course use Edge or Chrome on other platforms. On Windows you may need to run that as Admin, it should be less than one blink, so fast I did not think it was done.
NOTE recently the switch --disable-gpu was removed from the options so may not be needed.
"C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe" --headless --disable-gpu --run-all-compositor-stages-before-draw --print-to-pdf="C:\Users\WDAGUtilityAccount\Desktop\SandBox\division.pdf" --print-to-pdf-no-header "C:\Users\WDAGUtilityAccount\Desktop\SandBox\division.html"
However note that due to cross site security some images are missing so we need to ensure they are local and simply remove the remote part of url
Add this at the end just for a tidy approach </body></html> and use this as your heading
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<!-- saved from url=https://stackoverflow.com/questions/71998862 -->
<html><head>
<link href="https://cdn.jsdelivr.net/npm/bootstrap#5.1.3/dist/css/bootstrap.min.css" rel="stylesheet" />
<meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
<title>Lorum Ipsum</title>
<meta name="GENERATOR" content="KJs Template Builder V 2022-04">
<meta http-equiv="Content-Style-Type" content="text/css"><style>
#media print {
#page {
/* For different margins – use the standard CSS margin property: north, east, south, west, here it is one value */
margin: 0;
/* Browser default, customisable by the user if using the print dialogue. */
size: auto;
/* Different width and height. here using stated width="1000" height="500" can be px or pt or cm. For square, just use one value or use name like A6 landscape; note this is over-riding any above size: but we need to bump up for browser rounding*/
size: 1020px 520px;
}
body { margin: 0; }
}
</style></head><body bgcolor="white" text="black" link="blue" vlink="purple" alink="red">
I have this:
<section>
<div id="dont-scroll">
Unknown content!
</div>
<div>
<div id="scroll-this">
This part should be scrollable when
the total content overflows the SECTION
</div>
</div>
</section>
As you can see I want the user to be able to scroll the content in the lower half, but not the upper.
I can achieve this by using "resize" events, checking the size of SECTION and "dont-scroll", etc.
However, is there an easier way today, using only CSS?
A possible approach using Flexbox
body, html {
margin: 0;
padding: 0;
}
section {
height: 100vh;
display: flex;
flex-flow: column nowrap;
}
section > div {
padding: 20px;
}
div:not([id]) {
background: #d8d8dc;
flex: 1;
overflow: auto;
}
<section>
<div id="dont-scroll">
Unknown content! <br />
Lorem ipsum sit dolor amet
</div>
<div>
<div id="scroll-this">
This part should be scrollable when
the total content overflows the SECTION
<br /><br />
<p>Lorem ipsum dolor sit amet,
consectetuer adipiscing elit. Donec
odio. Quisque volutpat mattis eros.
Nullam malesuada erat ut turpis.
Suspendisse urna nibh, viverra non,
semper suscipit, posuere a, pede.</p>
...
</div>
</div>
</section>
Example on codepen
Defining height of scroll-this id and using overflow-y: scroll will make scroll-this id scroll able
#scroll-this {
height: 10px; //this can be as per your choice
overflow-y: scroll;
}
I used 10px because your content is too less.
"This part should be scrollable when the total content overflows the
SECTION".
Scroll will show only if line breaking content is greater then provided height.
#scroll-this {
height: 20px;
overflow-y: scroll;
}
<section style="width:200px">
<div id="dont-scroll">
Unknown content!
</div>
<div>
<div id="scroll-this">
This part should be scrollable when the total content overflows the SECTION
</div>
</div>
</section>
I have a basic slider with Previous and Next buttons and Im trying to figure out how to scroll through the slides and add/remove a class to the relevant slides while cycling. Please can I get some help.
Heres what I have so far,I'd like the previous and next links to cycle through the slides adding and removing classes as it goes. Hope that makes sense.
Thanks.
Codepen : https://codepen.io/ukscotth/pen/LYERPvJ
HTML
<div class="slider-container">
<div class="slide show" data-index="1">
<div class="image-container">
<div class="image" style="background-image:url('https://images.pexels.com/photos/3233372/pexels-photo-3233372.jpeg');">
</div>
</div>
<div class="info-container">
<h1>Slide 1 Title</h1>
<h4>Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.</h4>
</div>
</div>
<div class="slide" data-index="2">
<div class="image-container">
<div class="image" style="background-image:url('https://images.pexels.com/photos/3268443/pexels-photo-3268443.jpeg');">
</div>
</div>
<div class="info-container">
<h1>Slide 2 Title</h1>
<h4>Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.</h4>
</div>
</div>
<div class="prev-button">PREV</div>
<div class="next-button">NEXT</div>
</div>
CSS
.slider-container {
width:100%;
padding:50px;
}
.slide {
position:absolute;
opacity:0;
}
.slide.show {
opacity:1;
}
.image-container{
display: inline-block;
margin-right:30px;
}
.image {
width:300px;
height:300px;
background-size:cover;
}
.info-container{
display: inline-block;
width:300px;
vertical-align: top;
}
.prev-button{
position:absolute;
top:400px;
left:150px;
}
.next-button{
position:absolute;
top:400px;
left:250px;
}
JS
(function($) {
"use strict";
var count;
$count = 1;
$('.next-button').click(function(e) {
$('.slide[data-index=2]').addClass('show');
});
})(jQuery);
Replace the next and prev function as below and it works. You just have to use a simple logic........
$('.next-button').click(function(e) {
if(active==4){
prev = 4; active = 1; next = 2;
$('.slide[data-index='+active+']').addClass('show');
$('.slide[data-index='+prev+']').removeClass('show');
} else {
$('.slide[data-index='+active+']').removeClass('show');
$('.slide[data-index='+next+']').addClass('show');
if (prev == 4) {
prev = 0;
}
prev++;
active++;
next++;
}
console.log('prev'+prev);
console.log('active'+active);
console.log('next'+next);
});
$('.prev-button').click(function(e) {
if(active==1){
prev = 3; active = 4; next = 1;
$('.slide[data-index='+active+']').addClass('show');
$('.slide[data-index='+next+']').removeClass('show');
} else {
$('.slide[data-index='+active+']').removeClass('show');
$('.slide[data-index='+prev+']').addClass('show');
prev--;
active--;
if (next == 1) {
next = 5;
}
next--;
}
console.log('prev'+prev);
console.log('active'+active);
console.log('next'+next);
});
I have done my own slider before. I can give you an idea.
when "next" is pressed, remove the "show" class from the current slide, increment the index and add the "show" class to the next. When the current index is the maximum, make the next index to "1".
If you want to automate the slider, have a time interval
setInterval( "slideSwitch()", 5000 ); //this will run slideSwitch every 5 seconds.
Inside this function, add the "show" class to next slide and remove the "show" class to previous(current) slide.
Hope this idea helps.....
Try to put the "if" statement first.....
$('.prev-button').click(function(e) {
if(active==1){
prev = 4; active = 1; next = 2;
// comment this out...$('.slide[data-index='+active+']').addClass('show');
}
$('.slide[data-index='+active+']').removeClass('show');
$('.slide[data-index='+prev+']').addClass('show');
prev--;
active--;
next--;
console.log('prev'+prev);
console.log('active'+active);
console.log('next'+next);
});
I have an element with a certain size, that contains texts of single or multiple lines in different lengths. Now I want to scale the font-size of these texts in such a way, that the longest line of the text fits perfectly into the containers width.
As an example, I want this markup
.container {
width: 400px;
border: 1px solid green;
padding: .5em;
}
.container>div {
border: 1px dotted gray;
}
<div class="container">
<div>Lorem ipsum dolor sit amet.</div>
<div>Lorem ipsum.</div>
<div>Lorem ipsum dolor sit amet, consetetur sadipscing elitr,<br />sed diam nonumy eirmod tempor invidunt<br />ut labore et dolore magna aliquyam erat, sed diam voluptua.</div>
</div>
produce something like this:
I tried using relative font sizing unit, but always ended up adjusting the font-size of every child element manually, which isn't an option.
Also this post about dynamically scaling text to fit the viewport doesn't help, since I have multiple different text lengths.
Can this be solved with CSS? Or do I have to take a Javascript approach where I count the letters and adjust the font-size accordingly? But what if I use a font where letters have different sizes?
How about this?
$(document).ready(function() {
var divEls = $('.container div');
for(var i=0; i<divEls.length;i++){
var span = $(divEls[i]).find('span');
var fontSize = 16;
while (span.width() < $(divEls[i]).width()) {
span.css('font-size', fontSize++)
}
// wrap if span exceeds div width
if (span.width() > $(divEls[i]).width()) {
span.css('white-space', 'pre-wrap');
}
}
});
.container {
width: 400px;
border: 1px solid green;
padding: .5em;
}
.container>div {
border: 1px dotted gray;
white-space: pre;
}
<div class="container">
<div><span>Lorem ipsum dolor sit amet.</span></div>
<div><span>Lorem ipsum.</span></div>
<div><span>Lorem ipsum dolor sit amet, consetetur sadipscing elitr,<br />sed diam nonumy eirmod tempor invidunt<br />ut labore et dolore magna aliquyam erat, sed diam voluptua .</span></div>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
You can also try an ES6 solution like this CodePen Demo
Update - per the comment below, here is a reponsive solution (also see this CodePen Demo):
function resizeFont() {
var divEls = $(".container div");
for (var i = 0; i < divEls.length; i++) {
var span = $(divEls[i]).find("span");
var fontSize = (span.css("font-size").match(/\d+/)[0]);
while (span.width() < $(divEls[i]).width()) {
span.css("font-size", fontSize++);
}
while (span.width() > $(divEls[i]).width()) {
span.css("font-size", fontSize--);
}
}
}
$(document).ready(function() {
resizeFont();
$(window).on("resize", resizeFont);
});
body {
margin: 0;
}
.container {
max-width: 100vw;
border: 1px solid green;
padding: .5em;
}
.container>div {
border: 1px dotted gray;
white-space: pre;
}
<div class="container">
<div><span>Lorem ipsum dolor sit amet.</span></div>
<div><span>Lorem ipsum.</span></div>
<div><span>Lorem ipsum dolor sit amet, consetetur sadipscing elitr,<br />sed diam nonumy eirmod tempor invidunt<br />ut labore et dolore magna aliquyam erat, sed diam voluptua .</span></div>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
I have several divs arranged vertically one on top of the other which from here on out I will call panels. Each panel has the width and height of the viewport. All panels have the same background color at all times. Initially, that color is black.
Every other panel is empty, and acts as a gap between panels that actually have content. The order is like this:
Content
No content
Content
No content
Content
What I want to do is make it so that when a user has scrolled down enough for a panel with content to be out of view, the color should change from black to white. Then, once they have scrolled far enough for the second panel with content to be out of view, it should change back.
This is the part I cannot figure out. I have a working demo with my code so far:
$(document).scroll(function() {
var viewportHeight = $("html").outerHeight();
var currentY = $(document).scrollTop();
if (currentY % viewportHeight != 0) {
lighten();
} else {
darken();
}
});
function darken() {
$("body").css("background-color", "black");
$(".panel.content").css("color", "white");
}
function lighten() {
$("body").css("background-color", "white");
$(".panel.content").css("color", "black");
}
html,
body,
.panel {
width: 100%;
height: 100%;
}
body {
background-color: black;
overflow-y: visible;
overflow-x: hidden;
transition: background-color 500ms linear;
}
.panel {
border: 2px solid red;
}
.content {
color: white;
text-align: center;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<body>
<div class="panel content">
<h2> CONTENT </h2>
</div>
<div class="panel blank">
</div>
<div class="panel content">
<h2> CONTENT </h2>
</div>
<div class="panel blank">
</div>
<div class="panel content">
<h2> CONTENT </h2>
</div>
</body>
As you can see, my code is a ways off from achieving the desired result. Not only is the order wrong, the main problem is that it only triggers when the user is at the exact Y for the change to happen.
The order should be:
Black
White
White
Black
Black
White
White
Black
Black
etc.
How do I do this?
$(document).scroll(function() {
var viewportHeight = $("html").outerHeight();
var currentY = $(document).scrollTop();
var panelNumber = Math.floor(currentY / viewportHeight);
if (panelNumber % 4 === 1 || panelNumber % 4 === 2) {
lighten();
} else {
darken();
}
});
function darken() {
$("body").css("background-color", "black");
$(".panel.content").css("color", "white");
}
function lighten() {
$("body").css("background-color", "white");
$(".panel.content").css("color", "black");
}
html,
body,
.panel {
width: 100%;
height: 100%;
}
body {
background-color: black;
overflow-y: visible;
overflow-x: hidden;
transition: background-color 500ms linear;
}
.panel {
border: 2px solid red;
}
.content {
color: white;
text-align: center;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<body>
<div class="panel content">
<h2> CONTENT </h2>
</div>
<div class="panel blank">
</div>
<div class="panel content">
<h2> CONTENT </h2>
</div>
<div class="panel blank">
</div>
<div class="panel content">
<h2> CONTENT </h2>
</div>
<div class="panel blank">
</div>
<div class="panel content">
<h2> CONTENT </h2>
</div>
<div class="panel blank">
</div>
</body>
Not only is the order wrong, the main problem is that it only triggers
when the user is at the exact Y for the change to happen.
yes..that is right. currentY % viewportHeight != 0 will not work. Scrolling is not smooth. Pulling scrollbar down may result in change of 10000 px/sec, but browser renders 60fps which means your currentY (scroll-y) will increase by 150px every frame (your are expecting a change of 1px). So if your code contains if(currentY === 100){} definitely not going to work. currentY may have values like 0,50,80,99,120,....
It should be clear currentY % viewportHeight != x is not so much different.
So if(0<currentY<500) will be be better option.
Now suppose viewportHeight = 500. We can get panelNumber = Math.floor(currentY/viewportHeight) (=>0,1,2,3,4,5...)
(Not clear from your question) Suppose you want to have
panel: 0 =>black, 1=>white, 2=>white, 3=>black, 4=>black ...
you can get black by panelNumber%4==0 || panelNumber%4==3.
[please change accordingly if you want something different]
I know it's a bit late, but I made a solution for this and didn't had time to post it.
So: "How is my solution any different?"
I get gap-from-top values to all your .blank divs and then check where view-port is located. This allows you to use borders, add any other divs in between, change size of your divs and this will not lose functionality.
var elem = document.getElementsByClassName("blank");
var i;
var marks = [];
for (i = 0; i < elem.length; i++) {
var rect = elem[i].getBoundingClientRect();
marks.push(rect.top);
}
$(document).scroll(function() {
if (findi() % 2 == 1) {
lighten();
} else {
darken();
}
});
function findi() {
pos = 0;
for (i = 0; i < marks.length; i++) {
if (marks[i] < $(document).scrollTop()) {
pos++;
}
}
return (pos);
}
function darken() {
$("body").css("background-color", "black");
$(".panel.content").css("color", "white");
}
function lighten() {
$("body").css("background-color", "white");
$(".panel.content").css("color", "black");
}
body {
background-color: black;
overflow-y: visible;
overflow-x: hidden;
transition: background-color 500ms linear;
}
html,
body {
padding: 0;
margin: 0;
}
html,
body,
.panel {
width: 100%;
height: 100%;
}
.panel {
border-bottom: 32px solid red;
}
.content {
color: white;
text-align: center;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="panel content">
<h2> CONTENT </h2>
</div>
<div class="panel blank">
</div>
<div class="panel content">
<h2> CONTENT </h2>
</div>
<div class="panel blank">
</div>
<div class="panel content">
<h2> CONTENT </h2>
</div>
<div class="panel blank">
</div>
<div class="panel content">
<h2> CONTENT </h2>
</div>
<div class="panel blank">
</div>
<div class="panel content">
<h2> CONTENT </h2>
</div>
<div class="panel blank">
</div>
<div class="panel content">
<h2> CONTENT </h2>
</div>
<div class="panel blank">
</div>
<div class="panel content">
<h2> CONTENT </h2>
</div>
<div class="panel blank">
</div>
<div class="panel content">
<h2> CONTENT </h2>
</div>
<div class="panel blank">
</div>
<div class="panel content">
<h2> CONTENT </h2>
</div>
Here is my solution. I'm pretty sure this is the order you need.
(function() {
var lastfunc = darken;
$(document).scroll(function() {
var y = $(document).scrollTop();
var x = $("html").outerHeight();
var func = (Math.floor(((y + x) / (2 * x))) % 2) ? lighten : darken;
if (func !== lastfunc) {
lastfunc = func;
func();
}
});
})();
This does the following:
Create a variable lastfunc to keep track of the last thing we called.
Get the user's Y and the height of the viewport.
Use evil factorized math to get a bool which decides which of the two functions, lighten() or darken() to assign to func.
Check to see if lastfunc is equal to func, to see if a change is necessary.
If they are not equal, call func() and set lastfunc equal to func
This has the following benefits:
All wrapped up to prevent making lastfunc a global.
Math is solid.
This calls the style modifying functions only if a change is required.
I've also optimized your darken() and lighten() functions:
function darken() {
document.body.style.backgroundColor = "black";
$(".panel.content").css("color", "white");
}
function lighten() {
document.body.style.backgroundColor = "white";
$(".panel.content").css("color", "white");
}
This slight optimization saves jQuery the trouble of finding your body, which should save off a couple of milliseconds. Not a huge difference, but this is optimal.
Additional note: if you are able to get rid of the second style change in lighten and darken, we can get rid of the overhead of having the function calls at all, and do it all within scroll():
(function() {
var lastColor;
$(document).scroll(function() {
var y = $(document).scrollTop();
var color = (Math.floor(((y + x) / (2 * x))) % 2) ? "red" : "blue";
if (color !== lastColor) {
lastColor = color;
document.body.style.color = color;
}
});
})();
Demo of the first solution:
(function() {
var lastfunc = darken;
$(document).scroll(function() {
var y = $(document).scrollTop();
var x = $("html").outerHeight();
var func = (Math.floor(((y + x) / (2 * x))) % 2) ? lighten : darken;
if (func !== lastfunc) {
lastfunc = func;
func();
}
});
})();
function darken() {
document.body.style.backgroundColor = "black";
$(".panel.content").css("color", "white");
}
function lighten() {
document.body.style.backgroundColor = "white";
$(".panel.content").css("color", "white");
}
html,
body,
.panel {
width: 100%;
height: 100%;
}
body {
background-color: black;
overflow-y: visible;
overflow-x: hidden;
transition: background-color 500ms linear;
}
.panel {
border: 2px solid red;
}
.content {
color: white;
text-align: center;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<body>
<div class="panel content">
<h2> CONTENT </h2>
</div>
<div class="panel blank">
</div>
<div class="panel content">
<h2> CONTENT </h2>
</div>
<div class="panel blank">
</div>
<div class="panel content">
<h2> CONTENT </h2>
</div>
</body>
You can use .hover() on $(document).ready(); I have added an example of it if it works for you.
$(document).ready(function() {
$(".panel.content").hover(function(){
$("body").css("background-color", "white");
$(this).css("color", "black");
},function(){
$("body").css("background-color", "black");
$(this).css("color", "white");
});
});
$(document).scroll(function() {
$(".panel.content").hover(function(){
$("body").css("background-color", "white");
$(this).css("color", "black");
},function(){
$("body").css("background-color", "black");
$(this).css("color", "white");
});
});
html,
body,
.panel {
width: 100%;
height: 100%;
}
body {
background-color: black;
overflow-y: visible;
overflow-x: hidden;
transition: background-color 500ms linear;
}
.panel {
border: 2px solid red;
}
.content {
color: white;
text-align: center;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<body>
<div class="panel content">
<h2> CONTENT </h2>
</div>
<div class="panel blank">
</div>
<div class="panel content">
<h2> CONTENT </h2>
</div>
<div class="panel blank">
</div>
<div class="panel content">
<h2> CONTENT </h2>
</div>
</body>
I've made it so you can choose which panel sets the background color to white/black. You can do that by adding the class 'black' or 'white' to it, though the way you requested it makes perfect sense afterall.
Also my solution uses a class to change the background color of the body. This should make it more easy to make style changes.
$(document).ready(init)
function init(){
$(document).scroll(updateBackground)
updateBackground()
}
function updateBackground(){
var w = $(window).width()
var h = $(window).height()
var panels = $('.panel') // get all panels on page
for(var i=0;i<panels.length;i++){ // loop though each panel
var panel = panels.eq(i) // get the current panel
var panel_y = panel.offset().top - $(document).scrollTop() // get the panels y coordinate relative to the window
var panel_height = panel.height() // get the panels height
if(panel_y<=0 && panel_y+panel_height>0){ // check if the panel is in the visible area
if(panel.hasClass('black')){ // check if the panel is set to make the background black
$('body').removeClass('white')
$('body').addClass('black')
}else if(panel.hasClass('white')){
$('body').removeClass('black')
$('body').addClass('white')
}
return // return, because we already found the visible panel
}
}
}
html{
height: 100%
}
body{
margin: 0;
padding: 0;
transition: background-color 500ms linear;
height: 100%
}
body.white{
background-color: white;
color: black;
}
body.black{
background-color: black;
color: white;
}
.panel{
width: 100%;
height: 100%;
box-sizing: border-box;
padding: 50px;
border: solid 1px #888888;
text-align: center;
overflow: hidden;
}
.panel > h1{
font-size: 38pt;
}
.panel > p{
font-size: 18pt;
line-height: 200%;
}
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
</head
<body>
<div class="panel with-content black">
<h1>Content</h1>
<p>
Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.
</p>
</div>
<div class="panel gap white"></div>
<div class="panel with-content white">
<h1>Content</h1>
<p>
Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.
</p>
</div>
<div class="panel gap black"></div>
<div class="panel with-content black">
<h1>Content</h1>
<p>
Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.
</p>
</div>
<div class="panel gap white"></div>
<div class="panel with-content white">
<h1>Content</h1>
<p>
Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.
</p>
</div>
<div class="panel gap black"></div>
<div class="panel with-content black">
<h1>Content</h1>
<p>
Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.
</p>
</div>
</body>
</html>
Add a condition in your code
Math.floor(currentY / viewportHeight) % 4 == 1 || Math.floor(currentY / viewportHeight) % 4 == 2
and your code is working now.
Testing
If you run this code in java it will display same output as you expected.
public static void main(String...arr){
for(int i = 0; i<100; i++){
if(i%4 ==1 || i%4 == 2){
System.out.println("true");
} else {
System.out.println("false");
}
}
}
$(document).scroll(function() {
var viewportHeight = $("html").outerHeight();
var currentY = $(document).scrollTop();
if (Math.floor(currentY / viewportHeight) % 4 == 1 || Math.floor(currentY / viewportHeight) % 4 == 2) {
lighten();
} else {
darken();
}
});
function darken() {
$("body").css("background-color", "black");
$(".panel.content").css("color", "white");
}
function lighten() {
$("body").css("background-color", "white");
$(".panel.content").css("color", "black");
}
html,
body,
.panel {
width: 100%;
height: 100%;
}
body {
background-color: black;
overflow-y: visible;
overflow-x: hidden;
transition: background-color 500ms linear;
}
.panel {
border: 2px solid red;
}
.content {
color: white;
text-align: center;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<body>
<div class="panel content">
<h2> CONTENT </h2>
</div>
<div class="panel blank">
</div>
<div class="panel content">
<h2> CONTENT </h2>
</div>
<div class="panel blank">
</div>
<div class="panel content">
<h2> CONTENT </h2>
</div>
</body>
What I want to do is make it so that when a user has scrolled down enough for a panel with content to be out of view, the color should change from black to white. Then, once they have scrolled far enough for the second panel with content to be out of view, it should change back.
This statement conflicts with the order you mentioned. From the statement, it is implied that the color changes should be alternate, but the order mentioned in your question is not alternate.
Please see the below code which changes colors on alternate divs through out the scrolling.
$(document).scroll(function() {
var viewportHeight = $("html").outerHeight();
var currentY = $(document).scrollTop();
if (Math.floor(currentY / viewportHeight) % 2) {
lighten();
} else {
darken();
}
});
function darken() {
$("body").css("background-color", "black");
$(".panel.content").css("color", "white");
}
function lighten() {
$("body").css("background-color", "white");
$(".panel.content").css("color", "black");
}
html,
body,
.panel {
width: 100%;
height: 100%;
}
body {
background-color: black;
overflow-y: visible;
overflow-x: hidden;
transition: background-color 500ms linear;
}
.panel {
border: 2px solid red;
}
.content {
color: white;
text-align: center;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<body>
<div class="panel content">
<h2> CONTENT </h2>
</div>
<div class="panel blank">
</div>
<div class="panel content">
<h2> CONTENT </h2>
</div>
<div class="panel blank">
</div>
<div class="panel content">
<h2> CONTENT </h2>
</div>
</body>