Prevent image distortion with image within transformed div? - javascript

I am looking for a way to adjust the transform on the background for this codepen. The goal would be to adjust the placeholder images so that it sits in it's normal position before the mouseenter, but still have the div rotated so it's a diamond square. As you can see, I have a jQuery animation that will come into play as well. Here is the Codepen:
http://codepen.io/pdnellius/pen/EfkHl
EDIT: I've updated my code to reflect my changes that I've made which gets the effect 90% there, however this feels really hacky.
I had to use a <img> tag instead of a background image on a <div> to achieve the desired effect. Can anyone recommend a solution that could center the <img> while maintaining the proportions when it goes 100% width? Usually I would use a background image with a contain property to achieve this effect, but since I've had to use a <img> tag in order to get this effect working, I'm unable to do that. I've updated the Codepen above to reflect my progress.
HTML
<div id="wrapper">
<div class="diamond">
<img src="http://placekitten.com/2100/2800" class="diamond-img">
</div>
</div>
CSS
body {
margin: 0;
top: 0;
left: 0;
right: 0;
}
#wrapper {
margin-top: 15em;
}
.diamond {
width: 30em;
height: 30em;
-webkit-transform: rotate(-45deg);
transform: rotate(-45deg);
-webkit-transform-origin: 0 100%;
transform-origin: 0 100%;
background: aquamarine;
margin: 0% 50%;
position: absolute;
overflow: hidden;
}
.diamond:before {
content: "";
position: absolute;
width: 200%;
height: 200%;
top: -50%;
left: -50%;
z-index: -1;
background: url(background.png) 0 0 repeat;
-webkit-transform: rotate(-30deg);
-moz-transform: rotate(-30deg);
-ms-transform: rotate(-30deg);
-o-transform: rotate(-30deg);
transform: rotate(-30deg);
}
.diamond-img {
height: 60em;
-webkit-transform: rotate(45deg);
-webkit-transform-origin-y: 30%;
-webkit-transform-origin-x: 96%;
}
JS
$( document ).ready(function() {
$(".diamond").on("mouseenter", function(){
console.log("entered .diamond");
$(".diamond").animate({
transform: 'rotate(0deg)',
transformOrigin: '0 0',
margin: '0 0',
width: '100%',
height: '40em'
}), $(".diamond-img").animate({
width: '100%',
height: 'auto',
transform: 'rotate(0deg)',
}),
$("#wrapper").animate({
marginTop: '0'
})
}).on("mouseleave", function(){
$(".diamond").animate({
transform: 'rotate(-45deg)',
transformOrigin: '0 100%',
width: '30em',
height: '30em',
margin: '0 50%'
}), $(".diamond-img").animate({
height: '60em',
transform: 'rotate(45deg)',
width: '45em',
// transformOriginX: '30%',
// transformOriginY: '96%'
}),
$("#wrapper").animate({
marginTop: '15em'
})
});
});

