react-marquee-slider-vertical
Version:
The marquee slider of your wildest dreams. Only for React.js ⛺
274 lines (247 loc) • 6.26 kB
JavaScript
import React, { Fragment, useState, useEffect, useRef } from "react";
import Marquee, {
Motion,
Scale,
randomIntFromInterval,
randomFloatFromInterval,
} from "../../../src";
import styled from "styled-components";
import { Slider, FormControlLabel, RadioGroup, Radio, Switch, Button } from "@material-ui/core";
import { nanoid } from "nanoid";
import { GithubPicker } from "react-color";
import times from "lodash/times";
import { SizeMe } from "react-sizeme";
import FullWidth from "./FullWidth";
import LoadingIcon from "./LoadingIcon";
import ComputationTime from "./ComputationTime";
import CodePlayground from "./code/Playground";
import logoAmazon from "../images/amazon.svg";
import logoAngular from "../images/angular.svg";
import logoApple from "../images/apple.svg";
import logoGatsby from "../images/gatsby.svg";
import logoLamborghini from "../images/lamborghini.svg";
import logoMicrosoft from "../images/microsoft.svg";
import logoNext from "../images/next.svg";
import logoPython from "../images/python.svg";
import logoRollsRoyce from "../images/rolls-royce.svg";
import logoTesla from "../images/tesla-motors.svg";
import logoTwilio from "../images/twilio.svg";
const Row = styled.div`
display: flex;
flex-direction: column;
@media (min-width: 42rem) {
flex-direction: row;
}
`;
const Height = styled.div`
position: relative;
width: 100%;
height: ${(props) => (props.height ? props.height + "px" : "auto")};
background: ${(props) => props.background};
`;
const Company = styled.div`
position: relative;
width: ${(props) => props.scale * 75}px;
height: ${(props) => props.scale * 75}px;
`;
const Circle = styled.div`
position: absolute;
transform: scale(0.5);
object-position: center center;
will-change: transform, opacity;
width: ${(props) => props.scale * 150}px;
height: ${(props) => props.scale * 150}px;
top: -50%;
left: -50%;
border-radius: 50%;
box-shadow: 0 15px 35px rgba(0, 0, 0, 0.1), 0 3px 10px rgba(0, 0, 0, 0.07);
display: flex;
justify-content: center;
align-items: center;
`;
const Logo = styled.img`
display: block;
/* https://stackoverflow.com/questions/24843676/how-can-i-fit-a-square-html-image-inside-a-circle-border */
/* just making it < 70.7% */
width: 60%;
height: 60%;
`;
const ColorPickers = styled.div`
margin-bottom: 35px;
> .github-picker {
box-sizing: content-box !important;
}
@media (min-width: 42rem) {
width: 50%;
margin-bottom: 0;
}
`;
const Settings = styled.div`
@media (min-width: 42rem) {
width: 50%;
}
`;
const Separator = styled.div`
height: ${(props) => props.height}px;
`;
const SLabel = styled.label`
font-size: 0.9rem;
font-weight: 600;
margin-right: 10px;
`;
const SValue = styled.span`
font-weight: 900;
`;
const Help = styled.span`
font-size: 0.7rem;
color: #777;
`;
const Loading = styled.div`
display: flex;
position: absolute;
left: 0;
top: 0;
right: 0;
left: 0;
width: 100%;
height: 100%;
transition: all 1s linear;
opacity: ${(props) => (props.loading === "true" ? 1 : 0)};
background: #fff;
justify-content: center;
align-items: center;
`;
const IconPadding = styled.div`
padding: 15px;
`;
const icons = [
logoAmazon,
logoGatsby,
logoAngular,
logoApple,
logoLamborghini,
logoMicrosoft,
logoNext,
logoPython,
logoRollsRoyce,
logoTesla,
logoTwilio,
];
const colors = [
"transparent",
"#eeeeee",
"#fa8072",
"#ffefd5",
"#87ceeb",
"#7fffd4",
"#ffe4e1",
"#f0f8ff",
];
const Label = ({ label, value, help, color }) => (
<div>
<SLabel>{label}</SLabel>
{value && <SValue>{value}</SValue>}
<div />
{help && <Help>{help}</Help>}
<Separator height={5} />
</div>
);
const CodeNote = ({ url }) => (
<p>
Have a look{" "}
<a href={url} target="_blank" rel="noreferrer">
at the original, full code for this example
</a>{" "}
or just the basic, simplified gist:
</p>
);
const PerfMarquee = React.memo(
({
artificialKey,
direction,
velocity,
scatterRandomly,
minScale,
maxScale,
scale,
resetAfterTries,
iconsAmount,
iconsMeta,
onInit,
onFinish,
motionVelocity,
motionRadius,
palette,
}) => (
<Marquee
key={artificialKey}
direction={direction}
velocity={velocity}
scatterRandomly={scatterRandomly}
minScale={minScale}
maxScale={maxScale}
resetAfterTries={resetAfterTries}
onInit={onInit}
onFinish={onFinish}
>
{times(iconsAmount, Number).map((index) => (
<Scale scale={iconsMeta[index].scale} key={`marquee-example-playground-${index}`}>
{motionVelocity > 0 && (
<Motion
{...iconsMeta[index]}
velocity={motionVelocity}
radius={motionRadius}
backgroundColors={palette}
>
<Company scale={scale}>
<Circle scale={scale}>
<Logo src={icons[index]} alt="" />
</Circle>
</Company>
</Motion>
)}
{motionVelocity === 0 && (
<IconPadding>
<Company scale={scale}>
<Circle scale={scale}>
<Logo src={icons[index]} alt="" />
</Circle>
</Company>
</IconPadding>
)}
</Scale>
))}
</Marquee>
),
);
const Playground = ({ perfData, onStartPerformance, onEndPerformance }) => {
return (
<div style={{ height: "500px" }}>
<Marquee velocity={12} minScale={0.7} resetAfterTries={200} scatterRandomly>
{times(5, Number).map((id) => (
<Motion
key={`child-${id}`}
initDeg={randomIntFromInterval(0, 360)}
direction={Math.random() > 0.5 ? "clockwise" : "counterclockwise"}
velocity={10}
radius={50}
>
<div
style={{
width: "50px",
height: "50px",
borderRadius: "50%",
backgroundColor: "yellow",
textAlign: "center",
lineHeight: "50px",
}}
>
{id}
</div>
</Motion>
))}
</Marquee>
</div>
)
};
export default Playground;