Skip to content

Commit

Permalink
feature: Sticker Positioning (#76)
Browse files Browse the repository at this point in the history
* update: removed deadzone

* feat: position stickers relative to page elements

* refactor: centralize sticker positioning logic to base sticker component

* fix: position value wrapped with quotes

* refactor: remove unnecessary forwardRef on sticker

* feat: sticker positioning component

* fix: remove extraneous broken sticker layout component

* feat: remove hack sticker from button

---------

Co-authored-by: Tyler Yu <tyleryy@uci.edu>
  • Loading branch information
alexanderl19 and tyleryy committed Oct 29, 2023
1 parent cca3883 commit ff15acf
Show file tree
Hide file tree
Showing 13 changed files with 142 additions and 71 deletions.
4 changes: 3 additions & 1 deletion apps/site/src/components/Sticker/BaseSticker.module.scss
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
.stickerContainer {
.sticker {
cursor: grab;
position: absolute;
z-index: 100;
}
20 changes: 14 additions & 6 deletions apps/site/src/components/Sticker/BaseSticker.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
"use client";

import { MutableRefObject, useRef } from "react";
import { motion } from "framer-motion";

import styles from "./BaseSticker.module.scss";
import { MutableRefObject, useRef } from "react";

interface StickerProps {
imageSrc: string;
Expand All @@ -14,9 +15,11 @@ interface StickerProps {
// dragConstraints prop can be an object containing coordinates, a Falsy boolean, or a parent ref (https://www.framer.com/motion/gestures/#:~:text=%23-,dragConstraints%3A,-false%20%7C%20Partial%3CBoundingBox2D)
animate?: object | undefined;
transition?: object | undefined;
offsetX?: number;
offsetY?: number;
}

export default function Sticker({
const BaseSticker: React.FC<StickerProps> = ({
imageSrc,
alt,
height = 100,
Expand All @@ -25,7 +28,9 @@ export default function Sticker({
dragConstraints = false,
animate = {},
transition = {},
}: StickerProps) {
offsetX = 0,
offsetY = 0,
}) => {
// prevent next from throwing error involving DOM API
const pageRef = useRef(
typeof document !== "undefined" ? document.documentElement : undefined,
Expand Down Expand Up @@ -53,6 +58,7 @@ export default function Sticker({
filter: `drop-shadow(10px 14px 10px rgba(0, 0, 0, 0.2))`,
},
drag: true,
initial: { x: -width / 2 + offsetX, y: -height / 2 + offsetY },
dragMomentum: false,
dragConstraints: dragConstraints ? dragConstraints : pageRef,
dragElastic: 0.2,
Expand All @@ -62,13 +68,15 @@ export default function Sticker({

return (
<motion.img
className={styles.stickerContainer}
animate={animateProps}
src={imageSrc}
alt={alt}
height={height}
width={width}
className={styles.sticker}
animate={animateProps}
{...drag}
/>
);
}
};

export default BaseSticker;
12 changes: 12 additions & 0 deletions apps/site/src/components/Sticker/StickerPosition.module.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
.stickerPosition {
position: relative;
display: flex;
justify-content: center;
width: max-content;
}

.stickerParent {
position: relative;
width: 0;
height: 0;
}
56 changes: 56 additions & 0 deletions apps/site/src/components/Sticker/StickerPosition.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import type { StickerProps } from "./Stickers/stickerProps";
import styles from "./StickerPosition.module.scss";

interface Sticker {
Node: React.ComponentType<StickerProps>;
positionX?: "left" | "right";
positionY?: "top" | "bottom";
offsetX?: number;
offsetY?: number;
}

const StickerParent: React.FC<Sticker> = ({
Node,
positionY = "top",
offsetX,
offsetY,
}) => (
<div
className={styles.stickerParent}
style={{
alignSelf: positionY === "top" ? "flex-start" : "flex-end",
}}
>
<Node offsetX={offsetX} offsetY={offsetY} />
</div>
);

interface StickerPositionProps {
children?: React.ReactNode;
stickers: Sticker[];
}

const StickerPosition: React.FC<StickerPositionProps> = ({
children,
stickers,
}) => {
return (
<div className={styles.stickerPosition}>
{stickers
.filter(({ positionX }) => !positionX || positionX === "left")
.map((sticker) => (
// eslint-disable-next-line react/jsx-key
<StickerParent {...sticker} />
))}
{children}
{stickers
.filter(({ positionX }) => positionX === "right")
.map((sticker) => (
// eslint-disable-next-line react/jsx-key
<StickerParent {...sticker} />
))}
</div>
);
};

export default StickerPosition;

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
import type React from "react";
import type { StickerProps } from "../stickerProps";
import HackLogo from "@/assets/icons/hack.png";
import BaseSticker from "../../BaseSticker";
import styles from "./HackSticker.module.scss";
import { lightShake } from "@/components/animation";

export default function HackSticker({ style }: { style?: object | undefined }) {
return (
<div className={styles.stickerContainer} style={{ ...style }}>
<BaseSticker
imageSrc={HackLogo.src}
alt="Hack at UCI sticker"
height={200}
width={200}
{...lightShake}
/>
</div>
);
}
const HackSticker: React.FC<StickerProps> = (props) => (
<BaseSticker
imageSrc={HackLogo.src}
alt="Hack at UCI sticker"
height={200}
width={200}
{...lightShake}
{...props}
/>
);

export default HackSticker;
Original file line number Diff line number Diff line change
@@ -1,21 +1,18 @@
import type React from "react";
import type { StickerProps } from "../stickerProps";
import HeartEmoji from "@/assets/images/heart_emoji.png";
import BaseSticker from "../../BaseSticker";
import { fastShake } from "@/components/animation";

export default function HeartSticker({
style,
}: {
style?: object | undefined;
}) {
return (
<div style={{ ...style }}>
<BaseSticker
imageSrc={HeartEmoji.src}
alt="heart emoji sticker"
height={150}
width={150}
{...fastShake}
/>
</div>
);
}
const HeartSticker: React.FC<StickerProps> = (props) => (
<BaseSticker
imageSrc={HeartEmoji.src}
alt="heart emoji sticker"
height={150}
width={150}
{...fastShake}
{...props}
/>
);

export default HeartSticker;
4 changes: 4 additions & 0 deletions apps/site/src/components/Sticker/Stickers/stickerProps.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export interface StickerProps {
offsetX?: number;
offsetY?: number;
}
3 changes: 0 additions & 3 deletions apps/site/src/views/Home/Home.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,11 @@ import Mentor from "./sections/Mentor/Mentor";
import Sponsors from "./sections/Sponsors/Sponsors";
import FAQ from "./sections/FAQ/FAQ";

import StickerLayout from "./components/StickerLayout/StickerLayout";

import styles from "./Home.module.scss";

function Home() {
return (
<>
<StickerLayout />
<div className={styles.home}>
<Landing />
<Intro />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,11 @@ $skew-amount: -30deg;

@include bootstrap.font-size(bootstrap.$h4-font-size);

max-width: 70%;
transform: skew($skew-amount);
// unskew children
> * {
width: max-content;
display: block;
transform: skew(-$skew-amount);
}

Expand Down
30 changes: 22 additions & 8 deletions apps/site/src/views/Home/components/ApplyButton/ApplyButton.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,31 @@
import Button from "react-bootstrap/Button";
import StickerPosition from "@/components/Sticker/StickerPosition";
import { HackSticker, HeartSticker } from "@/components/Sticker/Stickers";

import styles from "./ApplyButton.module.scss";

export default function ApplyButton() {
return (
<Button
className={styles.applyButton}
href="/apply"
variant=""
target="_blank"
disabled
<StickerPosition
stickers={[
{
Node: HeartSticker,
positionX: "right",
positionY: "bottom",
offsetX: 50,
offsetY: 50,
},
]}
>
<div>Applications have closed!</div>
</Button>
<Button
className={styles.applyButton}
href="/apply"
variant=""
target="_blank"
disabled
>
<span>Applications have closed!</span>
</Button>
</StickerPosition>
);
}

This file was deleted.

3 changes: 1 addition & 2 deletions apps/site/src/views/Home/sections/Landing/Landing.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
"use client";

import ApplyButton from "../../components/ApplyButton/ApplyButton";
import ApplyButton from "@/views/Home/components/ApplyButton/ApplyButton";

import styles from "./Landing.module.scss";

Expand Down

0 comments on commit ff15acf

Please sign in to comment.