Ok, from THIS webpage, we modify your fiddle with a :before kludge to get this - FIDDLE.
Any better?
CSS
#wrapper {
margin-top: 15em;
}
.diamond {
position: relative;
overflow: hidden;
width: 30em;
height: 30em;
margin: 0% 50%;
}
.diamond:before
{
content: "";
position: absolute;
width: 200%;
height: 200%;
top: -50%;
left: -50%;
z-index: -1;
background: url(http://www.placehold.it/2000x2000) 0 0 no-repeat;
background-size: cover;
background-position: center;
}
.diamond:hover:before
{
content: "";
position: absolute;
width: 200%;
height: 200%;
top: -50%;
left: -50%;
z-index: -1;
background: url(http://www.placehold.it/2000x2000) 0 0 no-repeat;
background-size: cover;
background-position: center;
transform: rotate(45deg);
}

Related

Simple popup as a graphic with a closing button

I need to code a image that appears as a popup with the option to close it with a button. I already have the button style, I just need your help on how to code it together? Do you have any suggestions?
I have created a simple script for you with pure js. If you find this helpful. Select my answer and give +1.
document.querySelectorAll('.popup-img img').forEach(single=>{
single.addEventListener('click',(e)=>{
let img = e.target;
img.classList.add('popped');
let back = document.createElement('div');
back.classList.add('img-popup');
let close = document.createElement('span');
close.classList.add('close');
back.appendChild(close);
document.body.appendChild(back);
back.addEventListener('click',(e)=>{
back.classList.add('closed');
img.classList.remove('popped');
setTimeout(function(){
document.querySelector('.img-popup').remove();
},500)
})
})
})
.img-popup {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0,0,0,.95);
transform: scale(1);
transition: .5s ease;
}
.img-popup.closed {
transform: scale(0);
}
.img-popup .close {
position: absolute;
top: 0;
right: 0;
width: 40px;
height: 40px;
cursor: pointer;
}
.img-popup .close:before, .img-popup .close:after {content: '';width: 24px;height: 2px;background: #fff;position: absolute;top: 0;left: 0;}
.img-popup .close:before {
transform: rotate(45deg);
transform-origin: left;
top: 13px;
left: 13px;
}
.img-popup .close:after {
transform: rotate(-45deg);
transform-origin: right;
top: 13px;
right: 10px;
left: initial;
}
img.popped {
position: fixed;
top: 50%;
left: 50%;
max-height: 85vh;
max-width: 85vw;
transform: translate(-50%,-50%);
transition: .5s ease;
z-index: 1;
}
<div>
<img src="https://preview.ibb.co/cyESoU/img1.jpg" width="200">
<div class="popup-img"><img src="https://preview.ibb.co/cyESoU/img1.jpg" width="250"></div>
</div>

Create Slanted Div with just border , no background color

I have to create a slanted div and i have gone through many of the available content on internet but not getting the expected result.
I have attached the image(slanted Images) for expected slanted div. I want div to be look slanted using border but not using background color. In case of border one of the edge is not visible. Please, let me know how i can achieve it.
new Image (Attached Image for slanted div)
#slanted_div{
position: relative;
display: inline-block;
padding: 1em 5em 1em 1em;
overflow: hidden;
color: #08393A;
}
#slanted_div:before{
content: '';
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
border:1px #08393A;
-webkit-transform-origin: 100% 0;
-ms-transform-origin: 100% 0;
transform-origin: 100% 0;
-webkit-transform: skew(-45deg);
-ms-transform: skew(-45deg);
transform: skew(-45deg);
z-index: -1;
border-style: solid;
}
<div id="slanted_div"></div>
check if you can set fixed width and height to your #slanted_div and add an ::after selector to use it as bottom-left borders while ::before remains setting up and right borders. Leave you here a example of what I mean:
#slanted_div{
position: relative;
display: inline-block;
overflow: hidden;
width: 300px;
height: 100px;
}
#slanted_div::before{
content: '';
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
border: 1px rgb(8, 57, 58) solid;
-webkit-transform-origin: 100% 0;
-ms-transform-origin: 100% 0;
transform-origin: 100% 0;
-webkit-transform: skew(-45deg);
-ms-transform: skew(-45deg);
transform: skew(-45deg);
z-index: -1;
}
#slanted_div::after{
content: '';
position: absolute;
bottom: 0;
left: 0;
width: 202px;
height: 100%;
border-bottom: 1px rgb(8, 57, 58) solid;
border-left: 1px rgb(8, 57, 58) solid;
border-right: 0;
z-index: -1;
}
<div id="slanted_div"></div>

Need to dynamically set width of an element and ::after [duplicate]

I have an element whose :before style has to be modified based on calculations.
export class Content extends React.Component {
render() {
return (
<div className="ring-base">
<div className="ring-left" style={{/* Change here */}}></div>
<div className="ring-right" style={{/* Change here */}}></div>
<div className="ring-cover">
<div className="ring-text">10%</div>
</div>
</div>
);
}
}
CSS Code:
.ring-base {
position: absolute;
height: 200px;
width: 200px;
border-radius: 50%;
background: red;
transform: rotate(90deg);
overflow:hidden;
}
.ring-cover {
position: absolute;
height: 180px;
width: 180px;
background: #fff;
border-radius: 50%;
top: 5%;
left: 5%;
}
.ring-cover .ring-text {
position: absolute;
width: 100%;
height: 100%;
text-align: center;
font-size: 2em;
display: flex;
justify-content:center;
align-content:center;
flex-direction:column;
transform: rotate(-90deg);
}
.ring-right, .ring-left {
height: 100px;
width: 200px;
overflow: hidden;
position: absolute;
}
.ring-right:before, .ring-left:before {
height: inherit;
width: inherit;
position: absolute;
content: "";
border-radius: 100px 100px 0 0;
background-color: grey;
transform: rotate(0deg);
}
.ring-right {
-webkit-transform-origin: 50% 0%;
-moz-transform-origin: 50% 0%;
-ms-transform-origin: 50% 0%;
transform-origin: 50% 0%;
transform: rotateZ(0deg);
}
.ring-left {
transform: rotate(180deg);
-webkit-transform-origin: 50% 100%;
-moz-transform-origin: 50% 100%;
-ms-transform-origin: 50% 100%;
transform-origin: 50% 100%;
}
.ring-right:before {
-webkit-transform-origin: 50% 100%;
-moz-transform-origin: 50% 100%;
-ms-transform-origin: 50% 100%;
transform-origin: 50% 100%;
transform: rotate(0deg);
}
.ring-left:before {
-webkit-transform-origin: 50% 100%;
-moz-transform-origin: 50% 100%;
-ms-transform-origin: 50% 100%;
transform-origin: 50% 100%;
-webkit-transform: rotate(0deg);
-moz-transform: rotate(0deg);
-ms-transform: rotate(0deg);
transform: rotate(0deg);
}
The ask is to be able to update the transform property for .ring-left:before and .ring-right:before via ReactJS.
If there is a way to not update the :before class and change the CSS to not make use of :before at all, then do suggest that as well.
Js-Fiddle
You can iterate document.styleSheets, set .style of .cssRules where .selectorText matches pseudo selector
let sheets = document.styleSheets;
let selector = "div::before";
let replacementContent = '"after"';
for (let sheet of sheets) {
for (let rule of sheet.cssRules) {
if (rule.selectorText === selector) {
rule.style["content"] = replacementContent;
}
}
}
div:before {
content: "before";
color: red;
font-weight: bold;
text-align: center;
text-shadow: 2px 2px 2px #000;
background: green;
width: 50px;
height: 50px;
display: block;
}
<div></div>

