How to hide with animation? React + SCSS - reactjs

I think is just something very simple, but I can't think of anything;
import React, { useState } from "react"
import "./header.scss"
export default function(){
let [curtain, setCurtain] = useState(false);
return (
<div className="header"
onMouseEnter={() => setCurtain(true)}
onMouseLeave={() => setCurtain(false)}
>
{ curtain && <div className="header__curtain__black header__curtain"/> }
</div>
)
}
And here is SCSS
.header{
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 70px;
&__curtain{
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: black;
animation: slide_down 0.2s linear;
}
}
#keyframes slide_down {
0%{
transform: translateY(-100%);
}
100%{
transform: translateY(0);
}
}
Code is super simple and task is super simple too, I want to make a reverse on closing but what do I do ?

You can assign different class names to the curtain div according to curtain state value. I would also suggest to use transition property in your css styles instead of keyframe animations.
Here is the edited code.

Related

Mapped buttons that have opacity of 0 are showing, and are overlapping when resizing the window

I've successfully mapped over text and have styled it with transition effects when going from one slide to the next as you can see here:
Following a similar concept with buttons isn't working. There should only be one button active per slide like you see here:
I want the buttons to have the same effect as the text, but I'm getting behaviors like you see here:
As you can see, there is no transition effect on the button when clicking to the second slide, and it also appears in a lower spot.
And lastly, when resizing the window, buttons are overlapping like you see here:
Don't know what to try next.
Here's the ImageSlider component:
import { useState } from "react";
import { SliderData } from "../data";
import { categories } from "../data";
import ShopNowButtonActive from "./ShopNowButtonActive";
import { IoIosArrowBack } from "react-icons/io";
import { IoIosArrowForward } from "react-icons/io";
import "./ImageSlider.css";
import ShopNowButton from "./ShopNowButton";
const ImageSlider = ({ slides }) => {
const [current, setCurrent] = useState(0);
const length = slides.length;
const nextSlide = () => {
setCurrent(current === length - 1 ? 0 : current + 1);
};
const prevSlide = () => {
setCurrent(current === 0 ? length - 1 : current - 1);
};
return (
<div className="slider">
<IoIosArrowBack className="left-arrow" onClick={prevSlide} />
{SliderData.map((slide, index) => (
<div key={slide.id}>
<img
src={slide.img}
alt=""
className={index === current ? "slide active" : "slide"}
/>
<div className="info-container">
<div className={index === current ? "title active" : "title"}>
{slide.title}
</div>
<div className={index === current ? "desc active" : "desc"}>
{slide.desc}
</div>
{categories.map((item, index) =>
index === current ? (
<ShopNowButtonActive item={item} />
) : (
<ShopNowButton item={item} />
)
)}
</div>
</div>
))}
<IoIosArrowForward className="right-arrow" onClick={nextSlide} />
</div>
);
};
export default ImageSlider;
The css file:
.slider {
height: 90vh;
margin-bottom: 0.5rem;
}
.left-arrow {
position: absolute;
top: 45%;
left: 32px;
font-size: 2rem;
cursor: pointer;
opacity: 0.5;
z-index: 1;
}
.slide.active {
opacity: 1;
width: 100%;
height: 88%;
object-fit: cover;
object-position: center;
-webkit-clip-path: polygon(100% 0, 100% 80%, 50% 100%, 0 80%, 0% 0%);
clip-path: polygon(100% 0, 100% 80%, 50% 100%, 0 80%, 0% 0%);
}
.slide {
opacity: 0;
transition: 500ms opacity ease-in-out;
width: 100%;
height: 88%;
object-fit: cover;
object-position: center;
position: absolute;
-webkit-clip-path: polygon(100% 0, 100% 80%, 50% 100%, 0 80%, 0% 0%);
clip-path: polygon(100% 0, 100% 80%, 50% 100%, 0 80%, 0% 0%);
}
.info-container {
display: flex;
flex-direction: column;
width: 40%;
height: 100%;
position: absolute;
top: 45%;
right: 30px;
}
.title.active {
opacity: 1;
transition-delay: 700ms;
font-size: 4rem;
}
.title {
opacity: 0;
transition: 200ms opacity ease-in-out;
font-size: 4rem;
}
.desc.active {
opacity: 1;
padding-top: 1.5em;
transition-delay: 700ms;
font-size: 1.25rem;
font-weight: 500;
letter-spacing: 3px;
}
.desc {
opacity: 0;
padding-top: 1.5em;
transition: 200ms opacity ease-in-out;
font-size: 1.25rem;
font-weight: 500;
letter-spacing: 3px;
}
.right-arrow {
position: absolute;
top: 45%;
right: 32px;
font-size: 2rem;
cursor: pointer;
opacity: 0.5;
z-index: 1;
}
The ShopNowButtonActive component:
import React from "react";
import styled from "styled-components/macro";
import { Link } from "react-router-dom";
const ButtonActive = styled.button`
opacity: 1;
padding: 0.5rem;
margin-top: 2.5rem;
width: 8rem;
font-size: 20px;
background-color: transparent;
cursor: pointer;
transition-delay: 700ms;
`;
const ShopNowButtonActive = ({ item }) => {
return (
<Link to={`/products/${item.cat}`}>
<ButtonActive>SHOP NOW</ButtonActive>
</Link>
);
};
export default ShopNowButtonActive;
And finally, the ShopNowButton component:
import React from "react";
import styled from "styled-components/macro";
import { Link } from "react-router-dom";
const Button = styled.button`
opacity: 0;
/* display: none; */
padding: 0.5rem;
margin-top: 2.5rem;
width: 8rem;
font-size: 20px;
background-color: transparent;
cursor: pointer;
transition: 200ms opacity ease-in-out;
`;
const ShopNowButton = ({ item }) => {
return (
<Link to={`/products/${item.cat}`}>
<Button>SHOP NOW</Button>
</Link>
);
};
export default ShopNowButton;
(Sorry for the use of both an external css file and styled components.)
Any suggestions?
I have recreated the above scenario using some static data. I have modified some of the css. It is working as expected. I also observed that the only major difference between ShopNowButton and ShopNowButtonActive was opacity property which hides the element. The reason you are observing 2 buttons because they were all there in the dom actually.(They were not hiding properly due to which we are observing more shop now buttons and every time we click on next icon the corresponding button is being displayed. Basically all the buttons are there on the page itself.)
Please find the sandbox url below.
https://codesandbox.io/s/stackoverflow-6u05e7?file=/src/ImageSlider/ImageSlider.js

