How to custom transition for each component? - css

I have 3 components which I want to show a transition effect when they enter/leave.
There's 1 "main" component and the 2 others show up when you press the associated button. My current sample code is here: https://jsfiddle.net/5aq1k05L/
<transition :name="'step_' + currentView" mode="out-in">
<component :is="currentView"></component>
</transition>
CSS:
.step_componentA-enter-active {
transition: transform 0.4s;
}
.step_componentA-leave-active {
transition: transform 0s;
}
.step_componentA-enter {
transform: translateX(-100%);
}
.step_mainComponent-leave-active {
transition: transform 0.3s;
}
.step_mainComponent-leave-to {
transform: translateX(-100%);
}
.step_componentB-enter-active {
transition: transform 0.4s;
}
.step_componentB-leave-active {
transition: transform 0s;
}
.step_componentB-enter {
transform: translateX(100%);
}
What I am trying to do:
When I click on the "componentA" button, I want that component to slide from the left while "mainComponent" is still visible in the background (not stripped out of elements like now) during the transition.
Same thing for "componentB", except it will slide from the right, and will back to the right when clicking back.
What am I missing? https://jsfiddle.net/5aq1k05L/

Edit 2:
Here a working example with the componentA and componentB that are sliding over the mainComponent -> https://jsfiddle.net/5aq1k05L/8/
I changed the transition to mode:in-out, I added a z-index for each component, and put the components in position:absolute and the app in position:relative
Edit:
Here a working example for your case -> https://jsfiddle.net/5aq1k05L/4/
When you analyse the script step by step, you see that the class when the componentB is leaving is step_mainComponent-leave-active step_mainComponent-leave-to that it makes a classic toggle relative to the mainComponent style.
If you want to use different animations, you should use enter-active-class and leave-active-class etc (see more here) - or put two vars in name, i guess, with a dynamic value relative to the previous view, in the store like currentView is.
It could be like this :
<transition
:name="'step_' + currentView + '_from_' + prevView"
mode="out-in"
>
In the store (you ll need to update the states, mapState, etc.. as well too) :
SET_CURRENT_VIEW(state, new_currentView) {
state.prevView = state.currentView;
state.currentView = new_currentView;
}
Hope it ll help you

Related

vue v-bind style - smooth changes, not instantly

I use "vuex-module-decorators" and dynamically determine the style in this getter:
<div class="viewport":style="viewportStyleVars">...</div>
get viewportStyleVars() {
const tx = -this.viewportRect.x;
const ty = -this.viewportRect.y;
return {
'--translate-x': `${tx}px`,
'--translate-y': `${ty}px`,
}
}
How to make change happen smoothly, not instantly?
I would be grateful for the hints, I am not familiar with the animation.
You just need to add transition in CSS to the div with class .viewport something like:
.viewport{
transition: all 1s linear;
}
The 1s in the transition, is the time, that the action will take, you can tweak this value to something smaller, like 0.1s, if that suits you better.

ReactCSSTransitionGroup troubles - trying to get smooth slide in/out animation

I'm writing a questionnaire system in react and want to get the questions smoothly transitioning in and out.
Here's the render method for my component that displays the questions within.
render () {
const { loadingQuestion, question, userId, actions } = this.props;
const q = this.renderQuestion(question, (...args) => actions.answerQuestion(userId, ...args), (...args) => actions.skipQuestion(userId, ...args));
return (
<ul className="questions">
<ReactCSSTransitionGroup
transitionName="question"
transitionEnterTimeout={1000}
transitionLeaveTimeout={1000}
>
{q}
</ReactCSSTransitionGroup>
</ul>
);
}
And also the css I'm using at the moment to achieve the vertical transition:
.question-enter {
transform: translateY(100%);
}
.question-enter.question-enter-active {
transform: translateY(0%);
transition: transform 1000ms ease-in-out;
}
.question-leave {
transform: translateY(0%);
}
.question-leave.question-leave-active {
transform: translateY(-100%);
transition: transform 1000ms ease-in-out;
}
Here's a link to a page showing the current behaviour:
http://price-it.co:8080/frame
Does anyone know why this css doesn't cause the question to slide out and instead just causes it to disappear?
Thanks!
Your example is not working in my browser (I got app.js:12Redux DevTools could not render. Did you forget to include DevTools.instrument() in your store enhancer chain before using createStore()? error).
But I could say I have the same kind of experience with CSSTransitionGroup, so I decided to use <TransitionGroup> with Velocity instead - sure it's a little bit more jQuery-style, but it obviosely works better then css animation.

Animating div content populated by AngularJS without jQuery

