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!
Related
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
This question already has answers here:
Shape with a slanted side (responsive)
(3 answers)
Closed 3 years ago.
I've attached a picture to show the exact layout. The line in the photo is only there to show where the colors should change.
Here is some code I have tried but doesn't look how I want.
.block {
background-color: black;
left: -50;
height: 150px;
width: 100%;
transform: rotate(-40deg);
}
<body>
<div class="block">
</div>
</body>
You can use pseudo element with skew transformation :
body {
height: 100vh;
margin: 0;
background: yellow;
}
body:before {
content: "";
position: absolute;
top: 0;
bottom: 0;
left: 0;
width: 300px;
background: #000;
transform: skew(-30deg);
transform-origin:top;
}
To keep the same visual on resize, set a big fixed height for the pseudo element and center it:
html {
background: yellow;
}
html:before {
content: "";
position: fixed;
top: calc(50% - 1000px);
left: 0;
width: 500px;
height:2000px;
background: #000;
transform: skew(-15deg);
transform-origin:top;
}
Use a linear gradient at an angle
body {
margin:0;
}
div {
height: 100vh;
background: linear-gradient(105deg, black 25%, yellow 25%)
}
<div></div>
.left-sidebar {
position: absolute;
width: 20%;
background: #000;
transform: skewY(5px);
}
.content {
background: #fff;
}
The property that "curves" the div is this property in CSS transform: skew(X,Y).Try that, hope it helps.
But I suggest that you create 2 div side-by-side in order to get the desired effect.
I want to create a landing page like a game. The visitor gets the option either to chose "Professioneel" or "Speels".
Telling it is easy but programming it is hard for me, so this is what I want:
2 div's with 2 different background-image when someone hover over one of the divs I want the background-image to scale (ONLY THE IMAGE) and the opacity placed on the div to change from 50% to 80%.
And a really nice future would be to display a snow falling gif over the image.
This is what I want to create:
Before
After:
What I have achieved till now is making the 2 divs with a background-image and I'm not even sure if that is the right way.
Can someone please help me out?
This is what happens when I hover with my current code: (the whole div scales, not only the image)
As an user asked, here some code:
#containerEntree {
height: 100vh;
width: 1920px;
padding-left: 0;
padding-right: 0;
}
#professioneelContainer {
background-color: red;
text-align: center;
width: 1920px;
height: 475px;
}
#speelsContainer {
background: red;
width: 100%;
height: 475px;
text-align: center;
}
.entreeTekst:hover {
transform: scale(1.2);
}
.entreeTekst {
width: 100%;
height: 100%;
position: relative;
transition: all .5s;
margin: auto;
}
.entreeTekst > span {
color: white;
/* Good thing we set a fallback color! */
font-size: 70px;
position: absolute;
}
<div class="container" id="containerEntree">
<div id="professioneelContainer">
<div class="entreeTekst">
<span>professioneel</span>
<img src="img/professioneel.jpg" />
</div>
</div>
<div id="speelsContainer">
<div class="entreeTekst">
<span>Speels</span>
<img src="img/speels.jpg" />
</div>
</div>
</div>
Please note that I'm still working on it so don't say that this (of course) won't work.
You can do this by using 2 divs with background images and use padding on the div to replicate the aspect ratio of the background image. Scale the image using background-size on :hover. Then use a pseudo element to create the color overlay and transition the opacity on :hover, then use the other pseudo element on top of that with the text and the "snow" gif as a background.
body {
width: 600px;
max-width: 80%;
margin: auto;
}
div {
background: url('https://static.tripping.com/uploads/image/0/5240/towns-funny-names-us_hero.jpg') center center no-repeat / 100%;
height: 0;
padding-bottom: 33.33333%;
position: relative;
transition: background-size .25s;
}
.speel {
background-image: url('http://www.luketingley.com/images/large/The-Punchbowl-Web-Pano.jpg');
}
div::after, div::before {
content: '';
position: absolute;
top: 0; left: 0; right: 0; bottom: 0;
}
div::before {
opacity: .5;
transition: opacity .25s;
}
.pro::before {
background: blue;
}
.speel::before {
background: red;
}
div::after {
display: flex;
align-items: center;
justify-content: center;
color: #fff;
font-family: sans-serif;
font-size: 1.5em;
font-weight: bold;
}
.pro::after {
content: 'PROFESSIONEEL';
}
.speel::after {
content: "SPEELS";
}
div:hover::after {
background: url('https://media.giphy.com/media/26BRyql7J3iOx875u/giphy.gif') center center no-repeat / cover;
}
div:hover::before {
opacity: 0.8;
}
div:hover {
background-size: 150%;
}
<div class="pro">
</div>
<div class="speel">
</div>
You can simply increase the background-size: height width; and opacity: value; property when you hover over an element. You can, if you want to, add some transition to make it smooth. This only scales the background image, not the div itself.
#d {
background-image: url(https://cdn.pixabay.com/photo/2016/10/29/20/52/cincinnati-1781540_960_720.png);
height: 200px;
width: 200px;
background-size: 100px 100px;
background-repeat: no-repeat;
background-position: center;
/*To make the transistion smooth*/
-o-transition:.5s;
-ms-transition:.5s;
-moz-transition:.5s;
-webkit-transition:.5s;
transition:.5s;
opacity: 0.5;
}
#d:hover {
background-size: 110px 110px;
opacity: 0.8;
}
<div id='d'>
</div>
I'm scaling a div up with the transform property, but I want to keep its children (which have 1px width or height) the same size. I counter-scaled them by .5, with the expected result that an element of 1px scaled by 2, and then .5, should end up back at 1px, but they wind up a blurry 2px.
Here's the box before scaling it:
.container {
width: 200px;
height: 200px;
margin: 100px;
background-color: #EEE;
position: absolute;
}
.outline {
position: absolute;
background: #1899ef;
z-index: 999999;
opacity: 1 !important;
}
.outlineBottom, .outlineTop {
width: 100%;
height: 1px;
}
.outlineLeft, .outlineRight {
height: 100%;
width: 1px;
}
.outlineRight {
right: 0px;
}
.outlineBottom {
bottom: 0px;
}
<div class="container">
<div class="outline outlineTop"></div>
<div class="outline outlineRight"></div>
<div class="outline outlineBottom"></div>
<div class="outline outlineLeft"></div>
</div>
As you can see, the elements at the edges are a clear, dark 1px blue. Here's what the box looks like after scaling, though:
.container {
width: 200px;
height: 200px;
margin: 100px;
background-color: #EEE;
position: absolute;
transform: scale(2);
}
.outline {
position: absolute;
background: #1899ef;
z-index: 999999;
opacity: 1 !important;
transform: scale(.5);
}
.outlineBottom, .outlineTop {
width: 100%;
height: 1px;
transform: scale(1,.5);
}
.outlineLeft, .outlineRight {
height: 100%;
width: 1px;
transform: scale(.5,1);
}
.outlineRight {
right: 0px;
}
.outlineBottom {
bottom: 0px;
}
<div class="container">
<div class="outline outlineTop"></div>
<div class="outline outlineRight"></div>
<div class="outline outlineBottom"></div>
<div class="outline outlineLeft"></div>
</div>
And here's a post-scaled render from Chrome 41.0.2272.89 Mac, which is what I'm running.
Adding transform-3d(0, 0, 0) didn't appear to help. A solution was found using the zoom property, but since zoom isn't well supported I'd like to avoid that. Adding filter: blur(0px); didn't appear to have any effect either.
It was posited in chat that perhaps the children are first scaled to .5 and then doubled in size, causing them to be scaled down to .5px and then back up from there. Is there any way to ensure the order that they're rendered in causes them to first be scaled up to 2px and then halved? Against my better judgement, I tried forcing the render order with JS, but unsurprisingly, that didn't have any effect (though, interestingly, the bottom element did maintain its original color).
Failing that, are there any other solutions floating around out there? I can't be the only one who's run into this problem.
It is to do with the default transform-origin on the scaled elements. It defaults to 50% 50% for any element being transformed, but this has issues when scaling down 1px values as it has to centre the scale on a half pixel and the rendering of the elements has issues from here on out. You can see it working here with the transform-origin moved to the relevant extremes for each item.
A bit of playing about shows that this same blurring happens on scaled elements for any dimension where the scaling ends up halving a pixel.
body {
padding: 1em;
}
.container {
width: 200px;
height: 200px;
margin: 100px;
background-color: #EEE;
position: absolute;
transform: scale(2);
}
.outline {
position: absolute;
background: #1899ef;
z-index: 999999;
opacity: 1 !important;
}
.outlineBottom, .outlineTop {
width: 100%;
height: 1px;
transform: scale(1, 0.5);
}
.outlineBottom {
bottom: 0;
transform-origin: 0 100%;
}
.outlineTop {
transform-origin: 0 0;
}
.outlineLeft, .outlineRight {
height: 100%;
width: 1px;
transform: scale(.5,1);
}
.outlineRight {
right: 0px;
transform-origin: 100% 0;
}
.outlineLeft {
left: 0px;
transform-origin: 0 0;
}
<div class="container">
<div class="outline outlineTop"></div>
<div class="outline outlineRight"></div>
<div class="outline outlineBottom"></div>
<div class="outline outlineLeft"></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>