CSS display one li at a time - css

I am using Angular2. I have a list
<ul>
<li *ngFor="let show of (ann)">
{{show}}
</li>
</ul>
I would like to display one li at a time in every 3 second. Moreover, it will be infinite loop.
Here is my array:
ann: Array<any> = [
{
name: "ABC"
},
{
name: "DEF"
},
{
name: "ZZZ"
}
];
First 3 second: display ABC
next 3 second: display DEF and ABC will be disappeared
next 3 second: display ZZZ and DEF will be disappeared
next 3 second: display ABC since it is end of the array. It will be
infinite loop.
How can I do with CSS?

We could achieve with animations in angular 2
Check preview https://plnkr.co/edit/fNZLspjrendI5SdK5gBC?p=preview
app.component.ts
#Component({
selector: 'my-app',
animations: [
trigger('displayName', [
state('in', style({ opacity: 1, transform: 'translateY(0)' })),
state('out', style({ opacity: 0, display: "none", transform: 'translateY(100%)' })),
transition('in => out', [
style({ transform: 'translateY(0)', opacity: 1 }),
animate('0.3s', style({ transform: 'translateY(100%)', opacity: 0 }))
]),
transition('out => in', [
style({ transform: 'translateY(100%)', opacity: 0 }),
animate('0.3s 200ms', style({ transform: 'translateY(0)', opacity: 1 }))
])
])
]
})
export class App {
name:string;
currentIndex: number;
students: [] = [
{
name: "Alan",
animationState: 'in'
},
{
name: "Jake",
animationState: 'out'
},
{
name: "Harry",
animationState: 'out'
},
{
name: "Susan",
animationState: 'out'
},
{
name: "Sarah",
animationState: 'out'
},
{
name: "Esther",
animationState: 'out'
}
];
constructor() {
this.name = 'Angular2';
this.currentIndex = 0;
}
ngOnInit() {
setInterval((function(){
console.log(this.currentIndex);
this.students[this.currentIndex].animationState = 'out';
this.currentIndex++;
if(this.currentIndex >= this.students.length) {
this.currentIndex = 0;
}
this.students[this.currentIndex].animationState = 'in';
}).bind(this), 3000);
}
}
html
<div>
<h2>Hello {{name}}</h2>
</div>
<div *ngFor="let student of students" [#displayName]="student.animationState">
{{student.name}}
</div>

You can use Rxjs to acheive this
in template
<div>
<h2>Hello {{name}}</h2>
</div>
<div *ngFor="let student of $students | async">
{{student.name}}
</div>
and in component
students: Array<any> = [
{
name: "Alan"
},
{
name: "Jake"
},
{
name: "Harry"
},
{
name: "Susan"
},
{
name: "Sarah"
},
{
name: "Esther"
}
];
constructor() {
this.name = 'Angular2'
var timer = 0;
this.$students = Observable.from([[], ...this.students])
.mergeMap(x => Observable.timer(timer++ * 1000).map(y => x))
.scan((acc, curr, seed) => {
acc.push(curr);
return acc;
});
}
https://plnkr.co/edit/MgJkFskZRp39FubSUbmH?p=preview

If I'm understanding you better, you're looking for something more like this:
li {
opacity: 0;
animation: display 10s infinite;
}
li:nth-child(1) {
animation-delay: 1s;
}
li:nth-child(2) {
animation-delay: 3s;
}
li:nth-child(3) {
animation-delay: 5s;
}
li:nth-child(4) {
animation-delay: 7s;
}
li:nth-child(5) {
animation-delay: 9s;
}
#keyframes display {
0% { opacity: 1 }
20% { opacity: 0 }
}
<ul class="num-1">
<li>Jake</li>
<li>Esther</li>
<li>John</li>
<li>Ann</li>
<li>Someone</li>
</ul>
Or this:
li {
opacity: 0;
animation: display 10s infinite;
}
li:nth-child(1) {
animation-delay: 1s;
}
li:nth-child(2) {
animation-delay: 3s;
}
li:nth-child(3) {
animation-delay: 5s;
}
li:nth-child(4) {
animation-delay: 7s;
}
li:nth-child(5) {
animation-delay: 9s;
}
#keyframes display {
20% { opacity: 1 }
30% { opacity: 0 }
}
<ul class="num-1">
<li>Jake</li>
<li>Esther</li>
<li>John</li>
<li>Ann</li>
<li>Someone</li>
</ul>

