Photoresistor

This commit is contained in:
Nomi Nonsense (Nonszy) 2024-03-09 18:28:28 +07:00
parent c8aa4fffc8
commit 6d4167809b
10 changed files with 252 additions and 5 deletions

View File

@ -15,7 +15,7 @@ function Primary ({
}: ButtonProps) {
return (
<button
className={`px-5 py-4 transition font-roboto-mono bg-primary bg-opacity-100 hover:bg-opacity-80 rounded-lg ${className}`}
className={`btn bg-primary bg-opacity-100 hover:bg-opacity-80 ${className}`}
style={style}
onClick={onClick}
>{children}</button>
@ -30,7 +30,23 @@ function Secondary ({
}: ButtonProps) {
return (
<button
className={`px-5 py-4 transition font-roboto-mono bg-finn border hover:bg-secondary border-border rounded-lg ${className}`}
className={`btn bg-finn border hover:bg-secondary border-border ${className}`}
style={style}
onClick={onClick}
>{children}</button>
)
}
function Danger ({
className,
style,
onClick,
children
}: ButtonProps) {
return (
<button
className={`btn bg-transparent border text-danger hover:bg-danger hover:text-white border-danger ${className}`}
style={style}
onClick={onClick}
>{children}</button>
@ -45,7 +61,7 @@ function Button ({
}: ButtonProps) {
return (
<button
className={`px-5 py-4 transition font-roboto-mono bg-finn border hover:bg-secondary border-border rounded-lg ${className}`}
className={`btn bg-finn border hover:bg-secondary border-border ${className}`}
style={style}
onClick={onClick}
>{children}</button>
@ -54,5 +70,6 @@ function Button ({
Button.Primary = Primary;
Button.Secondary = Secondary;
Button.Danger = Danger;
export default Button;

View File

@ -25,7 +25,7 @@ export default function EvoInput ({
<label className={`flex items-center justify-between cursor-pointer bg-finn border border-border rounded-lg ${className}`} onClick={handleClick}>
<div className="w-fit p-2 text-sm ps-4">{name}</div>
<input
className="w-1/2 h-full p-2 text-center text-sm font-roboto-mono bg-transparent"
className="w-1/2 h-full p-2 text-right pe-4 text-sm font-roboto-mono bg-transparent"
type={type}
name=""
id=""

View File

@ -0,0 +1,14 @@
interface TwoRowTab {
className?: string;
prop?: string;
value?: string | number;
}
export default function TwoRowTab ({ className, prop, value }: TwoRowTab) {
return (
<div className={`flex justify-between font-roboto-mono ${className}`}>
<div>{prop}</div>
<div>{value}</div>
</div>
)
}

View File

@ -0,0 +1,121 @@
import { ChangeEvent, MouseEventHandler, Ref, useState } from "react";
import { usePhotoresistor } from "../../hooks";
import { DynamicPinState } from "../../types/board";
import CircleResistance from "../shapes/CircleResistance";
import TwoRowTab from "../info/TwoRowTab";
import EvoInput from "../forms/EvoInput";
import Button from "../forms/Button";
function Card ({ index, resistor }: { index: number, resistor: DynamicPinState }) {
const { setResistorPin, removeResistor } = usePhotoresistor();
const [isListen, setListen] = useState(false);
const resistance = resistor.state;
const intensity = `${resistor.state / 1023 * 100}%`;
const toggleListen = () => {
setListen(!isListen);
}
const handleChange = (e: ChangeEvent<HTMLInputElement | null>) => {
setResistorPin(index, e.target.value);
}
const handleDelete = () => {
removeResistor(index);
}
return (
<div className="border border-border bg-secondary col-span-2 rounded-lg p-6 animate-size-fade-in">
<div className="flex justify-items-end">
<button className="ms-auto bg-finn hover:bg-secondary transition border border-border rounded-lg px-5" onClick={handleDelete}>
<i className="bi bi-dash text-xl"></i>
</button>
</div>
<div className="h-52 flex items-center justify-center">
<CircleResistance
resistance={0}
/>
</div>
<div className="flex flex-col mt-3 gap-3">
<TwoRowTab
prop="Resistance"
value={resistance}
/>
<TwoRowTab
prop="Light Intensity"
value={intensity}
/>
<EvoInput
className="h-10"
name="Pin"
type="text"
value={resistor.pin.toString()}
onChange={(handleChange)}
/>
{!isListen ? (
<Button.Primary onClick={toggleListen} className="text-sm !p-0 h-11">Start Listening</Button.Primary>
) : (
<Button.Danger onClick={toggleListen} className="text-sm !p-0 h-11">Stop Listening</Button.Danger>
)}
</div>
</div>
)
}
function CardPlus ({ onClick }: { onClick?: MouseEventHandler<HTMLButtonElement> }) {
return (
<button
className="bg-finn h-[470px] hover:bg-secondary transition col-span-2 rounded-lg border border-border flex items-center justify-center"
onClick={onClick}
>
<i className="bi bi-plus text-6xl text-border"></i>
</button>
)
}
function ControlPhotoresistor ({ refto }: { refto?: Ref<HTMLDivElement> }) {
const { photoresistor: resistors, addResistor } = usePhotoresistor();
const handleAdd = (): void => {
let anopin = 5;
for (let i = 0; i < resistors.length; i++) {
if (resistors.filter(resistor => (resistor.pin == `A${anopin}` || resistor.pin == anopin)).length > 0) {
anopin--;
}
else break;
}
addResistor(`A${anopin}`, 0);
}
return (
<div className="container py-16" id="rgb-led" ref={refto}>
<div className="container-grid items-center relative">
<div className={`col-span-8`}>
<h2 className="text-4xl font-poppins font-bold leading-normal mb-4">
Photoresistor
</h2>
<div className="grid grid-cols-8 mb-8">
<p className="col-span-6">Also known as LDR (Light Dependent Resistor), it is an electronic component whose resistance changes based on the intensity of light it receives. The higher the light intensity, the lower the resistance, When exposed to intense light, a photoresistor experiences a decrease in resistance due to photoconduction. The molecules in the photoresistor material become more active and allow electric current to flow through the material more easily.</p>
</div>
<div className={`grid grid-cols-8 gap-6`}>
{resistors.map((resistor, i) => (
<Card
key={i}
resistor={resistor}
index={i}
/>
))}
{resistors.length < 6 && <CardPlus
onClick={handleAdd}
/>}
</div>
</div>
</div>
</div>
)
}
export default ControlPhotoresistor;

View File

@ -0,0 +1,39 @@
interface CircleResistanceProps {
className?: string;
width?: number;
height?: number;
blur?: number;
resistance?: number;
}
export default function CircleResistance({
className,
width,
height,
blur,
resistance,
}: CircleResistanceProps) {
return (
<div
className={className}
style={{
borderRadius: 999,
width: width || 122,
height: height || 122,
backgroundColor: "rgba(255, 255, 255, 0.20)",
}}
>
<div
style={{
backgroundColor: "white",
borderRadius: 999,
width: width || 122,
height: height || 122,
filter: `blur(${blur || 12}px)`,
boxShadow: '0 0 52 22 #FF2929',
opacity: resistance ? resistance/1023*100 : 0
}}
></div>
</div>
);
}

View File

@ -47,7 +47,12 @@ const INIT_VALUES: ControllerContextProps = {
}
],
motoServo: [],
photoresistor: [],
photoresistor: [
{
pin: "A0",
state: 0
}
],
}
export const BoardControllerContext = createContext<ControllerContextProps>(INIT_VALUES);

View File

@ -30,6 +30,17 @@
to { opacity: 1; }
}
@keyframes size-fade-in {
from {
transform: scale(0);
opacity: 0;
}
to {
transform: scale(1);
opacity: 1;
}
}
@keyframes wewew {
0% { transform: scale(1, 1); }
12% { transform: scale(1.1, .9); }
@ -47,6 +58,7 @@
@apply grid grid-cols-8 gap-6;
}
.switch {
@apply rounded-lg transition;
}
@ -55,6 +67,11 @@
}
.btn {
@apply px-5 py-4 transition font-roboto-mono rounded-lg
}
.switch-on {
@apply border-primary bg-primary bg-opacity-40;
}

View File

@ -6,6 +6,7 @@ export function usePin () {
return useContext(BoardControllerContext);
}
export function useLed () {
const { leds, setLeds } = useContext(BoardControllerContext);
@ -117,3 +118,33 @@ export function usePiezo () {
return { piezo, getPiezo, addPiezo, removePiezo, setFrequency, setPiezoPin };
}
export function usePhotoresistor () {
const { photoresistor, setPhotoresistor } = useContext(BoardControllerContext);
const getResistor = (pin: number | string) => {
return photoresistor.find(val => val.pin == pin);
}
const addResistor = (pin: number | string, state: number) => {
const newPesistor = [...photoresistor, { pin, state }];
setPhotoresistor!(newPesistor);
}
const removeResistor = (index: number) => {
const newPesistor = photoresistor.filter((_resist, i) => i != index);
setPhotoresistor!(newPesistor);
}
const setResistorPin = (index: number, newPin: number | string) => {
const newPesistor = photoresistor.map((resist, i) => {
if (i == index) return { pin: newPin, state: resist.state };
return resist;
})
setPhotoresistor!(newPesistor);
}
return { photoresistor, getResistor, addResistor, removeResistor, setResistorPin };
}

View File

@ -10,6 +10,7 @@ import LunarImg from "../assets/img/ocs/lunar-oc.png";
import ControlNav from "../data/control-navigation.json";
import ControlRgbLed from "../components/landing/ControlRgbLed";
import ControlPiezo from "../components/landing/ControlPiezo";
import ControlPhotoresistor from "../components/landing/ControlPhotoresistor";
function MainPage () {
const led = useRef<HTMLDivElement | null>(null);
@ -26,6 +27,7 @@ function MainPage () {
<ControlLED refto={led} />
<ControlRgbLed refto={rgbLed} />
<ControlPiezo refto={piezo} />
<ControlPhotoresistor />
</MainBody>
</>)
}

View File

@ -24,6 +24,7 @@ export default {
animation: {
'size-in': 'size-in .3s ease-in-out',
'fade-in': 'fade-in .3s ease-in-out',
'size-fade-in': 'size-fade-in .3s ease-in-out',
'wewew': 'wewew .9s ease-in-out infinite',
}
},