CSS Zoom into specific image point - html

I have an image which I need to zoom a specific point depending on which input is focused
Here's a fiddle so far
I used the attributes transform and transform-origin. It's working fine on Firefox (notice how it's moving toward the point while zooming at same time).
However on Chrome, the scale/zoom is done first, then it teleports the point. It's actually very confusing
Any idea how to make this work on Chrome ?

I experimented with putting both the transform and the transform-origin into a CSS animation and it seemed to manage to do them both at once, so avoiding the 2 step problem you saw on Chrome (tested on Edge):
#keyframes focusin {
0% {
transform: scale(1);
transform-origin: 0% 0%;
}
100% {
transform: scale(3);
transform-origin: 25% 75%;
}
}
Here's a snippet. I've put the animation time to 10s so you can see the 'journey' the paper takes when focus is on input1. It seems to be smooth, so a bit of an improvement, but it isn't 'direct' on Edge/Chrome which I guess (and it is only a guess) is to do with how the browser animates (or doesn't) transform-origin.
$("#input1").focus(function(e) {
/* $("#image").css({
"transform": "scale(3)",
"transform-origin": "25% 75%"
});*/
document.getElementById('image').style.animationName = 'focusin';
});
$("#input2").focus(function(e) {
$("#image").css({
"transform": "scale(3)",
"transform-origin": "75% 25%"
});
});
$("#input1, #input2").focusout(function(e) {
$("#image").css({
"transform": "scale(1)"
});
});
#wrapper {
width: 400px;
height: 267px;
border: 1px solid black;
overflow: hidden;
position: relative;
}
#image {
background-image: url('http://i.imgur.com/n9q7jhm.jpg');
background-size: 400px 267px;
background-position: center;
/* transition: all 1s ease; */
width: 100%;
height: 100%;
/* transform: scale(1); */
position: relative;
left: 0;
top: 0;
animation-duration: 10s;
animation-iteration-count: 1;
animation-name: none;
animation-fill-mode: forwards;
}
#keyframes focusin {
0% {
transform-origin: 0% 0%;
transform: scale(1);
}
100% {
transform-origin: 25% 75%;
transform: scale(3);
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input type="text" id="input1">
<input type="text" id="input2">
<div id='wrapper'>
<div id='image'></div>
</div>

Related

keyframes animation doesn't work for some reason

I have some text in html that I want to animate
<div class="sofa-text inner-text">
<h1>Sofa, we have cool sofas</h1>
</div>
<div class="light-text inner-text">
<h1>our stand light is out-standing</h1>
</div>
and here's CSS
.inner-text {
display: none;
width: 100px;
height: 100px;
background-color: black;
position: absolute;
transition: 1s;
transform: translateY(200%);
animation-name: slide-up;
animation-duration: 2s;
animation-delay: .5s;
}
#keyframes slide-up{
0% {
transform: translateY(200%);
}
100% {
transform: translateY(0);
}
}
and I wanted to display this animation, after the button was clicked
let $sofaText = document.querySelector('.sofa')
let $lightText = document.querySelector('.light')
let showSofa = () => {
$sofaText.style.display = 'flex'
}
let showStand = () => {
$lightText.style.display = 'flex'
}
$sofaBtn.addEventListener('click', showSofa)
$standBtn.addEventListener('click', showStand)
However this doesn't work. I tested step by step and problem was in #keyframes. I even added -webkit but it still didn't work. I have no idea what's wrong with this
It's working you just can't see it because display:none;
function tran(){
let t = document.querySelector('.sofa-text');
t.classList.add("anim");
t.style.display = "flex";
}
.inner-text {
display:none;
width: 100px;
height: 100px;
background-color: black;
position: absolute;
transition: 1s;
transform: translateY(200%);
}
.anim{
animation-name: slide-up;
animation-duration: 2s;
animation-delay: .5s;
}
#keyframes slide-up{
0% {
transform: translateY(200%);
}
100% {
transform: translateY(0);
}
}
<button onclick="tran()">click</button>
<div class="sofa-text inner-text">
<h1>Sofa, we have cool sofas</h1>
</div>
<div class="light-text inner-text">
<h1>our stand light is out-standing</h1>
</div>

Reveal animation

