Animated bar / text with Tailwind CSS and react - css

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

Related

How to replace image with effect with React?

I have the following code -
render() {
return <DeviceThemeProvider><GlobalStyle /><div>
<div class="grids">
<div id="grid">
<div class="grid-element">
<img class="displayed" src={process.env.PUBLIC_URL + '/img/692.png'} />
</div>
Now I would like to replace the image 692.png with 693.png.
I understand how to do with setState/src. But how to do it with some effect? Fade out/fade in? I found CSS transition property. Could it be used with React somehow?
What if I need to replace it with no image and replace no image with 692.png?
As far as I understand, majority of the browsers supports:
.cat {
width: 500px;
height: 500px;
transition: background 1s;
}
https://jsfiddle.net/6jwqkes3/1/
! But this is not included in the standard.
Thanks to #TusharShahi I used http://reactcommunity.org/react-transition-group/switch-transition library.

detect when css keyframe is done - Angular

I have an animation that last one second and I have an #InputI'm taking, but the #Input happens so fast that the animation doesn't take place. How can I know when the animation is done in order to trigger the #Input after
CSS
#keyframes bulkSlideOut {
100% {
transform: translateY(100vh);
}
}
HTML
<div *ngIf="displayBulkPay" class="bulk-pay-storage-container">
<div class="header-container">
.
.
</div>
</div>
TS
#Input()
displayBulkPay: boolean;
There is a .start and .done event in your animation triggers that you can call a function or set a value with.
<div id="whatever" [#displayBulkPay]="canDoAFunctionToo(anything)"
(#displayBulkPay.start)="onStart($event)"
(#displayBulkPay.done)="onDone($event)">

Angular Material Side Bar with "Half" side mode

I am working on the dynamic side bar for our project, basically what we want to do is to set up a dynamic side bar when user click on the side bar it will spread when user click back sidebar should collapse and show only icons (but not totally collapse it will keep the icons) for example before user click the icon. We are using sidenav.toggle()from angular material function which basically closes the sidebar completely and if I don't use toggle() function "Side" mode for navbar does not work. So I want collapse to icon with side mode. (The other reason we need to keep the side mode is that we also need to make sure when user spread the sidebar, right side content should push to right)
After user click the icon
Is there a way to do that?
Thanks.
Option 1: Generating Automatically:
You can create a navigation component from templates provided by Material itself using 'Angular CLI component schematics'
ng generate #angular/material:nav your-component-name
The above command will generate a new component that includes a toolbar with the app name and a responsive side nav based on Material breakpoints.
See more about angular material schematics here
Option 2: Implementing Manually:
To implement that, you just have to refer these two links:
Resizing Sidenav | Angular Material
Navigation List | Angular Material
glance through the following code. Implementation will be something like this:
<mat-drawer-container class="example-container mat-typography" autosize>
<mat-drawer #drawer mode="side" disableClose="true" opened="true">
<button mat-mini-fab (click)="isExpanded = !isExpanded" color="warn" style="margin: 10px;">
<mat-icon aria-label="Menu">menu</mat-icon>
</button>
<mat-nav-list>
<mat-list-item>
<mat-icon mat-list-icon>person</mat-icon>
<h4 mat-line *ngIf="isExpanded">Management A</h4>
</mat-list-item>
<mat-list-item>
<mat-icon mat-list-icon>assignment</mat-icon>
<h4 mat-line *ngIf="isExpanded">Management B</h4>
</mat-list-item>
<mat-list-item>
<mat-icon mat-list-icon>domain</mat-icon>
<h4 mat-line *ngIf="isExpanded">Management C</h4>
</mat-list-item>
<mat-list-item>
<mat-icon mat-list-icon>folder_shared</mat-icon>
<h4 mat-line *ngIf="isExpanded">Management X</h4>
</mat-list-item>
</mat-nav-list>
</mat-drawer>
<div class="example-sidenav-content">
You cards and screen Contents goes here..
Will be pushed towards right on expanding side navbar.
</div>
</mat-drawer-container>
I did this with a bit of CSS
mat-sidenav:not(.mat-drawer-opened) {
transform: translate3d(0, 0, 0) !important;
visibility: visible !important;
width: 60px !important;
overflow: hidden;
}
So when the draw is NOT open, the width of the sidenav is 60px and not 0. Just enough to show your icons.
OK, the next issue is that you'll need to hide a bunch of stuff like button name and other descriptive stuff, for me I need to change the height of the profile image and hide additional text. I did this in the same way as above using the :not selector:
mat-sidenav:not(.mat-drawer-opened) div.leftNav div.navProfile img {
width: 40px; margin: 16px 0 0px 0;
}
mat-sidenav:not(.mat-drawer-opened) .navTitle,
mat-sidenav:not(.mat-drawer-opened) .profileTitle {
display: none;
}
When collapsed I didn't want to show the button names so I wrapped the name in a *ngIf
<span class="navName" *ngIf="opened">{{ page?.name }} </span>
This should work, and it does but there is a problem. The ngIf is bound to the opened event and you will notice a delay when the event is firing (to account for it animation) to show your labels when the drawer is open.
To fix this I had to delve into the api of sidenav and found an eventemitter call openedStart and closedStart. I created a new bool in the component class,
showNavLabels: boolean;
then bound the events to this bool in the HTML.
<mat-sidenav class="sidenav" #sidenav mode="side" [(opened)]="opened"
(openedStart)='showNavLabels = !showNavLabels'
(closedStart)='showNavLabels = !showNavLabels' >
I am sure there is better way as I am not that experienced with Angular yet.
I hope it helps you out.
I created an example based on scss. Maybe someone can help to create the mobile version according to this sample.
Step 1: Add below style to styles.scss
// src/styles.scss
:root {
--menu-width-open: 200px;
--menu-width-closed: 64px;
}
.mat-drawer-container {
.mat-drawer {
box-sizing: content-box;
width: var(--menu-width-open);
transition: all 0.3s ease-in-out !important;
}
.mat-drawer-content {
// transform: translateX(200px);
margin-left: var(--menu-width-open) !important;
transition: all 0.3s ease-in-out !important;
}
&.container-closed {
.mat-drawer {
width: var(--menu-width-closed);
}
.mat-drawer-content {
// transform: translateX(64px) !important;
margin-left: var(--menu-width-closed) !important;
}
}
}
Step 2: Add drawer to app.componenet.html
<mat-drawer-container class="example-container" autosize [ngClass]="{ 'container-closed': !showFiller }">
<mat-drawer #drawer class="example-sidenav" mode="side" disableClose="true" opened="true">
<button (click)="showFiller = !showFiller" mat-raised-button>click</button>
</mat-drawer>
<div class="example-sidenav-content">
<router-outlet></router-outlet>
<button type="button" mat-button (click)="drawer.toggle()">Toggle sidenav</button>
</div>
</mat-drawer-container>
Step 3: And add showFiller = false; to app.component.ts file.
// app.component.ts
#Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss'],
})
export class AppComponent {
showFiller = false;
}
There is a feature request for this https://github.com/angular/material2/issues/1728
if you read the comments you'll also find a few examples on how to implement it yourself while it's not officialy available.

Vue2 : Make Page Fade In with "appear" transition and still use routing transition too

I was trying to do a page fade in when my app initially loads using appear; however, I am already using a routing css animation that does a fade in and fade out when going from page to page, but it still leaves me with an abrupt display of my page when it initially loads. So far, my attempts to add another transition tag around the routing transition in a outer nested way has failed. It still loads with an abrupt display of page. Any suggestions?
<template>
<div id="app">
<v-app>
<main>
<transition name="appearPageFadeIn" appear><!-- new appear tag -->
<cq-nav-mobile></cq-nav-mobile>
<cq-nav-desktop></cq-nav-desktop>
<transition name="interPageFadeOutIn" mode="out-in">
<router-view></router-view>
</transition>
<cq-footer></cq-footer>
</transition>
</main>
</v-app>
</div>
</template>
<!-- CSS -->
/* appear page animation */
.appearPageFadeIn-appear {
opacity: 0;
}
.appearPageFadeIn-appear-active {
transition: opacity 1s;
}
/* inter page routing animation */
.interPageFadeOutIn-enter {
opacity: 0;
}
.interPageFadeOutIn-enter-active {
transition: opacity 1s;
}
.interPageFadeOutIn-leave {
opacity: 1; //default
}
.interPageFadeOutIn-leave-active {
transition: opacity 1s;
opacity: 0;
}

Angular ng-repeat animate once

I am using ngAnimate to animate entries in an ng-repeat. When loading the data all elements are animated as I have defined in my css:
.chat-message.notice.ng-enter {
-webkit-animation: rubberBand 1s;
-moz-animation: rubberBand 1s;
-ms-animation: rubberBand 1s;
animation: rubberBand 1s;
}
This works when a notice is appended with the following html:
<ul>
<li class="media chat-message pointer fade-animate"
ng-repeat-start="message in guestbook.messages track by $index"
ng-if="!message.bot">
<!-- more html -->
</li>
<li class="chat-message notice" ng-repeat-end ng-if="message.bot">
<div>
<p class="text-center">
{{ message.message }}
<small>({{ message.date | amTimeAgo }})</small>
<span class="close pull-right" ng-click="guestbook.remove(message)">×</span>
</p>
</div>
</li>
</ul>
However, when a new message is appended (at the top), every element is again animated. Is there a way that elements animate only once? That when a new message is appended to the array, only that element will animate?
JSFIDDLE
EDIT
After a few clicks on a 'new message', I can see not all notices are animated. Maybe it has something to do with the ng-repeat-start and ng-repeat-end?
If understood correctly just change this:
$scope.messages.unshift(message);
to this:
$scope.messages.push(message);
Even above answer fixed the problem, my solution might be helpful in other scenarios. The fix is pretty straightforward.
Use Angular varible $first and just add CSS class for the first element using ng-class directive in your HTML. In this example, class "first" will be added only to first element in ng-repeat:
ng-class="{'first': $first===true}"
and then apply animation rules to element with "first" CSS class
.chat-message.notice.first.ng-enter {
color:red !important;
font-weight:bold;
animation: rubberBand 1s;
}
Updated JSFIDDLE: http://jsfiddle.net/t6x3a1zj/7/

Resources