I'm playing with angular animation in a simple ionic 6 app.
the animation is very simple (taken from the Angular doc)
animations: [
trigger('openClose', [
state('open', style({
opacity: 1,
})),
state('closed', style({
opacity: 0,
})),
transition('closed => open', [
animate('2s')
]),
]),
then in my html code I have used the application:
<ion-card class="test" [#openClose]="loaded ? 'open' : 'closed'">
<div *ngIf="!loaded" style="text-align: center ;">
<ion-spinner name="lines" color="primary"></ion-spinner>
</div>
<div *ngIf="loaded" >
<ion-card-header >
</ion-card-header>
</div>
and yes... it works...
But if I put the animation on the div inside ion-card, well... it doesnt works anymore.
<ion-card class="test" >
<div *ngIf="!loaded" style="text-align: center ;">
<ion-spinner name="lines" color="primary"></ion-spinner>
</div>
<div *ngIf="loaded" [#openClose]="loaded ? 'open' : 'closed'">
<ion-card-header >
</ion-card-header>
</div>
So I'm confused... Why the animation works only in the ion-card element?
And... What is the best practice to animate content in ionic?
I saw css animations, ionic animations and angular animations.... a lot of way to do the same thing...
Thanks for all responses
Related
When I open and close a menu item, there is no animation. I would like to know how to create an animation, please?
HTML file
<div class="wrapper">
<!-- Top Menu -->
<div class="sidebar">
<!-- Menu Item -->
<ul>
<li
*ngFor="let menu of menus; let i = index"
[class.active]="menu.active"
>
<ng-container>
<a class="item" (click)="selectMenu(menu)">
<i [class]="menu.iconClass"></i> {{ menu.name }}
<i class="fa fa-chevron-down"></i>
</a>
<ul *ngIf="menu.active">
<li *ngFor="let submenu of menu.submenu" class="submenu">{{submenu.name}}</li>
</ul>
</ng-container>
</li>
</ul>
</div>
</div>
I don't know if it's possible to do it in Angular or CSS? I made you a reproduction of the project => Stackblitz.
the easer is using Angular animations. add this animation to your component
animations:[
trigger('accordion', [
transition(':enter', [
style({ height: 0 }),
animate('1000ms', style({ "height": '*' })),
]),
transition(':leave', [
animate('100ms', style({ "height": 0 }))
])
]),
]
See that, when "enter" start with style:height=0 and animate to reach style:height=* (the * main that reach the "normal" height) and you use "leave" to animate and change the style to "height=0".
Then just use
<ul #accordion *ngIf="menu.active">
<li *ngFor="let submenu of menu.submenu" class="submenu">
{{submenu.name}}
</li>
</ul>
NOTE1: don't forget import the BrowserAnimationsModule in your module
NOTE2: You need add to your .css
.wrapper ul li ul{
overflow:hidden;
}
Your forked stackblitz
I think you should change app.component.ts like this.
selectMenu(parentMenu: { name: string, active:boolean }): void {
this.menus.forEach((menu) => {
if (menu.name === parentMenu.name) {
menu.active = !menu.active;
}
});
}
}
because Each time active is pressed, the boolean value should change.
have a nice day:)
anyone please can help me figure it out how to make the 2 animations used in this website https://worldofwomen.art/ using react and tailwind css
First: the animated bar of this picture
second: the animated text : • NEW SITE LAUNCHING SOON
I am looking forward for the help from someone, i really passed the whole night searching of animation in react and tailwind css but i didn't find any tutorial about this.
Thank you so much for the help and the stop you put on my question
You can achieve the animation with just css (ie Tailwindcss) by using 'animation' css property
I- Create a nextjs project with the command: $npx create-next-app my-app
II- Setup tailwindcss with nextjs project: https://tailwindcss.com/docs/guides/nextjs
III- Create new React component animation.js, inside pages/ folder
import React from 'react'
export default function Animation2() {
return (
<>
{/* Image Animation */}
<div className="animate">
<img src="/frise-2.2f579f.png" alt="" />
<img src="/frise-2.2f579f.png" alt="" />
</div>
{/* Image Animation - Reversed direction */}
<div className="animate-reversed">
<img src="/frise-2.2f579f.png" alt="" />
<img src="/frise-2.2f579f.png" alt="" />
</div>
{/* Text Animation */}
<div className="bg-[#332970] w-screen box-border p-4 flex items-center overflow-hidden fixed bottom-0">
<div className="animate">
{
[0,1,2,3,4,5,6,7,8,9,10,11].map((i) => (
<div className="text-[#139bac] whitespace-nowrap inline-flex items-center justify-center">• NEW SITE LAUNCHING SOON </div>
))
}
</div>
</div>
</>
);
}
The first div responsible for the animation of the image with the default direction from right to left. I used 2 img tags because it has to have 2 separate sets of the same img tag. because with the infinite loop, when one image disappears the second one appears and it will restart the loop without any gap (You can comment the second img tag to check the gap am talking about)
the second div is similar to the first one but it has the reversed direction property.
For the text animation, we do the same thing we have to create the text multiple times to avoid the gap when we animate the text for an infinite loop. And to avoid multiple lines of the same tag: • NEW SITE LAUNCHING SOON I wrapped in an array and loop through it
all the styles are integrated in the same component using tailwindcss except the animation that will be added in globals.css file like this:
Go to globals.css file and add the animation css code:
#tailwind base;
#tailwind components;
#tailwind utilities;
#layer components {
.animate{
display: flex;
animation: scroll 20s linear infinite;
}
.animate:hover{
animation-play-state: paused;
}
.animate-reversed{
display: flex;
animation: scroll 20s linear infinite;
animation-direction: reverse;
}
.animate-reversed:hover{
animation-play-state: paused;
}
#keyframes scroll {
0%{
transform: translateX(0);
}
100%{
transform: translate(-50%);
}
}
}
There are a few ways to do this, but taking into account the site you referenced, I noticed that it works with an infinite increment, so it's most likely done with JS.
PS.: I could do everything with javascript.
const sleed1 = document.getElementById("sleed1");
let position1 = 0;
setInterval(() => {
position1 = position1 + 10;
sleed1.style.backgroundPosition = position1 + 'px';
sleed1.style.transitionDuration = '100ms';
}, 40)
#sleed1 {
width: 100%;
height: 200px;
background-color: #ccc;
background-image: url("https://i.stack.imgur.com/zJXIx.png");
}
<div id="sleed1" />
To control the speed you can change 3 values:
Number of pixels increased, I put 10.
The duration of the transition, I put '100ms'.
The setInterval interval, I put 40.
Both will influence speed but in different ways, so adjust until you find the best solution for you.
To change the sleed side, change "position + n" to "position-n".
Same code in React. Using "useEffect" with ",[ ]". Important not to forget this for the code to run only once and avoid undesirable effects.
https://codesandbox.io/s/slide-image-animation-with-react-and-css-rfhvd?file=/src/App.js
I have a sidebar that gets bigger on hover. In that sidebar, I have divs that contains extra-content which is only displayed when the sidebar is hovered. The code below works well:
HTML file
<!--Sidebar-->
<div class="group w-16 bg-blue-700 hover:w-44">Sidebar
<div>Item 1
<span class="hidden group-hover:inline">Item 1: Details</span>
</div>
<div>Item 2
<span class="hidden group-hover:inline">Item 2: Details</span>
</div>
</div>
CSS file
#tailwind base;
#tailwind components;
#tailwind utilities;
tailwind.config.js
module.exports = {
purge: [],
darkMode: false, // or 'media' or 'class'
theme: {},
extend: {},
variants: {
extend: {
width: ['hover'],
display: ['group-hover'],
},
},
plugins: [],
}
However, I would like to create a nice transition when the sidebar is hovered so that it gets bigger smoothly. I do this by changing the HTML file to -->
New HTML file
<!--Sidebar-->
<div class="group w-16 bg-blue-700 hover:w-44 transition-all">Sidebar
<div>Item 1
<span class="hidden group-hover:inline">Item 1: Details</span>
</div>
<div>Item 2
<span class="hidden group-hover:inline">Item 2: Details</span>
</div>
</div>
Doing so, now, there is small bug when the sidebar is hovered: the extra content is displayed before the sidebar reaches its full-size.
I need to add a delay to the display of the extra content. Ideally, the sidebar would first gets bigger smoothly and reach its full-size, and only then the extra-content would appear. Is there a way to do so in native tailwind css?
To achieve this I did a simple hack for it.
As you may find yourself, tailwindcss-> group-hover:visible class represents:
.group:hover .group-hover\:visible {
visibility: visible;
}
So I changed group-hover:visible to xgroup-hover:visible and added some animation instead of original tailwindcss:
#keyframes tooltip-show {
0% {opacity: 0;}
5% {visibility: visible;}
25% {opacity: 50;}
50% {opacity: 75;}
100% {opacity: 100;}
}
.group:hover .xgroup-hover\:visible {
animation-delay: 0.7s;
animation-name: tooltip-show;
animation-duration: 2s;
}
this simple hack worked for me :)
So you can follow same way for your desired group-hover:inline class and add your own animation keyframes as you like.
Thanks to Ali javanmardi hints, I managed to achieve what I wanted. The main findings are:
Need to use Absolute positioning for Items Details in the sidebar
Adding a delay on a transition such as group-hover:visible delay-150 does not work in this specific case because this would lead the details to disappear after the sidebar is closed (because delay is applied at Start and End)
Instead, I created a custom animation of 1s, where the first "transition" keyframes happens at 15%, thus creating effectively a delay from 0% to 15%, combined with animation-fill-mode: forwards; Below is my code.
HTML file
<!--Sidebar-->
<div class="group w-16 bg-blue-700 hover:w-44 transition-all">Sidebar
<div class="relative">Item 1
<span class="absolute opacity-0 invisible group-hover:animate-tooltip_show ml-2">Item 1: Details</span>
</div>
<div class="relative">Item 2
<span class="absolute opacity-0 invisible group-hover:animate-tooltip_show ml-2">Item 2: Details</span>
</div>
</div>
tailwind.config.js
module.exports = {
purge: [],
darkMode: false, // or 'media' or 'class'
theme: {
extend: {
keyframes: {
tooltip_show: {
'0%' : { visibility: 'hidden', opacity: '0'},
'15%' : { visibility: 'hidden', opacity: '0'},
'100%' : { visibility: 'visible', opacity: '100'},
}
},
animation: {
tooltip_show: 'tooltip_show 1s ease forwards',
}
},
},
variants: {
extend: {
width: ['hover'],
animation: ['group-hover'],
},
},
plugins: [],
}
Here's my implementation without using custom animation. You just need to add a delay when the parent is hovered, and reset the delay back to zero when the parent is not hovered.
<script src="https://cdn.tailwindcss.com"></script>
<style type="text/tailwindcss">
#layer components {
#container {
#apply flex flex-col items-center gap-2 mt-4;
};
#button {
#apply bg-blue-400 text-white p-1 rounded;
};
#tooltips {
#apply bg-green-400 p-0.5 w-24 left-1/2 -translate-x-1/2
translate-y-10 transition-opacity rounded;
};
};
</style>
<!-- Ignore previous code block, it's just for styling -->
<div id='container'>
<h1>Hover with delay tailwindcss<h1>
<button id='button' class='relative group'
>Hover me
<span id='tooltips' class='absolute
opacity-0
delay-0
group-hover:opacity-100
group-hover:delay-300'
>I'm here 👋</span>
</button>
</div>
I'm trying to style the stripe dropdown select to match bootstrap's select. here is my html
<form id="payment-form">
<div class="form-row">
<div>
<label for="bank-element">
Bank
</label>
<div id="bank-element">
<!-- A Stripe Element will be inserted here. -->
</div>
</div>
</div>
<button id="button" data-secret="<?= $intent->client_secret ?>">
Submit Payment
</button>
<!-- Used to display form errors. -->
<div id="error-message" role="alert"></div>
</form>
in my js file i have this
var style = {
base: {
'padding': "10px 12px",
'color': '#495057',
'fontFamily': 'apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif',
'border-color': '#80BDFF',
'outline':'0',
'box-shadow': '0 0 0 .2rem rgba(0,123,255,.25)',
'transition': 'border-color .15s ease-in-out, box-shadow .15s ease-in-out'
},
invalid: {
color: "#fa755a"
}
};
var Bank = elements.create(
'Bank',
{style: style, accountHolderType: 'individual'}
);
id="bank-element" is there the dropdown select is. Anyone know how to do this? or that I'm missing. Thank you
Great question, but unfortunately you're limited to the style options listed here:
https://stripe.com/docs/js/appendix/style
This means that you won't be able to set: border-color, transition, border-color, or outline on the element itself. You can apply a border & animations to the container div, but you won't be able to set up the animation transition on anything inside the Element.
i'm new to ReactJs and my question may seem stupid to many of you, but i have a problem with setting the background. My React code is:
<header className="masthead ttt">
<div className="overlay"></div>
<div className="container">
<div className="row">
<div className="col-lg-8 col-md-10 mx-auto">
<div className="site-heading">
<h1>Blog Name</h1>
<span className="subheading">blablablablabla</span>
</div>
</div>
</div>
</div>
</header>
So basically i'm trying to set an image as background in my header , so i created a class .ttt and modified it to my css that way :
.ttt{
background-image: url("../img/home-bg.jpg");
}
And finally here's the way the folders are set :
Am i doing anything wrong in my code ? Or there's another way of doing things in ReactJS!
Thanks!
So far what I understood from your problem is that you are not getting the image on the front-end. While checking it through developer options it must be pointing you to a blank div at the top of the screen.
If that's the case then it is because that every background image needs some size to be displayed.
You can either give width and height or you can give background-size property as follows:
.ttt{
background-image: url("../img/home-bg.jpg");
width: 100%;
height: 100%; // giving height is not compulsary but just for good practice.
}
OR
.ttt{
background-image: url("../img/home-bg.jpg");
background-size: 100% 100%; // First value: {Width} Second value: {Height}
}
This would resolve your issue.
Use inline css in javascript like this:
import Background from '../img/home-bg.jpg'; // make sure path is correct
<header className="masthead" style={{ backgroundImage: `url(${Background})` }} >
ref Be mindful of using backgroundImage instead of background-image
Working for me
<div className="drag-dashboard" style={{ backgroundImage: `url(${config.DESTINATION_MEDIA_CDN+ "assets/icons_skining/upload_placeholder_skining.png"})`}}>
</div>