I've coded a reveal image animation and have stumbled across an issue when in the creation.
.container{
overflow: hidden;
}
.image {
background-image: url('https://images.wallpaperscraft.com/image/honda_civic_type_r_honda_type_r_honda_129270_3840x2160.jpg');
background-size: cover;
width: 400px;
height: 400px;
animation: 1s ease-out 0s 1 slideInFromLeft;
overflow: hidden;
}
#keyframes slideInFromLeft {
0% {
transform: translatex(-100%);
}
100% {
transform: translatex(0%);
}
}
<div class="container">
<div class="image">
</div>
</div>
The animation seems to be working fine except for it not sliding smoothly. It seems to have a jitter of some sort.
How can I make the animation slide more smoothly?
You could wait for the page/image to load and then trigger the animation to happen. The code below is a crude way of applying the animation class once with js.
window.onload = function() {
var element = document.getElementById('img1');
element.classList.add("show");
element.classList.add("animate");
}
.container{
overflow: hidden;
}
.image {
background-image: url('https://images.wallpaperscraft.com/image/honda_civic_type_r_honda_type_r_honda_129270_3840x2160.jpg');
background-size: cover;
width: 400px;
height: 400px;
opacity: 0;
overflow: hidden;
}
#img1.animate{
animation: 1s ease-out 0s 1 slideInFromLeft;
}
.show {
opacity:1;
}
#keyframes slideInFromLeft {
0% {
transform: translatex(-100%);
}
100% {
transform: translatex(0%);
}
}
<div class="container">
<div id="img1" class="image" >
</div>
</div>
I'd use an <img> element for this and remove it when it loaded, after I pass it's src to the backgroundImage of the parent, as it was already loaded:
let imageDivs = document.querySelectorAll('.image img');
for (var i = 0; i < imageDivs.length; i++) {
imageDivs[i].addEventListener('load', imageLoaded)
}
function imageLoaded(e) {
let div = e.target.closest('div');
div.style.backgroundImage = 'url('+this.src+')';
div.classList.add('loaded');
div.removeChild(div.querySelector('img'));
}
.container{
overflow: hidden;
}
.image {
background-size: cover;
width: 400px;
height: 400px;
transform: translatex(-100%);
overflow: hidden;
}
.image.loaded{
animation: slideInFromLeft 1s cubic-bezier(.5,0,.3,1) forwards;
}
.image img {
height: 0;
}
#keyframes slideInFromLeft {
0% {
transform: translatex(-100%);
}
100% {
transform: translatex(0);
}
}
<div class="container">
<div class="image">
<img src="https://images.wallpaperscraft.com/image/honda_civic_type_r_honda_type_r_honda_129270_3840x2160.jpg">
</div>
</div>
This triggers the animation of a particular <div> (if you have more than one) as soon as that image loaded, rather than triggering all of them after all images in the page have loaded (if you use window.load).
However, this doesn't mean you should load huge resources in your page. Optimizing your images and loading them the right size for current device is a very important step in website optimization. You should use srcset for this purpose.

CSS cannot fade out and then hide

I'm trying to make a css class and animation which will make a div (and it's contents) fade out or move, but ultimately, the div to have display:none and visibility:hidden
My effort is not working! I can get it to either animate, or to appear to be "removed"
This crude example demonstrates the issue
.hide {
animation-name:fadeOut;
animation-duration:1s;
/*visibility: hidden;
display: none;*/
}
#keyframes fadeOut {
from {
opacity: 1;
margin-left: 0%;
}
to {
opacity: 0;
margin-left: -100%;
}
}
<div class="hide">
<div style="padding:20px;background:orange;">
<div style="padding:5px;background:azure;">
My content
</div>
</div>
</div>
I also tried updating the CSS to
to {
opacity: 0;
margin-left: -100%;
visibility: hidden;
display: none;
}
And also on https://jsfiddle.net/
As you can see, in the CSS I have commented out the hiding part (although the opacity makes it hidden).
Is it possible to apply the fadeout and then update the visibility and display without using JavaScript?
Add animation-fill-mode: forwards; so that the element you're animating stays on the last (key)frame, and it doesn't start over or refresh to the beginning.
Learn more about animation-fill-mode.
Another way to write this animation:
.hide {
animation: fadeOut 1s forwards;
}
.hide {
animation-name:fadeOut;
animation-duration:1s;
animation-fill-mode: forwards; /* added */
/*visibility: hidden;
display: none;*/
}
#keyframes fadeOut {
from {
opacity: 1;
margin-left: 0%;
}
to {
opacity: 0;
margin-left: -100%;
height: 0; /* added */
}
}
<div class="hide">
<div style="padding:20px;background:orange;">
<div style="padding:5px;background:azure;">
My content
</div>
</div>
</div>
<div>
Other content
</div>
Scrollbar fix
A possible solution to the scrollbar issue is to bring the hidden element back to the initial position with margin: 0; (or whatever the initial margin was):
#keyframes fadeOut {
0% {
opacity: 1;
margin-left: 0%;
}
99% {
opacity: 0;
margin-left: -100%;
height: 0;
}
100% {
opacity: 0;
margin-left: 0; /* added */
height: 0;
}
}

CSS scale out and fade effect

