I have parallax background that's moving at a certain speed with javascript. I need to put the text inside those background divs, so each background has its own text block. But when I put the text inside it goes to the top of the page, despite the container it's located. Something in the positions needs to change but I'm not sure what exactly. Any ideas?
HTML
<div id='hero'>
<div class='layer-bg layer' data-depth='0.10' data-type='parallax'>
<img class="logo" />
</div>
<div class='layer-1 layer' data-depth='0.20' data-type='parallax'>
</div>
<div class="relative">
<div class='layer-2 layer' data-depth='0.30' data-type='parallax'>
<div class="video">
Text
</div>
</div>
</div>
<div class='layer-3 layer' data-depth='0.40' data-type='parallax'></div>
</div>
<div id='hero-mobile'></div>
CSS
body {
padding: 0;
margin: 0;
background-color: $bronze;
font-family: 'Playfair Display', serif;
color: $white;
}
//
#hero {
height: $heroHeight;
overflow: hidden;
position: relative;
}
#content {
background-color: $bronze;
}
.layer {
background-position: bottom center;
background-size: auto;
background-repeat: no-repeat;
width: 100%;
height: $heroHeight;
position: fixed;
z-index: -1;
}
.first-section {
padding: 50px 0 20px 0;
}
.text-header {
font-size: 50px;
text-align: center;
}
h1 {
line-height: 120%;
margin-bottom: 30px;
}
p {
color: #ede0d5;
font-size: 18px;
line-height: 150%;
}
// #hero, .layer {
// min-height: 800px;
// }
.layer-bg {
background-image: url('');
height: 4000px!important;
background-position: top center;
width: 100%;
}
.layer-1 {
background-image: url('
');
height: 3000px;
}
.layer-2 {
background-image: url('');
height: 5500px;
}
.layer-3 {
background-image: url('
');
height: 8000px;
}
.layer-4 {
background-image: url('
');
background-position: center bottom;
}
.layer-overlay {
background-image: url('
');
}
.relative {
position: relative;
}
.logo {
margin: 0px auto;
max-width: 600px;
margin-top: 100px;
display: block;
}
JS
(function() {
window.addEventListener('scroll', function(event) {
var depth, i, layer, layers, len, movement, topDistance, translate3d;
topDistance = this.pageYOffset;
layers = document.querySelectorAll("[data-type='parallax']");
for (i = 0, len = layers.length; i < len; i++) {if (window.CP.shouldStopExecution(1)){break;}
layer = layers[i];
depth = layer.getAttribute('data-depth');
movement = -(topDistance * depth);
translate3d = 'translate3d(0, ' + movement + 'px, 0)';
layer.style['-webkit-transform'] = translate3d;
layer.style['-moz-transform'] = translate3d;
layer.style['-ms-transform'] = translate3d;
layer.style['-o-transform'] = translate3d;
layer.style.transform = translate3d;
}
window.CP.exitedLoop(1);
});
}).call(this);
I don't why you are using 8000px height in your CSS but
check the link may be it will be helpful for you
https://www.w3schools.com/howto/tryhow_css_parallax_demo.htm
Its because you fixed the position of every .layer class div that's why they all are in same position of your DOM.
And overflow: hidden; of your main div #hero
Solution
You have to remove fixed position of your .layer class and overflow: hidden;.
Example:- see fiddle
Related
As I'm trying to make a "our story" section, when I scroll, the divs on it move up and the background picture changes when the specific div comes in the center. I want a fixed background image. When the div moves to the middle, the background picture may be changed with ease. Background image and div are related.
I'm still learning how to style, I can't create it correctly.
I've included a reference link so you can see what I'm aiming for.
Reference: https://webflow.com/made-in-webflow/website/Change-Background-Image-on-Scroll
.parent {
background-image: url(https://picsum.photos/1080/1920);
background-size: cover;
background-repeat: no-repeat;
background-position: center;
background-attachment: fixed;
height: 300vh;
text-align: center;
color: white;
}
.div1{
background-color: aqua;
height: 50vh;
margin-top: 90vh;
padding: 20px;
width: 400px;
margin: 90px auto
}
.div2{
background-color: skyblue;
height: 50vh;
padding: 20px;
width: 400px;
margin: 90px auto
}
.div3{
background-color: grey;
height: 50vh;
margin-top: 90vh;
padding: 20px;
width: 400px;
margin: 90px auto
}
<div class="parent">
<div class="div1" >
Content about desert
</div>
<div class="div2" >
Content about mountains
</div>
<div class="div3" >
Content about birds
</div>
</div>
The code below is a rough example of how you might do it. It should give you a starter to experiment with, and things to lookup on the WWW.
var sections;
const backgrounds = [
"url(https://i.picsum.photos/id/604/1080/1920.jpg?hmac=ZGdArZ8jNmfX3SDYlQMsYeGsKy6b_1uBH2WGFt3wYzk)",
"url(https://i.picsum.photos/id/301/1080/1920.jpg?hmac=7cyfS0iaSux6TVm9Wnkg4vtXIWyg_YyhhWYHM6yUTnE)",
"url(https://i.picsum.photos/id/155/1080/1920.jpg?hmac=UZT1atpRomcjj2ijIjwR9C3DY0xtD4On3m5XMNLak6o)"
];
var parent;
var bottomOffset;
function getViewScrollingElements() {
parent = document.getElementById("parent");
sections = document.getElementsByClassName("section");
bottomOffset = window.getComputedStyle(parent).getPropertyValue("height");
bottomOffset = parseInt(bottomOffset.substr(0, bottomOffset.length - 2)) / 3;
// Do first check before a scroll could have occured
checkInView();
}
function checkInView () {
var boundingRect;
for ( var i = 0; i < sections.length; i++ ) {
// Get the extremities of the div
boundingRect = sections[i].getBoundingClientRect();
// Are the div's extremities in view
if ( boundingRect.top < window.innerHeight && boundingRect.bottom >= bottomOffset ) {
parent.style.backgroundImage = backgrounds[i];
break; // Only want one at a time
}
}
}
.background {
background-size: cover;
background-repeat: no-repeat;
background-position: center;
background-attachment: fixed;
}
.parent {
text-align: center;
color: white;
height: 100%;
overflow-y: auto;
}
.section {
height: 70vh;
padding: 20px;
width: 400px;
margin: 90px auto;
opacity: 85%;
}
.section:nth-of-type(1) {
background-color: aqua;
}
.section:nth-of-type(2) {
background-color: skyblue;
}
.section:nth-of-type(3) {
background-color: grey;
}
<body onLoad="getViewScrollingElements()">
<div class="background"></div>
<div id="parent" class="parent" onScroll="checkInView()">
<div class="section">
Content about desert
</div>
<div class="section">
Content about mountains
</div>
<div class="section">
Content about birds
</div>
</div>
</body>
It does not like iframes as is so will not run properly in SOs fiddler, but does work in Chrome and Firefox.
I am making a hover effect on the image. I set the image to grayscale by default and when it hovered over, a circle follows the cursor and shows the colored part. Basically, there are two images. grayscale one is shown by default and on hover inside the circle, the colored part is shown.
Everything is working good except when I try to size the image using background-size the circle part doesn't follow. As the background property sets the circle part image according to its size. See the code:
I set the background-size of video card to 100% to fill up its parent container but when I do it for the circle, the image is sized inside the circle.
$('.video-card').mousemove(function(e) {
var offs = $(this).offset(),
p = {
x: offs.left,
y: offs.top
},
mPos = {
x: e.pageX,
y: e.pageY
},
x = mPos.x - p.x - 75,
y = mPos.y - p.y - 75;
$('.gray', this).css({
left: x,
top: y,
backgroundPosition: -x + 'px ' + -y + 'px'
});
});
.video-card {
position: relative;
width: 100%;
height: 950px;
overflow: hidden;
background-size: 100% !important;
}
.video-card-overlay {
content: "";
top: 0;
left: 0;
width: 100%;
height: 100%;
position: absolute;
background: gray;
filter: grayscale(100%);
background-size: 100% !important;
}
.gray {
position: absolute;
top: 0;
left: 0;
width: 150px;
height: 150px;
display: none;
border-radius: 50%;
}
.video-card:hover>.gray {
display: block;
}
.video-gallery-section .container {
max-width: 100%;
width: 100%;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="video-card" style="background: url('assets/img/home/1.png') no-repeat">
<div class="video-card-overlay" style="background: url('assets/img/home/1.png') no-repeat"></div>
<div class="gray" style="background: url('assets/img/home/1.png') no-repeat"></div>
</div>
How about using clip-path instead of trying to achieve the same effect through positioning?
const $overlay = $('.video-card-overlay');
$('.video-card').mousemove(function (e) {
$overlay.css({
clipPath: `circle(150px at ${e.offsetX}px ${e.offsetY}px)`
})
});
.video-card {
height: 950px;
position: relative;
width: 100%;
}
.gray,
.video-card-overlay {
background-image: url('assets/img/home/1.png');
background-position: center center;
background-size: cover;
inset: 0;
position: absolute;
}
.gray {
filter: grayscale(100%);
}
.video-card:not(:hover) .video-card-overlay {
display: none;
}
<div class="video-card">
<div class="gray"></div>
<div class="video-card-overlay"></div>
</div>
See how much shorter the code became!
I am working with this parallaxish 3d effect i found in a codepen. However I need to add an additional wrapper around all the html. When i wrap the html contents in a <div> everything disappears. When I wrap it in a <span> tag everything is fine. Also if i set that <span> tag to display:block; everything disappears again.
Why is this happening when wrapped in a block element?
Thanks!
https://codepen.io/anon/pen/JapeJX
When you add display: block make sure u set its height to 100% as its inner elements have height set in %.
Checkout https://stackoverflow.com/a/5658062/7333443
CodePen: https://codepen.io/anon/pen/QVQJPR
!(function ($doc, $win) {
var screenWidth = $win.screen.width / 2,
screenHeight = $win.screen.height / 2,
$elems = $doc.getElementsByClassName("elem"),
validPropertyPrefix = "",
otherProperty = "perspective(1000px)",
elemStyle = $elems[0].style;
if (typeof elemStyle.webkitTransform == "string") {
validPropertyPrefix = "webkitTransform";
} else if (typeof elemStyle.MozTransform == "string") {
validPropertyPrefix = "MozTransform";
}
$doc.addEventListener("mousemove", function (e) {
var centroX = e.clientX - screenWidth,
centroY = screenHeight - (e.clientY + 13),
degX = centroX * 0.02,
degY = centroY * 0.01,
$elem;
for (var i = 0; i < $elems.length; i++) {
$elem = $elems[i];
$elem.style[validPropertyPrefix] =
otherProperty + "rotateY(" + degX + "deg) rotateX(" + degY + "deg)";
}
});
})(document, window);
/* CREDITS TO DESKTOPOGRAPHY FOR IMAGE USED */
html,
body {
width: 100%;
height: 100%;
}
body {
background: #004382;
overflow: hidden;
}
.wrapper {
transform-style: preserve-3d;
margin: 0 auto;
max-width: 982px;
width: 100%;
height: 100%;
position: relative;
display: flex;
justify-content: center;
align-self: center;
background: url("http://portalpacific.net/img/desk/icon-circles.png")
no-repeat center center;
background-size: contain;
}
.bloc {
height: 100%;
width: 100%;
position: relative;
display: flex;
justify-content: center;
align-self: center;
background-size: contain;
background-position: center;
}
.content {
transform: translateZ(80px) scale(1);
-webkit-transform: translateZ(80px) scale(1);
height: 100%;
width: 100%;
max-width: 720px;
position: absolute;
margin: auto;
color: #fff;
z-index: 3;
}
.content1 {
background: url("http://portalpacific.net/img/desk/Website.png") no-repeat;
background-position: center;
max-width: 982px;
width: 100%;
height: 100%;
position: relative;
display: flex;
justify-content: center;
align-self: center;
background-size: contain;
}
.content p:nth-of-type(1) {
font-size: 36px;
line-height: 60px;
position: absolute;
}
.content p:nth-of-type(2) {
position: absolute;
}
.block {
display: block;
height: 100%;
}
<span class="block">
<div class="wrapper elem" style="transform: perspective(700px) rotateY(0deg) rotateX(0deg);">
<div class="bloc">
<div class="content content1"></div>
<div class="content content2">
</div>
</div>
</div>
</span>
I'm trying to arrange 2 divs inside a parent div so that is looks like the parent div is being divided into 2 parts diagonally. The diagram below will show what is required
This is the code i have tried.
App.js
import React, { Component } from "react";
import "./App.css";
class InnerMainDiv extends Component {
constructor() {
super();
this.section = React.createRef();
}
componentDidMount() {
this.handleResize();
window.addEventListener("resize", this.handleResize);
}
componentWillUnmount() {
window.addEventListener("resize", null);
}
handleResize = (WindowSize, event) => {
let h = this.section.current.clientHeight;
let w = this.section.current.clientWidth;
let angle = Math.atan(h / w) * 57.29577;
let rotateProperty = "rotate(" + angle + "deg)";
this.section.current.style.webkitTransform = rotateProperty;
this.section.current.style.transform = rotateProperty;
this.section.current.style.mozTransform = rotateProperty;
};
render() {
return (
<div className="maindiv">
<section ref={this.section}>
<div href="#1" />
</section>
<section ref={this.section}>
<div href="#2" />
</section>
</div>
);
}
}
export default InnerMainDiv;
App.css
html,
body,
div {
height: 100%;
width: 100%;
padding: 0;
margin: 0;
}
div {
overflow: hidden;
position: relative;
}
section {
position: absolute;
top: -100%;
height: 5000vw;
width: 5000vh;
background: #ccc;
-webkit-transform-origin: 0 0;
-moz-transform-origin: 0 0;
transform-origin: 0 0;
}
section + section {
background: #666;
top: 0%;
}
section div {
display: block;
width: 100%;
height: 100%;
cursor: pointer;
}
Any ideas or suggestions on how to achieve this?.
You can use clip-path to achieve this:
.container {
width: 200px;
height: 200px;
position: relative;
}
.container > * {
height: 100%;
background: red;
}
.container :last-child {
position: absolute;
top: 0;
left: 0;
width: 100%;
background: blue;
-webkit-clip-path: polygon(0 0, 100% 0%, 100% 100%);
clip-path: polygon(0 0, 100% 0%, 100% 100%);
}
<div class="container">
<div></div>
<div></div>
</div>
But in case you want more browser support you can use rotation like this:
.container {
width: 200px;
height: 200px;
position: relative;
overflow:hidden;
}
.container > * {
height: 100%;
background: red;
}
.container :last-child {
position: absolute;
top: 0;
left: 0;
width: 141%; /* = 1.41 * 100% --> 1.41 = sqrt(2) */
height: 141%;
background: blue;
transform-origin:top left;
transform:rotate(-45deg);
}
<div class="container">
<div></div>
<div></div>
</div>
I've an image and I have put a mask over it.
The mask is divided into 3 equal parts. Each part has the same image as its background.
Each part has 1/3rd portion of image. I am changing background position of each part, so the masks (collectively) look exactly like the image.
Everything works great, but 2nd part has some issue in background-image, and it looks few pixels shifted to the right.
I need to remove that shifting.
Demo
HTML:
<div id="wrapper">
<div id="main">
<img src="http://images.all-free-download.com/images/graphiclarge/grasshopperpraying_mantis_195444.jpg" />
</div>
<div id="mask">
<div class="part part1"></div>
<div class="part part2"></div>
<div class="part part3"></div>
</div>
</div>
<br>
<button id="switcher" class="main">Put mask on top</button>
CSS:
img {
width: 100%;
height: 100%;
}
#wrapper {
position: relative;
width: 390px;
height: 300px;
}
#main {
z-index: 2;
}
#mask {
z-index: 1;
}
#main, #mask, .part {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
.part {
background-image: url('http://images.all-free-download.com/images/graphiclarge/grasshopperpraying_mantis_195444.jpg');
background-size: 390px 300px;
width: 130px;
}
.part2 {
background-position: -130px 0;
left: 130px;
}
.part3 {
background-position: -260px 0;
left: 260px;
}
JS:
$('#switcher').click(function () {
if ($(this).hasClass('main')) {
$(this).html('Put mask on top').removeClass('main');
$('#main').css({
zIndex: 1
});
$('#mask').css({
zIndex: 2
});
} else {
$(this).html('Put main on top').addClass('main')
$('#main').css({
zIndex: 2
});
$('#mask').css({
zIndex: 1
});
}
});
It is because you are using image of dimension 425x318 and resizing background to 390x300, so image gets distorted as aspect ratios of them do not match.
Check updated demo, here I have used wrapper dimension of same size as of image, i.e. 425x318.
JS Fiddle Demo
Update in code:
CSS
Remove background-size from .part and change #wrapper width, height.
img {
width: 100%;
height: 100%;
}
#wrapper {
position: relative;
width: 425px;
height: 318px;
}
#main {
z-index: 2;
}
#mask {
z-index: 1;
}
#main, #mask, .part {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
.part {
background-image: url('http://images.all-free-download.com/images/graphiclarge/grasshopperpraying_mantis_195444.jpg');
/*background-size: 390px 300px;*/
width: 130px;
}
.part1 {
background-position: 0 0;
left: 0;
}
.part2 {
background-position: -130px 0;
left: 130px;
}
.part3 {
background-position: -260px 0;
left: 260px;
}
UPDATE:
As you mentioned in comment that Image is not in control, background-size properties contain and cover also not working.
The only feasible option seems to get the image dimensions by some method (javascript OR server side code) and dynamically set the #wrapper dimensions to match image dimensions.
JavaScript Code: (For getting image dimensions and set Wrapper dimensions accordingly)
http://jsfiddle.net/8au8nhe5/19/
$(document).ready(function() {
var myImage = new Image();
myImage.src = "http://images.all-free-download.com/images/graphiclarge/grasshopperpraying_mantis_195444.jpg";
$(myImage).on('load', function() {
console.log('My width is: ', this.naturalWidth);
console.log('My height is: ', this.naturalHeight);
$("#wrapper").css({"width": this.naturalWidth + "px", "height": this.naturalHeight + "px"});
});
});
For Reference:
http://davidwalsh.name/get-image-dimensions
https://developer.mozilla.org/en-US/docs/Web/API/HTMLImageElement
As pointed out by Dharmang, cause of the issue was aspect ratio of image. And, it was not possible to fix, without changing the #wrapper dimension, or the image itself.
I've found a workaround, but using img tag, instead of background-image, so that I can distort the aspect ratio of images of mask div, in equal amount, as it is destroyed by the 'real image'.
$('#switcher').click(function () {
if ($(this).hasClass('main')) {
$(this).html('Put mask on top').removeClass('main');
$('#main').css({
zIndex: 1
});
$('#mask').css({
zIndex: 2
});
} else {
$(this).html('Put main on top').addClass('main')
$('#main').css({
zIndex: 2
});
$('#mask').css({
zIndex: 1
});
}
});
img {
width: 100%;
height: 100%;
}
#wrapper {
position: relative;
width: 390px;
height: 300px;
}
#main {
z-index: 2;
}
#mask {
z-index: 1;
}
#main, #mask, .part {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
.part {
width: 130px;
}
.part img {
margin-left: 0;
width: 390px;
height: 300px;
}
.part2 {
left: 130px;
}
.part2 img {
margin-left: -130px;
}
.part3 {
left: 260px;
}
.part3 img {
margin-left: -260px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="wrapper">
<div id="main">
<img src="http://images.all-free-download.com/images/graphiclarge/grasshopperpraying_mantis_195444.jpg" />
</div>
<div id="mask">
<div class="part part1"><img src="http://images.all-free-download.com/images/graphiclarge/grasshopperpraying_mantis_195444.jpg" /></div>
<div class="part part2"><img src="http://images.all-free-download.com/images/graphiclarge/grasshopperpraying_mantis_195444.jpg" /></div>
<div class="part part3"><img src="http://images.all-free-download.com/images/graphiclarge/grasshopperpraying_mantis_195444.jpg" /></div>
</div>
</div>
<br>
<button id="switcher" class="main">Put mask on top</button>