I start a CSS animation using the following JavaScript code (element is a div, name is the name of an existing rule, destination is where the element should move to). The first time this function is called, it works as intended (the div moves softly to its final destination). The second time, it simply jumps to the destination (because I explicitly set left and top), but no movement happens. If I set a breakpoint in the line, where the name assignment happens (webkitAnimationName), the animation is performed as it is the first time. Do I need a delay?
function flyTo(element, name, destination) {
var rule = findKeyframesRule(name);
if (rule != null) {
element.style.webkitAnimationName = "none";
// remove the existing 0% and 100% rules
rule.deleteRule("from");
rule.deleteRule("to");
// create new 0% and 100% rules
rule.insertRule("from {top: " + element.style.top + "; left: " + element.style.left + ";}");
rule.insertRule("to {top: " + px(destination.y) + "; left: " + px(destination.x) + ";}");
// assign the animation to our element (which will cause the animation to run)
element.style.left = px(destination.x);
element.style.top = px(destination.y);
element.style.webkitAnimationDuration = "1s";
element.style.webkitAnimationTimingFunction = "linear";
element.style.webkitAnimationName = name;
} else {
element.style.left = px(destination.x);
element.style.top = px(destination.y);
}
}
I am using Google Chrome
I'm not sure where the mistake in your code is. But i try to give you another (and in my opinion better solution). Example of my code of a sliding menu:
#tag-menu {
top: 0px;
width: 270px;
height: 100%;
left: -370px;
background: #2F535C;
z-index: 9;
box-shadow: 5px 5px 10px 0px rgba(84,84,84,0.25);
position: fixed;
display: block;
transition: left 0.25s ease-out;
-webkit-transition: all 0.2s ease-out;
-moz-transition: all 0.2s ease-out;
-o-transition: all 0.2s ease-out;
-webkit-transform: translateX(-317px);
-moz-transform: translateX(-317px);
-o-transform: translateX(-317px);
-ms-transform: translateX(-317px);
}
#tag-menu.active{
left:0;
-webkit-transform: translateX(0px);
-moz-transform: translateX(0px);
-o-transform: translateX(0px);
-ms-transform: translateX(0px);
transform:translateX(0px);
transition:all 0.2s ease-in;
-webkit-transition: all 0.2s ease-in;
-moz-transition: all 0.2s ease-in;
-o-transition: all 0.2s ease-in;
}
And then u just add and remove the "active" class. The menu will slide. Hope i could help you.
Cheers
Related
I wrote an simple function which implements opacity on a blurred image on mouseover.
Note that parent is smaller than child(image), I need over-flow hidden.
You can see a bug, at the end of transition, the image size changes suddenly!
the problem disappears if I delete transition, (but I want transition)
the problem disappears if I supp blur (but I want blur)
the problem disappears if parent is bigger than child (but I want parent smaller with over-flow hidden)
there is a accumulation of parameter (opacity-transition, blur, overflow hidden on parent) which creates a bug, and I don't know how to fix it.
var my_parent = document.querySelector('.parent');
var my_child = document.querySelector('.child');
my_parent.addEventListener('mouseover', function() {
my_child.style.opacity = '1';
// SAME PROBLEM WITH ANIMATION
// my_child.style.animationName = 'my_animation';
// my_child.style.animationDuration = '1s';
// my_child.style.animationTimingFunction = 'ease-in-out';
// my_child.style.animationIterationCount = 'linear';
// my_child.style.webkitAnimationPlayState = 'running';
// my_child.style.animationFillMode = 'forwards';
});
.parent {
width: 200px;
height: 200px;
overflow: hidden;
}
.child {
width: 250px;
height: 250px;
opacity: 0;
-moz-filter: blur(40px);
-o-filter: blur(40px);
-ms-filter: blur(40px);
filter: blur(40px);
-webkit-transition: opacity 0.5s ease-out;
-moz-transition: opacity 0.5s ease-out;
-o-transition: opacity 0.5s ease-out;
transition: opacity 0.5s ease-out;
}
#-webkit-keyframes my_animation {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}
#keyframes my_animation {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}
<div class="parent">
<img class="child" src="https://cdn.pixabay.com/photo/2015/04/23/22/00/tree-736885__480.jpg">
</div>
I'm working on a project that is using Intersection Observer to add animation to an element's style upon entry. However, what I'm noticing is that the : hover attribute no longer works when I apply the style. Am I doing this wrong, or, are these two not compatible? On the JS Fiddle, I've commented out the hover attribute by default. Try uncommenting it and see what happens.
I've tried banner.classList.add(/new class in here/) but that method also took away the :hover as well.
DEMO:
Demo
disable animation on hover because animations has a higher specificity
const options = {
root: null,
threshold: 1,
};
const banner = document.querySelector('.product-banner');
const observerAnim = new IntersectionObserver(function(entries, observer) {
entries.forEach(entry => {
if (!entry.isIntersecting) {
return;
}
banner.style.animation = '1s ease-in-out home-page-fade';
banner.style.animationFillMode = 'forwards';
observer.unobserve(banner);
});
}, options);
observerAnim.observe(banner);
body {
background-color: #fff;
min-height: 2000px;
}
img.product-banner {
opacity:0;
position: relative;
top: 1000px;
-moz-transition: all ease 0.3s;
-webkit-transition: all ease 0.3s;
transition: all ease 0.3s;
}
#keyframes home-page-fade {
0% {
transform: translateY(50%);
opacity: 0;
}
100% {
transform: translateY(0);
opacity: 1;
}
}
img.product-banner:hover {
animation: none !important;
opacity: 0.8;
transform: scale(0.9);
-moz-transition: all ease 0.3s;
-webkit-transition: all ease 0.3s;
transition: all ease 0.3s;
}
<h1>
Scroll Effect
</h1>
<img class="product-banner" src="https://cdn.mos.cms.futurecdn.net/bQgcMwEnyhFu6ASuUFrtsn-1024-80.jpg" width="300">
When i change the className with js, it should TRANSITION in my mind.. But.. the code below didn't work
let canvas = document.getElementById("canvas");
let types = 'center'
canvas.addEventListener('click', function (e) {
let target = this
target.style.position = 'relative'
target.style.overflow = 'hidden'
let ripple = target.querySelector('.ripple')
/* 无ripple 说明第一次点击 */
if (!ripple) {
ripple = document.createElement('span')
ripple.className = 'ripple'
ripple.style.height = ripple.style.width = `120px`
target.appendChild(ripple)
} else {
ripple.className = 'ripple'
}
//ripple.style.top = e.pageY + 'px';
// ripple.style.left = e.pageX + 'px'
// console.log(e.pageY);
//console.log(e.pageX);
switch (types) {
case 'center':
ripple.style.top = `${ripple.offsetHeight / 2}px`
ripple.style.left = `${ripple.offsetWidth / 2}px`
break
default:
ripple.style.top = `${ripple.offsetHeight / 2}px`
ripple.style.left = `${ripple.offsetWidth / 2}px`
}
ripple.style.backgroundColor = '#999'
ripple.className = 'ripple active'
})
.ripple {
position: absolute;
border-radius: 100%;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
-webkit-transform: scale(0);
-ms-transform: scale(0);
transform: scale(0);
}
.ripple.active {
-webkit-transition: opacity 1.2s ease-out, -webkit-transform 0.6s ease-out;
transition: opacity 1.2s ease-out, -webkit-transform 0.6s ease-out;
transition: opacity 1.2s ease-out, transform 0.6s ease-out;
transition: opacity 1.2s ease-out, transform 0.6s ease-out, -webkit-transform 0.6s ease-out;
-webkit-transform: scale(2);
-ms-transform: scale(2);
transform: scale(2);}
<div id="canvas" style="width: 100%;height: 1024px">
canvas
</div>
As you can see the code above, if i change the className and using the
ripple.style.top = e.pageY + 'px';
ripple.style.left = e.pageX + 'px'
It cant emit the transition..However if using the switch code, which is the same as the code above i think, it worked!
It's so confusing, can anybody help me?
As I run your code with ripple.style.left = e.pageX + 'px' I saw that without use console.log() it does not work so as I understood you have to give the program few milliseconds to "rest" and set the new position to solve that I use setTimeout with 0 time then I set the new className
More information:
quara
stack overflow
setTimeout(function(){
ripple.style.backgroundColor = '#999999';
ripple.className = 'ripple active'
},0);
See working code:
let canvas = document.getElementById("canvas");
let types = 'center'
canvas.addEventListener('click', function (e) {
let target = this
target.style.position = 'relative'
target.style.overflow = 'hidden'
let ripple = target.querySelector('.ripple')
/* 无ripple 说明第一次点击 */
if (!ripple) {
ripple = document.createElement('span')
ripple.className = 'ripple'
ripple.style.height = ripple.style.width = `120px`
target.appendChild(ripple)
} else {
ripple.className = 'ripple'
}
ripple.style.top = e.pageY + 'px';
ripple.style.left = e.pageX + 'px';
setTimeout(function(){
ripple.style.backgroundColor = '#999999';
ripple.className = 'ripple active'
},0);
})
.ripple {
position: absolute;
border-radius: 100%;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
-webkit-transform: scale(0);
-ms-transform: scale(0);
transform: scale(0);
}
.ripple.active {
-webkit-transition: opacity 1.2s ease-out, -webkit-transform 0.6s ease-out;
transition: opacity 1.2s ease-out, -webkit-transform 0.6s ease-out;
transition: opacity 1.2s ease-out, transform 0.6s ease-out;
transition: opacity 1.2s ease-out, transform 0.6s ease-out, -webkit-transform 0.6s ease-out;
-webkit-transform: scale(2);
-ms-transform: scale(2);
transform: scale(2);
}
<div id="canvas" style="width: 100%;height: 1024px">
canvs
</div>
Is a CSS3 transition like described below feasible?
Given a modal overlay, on close, instead of just fading out, I would like to have it scale in size from 100% to 0% towards a specific button on the page.
Has anyone seen this done with CSS3? Possible?
Thanks
If you know the position of the button you're trying to shrink the overlay toward, you can animate the top, bottom, left, and right of the overlay to the top, bottom, left, and right of the button, respectively. If it varies, you might need some kind of JavaScript hook to determine the position of the button, like using jQuery's .offset.
Is this what you want?http://jsfiddle.net/AZWhQ/1/
.myOverlay{
width:100%;
height:100%;
-webkit-transition: -webkit-transform .5s ease-out;
-moz-transition: -moz-transform .5s ease-out;
-ms-transition: -ms-transform .5s ease-out;
-o-transition: -o-transform .5s ease-out;
transition: transform .5s ease-out;
background-color: rgba(0,0,0,.2);
}
.myOverlayClose{
-webkit-transform: scale(0.0);
-moz-transform: scale(0.0);
-ms-transform: scale(0.0);
-o-transform: scale(0.0);
transform: scale(0.0);
}
check the Demo
It is possible - here is a very simplistic version of it done by setting the transform-origin:
Fiddle
Code:
document.getElementById('dismiss').addEventListener('click', function() {
var button = document.getElementById('mybutton');
var overlay = document.getElementById('overlay');
overlay.style['-webkit-transform-origin'] = (button.offsetLeft + button.offsetWidth/2) + 'px ' +
(button.offsetTop + button.offsetHeight/2) + 'px';
overlay.style['-webkit-transform'] = 'scale(0)';
overlay.addEventListener('webkitTransitionEnd', function() {
overlay.className = 'hide';
});
});
The most difficult part of doing this would be to get the buttons position relative to the overlay. Then use that to set the transform-origin which will act as the vanishing point.
I wish to create an animation where upon every click of a button, an object moves a certain amount to its right.
e.g If the initial position of the object was say "left:10px" and every 1 loop of animation moves it by say 10px, then after first click it should be at 20px, after second click it should be at 30px and so on.
Here's my code right now:
JavaScript
document.getElementById( 'move-me' ).addEventListener( 'click', function () {
var move = document.getElementById( 'move' );
move.style.left = ( move.offsetLeft + 10 ) + 'px';
}, false );
HTML
<button id="move-me">Move</button>
<div id="move"></div>
CSS
#move {
background: green;
height: 50px;
left: 0px;
position: absolute;
top: 100px;
transition: left 250ms ease-in-out;
-moz-transition: left 250ms ease-in-out;
-ms-transition: left 250ms ease-in-out;
-o-transition: left 250ms ease-in-out;
-webkit-transition: left 250ms ease-in-out;
width: 50px;
}
This code uses CSS3 transitions but it doesn't make use of the -webkit-transform hardware acceleration on my android device. How do I fix that?
The choice is not between -webkit-transform and -webkit-transition, it's between left and -webkit-transform.
Here is how to make use of 3d acceleration:
#move {
background: green;
height: 50px;
left: 0px;
position: absolute;
top: 100px;
-moz-transition: -moz-transform 250ms ease-in-out;
-ms-transition: -ms-transform 250ms ease-in-out;
-o-transition: -o-transform 250ms ease-in-out;
-webkit-transition: -webkit-transform 250ms ease-in-out;
transition: transform 250ms ease-in-out;
width: 50px;
}
Javascript:
document.getElementById( 'move' ).addEventListener( 'click', function() {
var move = document.getElementById( 'move' );
var transform = "translate3d("+ (move.offsetLeft+200) + "px, 0, 0)";
move.style.webkitTransform = transform;
move.style.mozTransform = transform;
move.style.msTransform = transform;
move.style.oTransform = transform;
move.style.transform = transform;
}, false );
http://jsfiddle.net/CjQ8H/
You can also use translateX. This defintely hardware accelerates.
targetDiv.style.webkitTransition = "0ms"
targetDiv.style.webkitTransform = "translateX(100%)
This would move a div to the right by 100% but nice and smooth only in hardware accelerated devices.