Related

vuetify: how to make v-data-table row blink when item values are updated

I would like to create a table that when items is updated, the row blink once.
i managed to make a row blink when the component starts, but it does not blink when value is updated.
i created an example with two css class (only for test), one that blinks once and another that blinks infinite.
if we update items values, we can see that the infinite still blinks and change rows as the condition is filled, but the items that should blink once, didn't change.
any help will be appreciated.
Vue.config.productionTip = false;
Vue.config.devtools = false;
new Vue({
el: '#app',
vuetify: new Vuetify(),
data() {
return {
items: [{
id: 1,
name: 'Frozen Yogurt',
calories: 159,
},
{
id: 2,
name: 'Ice cream sandwich',
calories: 237,
},
{
id: 3,
name: 'Eclair',
calories: 262,
},
{
id: 4,
name: 'Cupcake',
calories: 305,
},
],
headers: [{
text: 'Dessert',
value: 'name',
},
{
text: 'Calories',
value: 'calories'
},
],
};
},
methods: {
blink(item) {
if (item.calories > 200){
return 'blink-great';
} else {
return 'blink-less';
}
},
getRandomInt(min, max) {
min = Math.ceil(min);
max = Math.floor(max);
return Math.floor(Math.random() * (max - min)) + min;
},
updateValues() {
const newValues = this.items.map((el) => {
return {...el, calories: this.getRandomInt(100,500)};
})
this.items = newValues
}
},
computed: {
displayItems() {
var newItems = this.items.map((el) => {
return {...el, calories: el.calories * 1};
})
return newItems
}
},
});
.blink-less {
animation: blinking ease-out 1s 3;
--background-color: #FF0000
}
.blink-great {
animation: blinking ease-out 1s infinite;
--background-color: #0000FF
}
#keyframes blinking {
0% {
background-color: var(--background-color);
}
100% {
background-color: #fff;
}
}
<link href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/#mdi/font#4.x/css/materialdesignicons.min.css" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/vuetify#2.x/dist/vuetify.min.css" rel="stylesheet">
<script src="https://cdn.jsdelivr.net/npm/vue#2.x/dist/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vuetify#2.x/dist/vuetify.js"></script>
<div id="app">
<v-app>
<v-container>
<v-row class="pa-5">
<v-btn
#click="updateValues()"
> Update value </v-btn>
</v-row>
<v-row class="px-5">
<v-data-table
hide-default-footer
:headers="headers"
:items="displayItems"
:item-class="blink"
/>
</v-row>
</v-container>
</v-app>
</div>
I created a flag and added new css classes.. it works but has poor code. If i found a better and clean solution i post it here
Vue.config.productionTip = false;
Vue.config.devtools = false;
new Vue({
el: '#app',
vuetify: new Vuetify(),
data() {
return {
controlAnimation: false,
items: [{
id: 1,
name: 'Frozen Yogurt',
calories: 159,
},
{
id: 2,
name: 'Ice cream sandwich',
calories: 237,
},
{
id: 3,
name: 'Eclair',
calories: 262,
},
{
id: 4,
name: 'Cupcake',
calories: 305,
},
],
headers: [{
text: 'Dessert',
value: 'name',
},
{
text: 'Calories',
value: 'calories'
},
],
};
},
methods: {
blink(item) {
if (this.controlAnimation) {
let itemClassTrue = 'blink-even-true'
/* check item.value, based on condition...
itemClassTrue = 'blink-less-true'
itemClassTrue = 'blink-even-true'
itemClassTrue = 'blink-great-true'
*/
return itemClassTrue;
} else {
let itemClassFalse = 'blink-great-false'
/* check item.value, based on condition...
itemClassTrue = 'blink-less-false'
itemClassTrue = 'blink-even-false'
itemClassTrue = 'blink-great-false'
*/
return itemClassFalse;
}
},
getRandomInt(min, max) {
min = Math.ceil(min);
max = Math.floor(max);
return Math.floor(Math.random() * (max - min)) + min;
},
updateValues() {
const newValues = this.items.map((el) => {
return {...el, calories: this.getRandomInt(100,500)};
})
this.items = newValues
}
},
computed: {
displayItems() {
this.controlAnimation = !this.controlAnimation
var newItems = this.items.map((el) => {
return {...el, calories: el.calories * 1};
})
return newItems
}
},
});
.blink-less-true {
animation: blinking-less-true 1s 2 !important;
--background-color: rgb(196, 76, 76) !important;
}
.blink-even-true {
animation: blinking-even-true 1s 2 !important;
--background-color: #fa0 !important;
}
.blink-great-true {
animation: blinking-great-true 1s 2 !important;
--background-color: rgb(3, 163, 70) !important;
}
.blink-less-false {
animation: blinking-less-false 1s 2 !important;
--background-color: rgb(196, 76, 76) !important;
}
.blink-even-false {
animation: blinking-even-false 1s 2 !important;
--background-color: #fa0 !important;
}
.blink-great-false {
animation: blinking-great-false 1s 2 !important;
--background-color: rgb(3, 163, 70) !important;
}
#keyframes blinking-less-false {
0% { background-color: var(--background-color); }
100% { background-color: #fff; }
}
#keyframes blinking-even-false {
0% { background-color: var(--background-color); }
100% { background-color: #fff; }
}
#keyframes blinking-great-false {
0% { background-color: var(--background-color); }
100% { background-color: #fff; }
}
#keyframes blinking-less-true {
0% { background-color: var(--background-color); }
100% { background-color: #fff; }
}
#keyframes blinking-even-true {
0% { background-color: var(--background-color); }
100% { background-color: #fff; }
}
#keyframes blinking-less-true {
0% { background-color: var(--background-color); }
100% { background-color: #fff; }
}
<link href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/#mdi/font#4.x/css/materialdesignicons.min.css" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/vuetify#2.x/dist/vuetify.min.css" rel="stylesheet">
<script src="https://cdn.jsdelivr.net/npm/vue#2.x/dist/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vuetify#2.x/dist/vuetify.js"></script>
<div id="app">
<v-app>
<v-container>
<v-row class="pa-5">
<v-btn
#click="updateValues()"
> Update value </v-btn>
</v-row>
<v-row class="px-5">
<v-data-table
hide-default-footer
:headers="headers"
:items="displayItems"
:item-class="blink"
/>
</v-row>
</v-container>
</v-app>
</div>
You're not far off with item-class. It can take a string, which tells it to look for a prop on the item's object. With this, as you're updating the data, you can just add/remove the blink class to a prop you create on the fly.
In this case, I'm just going to name the prop dynamicClass
something like this:
template:
<v-data-table
hide-default-footer
:headers="headers"
:items="items"
:item-class="dynamicClass"
/>
script:
methods: {
updateRandom() {
const randomIdx = this.generateRandomNumber(0, this.items.length - 1);
const randomNumber = this.generateRandomNumber(1, 1200);
let item = { ...this.items[randomIdx] };
item.calories = randomNumber;
item.dynamicClass = "blink-less";
this.$set(this.items, randomIdx, item);
setTimeout(() => {
delete item.dynamicClass;
this.$set(this.items, randomIdx, item);
}, 2000);
},
generateRandomNumber(min, max) {
return Math.floor(Math.random() * (max - min + 1) + min);
},
},
The idea here is that we are adding & removing the class from the item/object in the array. doing it with this.$set() guarantees reactivity. But you could also use Array.splice() but either way, you want to replace the data object at that index to maintain reactivity.
Here is a working example in a codesandbox