Div's border isn't a straight line after rotating in Firefox in Mac

I have a div which has two child div's, one div on the screen plan and other vertically perpendicular to the screen.
I try to rotate the div along Y axis for about 30 degrees. keeping its transform-style 3d preserved.
When doing it, in Firefox the border isn't a straight line anymore. It looks like this
For closer view
I happen to use the following code
.holder {
position: relative;
top: 0;
left: 0;
width: 200px;
height: 226px;
perspective: 2000px;
-moz-perspective: 2000px;
}
.box {
position: absolute;
left: 0;
top: 0;
width: 200px;
height: 226px;
background-color: transparent;
transform-style: preserve-3d;
-moz-transform-style: preserve-3d;
transform: translateZ( -100px ) rotateY(30deg);
-moz-transform: translateZ( -100px ) rotateY(30deg);
transition: transform 0.5s;
-moz-transition: transform 0.5s;
}
.box div {
position: absolute;
margin: 0;
display: block;
}
.box .front {
left: 0;
right: 0;
top: 0;
bottom: 0;
transform: rotateX(0deg) translateZ(10px);
-moz-transform: rotateX(0deg) translateZ(10px);
background-color: grey;
background-size: cover;
background-position: center;
background-repeat: no-repeat;
}
.box .left {
left: 0;
top: 0;
bottom: 0;
width: 20px;
transform: rotateY(-90deg) translateZ(10px);
-moz-transform: rotateY(-90deg) translateZ(10px);
background-color: black;
background-size: cover;
background-position: left;
background-repeat: no-repeat;
}
<div class="holder">
<div class="box">
<div class="front"></div>
<div class="left"></div>
</div>
</div>
Please let me know if I'm missing anything.
Picture of the link provided in one of the answers :
It's a Firefox aliasing problem, you can add
outline: 1px solid transparent;
as a workaround to .box .front.
I got a work around for your issue reference.
Try filter for the div having class="box".
Basically this is used for svg elements but it is working for your case as well.
filter: url('data:image/svg+xml;utf8,<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><defs><filter id="gaussian_blur"><feGaussianBlur in="SourceGraphic" stdDeviation="0" /></filter></defs></svg>#gaussian_blur');
Tested in latest version of Opera, FF and Chrome for both mac and windows.
Working Demo here
I'm not sure why using translateZ inside a transformed element is not works properly on FF.
Adding outline: 1px solid transparent; is not working, but adding border: 1px solid transparent; to the .box will working, with removing transform: rotateX(0deg) translateZ(10px); from the .box .front.
Example:
.holder {
position: relative;
top: 0;
left: 0;
width: 200px;
height: 226px;
perspective: 2000px;
-moz-perspective: 2000px;
}
.box {
position: absolute;
left: 0;
top: 0;
width: 200px;
height: 226px;
background-color: transparent;
border: 1px solid transparent;
transform-style: preserve-3d;
-moz-transform-style: preserve-3d;
transform: translateZ( -100px ) rotateY(30deg);
-moz-transform: translateZ( -100px ) rotateY(30deg);
transition: transform 0.5s;
-moz-transition: transform 0.5s;
}
.box div {
position: absolute;
margin: 0;
display: block;
}
.box .front {
left: 0;
right: -4px;
top: 0;
bottom: 0;
/* transform: rotateX(0deg) translateZ(10px); */
/* -moz-transform: rotateX(0deg) translateZ(10px); */
background-color: grey;
background-size: cover;
background-position: center;
background-repeat: no-repeat;
}
.box .left {
left: 0;
top: 0;
bottom: 0;
width: 20px;
transform: rotateY(-90deg) translateZ(10px);
-moz-transform: rotateY(-90deg) translateZ(10px);
background-color: black;
background-size: cover;
background-position: left;
background-repeat: no-repeat;
}
<div class="holder">
<div class="box">
<div class="front"></div>
<div class="left"></div>
</div>
</div>

Convert JQuery Animation to Javascript/CSS3

I'm trying to move a div left and increase the height and width by 100px. I could do this using JQuery but I was wondering how I will do it using JavaScript/CSS3?
$("#button").click(function(){
$("#div").animate({
left: '250px',
height: '+=100px',
width: '+=100px',
});
});
I'm using the translate function to move it
-webkit-transform: translate(100px,0);
But I'm not sure how to go about increasing the size.
Any ideas?
Thank you!
How about keyframes?
#keyframes identifier {
0% { width: 25%; height: 40%; }
30% { width: 30%; height: 30%; }
68%, 72% { width: 75%; }
100% { width: 80%; height: 50%; }
}
One option is scale:
transform: scale(sx[, sy]);
to make 2x:
transform: scale(2);
or 2x width, 3x height:
transform: scale(2,3);

Categories

Resources