i'm trying to scale image double when click zoom-in button, and half image when click zoom-out button
My issue is, when click zoom-in button (so, image size is double)
and if it's size over than container, the left side of image (or top side of image) cut off.
what should i do?
same question here, CSS Transform scale scrolling issue ... but it's not a good idea.
because it also scale focus on 'top-left side' when zoom-out
image, so center alignment is impossible
(i want to apply transform: scale(..) using transform-origin: center)
the only way that i know is every time calculate image size, and apply margin for cut-off, but it is hard to apply
any idea please? :o
code look like this.
constructor() {
super()
this._refs = { ratio: 100 }
}
getImageStyle() {
return {
transform: scale(calc(${this.state.ratio} / 100)),
'transform-origin': 'center'
}
}
zoomIn() {
this.setState({ ratio: this.state.ratio + 25 })
}
zoomIn() {
this.setState({ ratio: this.state.ratio - 25 })
}
render() {
const { src } = this.props
return (
<div
className={styles.wrapper}
<img
style={this.getImageStyle()}
ref={(elem) => setRefToNode(this._refs, 'image', elem)}
className={styles.image}
src={src} />
</div>
)
}
and css.
.wrapper {
display: flex;
position: relative;
width: 100%;
height: 100%;
align-items: center;
justify-content: center;
overflow: scroll;
.image {
position: relative;
max-width: 100%;
max-height: 100%;
background-color: white;
}
}
Don't understand what the problem is.
Image doesn't cut off when transforming.
$("#zoom-in").on("click", function() {
$(".image").removeClass("zoom-out");
$(".image").addClass("zoom-in");
});
$("#zoom-out").on("click", function() {
$(".image").removeClass("zoom-in");
$(".image").addClass("zoom-out");
});
$("#zoom-off").on("click", function() {
$(".image").removeClass("zoom-in");
$(".image").removeClass("zoom-out");
});
body {
display: flex;
align-items: center;
justify-content: center;
height: 100vh;
}
.wrapper {
display: flex;
align-items: center;
justify-content: center;
width: 100px;
height: 100px;
border: 4px solid;
}
.wrapper .image {
position: relative;
width: 100%;
height: 100%;
background-color: rgba(255, 0, 0, 0.4);
border-radius: 50%;
transform-origin: center;
transition: transform ease .3s;
}
.wrapper .image.zoom-in {
transform: scale(2);
}
.wrapper .image.zoom-out {
transform: scale(0.5);
}
section {
position: fixed;
bottom: 0;
left: 0;
margin: 10px;
}
section button {
width: 30px;
height: 30px;
margin: 10px;
font-weight: bold;
font-size: 20px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="wrapper">
<div class="image"></div>
</div>
<section>
<button id="zoom-out">−</button>
<button id="zoom-off">0</button>
<button id="zoom-in">+</button>
</section>
Related
My sandbox on JSFIDDLE
When 'OPEN' is clicked, the content div should expand to full width, but it ended up expanding by 100px width like on the red box. I tried to set width: 100%, in the gray box div and it didn't work.
In the .content class, I had the width set to 100vw without margin: 0 auto and it expanded 100% width to the right side, not screen-fulled size.
[]
I'm testing this function before I deploy it on my website.
jQuery -
$(".openit").on("click", function() {
$(".expandBG").toggleClass("content");
$(".openit").hide();
$(".closeit").show();
$(".text").delay(500).fadeIn();
});
$(".closeit").on("click", function() {
$(".expandBG").toggleClass("content");
$(".openit").show();
$(".closeit").hide();
$(".text").hide();
});
HTML -
<div class="wrapper">
<div class="back">BG
<div class="expandBG">
<div class="openit">OPEN</div>
<div class="flex-col">
<div class="closeit">CLOSE</div>
<div class="content text" style="display: none;">
<div>(CONTENT HERE)</div>
</div>
</div>
</div>
</div>
</div>
CSS -
body {
background-color: #000;
}
.wrapper {
width: 100%;
margin: 0 auto;
text-align: center;
border: solid red 1px;
}
.back {
position: relative;
color: #fff;
width: 110px;
height: 110px;
background-color: red;
margin: 0 auto;
text-align: center;
display: block;
}
.expandBG {
display: block;
width: 100px;
height: 100px;
transition: ease 0.3s;
background-color: #192D38;
overflow: hidden;
margin: 0 auto;
bottom: 0;
text-align: center;
font-family: sans-serif;
color: #fff;
position: relative;
}
.flex-col {
flex-direction: column;
}
.openit {
display: block;
text-align: center;
height: 100%;
cursor: pointer;
margin: 0 auto;
}
.closeit {
display: block;
text-align: center;
cursor: pointer;
width: 100%;
margin: 0 auto;
z-index: 1;
position: relative;
}
.text {
width: 100%;
display: flex;
align-items: center;
justify-content: center;
margin-top: -25px;
}
.content {
width: 100%;
height: 50vw;
position: relative;
margin: 0 auto;
}
It's because of the div with a class name back. increase the width of that div to 100% when opneit is clicked and then back to its original size when closeit is clicked.
// add this to your CSS file
.w-full {
width: 100%
}
then include these two lines in your javaScript file
$(".openit").on("click", function() {
$(".back").addClass("w-full"); // This line has been added to your code.
$(".expandBG").toggleClass("content");
$(".openit").hide();
$(".closeit").show();
$(".text").delay(500).fadeIn();
});
$(".closeit").on("click", function() {
$(".back").removeClass("w-full"); // This line has been added to your code.
$(".expandBG").toggleClass("content");
$(".openit").show();
$(".closeit").hide();
$(".text").hide();
});
I have a div where I want to change the image and text when I scroll on it. I have gotten some of the way but I cant figure out how to keep the "parallax-row" fixed, but act like its scrolling? I have a code pen link to help below.
MY GOAL : When you scroll anywhere in the parallax-window everything should stick, but the image and text changes. I have seen some cool image effects using parallax so thats why I am learning it.
codepen
<html>
<body>
<!---------PARALLAX------->
<div class="parallax-window">
<div class="parallax-container">
<div class="parallax-row">
<div class="parallax-image-container">
<img src="https://cdn.pixabay.com/photo/2016/11/18/19/07/happy-1836445_1280.jpg" alt="">
</div>
<div class="parallax-text">
<h1>Title 1</h1>
<h3>This is a description.
</h3>
<div class="mouseicon">
<div class="mousewheel"></div>
</div>
</div>
</div>
</div>
</div>
</body>
</html>
CSS
/*PARALLAX */
.parallax-container::-webkit-scrollbar {
display: none;
}
.parallax-window {
position: relative;
height: 400px;
width: 100vw;
overflow-y: scroll;
overflow-x: hidden;
-ms-overflow-style: none; /* IE and Edge */
scrollbar-width: none; /* Firefox */
}
.parallax-container {
display: flex;
align-items: center;
justify-content: flex-start;
flex-direction: column;
height: 1000px;
background-color: rgb(221, 221, 221);
}
.parallax-row {
display: flex;
justify-content: flex-start;
align-items: center;
height: 400px;
width: 100%;
}
.parallax-image-container {
display: block;
height: inherit;
}
.parallax-image-container img {
height: inherit;
}
.parallax-text {
height: inherit;
display: flex;
flex-direction: column;
align-items: left;
justify-content: center;
padding: 0em 4em;
}
.mouseicon {
margin: 1em;
display: flex;
justify-content: center;
width: 40px;
height: 65px;
border: solid 2px black;
border-radius: 50px;
}
.mousewheel {
width: 10px;
height: 20px;
background-color: black;
border-radius: 50px;
animation: scroll 1.5s infinite;
}
#keyframes scroll {
0% {
transform: translateY(0px);
opacity: 0.5;
}
100% {
transform: translateY(5px);
}
}
JS
//-------PARALLAX SCROLL-------- //
const parallaxContainer = document.querySelector(".parallax-window");
const parallaxImage = document.querySelector(".parallax-image-container img");
parallaxContainer.scrolltop = 0;
const parallaxText = document.querySelector(".parallax-text h1")
var scrollHandler = function () {
var newImageUrl = parallaxImage.src;
var scrollTopParallax =
parallaxContainer.scrollTop || parallaxContainer.scrollTop;
if (scrollTopParallax > 100) {
newImageUrl =
"https://cdn.pixabay.com/photo/2016/11/29/07/16/balancing-1868051__480.jpg";
parallaxText.innerHTML = "Title 2"
}
if (scrollTopParallax < 100) {
newImageUrl =
"https://cdn.pixabay.com/photo/2016/11/18/19/07/happy-1836445_1280.jpg";
parallaxText.innerHTML = "Title 1"
}
parallaxImage.src = newImageUrl;
console.log("new: " + parallaxImage.src);
};
parallaxContainer.addEventListener("scroll", scrollHandler);
I have updated my codepen with my own answer. essentially creating an overlay to scroll on and then changing the elements based on that invisible overlays scroll position. see link to codepen above.
CSS/JS beginner here, I'm following a webkit 3d-transforms guide and trying to apply a hidden front-face option for the ring-rotation part:
The "backfaces-visible" checkbox hides/shows the backface, could the opposite be implemented where the backface is visible and the front is hidden?
Edit:
With respect to the first comment, I'd like to clarify that the desired result should look like this (front planes are hidden while rotating):
(Front panels were erased with photo-editing, the rest are CSS changes. Mind the poorly edited left card)
Not 100% sure if this is what you are looking for, but If you don't use the backface-visiblity parameter at all, i.e. leave it at its default "visible" and if it has a non-transparent background, the backside will always cover the frontside, if its z-index or order in the HTML code is set that way.
My snippet below is derived from some older code I had at hand, in case you wonder. Press the button below the circle to trigger a turning animation.
function turn1() {
$('#front').css({transform: 'rotateY(180deg)'});
$('#back').css({transform: 'rotateY(360deg)'}).delay(2000).promise().then(turn2);
};
function turn2() {
$('#front').css({transform: 'rotateY(0deg)'});
$('#back').css({transform: 'rotateY(180deg)'}).delay(2000).promise().then(turn1);
};
$('#go').on('click', turn1);
.wrapper {
position: relative;
margin: 20px auto;
width: 180px;
height: 180px;
font-size: 36px;
perspective: 150px;
}
#front, #back {
position: absolute;
width: 100%;
height: 100%;
border-radius: 50%;
transition: transform 2s;
display: flex;
justify-content: center;
align-items: center;
}
#front {
background: green;
}
#back {
background: yellow;
transform: rotateY(180deg);
}
.x {
text-align: center;
}
button {
padding: 6px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="wrapper">
<div id="front">Front</div>
<div id="back">Back</div>
</div>
<div class="x"><button id="go">Press to rotate</button></div>
If you add backface-visibility: hidden to the otherwise unchanged code, you see both sides when rotating:
function turn1() {
$('#front').css({transform: 'rotateY(180deg)'});
$('#back').css({transform: 'rotateY(360deg)'}).delay(2000).promise().then(turn2);
};
function turn2() {
$('#front').css({transform: 'rotateY(0deg)'});
$('#back').css({transform: 'rotateY(180deg)'}).delay(2000).promise().then(turn1);
};
$('#go').on('click', turn1);
.wrapper {
position: relative;
margin: 20px auto;
width: 180px;
height: 180px;
font-size: 36px;
perspective: 150px;
}
#front, #back {
position: absolute;
width: 100%;
height: 100%;
border-radius: 50%;
transition: transform 2s;
display: flex;
justify-content: center;
align-items: center;
backface-visibility: hidden;
}
#front {
background: green;
}
#back {
background: yellow;
transform: rotateY(180deg);
}
.x {
text-align: center;
}
button {
padding: 6px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="wrapper">
<div id="front">Front</div>
<div id="back">Back</div>
</div>
<div class="x"><button id="go">Press to rotate</button></div>
I'll be using some SVGs that will be those avatars on the axis. For now all I need is a hint on how to set those avatars at the very end of every axis.
I am trying to achieve this:
This the code I have so far:
body {
background-color: #de4e40;
text-align: center;
justify-content: center;
align-items: center;
height: 100vh;
width: 100vw;
margin: 0;
display: flex;
}
.squareLoader {
height: 200px;
width: 200px;
background-color: white;
border: 1px solid black;
border-radius: 50%;
}
<div class='squareLoader'></div>
And here is a codepen in case you want to take a look.
Is there any guide or someone can help me on how to achieve this?
I can use flexbox and also I am using React Native. Just in case.
Make squareLoader a relative parent
Position element in corners using translate, top, left
Share styles wherever possible
Store repeated offset value in CSS variable
:root {
--offset: -1.4em;
}
body {
background-color: #de4e40;
text-align: center;
justify-content: center;
align-items: center;
height: 100vh;
width: 100vw;
margin: 0;
display: flex;
}
.squareLoader {
height: 200px;
width: 200px;
background-color: white;
border: 1px solid black;
border-radius: 50%;
position: relative;
}
.squareLoader img {
position: absolute;
width: 50px;
}
.one, .three {
left: 50%;
transform: translateX(-50%);
}
.two, .four {
top: 50%;
transform: translateY(-50%);
}
.one {
top: var(--offset);
}
.two {
right: var(--offset);
}
.three {
bottom: var(--offset);
}
.four {
left: var(--offset);
}
<div class="squareLoader">
<img src="https://image.flaticon.com/icons/svg/190/190675.svg" alt="" class="one">
<img src="https://image.flaticon.com/icons/svg/190/190675.svg" alt="" class="two">
<img src="https://image.flaticon.com/icons/svg/190/190675.svg" alt="" class="three">
<img src="https://image.flaticon.com/icons/svg/190/190675.svg" alt="" class="four">
</div>
https://jsfiddle.net/uf2t5p6r/3/
If I understand your post correctly, you want to place SVG images on the North, South, East, and West points of a circle with CSS; It is definitely possible to do this with CSS, but it depends completely on the size of the container and the size of the images being used.
The example circle you provided has a set height and width, so assuming that your SVG images are also a set size and do not change with page size you can do something like this.
body {
background-color: #de4e40;
text-align: center;
justify-content: center;
align-items: center;
height: 100vh;
width: 100vw;
margin: 0;
display: flex;
}
.squareLoader {
/* added 'position: relative', because parent elements of absolute positioned elements have to be positioned to prevent mayhem */
position: relative;
height: 200px;
width: 200px;
background-color: white;
border: 1px solid black;
border-radius: 50%;
}
.avatar {
position: absolute;
left: 75px;
top: 75px;
border: 1px solid black;
height: 50px;
width: 50px;
}
.avatarN {
top: -25px;
}
.avatarS {
top: 175px;
}
.avatarE {
left: 175px;
}
.avatarW {
left: -25px;
}
and the HTML with .avatar <div>s (you can stick the SVG images inside these divs):
<div class='squareLoader'>
<div class="avatar avatarN"></div>
<div class="avatar avatarS"></div>
<div class="avatar avatarE"></div>
<div class="avatar avatarW"></div>
</div>
In the previous example all four avatar <div>s are given a height and width of 50px.
.avatarN has a top position of -25px because that is half of the image's height and a left position of 75px (half of .squareLoader's width minus half of the image's width).
.avatarW has a top position of 75px (half of .squareLoader's height minus half of the image's height) and a left position of 25px, which is half of the image's height.
And so on for the other divs.
If you are going to make your .squareLoader <div> resize based on the page size, and the images resize based on page size, you can use the calc() CSS function which can be used anywhere a length unit is allowed in CSS.
https://developer.mozilla.org/en-US/docs/Web/CSS/calc
w3Schools has a pretty decent cursory explanation of all the units allowed in CSS:
https://www.w3schools.com/cssref/css_units.asp
And also, here's their page on position values in CSS as well:
https://www.w3schools.com/cssref/pr_class_position.asp
Whether or not you are using flexbox, you'll still have to use the position property to get the images where you want them.
One idea to create this is to consider only background and it will be easier to handle:
body {
background-color: #de4e40;
text-align: center;
justify-content: center;
align-items: center;
height: 100vh;
width: 100vw;
margin: 0;
display: flex;
}
.squareLoader {
height: 250px;
width: 250px;
background:
url(https://picsum.photos/50/50?image=1069) top center,
url(https://picsum.photos/50/50?image=1069) bottom center,
url(https://picsum.photos/50/50?image=1069) left center,
url(https://picsum.photos/50/50?image=1069) right center,
/*the circle*/
radial-gradient(farthest-side,
#fff calc(100% - 32px),#000 calc(100% - 30px),
#000 calc(100% - 30px),#000 calc(100% - 20px),
transparent calc(100% - 18px));
background-repeat:no-repeat;
}
<div class='squareLoader'></div>
I have an element with one diagonal side achieved by adjusting linear-gradient and height - in two different states. Now I try to toggle between these states and have a smooth transition of the red triangle, so that it would look like a seesaw :-) The problem is, that from one state to another it changes the direction and is jumpy, I did not find a way to animate it fluently .. Is there a way to to what I want using pure CSS e.g. using transitions?
let btn = document.getElementsByTagName('button')[0];
let stage = document.getElementById('stage');
btn.addEventListener('click', function() {
stage.classList.toggle('fixie');
});
body,
ul {
padding: 0;
margin: 0;
}
#stage {
width: 100%;
height: 14em;
background: pink;
padding: 0;
border: 1px solid blue;
}
#stage::before {
display: block;
position: relative;
width: 100%;
height: 100%;
/*as high as #stage*/
opacity: 0.4;
content: '';
z-index: 1;
background: linear-gradient(to left bottom, red 50%, pink 50%);
/*transition: height 4s;*/
/*transition: linear-gradient 4s 8s;*/
}
#stage.fixie::before {
height: 30%;
background: linear-gradient(to right bottom, red 50%, pink 50%);
}
<div id="stage"></div>
<button>animate gradient</button>
Here is my FIDDLE
As you can't animate linear-gradient, here is a workaround using transform
In this sample I used skew. As the degree of skew will differ based on the width/height, and as long as its ratio is kept, this will be fully responsive, else you'll need a small script.
(function(){
let btn = document.getElementsByTagName('button')[0];
let stage = document.getElementById('stage');
btn.addEventListener('click', function() {
stage.classList.toggle('fixie');
});
})();
body, ul {
padding: 0;
margin: 0;
}
#stage {
position: relative;
overflow: hidden;
width: 90vw;
height: calc(90vw * 0.2677); /* 0.2677, aspect ratio that match skew degree */
background: pink;
padding: 0;
border: 1px solid blue;
}
.navi {
width: 100%;
min-height: 4em;
height: auto;
background: green;
z-index: 2;
position: relative;
}
#stage::before {
content: '';
position: absolute;
width: 100%;
height: 100%; /*as high as #stage*/
bottom: 100%;
opacity: 0.4;
z-index: 1;
background: red;
transform: skewY(15deg);
transform-origin: left bottom;
transition: transform 2s;
}
#stage.fixie::before {
transform: skewY(-15deg) translateY(100%);
}
.navi ul {
list-style: none;
display: flex;
background: lightblue;
justify-content: flex-end;
}
.navi ul li {
display: flex;
align-items: center;
justify-content: center;
min-width: 4em;
width: auto;
height: 2em;
margin: 1px;
background: yellow;
}
<div id="stage"></div>
<button>
animate
</button>
Side note:
One can use any fixed value instead of vw, as long as the #stage's ratio is kept. If to change ratio, you'll either need a script, since CSS calc can't do math with sqrt and sin/cos etc. to get the angle, or using media query's, and have angle's and ratio's manually set for different screens.