Not able to use multiple animations - TailwindCSS

Currently am creating my first website.
I have added two custom animations within my tailwind.config.css, but only am able to use one of them.
content: [
"./src/**/*.{js,jsx,ts,tsx}",
],
theme: {
extend: {
animation: {
wiggle: 'wiggle 1s ease-in-out infinite',
},
animation: {
text: 'text 5s ease infinite',
},
keyframes: {
wiggle: {
'0%, 100%': { transform: 'rotate(-3deg)' },
'50%': { transform: 'rotate(3deg)' },
}
},
keyframes: {
text: {
'0%, 100%': {
'background-size': '200% 200%',
'background-position': 'left center'
},
'50%': {
'background-size': '200% 200%',
'background-position': 'right center'
}
},
}
}
}
}
Here is my tailwind.config.css
I am able to use the animate-text, but not animate-wiggle.
Thanks,
The way you define the animations and keyframes isn't valid JSON, instead of
animation: {
wiggle: 'wiggle 1s ease-in-out infinite',
},
animation: {
text: 'text 5s ease infinite',
},
you should write it as
animation: {
wiggle: 'wiggle 1s ease-in-out infinite',
text: 'text 5s ease infinite',
},
The same holds for the keyframes section.

Create component with CSS class depending on props given

Is there a way in Vue.js to create a component that is containing CSS class scoped on which some values are given as parameters (props) before his creation.
Like:
<BeautifulBar :colorSelected="red" :colorDefault="blue", :animDuration="10.0s"></BeautifulBar
And in the component itself:
<template>
<div :class="'bar ' + (selected ? 'selected animated' : 'default')" #click="select()">The Bar</div>
</template>
<script>
export default{
data: function () { return { selected: false } },
props: {
colorSelected : {default: "orange", type: String},
colorDefault: {default: "orange", type: String},
animDuration: {default: "4.0s", type: String},
},
method: {
select: function() { this.selected = !this.selected;}
}
}
</script>
/* HERE */
<style scoped>
selected: {
color: red,
background-color: var(this.colorSelected)
}
default: {
color: black,
background-color: var(this.colorDefault)
}
animate:{
-webkit-transition: var(animDuration) !important;
-moz-transition: var() !important;
-o-transition: var() !important;
transition: var() !important;
}
</style>
Have you tried using computed function for class?
computed:{
classObject:function(){
return {
'selected': this.selected,
'animated': this.selected,
'default': !this.selected
}
}
}
then
<div :class="classObject">
your template
</div>
I succeed doing it like this (showing a progress bar looping animation, you can pass the animation time as props):
<template>
<div class="progress" :style="`height: ${height}rem;`">
<div
:class="'progress-bar bg-success ' + 'progressAnimation'"
role="progressbar"
:style="`width: ${progressValue}%; --animationDuration: ${animationDurationStr};`"
:aria-valuenow="`${progressValue}`"
aria-valuemin="0"
aria-valuemax="100"
></div>
</div>
</template>
<script scoped>
import config from "../config";
export default {
props: {
animationDuration: { type: Number, default: 140 },
height: { type: Number, default: 0.25 }
},
created: function() {
config.log("------------ AutoLoopProgressBar -----------");
config.log(
"autoloopprogressbar",
"Set animation duration to " + this.animationDurationStr
);
},
mounted: function() {
config.log("autoloopprogressbar", "Setup timer");
setInterval(() => {
this.reset();
}, this.animationDuration * 1000);
this.reset();
},
data: function() {
return {
progressValue: 0
};
},
computed: {
animationDurationStr: function() {
return this.animationDuration + ".0s";
}
},
methods: {
reset: function() {
let tmp = this.animationDuration;
this.animationDuration = 0;
this.progressValue = 0;
setTimeout(() => {
this.animationDuration = tmp;
this.progressValue = 100;
}, 0);
}
}
};
</script>
<style scoped>
.progressAnimation {
--animationDuration: 1s;
-webkit-transition: var(--animationDuration) linear !important;
-moz-transition: var(--animationDuration) linear !important;
-o-transition: var(--animationDuration) linear !important;
transition: var(--animationDuration) linear !important;
}
</style>