I have a div like this:
<div class="row">
<alert ng-repeat="alert in alerts" type="alert.type" close="closeAlert($index)">{{alert.msg}}</alert>
</div>
I create the alerts in angularjs (and I'm using bootstrap), and while this works great, the visual effect is kind of uncool. As alerts are added to the div, all page content is shoved ungracefully down to make room for the new alert.
I would like to animate the movement so that it is at least smooth. But I don't want to use jQuery. I've played with the CSS3 transitions, but can't seem to get them to work smoothly.
Can I do this where the trigger is a change in div height? How?
you can do it with directives in their link function. i think you wont mind about so small piece on jquery code
myModule.directive('animateRight', function () {
var linker = function (scope, element, attrs) {
var right = function() {
$(this).animate({
{"height": "800px"},
"fast");
})
}
element.on('click', right);
};
return {
restrict:'A',
link:linker
}
})
<div animate-right class="box"></div>
Ok, so I don't like to answer my own question, but this seems like the way to do it...
I used AngularJS 1.2, along with the new ngAnimate module. You need to add angular-animate.js, and reference the animate module, so at the end here's what my modules looked like:
var app = angular.module('tracker', ['$strap.directives', 'ui.bootstrap', 'ngRoute', 'ngAnimate']);
After that, its super simple, and very much CSS3 animations. My alert line ended up with a class repeat-item:
<alert class="repeat-item" type="alert.type" data-ng-repeat="alert in alerts" close="closeAlert($index)">{{alert.msg}}</alert>
And I added some CSS to target that class with the angularjs triggers:
.repeat-item.ng-enter,
.repeat-item.ng-leave {
-webkit-transition: 0.2s linear all;
-moz-transition: 0.2s linear all;
-o-transition: 0.2s linear all;
transition: 0.2s linear all;
}
.repeat-item.ng-enter,
.repeat-item.ng-leave.ng-leave-active {
opacity: 0;
}
.repeat-item.ng-leave,
.repeat-item.ng-enter.ng-enter-active {
opacity: 1;
}
And voila a nice fade in and out animation.
This page really explains very well how to do it. Cheers to Michael Benford for the great link.

Stack CSS Transitions using multiple classes without overriding

I want to use multiple classes to optionally add transitions. Instead of stacking, the previous is getting overridden.
.container { transition: margin .2s; }
.container.t-padding { transition: padding .2s; }
The problem: Property is overridden rather than stacking
http://jsfiddle.net/yz2J8/2/ (The problem)
My temporary solution: Add the previous transition to the rule
.container { transition: margin .2s; }
.container.t-padding { transition: padding .2s, margin .2s; }
http://jsfiddle.net/ZfQcp/6/ (My temporary solution)
What's a better solution??
How can I avoid having to create tons of rules to combine these?
JavaScript could be a cleaner solution as you only need to have 1 CSS rule (the original rule).
If you know the position of you're rule you can do the following.
//First Save The Original Rule
var originalRule = document.styleSheets[0].cssRules[3].cssText;
//Save also the original Hover Rule
var originalHover = document.styleSheets[0].cssRules[4].cssText;
Now originalRule will contain this:
.container{
...
transition: margin .2s;
...
}
And originalHover will contain this:
.container:hover{
...
margin: 10px 0;
...
}
to simply add another transition effect, you can do the following.
document.styleSheets[0].cssRules[3].style.transitionProperty += ",background-color";
document.styleSheets[0].cssRules[4].style.transitionDuration += ",1s";
At this stage, both transitions will take effect.
If you want to only have the original transition, you can either add it manually or simply...
//Delete the Rule
document.styleSheets[0].deleteRule(3);
//Add the Original Rule Back Again
document.styleSheets[0].insertRule(originalRule,3);
If you do so, only the original transition (margin) will take effect, don't forget to also replace the originalHover rule to remove any other effects on hover.
Note:
For Chrome
document.styleSheets[0].cssRules[3].style.webkitTransitionProperty
For Firefox
document.styleSheets[0].cssRules[3].style.mozTransitionProperty
For IE
insertRule and deleteRule do not work, there's these ones instead:
addRule , removeRule
LIVE DEMO FOR CHROME AND FIREFOX

Meteor transition effects for auto-updating content

Looking at the meteor leaderboard example, I understand how content in the view templates is bound to functions in the javascript application file. For example, consider this snippet from the view file which defines the "selected" class to determine which name is highlighted yellow:
<template name="player">
<div class="player {{selected}}">
<span class="name">{{name}}</span>
<span class="score">{{score}}</span>
</div>
</template>
The value of {{selected}} is defined and kept up to date in this function from leaderboard.js:
Template.player.selected = function () {
return Session.equals("selected_player", this._id) ? "selected" : '';
};
My question is: How would you add transition effects to this auto updating process? For example, say we wanted the yellow highlighting to fade to white on the existing name, and then fade into yellow on the new name, whenever a new name was clicked. How could we accomplish that in meteor?
The easiest way would be using CSS transitions. Just ensure that the element is preserved (so it isn't replaced on re-draw, just patched):
Template.player.preserve(['.player']);
Then go nuts with the CSS transitions:
.player {
background-color: white;
transition: background-color 500ms linear 0;
-moz-transition: background-color 500ms linear 0;
// etc
}
.player.selected {
background-color: yellow;
}

Resources