Comments (18)
I wondered how long it'd be before someone noticed that!
The bottom element should always be 100% opacity, only the top element should change.
I was going to say that that would only solve cases where both elements had 100% opacity in their resting state, but then I realised that ramjet isn't respecting opacity anyway, so I just added a separate issue for that (#11). May have to have one rule for the both-100% situation, and another for everything else. Hmm.
from ramjet.
You could wrap both elements in another element and set the opacity on that
For example:
element 1 has 50% opacity
element 2 has 75% opacity
To transition them:
transition element 1 from 100% to 0%
keep element 2 at 100% opacity
transition the wrapper from 50% to 75%
It would fix both bugs.
from ramjet.
That's totally brilliant! Thanks, I think that should do the trick.
from ramjet.
I'm literally giggling of excitement and my coworkers are looking at me funny.
from ramjet.
Ah, I just realised where this gets tricky. If you transform a
to b
, and they're in different parts of the DOM, for them to be in the same wrapper element at least one of them has to move (right now, the clones are siblings of the originals). That would mean any cumulative opacity or transforms from their parent elements would have to be taken account of. Might get messy... will have to look into it
from ramjet.
I know it's really hacky, but how about something like this?
http://html2canvas.hertzen.com
from ramjet.
You could put the styles of the cloned elements in their style attributes.
Code example:
var flattenStyles = function(foo){
var bla=window.getComputedStyle(foo);
Object.getOwnPropertyNames(window.getComputedStyle(foo))
.filter(function(a){return isNaN(parseFloat(a))})
.forEach(function(a){foo.style[a]=bla[a]});
}
Run something similar on every element of the clone, and then you can place the element anywhere and the styles will work.
from ramjet.
That's actually what already happens - it's the nuclear option, but I found it necessary (though I can't remember why exactly - this was when I first started hacking on this idea several months ago!)
I was thinking about this over the weekend. Appending both cloned elements to a single parent, which is then appended to <body>
, should work, if we calculate the cumulative opacity and transform matrix. (That's basically what already happens with SVG elements, albeit imperfectly, but it's easier there because SVG elements have a node.getScreenCTM()
method that returns the current screen-space transform matrix - it's tricker for HTML elements.)
What you lose is
- z-index (because there's no global stacking order you can inspect and modify - the rules for the application of z-index are pretty wild, IIRC)
- clipping, e.g. if part of an element is outside a parent with
overflow: hidden
- possibly some other stuff we haven't thought of?
My hunch is that the trade-off is worth it, if it means better visual fidelity in all cases at the expense of some glitchiness in a small, contrived minority.
from ramjet.
This stuff is way more complicated than I would have expected, I'm happy you are making this library so I don't have to :D
You are doing a great service to mankind.
from ramjet.
I'm pretty sure theres a solvable formula for the opacity of the bottom and top layers at a given time T such that the bottom layer is 50% visible at T=.5 and the top layer is 50% visible. This should work even if you're transitioning from opacity levels != 1. I was working on it a little bit and I'm pretty sure I'm on track for a solution. This formula would also solve bug #11 .
from ramjet.
@DDKnoll have a look at #27 - it solves (or rather, will solve) both this and #11. As far as I can see it's the only way - any combination of opacities that are less than one will also be less than one (e.g. bottom layer = 0.9 + top layer = 0.9 = (1 - ((1 - 0.9) * (1 - 0.9))) = (1 - (0.1 * 0.1)) = 0.99, so the bottom layer has to stay at 100% opaque.
from ramjet.
I'm pretty positive the bottom layer doesn't have to be 100% opaque, and thats what I'm trying to nail down. Say you are transition between .5 opacity on the first element and 1 opacity on the second element. Then at the halfway point of the animation, where time T = .5 then you should be able to calculate two opacity values such that their combined opacity =.75 and the bottom one is still 50% visible. So at that time the bottom element might have opacity .6 and the top layer has opacity .3 which would get you close to .75 opacity (I'm still working on the calculation, need to figure out the compositing formula).
Does that make sense? If this works then you shouldn't have to lose the SVG support.
from ramjet.
Afraid I don't quite follow - as far as I can see, if both layers are less than 100% opaque then they'll be less than 100% opaque in combination, and you'll be able to see stuff underneath, which is exactly what we're trying to avoid. Unless I've misunderstood you?
SVG will still work, it's just a matter of rejigging a few things (right now they get shoved in the same <div>
as HTML elements, so they fail to render - they just need to be wrapped in an <svg>
and have the appropriate transforms applied)
from ramjet.
Right, so the problem is rather easy when you're transitioning from opacity 1 to 1. Then you just make the bottom layer 100% and transition the top layer. But it gets much harder when you're transitioning from one partially opaque element to another. In this case you can't just make the bottom layer 100% because it needs to know how to transition evenly between the two values.
I think theres a formula that can solve this perfectly. So in your getKeyframes function, it would have a much smarter opacity value than just using (t) and (1-t). It would handle cases where elements have different opacity levels and transition them smoothly.
from ramjet.
For most cases we can get the right effect by controlling the container element's opacity - by transitioning that from the first element's opacity to the second element's opacity, and having the first element stay at 100% while the second element goes from 100% to 0%, you get the right effect:
That breaks down when the second element has a background that isn't opaque (e.g. rgba colour or image with alpha channel). I was planning to work around that with a crossfade
option that falls back to the current behaviour, to replace any jarring glitches with 'wrong, but in a way that most people won't notice' - if there's an easing formula that gets us closer to the intended effect then I'm definitely all ears!
from ramjet.
Hmm... well I have a formula that works by transitioning the opacity of the child elements. It has the added benefit of also being able to animate the alpha channel of rgba backgroundColors. I don't think there is anything that can be done for transitioning something like an image (png) with a transparent background, but that is a whole different bucket of crabs. I think in that case you just fallback to using the crossfade
option.
It also can work without creating a new container for the new elements. Do you think there is a benefit of creating the new container? I'm not sure if its a good thing or a bad thing... definitely has different behaviour when parent elements have filters, clip paths, overflow:hidden, etc.
Either way... I'll push a branch once I have these changes finished tonight and you can see which you prefer.
from ramjet.
Alright, I pushed the code for animating both rgba backgrounds and opacities so that they blend when they composite. I haven't tested yet on IE, but was able to do Safari, Firefox, Chrome, Chrome for Android, and mobile Safari.
This branch is still duplicating into the new container, but it works without that. You can decide if thats the method you want to use or not. Heres the link to the pull request... #28
from ramjet.
This branch is still duplicating into the new container, but it works without that
That's great, I was prepared to sacrifice things like filters and stacking order (which would affect a few cases) for the sake of more accurate total opacity (which affects all cases), but now it looks like there's no need. Still, it was a worthwhile diversion - I think I now know how to do SVG transitions with CSS animations as a result.
from ramjet.
Related Issues (20)
- done function - shouldn't it pass a,b as arguments? HOT 2
- Artifacts in Firefor for Android HOT 4
- Morph border radius HOT 3
- ui-view / angular-ui-router HOT 3
- Support Jquery Selectors HOT 2
- Rotate HOT 5
- Transition problem in Chrome browser HOT 4
- Web Animations API HOT 1
- Docs need improvement [suggestion] HOT 1
- Position:relative and/or margins mess up the position HOT 3
- scrollTop is not cloned HOT 1
- Uncaught TypeError: e.getBoundingClientRect is not a function HOT 6
- iPhone glitch: "toNode" disappears for about 0.5 seconds
- Two steps transition ?
- ramjet.transform between 2 CSS rules? HOT 1
- Ignore certain CSS properties? HOT 2
- ramjet homepage demo partially broken on Chrome + macOS HOT 2
- Images gets transparent on transition start HOT 1
- Percentage-based Border Radii
- Current project status HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from ramjet.