React - JSS have element fade in when rendered

I have an element which should render when the page is loaded:
{this.state.pageLoaded && <MyComponent className={classes.container} /> }
When this component is rendered I would like for it to fade in. So I am trying to apply some jss, but can't get it quite work.
This is my JSS:
const styles = theme => ({
'#keyframes fadein': {
from: { opacity: 0 },
to : { opacity: 1 }
},
/* Firefox < 16 */
'#-moz-keyframes fadein': {
from: { opacity: 0 },
to : { opacity: 1 }
},
/* Safari, Chrome and Opera > 12.1 */
'#-webkit-keyframes fadein': {
from: { opacity: 0 },
to : { opacity: 1 }
},
/* Internet Explorer */
'#-ms-keyframes fadein': {
from: { opacity: 0 },
to : { opacity: 1 }
},
/* Opera < 12.1 */
'#-o-keyframes fadein': {
from: { opacity: 0 },
to : { opacity: 1 }
},
container: {
//How do I insert like -webkit-animation in here????
animation: '$fadein',
},
});
I do not know if my syntax is correct as I am confused with how to apply things with special character like #keyframes, --webkit-animation, etc... so that different browsers will work.
When I run the page no animations happen and I get the following warninings in my console:
Warning: [JSS] Unknown rule #-moz-keyframes fadein
Warning: [JSS] Unknown rule #-webkit-keyframes fadein
Warning: [JSS] Unknown rule #-ms-keyframes fadein
Warning: [JSS] Unknown rule #-o-keyframes fadein
To achieve this in JSS, you need to declare a key-frames property to your styles object like so;
export default ({
'#keyframes ring': {
from: {
transform: 'rotate(0deg)',
},
to: {
transform: 'rotate(360deg)',
},
},
someClassName: {
animationDelay: '-0.2s',
animationDuration: '1s',
animationIterationCount: 'infinite',
animationName: '$ring', <-- HERE IS HOW YOU REFERENCE TO IT
animationTimingFunction: 'cubic-bezier(0.5, 0, 0.5, 1)',
},
});
You can apply this effect with some css.
.fade-in {
animation: fade-in 2s;
}
#keyframes fade-in {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}
Just add fade-in className to your component and add this code to your css file.
Since you do not want to use css. You may save some time by adding something like http://react-animations.herokuapp.com/ or https://digital-flowers.github.io/react-animated-css.html to your app.
By following the documentation you can add animations to your react project.
I would go this route if you are unwilling to add css or sass to the project.