I am trying to recreate the following effect (click one of the colours on this page to see what I mean: http://flatuicolors.com) on an overlay when a link is clicked.
The transition is something like this: An overlay with a success message scales out and fades in, pauses and then scales out and fades out.
However, it is not producing the desired effect. What's more, the scaling is not visible at all. Any help is much appreciated.
html, body { height: 100%; }
.container {
position: relative;
margin: 0 auto; }
.container.questionnaire {
background:#f1c40f;
width: 100%;
max-width: 100%;
height: 100%;
}
.row-flex.buttons-only {
height:100%;}
.row-flex {
display: table;
width: 100%; }
.column {
box-sizing: border-box; }
.one-third-flex.column {
width: 33.3333%;
display: table-cell;
text-align: center;
vertical-align: middle;
float: none; }
.overlay {
position: fixed;
top: 0;
left: 0;
height: 100%;
width: 100%;
display: table;
background-color:#1abc9c;
z-index: 10;
}
h1.success-message { display: table-cell; text-align: center;
vertical-align: middle;}
.animated {
-webkit-animation-duration: 2s;
animation-duration: 2s;
-webkit-animation-fill-mode: both;
animation-fill-mode: both;
-webkit-animation-timing-function: ease-out;
animation-timing-function: ease-out;
}
#-webkit-keyframes fadeOut {
0% {visibility:visible; opacity: 1;transform: scale(2);}
40% {opacity: 1;transform: scale(1.5);}
60% {opacity: 1;transform: scale(1.5);}
100% {visibility:hidden; opacity: 0;transform: scale(1);}
}
#keyframes fadeOut {
0% {visibility:visible; opacity: 1; transform: scale(2);}
40% {opacity: 1;transform: scale(1.5);}
60% {opacity: 1;transform: scale(1.5);}
100% {visibility:hidden;opacity: 0; transform: scale(1);}
}
.fadeOut {
-webkit-animation-name: fadeOut;
animation-name: fadeOut;
}
<body>
<div class="overlay animated fadeOut"><h1 class="success-message">Success</h1></div>
<div class="container questionnaire">
<div class="row row-flex buttons-only">
<div class="one-third-flex column"></div>
<div class="one-third-flex column" style="background-color: #f4f4f4;">
<div role="button" class="ico-btn btn-settings-lg">CLICK
</div>
</div>
<div class="one-third-flex column"></div>
</div>
</div>
</body>
Well, I hope this answer may help you.
As I thought that was an interesting effect (created with flash), I have worked a bit creating it from scratch with css3 and jquery. It was easier for me to do my code insteed of trying to modify yours so that’s why It maybe not be usefull for You but maybe it may be for other users.
The html is simple:
<div class="square ">
</div>
<div class="effect ">
<div class="text">TEXT HERE</div>
</div>
Where square is the area to click and effect is the container of the animation, which is a div with 0 height and width placed at the center of the window in case you want to add more animations (as to make it “grow” or shrink).
With, also, some simple jquery:
$('. square).click(function () {
$('. effect).addClass("animation");
$('.text').addClass("text-effect");
setTimeout(function () {
$('. effect).removeClass("animation");
$('.text').removeClass("text-effect");
}, 1500);
});
to add a class to effect and text on click and remove it after animation is done
Then after some basic CSS styles I made the animation for effect:
.animation {
animation-name: background;
animation-duration: 1.5s;
animation-timing-function: linear;
animation-delay: 0s;
animation-iteration-count: 1;
}
#keyframes background {
0% {height:100%; width:100%; opacity:1}
80% {height:100%; width:100%; opacity:1}
99.999% {height:100%; width:100%; opacity:0}
100% {height:0; width:0; opacity:0}
}
And for the text I have just used a transition:
.text {
background-color:rgba(255,255,255,0.6);
width:100%;
text-align:center;
font-size:50px;
color:#fff;
font-weignt:bold;
text-shadow: 1px 1px 0 #000000;
font-family:arial;
padding:20px 0;
transition:all 0.2s linear;
position:absolute;
top:50%;
transform: translateY(-50%);
transition:all 0.2s linear;
}
.text-effect {
padding:10px 0;
font-size:40px;
}
All toguether and adding 8 squares with different colors:
JSFIDDLE
and, as I wrote above, the background fading and shrinking just with
#keyframes background {
0% {height:100%; width:100%; opacity:1}
80% {height:100%; width:100%; opacity:1}
100% {height:0; width:0; opacity:0}
}
JSFIDDLE2

CSS3 Animation transition

The problem is I can't figure out how to disable kind of scrolling effect to make each picture occupy whole space of box. To create kind of gif image, using only sprit-sheet and CSS.
JSFIDDLE
<title>Hey</title>
<link rel="stylesheet" href="learn.css">
<body>
<div class="animation"></div>
</body>
.animation {
width: 128px;
height: 128px;
margin: 2% auto;
background: url('http://s16.postimg.org/8f5770kpx/sprite.png') center;
animatio-play-state: paused;
animation: play 5s steps(10) infinite;
transorm: translateZ(0);
}
#keyframes play {
100% { background-position: 100px; }
}
This should do the trick:
.animation {
width: 128px;
height: 128px;
margin: 2% auto;
background: url('http://s16.postimg.org/8f5770kpx/sprite.png');
background-position:0px 0px;
animation-play-state: paused;
animation: play 5s steps(10) infinite;
transorm: translateZ(0);
}
#keyframes play {
from { background-position:0px 0px; }
to { background-position:1280px 0px; }
}
DEMO: http://jsfiddle.net/Hyg3C/4421/
So, from-to are actually 'steps', we move background position in 10 steps. If you remove steps parameter from animation - you can get nice infinite scrolling, btw, but this provides 'gif-like' behavior...