Map is only displaying one item in it

I am trying to display the items in the array, but only one item is being displayed. I have tried changing id, although it didnt work.
import React, { useState } from 'react';
import Note from './noteItself';
const NoteItems=[
{id:1, message:'asdf',title:'New Note'},
{id:2, message:'asdf',title:'e'}
]
const NoteDisplay = () => {
return (
<div className="note-container">
{NoteItems.map((items)=><Note items={items}/>)}
</div>
)
}
export default NoteDisplay;
import React from 'react';
const Note = ({items}) => {
console.log(items);
return (
<div className="note-box">
<h1 className="note-title">{items.title}</h1>
</div>
)
}
export default Note;
css
.note-container { display: flex; }
.note-box { flex-direction: row; flex-grow: 1; height: 181px; width: 181px; border-radius: 20px; position: absolute; left: 22.09%; right: 65.94%; top: 26.58%; bottom: 54.99%; background: #ffffff; box-shadow: 0px 3px 16px rgba(0, 0, 0, 0.09); border-radius: 20px; }
Since you have absolute positioning on the note-box class, all the items are going to get rendered on top of each other. You will want to remove all of your absolute positioning (position: absolute; left: 22.09%; right: 65.94%; top: 26.58%; bottom: 54.99%;) to let flexbox arrange your items.

How to Desktop View, Tablet View ,Mobile view change inside a browser ReactJS

I am new to Reactjs . How to add 3 views inside a browser,by automatically change view.
Reference Page Link
You can wrap all your content with a div and control the width of that div.
// App.js
import { useState } from 'react';
import './App.css';
function App() {
const [state, setState] = useState('desktop');
return (
<div className="App">
<button onClick={() => setState('desktop')}>Desktop</button>
<button onClick={() => setState('tablet')}>Tablet</button>
<button onClick={() => setState('phone')}>Phone</button>
<div className={`container ${state}`}>Your content here</div>
</div>
);
}
export default App;
/*App.css*/
.App {
height: 100%;
background-image: -webkit-linear-gradient(0deg, #766dff 0%, #88f3ff 100%);
}
/* General styling */
button {
padding: 0.5rem;
margin: 1rem;
border-radius: 10px;
cursor: pointer;
border: none;
}
.container {
/* General styling */
background-color: whitesmoke;
padding: 1rem;
border-radius: 5px;
margin-top: 1rem;
transition: all 1s;
/* Center the container */
margin-left: auto;
margin-right: auto;
}
.desktop {
width: 90%;
}
.tablet {
width: 768px;
}
.phone {
width: 480px;
}
/* index.css */
/* To make full width and height */
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
html,
body,
#root {
height: 100%;
}
The above answer is correct. You can simply give a width to the main container to 100% and place your other container with other elements inside of it, also specify width using #mediaqueries(" https://www.w3schools.com/css/css_rwd_mediaqueries.asp "). This way, you can control the elements inside the main container. I can say for sure that you need to try it by yourself and see how everything works, use devtools(there is toogle device toolbar).

How to loop a Draggable slider in React

I have a draggable horizontal slider in my current project and I would like to setting up it also to loop continuously. By loop continuously I mean it should respond to the process of showing images one after another when dragging? Right now, I do have only 3 images in my slider and when I drag slider to the left, slider with its 3rd image and a blank white space starts showing just after. Here at this point I want images to get start again continuously from the very beginning i.e. from the 1st image with aim to cover the white blank space.
Apart, one error I'm getting with my existing code is that when I start to drag slider to right side, suddenly a scroll comes up on browser and keep going in never ending state. By never ending state, I mean it still remain on screen when I drag all my 3 images fully in right direction.
So these are the two things I want to apply and want to resolve in my current project. I'm sharing my code below.
src > Routes > Home > Components > Carousel > Components > SliderDataItems > index.js
import React, { useRef, useEffect } from "react";
import { gsap } from "gsap";
import { Draggable } from "gsap/Draggable";
import { ZoomInOutlined } from '#ant-design/icons'
import { Images } from '../../../../../../Shared/Assets';
import ImagesIcon from '../../../../../../Components/Cells/ImagesIcon'
gsap.registerPlugin(Draggable);
const pictures = [
{
img: Images.xgallery1,
icon: <ZoomInOutlined />
},
{
img: Images.xgallery2,
icon: <ZoomInOutlined />
},
{
img: Images.xgallery4,
icon: <ZoomInOutlined />
},
];
const Slide = ({ img, icon }) => {
return (
<div className="slide">
<div className="image">
<ImagesIcon src={img} />
<div className="icon">
{icon}
</div>
</div>
</div>
);
};
export const Slider = () => {
const sliderRef = useRef(null);
useEffect(() => {
Draggable.create(sliderRef.current, {
type: "x"
});
}, []);
return (
<div className="slider" ref={sliderRef}>
{pictures.map((item, index) => {
return (
<Slide key={index} img={item.img} icon={item.icon} />
);
})}
</div>
);
};
export default Slider;
src > Routes > Home > Components > Carousel > style.scss
.slider {
display: flex;
cursor: unset !important;
overflow: hidden !important;
.slide {
.image {
position: relative;
img {
width: 100% !important;
height: auto !important;
object-fit: cover;
}
.icon {
transition: 0.5s ease;
opacity: 0;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
-ms-transform: translate(-50%, -50%);
text-align: center;
span {
svg {
font-size: 30px;
color: #fff;
}
}
}
}
}
.image:hover .icon {
opacity: 1;
}
}
.image:after {
content: "";
position: absolute;
width: 100%;
height: 100%;
top: 0;
left: 0;
background: rgba(211, 208, 208, 0.6);
opacity: 0;
transition: all 0.5s;
-webkit-transition: all 0.5s;
}
.image:hover:after {
opacity: 1;
}
Here's the link of demo (kindly see just above the footer section) for your reference.
Thank you for any help.
For draggle Slider there is a very lightweight JS Carousel package - siema
It is a great, lightweight carousel that is made with JS. There are also other packages built on top of this purely made for React.
In your case, I would offer to try out react-siema.
With it, you can simply use the carousel like that and it will be draggable by default. Plus, no need to load any css.

The next.js image is transparent

I'm using next.js and react.
I'm using sass for styling.
I want to use the after pseudo-element to make it look like the div tag and image are overlapping. (The image is in front and the pseudo-element is behind.)
However, the image is transparent and I can see the pseudo-elements behind the image.
I don't know why it's transparent when I'm not using opacity.
const Index: FunctionComponent = () => {
return (
<>
<div className="bg-index height-100vh">
<div className="frame">
<span className="absolute z-index-10 top-10 left-10 transform">
<Image
src="/peach.jpg"
alt="peach"
className="background-no-repeat absolute z-index-10"
width={200}
height={200}
/>
</span>
</div>
</div>
</>
);
};
export default Index;
// position
div,
img,
span {
&.absolute {
position: absolute;
}
&.top-200 {
top: 100px;
}
&.right-100 {
right: 160px;
}
&.transform {
transform: rotate(-15deg);
}
}
//
// z-index
div,
img {
&.z-index-10 {
z-index: 10;
}
}
//backgroundColor
div {
&.bg-index {
background-color: #ecd3e8;
}
&.background-no-repeat {
background-repeat: no-repeat;
}
}
// height
div {
&.height-100vh {
height: 100vh;
}
}
div {
&.frame::after {
position: absolute;
display: block;
content: '';
top: 10px;
left: 10px;
width: 200px;
height: 200px;
box-shadow: 0 4px 10px rgba(51, 51, 51, 0.3);
background: rgba(221, 221, 221, 0.25);
background-blend-mode: hard-light;
z-index: 1;
}
}
background-blend-mode: hard-light;
this is used to blend two items together and will make it semi-transparent. Remove it and it will no longer be transparent
https://www.w3schools.com/cssref/pr_background-blend-mode.asp

Resources