animate react component with transform and transition

I use this inline transform to iterate dynamically over slides
<div className="slides" style={{transform: `translate(${currentPosition}%, 0px)`, left: 0}}> {slider} </div>
</div>
which is working fine. However I would like to add some fadein to this element on position changing and the following css does not working
on element slides via css
opacity: 0;
animation: fadein 2s ease-in 1 forwards;
here is my fadein animation
#keyframes fadein {
from {
opacity:0;
}
to {
opacity:1;
}
}
What I'm missing in this case?
You can try something like this. That will give you idea how can you apply animations.
class Test extends React.Component {
constructor(props) {
super(props);
this.state = {
currentPosition: 0,
opacity: 0
}
}
componentDidMount() {
setTimeout(() => this.setState({
opacity: 1
}), 500);
}
handleClick() {
let self = this;
this.setState({
opacity: 0
}, () => setTimeout(() => self.setState({
opacity: 1
}), 2000))
}
render() {
return ( <
div >
<
div className = "slides"
style = {
{
transform: `translate(${this.state.currentPosition}%, 0px)`,
left: 0,
opacity: this.state.opacity
}
} > Some title to test animation < /div> <
button onClick = {
this.handleClick.bind(this)
} > Click < /button> <
/div>
)
}
}
React.render( < Test / > , document.getElementById('container'));
.slides {
transition: all 2s ease-in;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.14.8/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.14.8/react-dom.min.js"></script>
<div id="container"></div>
Here is the fiddle.
Hope it helps.

Resources