Skip to content

Commit

Permalink
👄🥻 ↝ [SSM-53 SSM-22 SSM-38 SSM-23]: Tutorial for DMP and trying (fail…
Browse files Browse the repository at this point in the history
…ing) to integrate annotation feature
  • Loading branch information
Gizmotronn committed Oct 26, 2024
1 parent d456810 commit e3d9c90
Show file tree
Hide file tree
Showing 5 changed files with 37 additions and 86 deletions.
11 changes: 3 additions & 8 deletions app/tests/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,18 @@

import React, { useEffect, useState } from "react";
import StarnetLayout from "@/components/Layout/Starnet";
import { ExoplanetTransitHunter } from "@/components/Projects/Telescopes/ExoplanetC23";
import MissionPathway from "@/components/Missions/Pathway";
import ProfileCardModal from "@/components/profile/form";
import { CommunityScienceStation } from "@/components/Structures/Community/StationModal";
import { CreateCommunityStation } from "@/components/Structures/Build/MakeCommunityStation";
import StationsOnPlanet from "@/components/Structures/Community/ViewAllStations";
import ImageAnnotation from "@/components/Projects/(classifications)/Annotation";

export default function TestPage() {
return (
<StarnetLayout>
<CreateCommunityStation />
<StationsOnPlanet />
<></>
</StarnetLayout>
);
};

/*
<ImageAnnotation src={imageUrls[currentImageIndex]} onUpload={uploadAnnotatedImage} />
anomalies = {[
{
id: "1",
Expand Down
2 changes: 1 addition & 1 deletion components/Layout/Starnet.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ export default function StarnetLayout({ children }: { children: React.ReactNode

<div className="flex-1 flex flex-col h-screen">
<header className="bg-squiggly border-b border-gray-200 p-4">
<h1 className="text-xl font-bold text-gray-800 text-center md:text-left">Starnet</h1>
<center><h1 className="text-xl font-bold text-gray-100 text-center md:text-left">Starnet</h1></center>
</header>

<nav className="md:hidden bg-gray-50 border-b border-gray-200">
Expand Down
58 changes: 22 additions & 36 deletions components/Projects/(classifications)/Annotation.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,11 @@ import { Card, CardContent, CardHeader, CardTitle, CardDescription } from "@/com
import * as markerjs2 from "markerjs2";

interface ImageProps {
src: string
};
src: string;
onUpload: (dataUrl: string) => Promise<void>;
}

export default function ImageAnnotation({ src }: ImageProps) {
export default function ImageAnnotation({ src, onUpload }: ImageProps) {
const imageRef = useRef<HTMLImageElement>(null);
const [markerArea, setMarkerArea] = useState<markerjs2.MarkerArea | null>(null);
const [annotationState, setAnnotationState] = useState<string | null>(null);
Expand All @@ -17,70 +18,55 @@ export default function ImageAnnotation({ src }: ImageProps) {
const ma = new markerjs2.MarkerArea(imageRef.current);
setMarkerArea(ma);

// Add render event listener to update the image after annotations
ma.addEventListener("render", (event) => {
if (imageRef.current) {
setAnnotationState(JSON.stringify(ma.getState()));
imageRef.current.src = event.dataUrl;
}
});

// Add close event listener to save the annotation state
ma.addEventListener("close", () => {
setAnnotationState(JSON.stringify(ma.getState()));
});

ma.show(); // Automatically show the marker area when initialized
}
}, []);

// Show MarkerArea to start annotation process
const showMarkerArea = () => {
if (markerArea) {
if (annotationState) {
markerArea.restoreState(JSON.parse(annotationState)); // Restore previous annotations
markerArea.restoreState(JSON.parse(annotationState));
}
markerArea.show();
}
};

// Download the annotated image
const downloadImage = () => {
const downloadImage = async () => {
if (imageRef.current) {
const dataUrl = imageRef.current.src;
if (dataUrl.startsWith('data:image')) {
const link = document.createElement('a');
link.href = dataUrl;
link.download = 'annotated_image.png';
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
} else {
console.error('No base64 data to download');
};
};
const dataUrl = imageRef.current.src; // Get the annotated image data URL
await onUpload(dataUrl);
}
};

return (
<Card className="w-full max-w-3xl mx-auto">
<Card>
<CardHeader>
<CardTitle>Image</CardTitle>
<CardDescription>Annotate the image using marker.js</CardDescription>
<CardTitle>Annotate Image</CardTitle>
<CardDescription>Click the button to start annotating the image.</CardDescription>
</CardHeader>
<CardContent className="flex flex-col items-center py-10 space-y-4">
<div className="flex space-x-2">
<Button onClick={showMarkerArea}>Start Annotating</Button>
<Button onClick={downloadImage} disabled={!annotationState}>Download Annotated Image</Button>
</div>
<div className="border border-gray-300 rounded-lg overflow-hidden">
{/* Ensure this image tag is used for annotation */}
<CardContent>
<div className="flex flex-col items-center">
<img
ref={imageRef}
src={src}
alt="Annotation"
crossOrigin="anonymous"
className="max-w-full h-auto"
alt="Annotated Image"
ref={imageRef}
className="w-full h-auto max-w-md rounded-md"
/>
<Button className="mt-4" onClick={showMarkerArea}>Annotate</Button>
<Button className="mt-2" onClick={downloadImage}>Upload Annotation</Button>
</div>
</CardContent>
</Card>
);
};
}
37 changes: 3 additions & 34 deletions components/Projects/(classifications)/PostForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -133,30 +133,6 @@ const ClassificationForm: React.FC<ClassificationFormProps> = ({

const showTextArea = classificationOptions.length === 0;

const [hasClassified, setHasClassified] = useState<boolean>(false);

// useEffect(() => {
// const checkUserClassification = async () => {
// if (!session?.user?.id || !anomalyId) return;

// const { data, error } = await supabase
// .from("classifications")
// .select("id")
// .eq("author", session.user.id)
// .eq("anomaly", anomalyId)
// .single();

// if (data) {
// setHasClassified(true);
// }
// if (error) {
// console.error("Error checking classification:", error.message);
// }
// };

// checkUserClassification();
// }, [session?.user?.id, anomalyId, supabase]);

useEffect(() => {
const fetchUserProfile = async () => {
if (!session) return;
Expand Down Expand Up @@ -348,10 +324,11 @@ const ClassificationForm: React.FC<ClassificationFormProps> = ({

// if (postSubmitted && showResearch) {
// return (
// <>
// {showModal && <IntroduceUserToResearch closeModal={closeModal} />}
// </>
// );
// if (postSubmitted) {
// return <ClassificationOutput configuration={classificationOutput} />;
// };
// };

const addMedia = async (e: React.ChangeEvent<HTMLInputElement>) => {
Expand Down Expand Up @@ -381,10 +358,6 @@ const ClassificationForm: React.FC<ClassificationFormProps> = ({
}
};

// if (postSubmitted) {
// return <ClassificationOutput configuration={classificationOutput} />;
// };

const [additionalFields, setAdditionalFields] = useState<{
[key: string]: string;
}>({});
Expand Down Expand Up @@ -451,7 +424,6 @@ const ClassificationForm: React.FC<ClassificationFormProps> = ({
<div className="flex flex-col gap-6">
{classificationOptions.length > 0 ? (
<>
{/* Multiple Choice Buttons */}
<div className="flex flex-col gap-2">
{classificationOptions.map((optionSet, setIndex) => (
<div key={setIndex} className="flex flex-col gap-4">
Expand All @@ -475,7 +447,6 @@ const ClassificationForm: React.FC<ClassificationFormProps> = ({
))}
</div>

{/* Text Area Inputs */}
<div className="flex flex-col gap-4">
<textarea
value={content}
Expand All @@ -484,7 +455,6 @@ const ClassificationForm: React.FC<ClassificationFormProps> = ({
placeholder={placeholder}
/>

{/* Additional Text Area Fields */}
{[...Array(additionalTextAreaConfig.count)].map((_, index) => (
<textarea
key={index}
Expand All @@ -498,7 +468,6 @@ const ClassificationForm: React.FC<ClassificationFormProps> = ({
/>
))}

{/* Upload Button and Submit */}
<div className="flex items-center justify-between">
<label className="flex gap-1 items-center cursor-pointer text-[#88C0D0] hover:text-white">
<input type="file" className="hidden" onChange={addMedia} />
Expand Down
15 changes: 8 additions & 7 deletions components/Projects/Telescopes/DailyMinorPlanet.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import ClassificationForm from "../(classifications)/PostForm";

import { Anomaly } from "../Zoodex/ClassifyOthersAnimals";
import { Button } from "@/components/ui/button";
import ImageAnnotation from "../(classifications)/Annotation";
interface Props {
anomalyid: number | bigint;
};
Expand Down Expand Up @@ -48,22 +49,22 @@ export function StarterDailyMinorPlanet({
<>
{line === 1 && (
<p className="text-[#EEEAD1]">

Welcome to the Asteroid Hunters project. In this project, you will be identifying minor planet candidates, like asteroids, around your local star.
</p>
)}
{line === 2 && (
<p className="text-[#EEEAD1]">

We use the apparent movement of asteroids from image to image to find them, so if you don't see movement, click through the different images to see if the circled object moves
</p>
)}
{line === 3 && (
<p className="text-[#EEEAD1]">

Find the green circle in the subject clip. Within the green circle is one object (light spot) that moves from frame to frame. We call this light spot inside the green circle a detection.
</p>
)}
{line === 4 && (
<p className="text-[#EEEAD1]">

That's it! Get ready to explore the skies. Click "Continue" to start classifying.
</p>
)}

Expand All @@ -84,7 +85,7 @@ export function StarterDailyMinorPlanet({
</button>
)}
{line < 5 && (
<div className="flex justify-center mt-4 w-full h-64">
<div className="flex justify-center mt-4 w-full h-128">
{line === 1 && <img src="/assets/Docs/Telescopes/DailyMinorPlanet/Step1.png" alt="Step 1" className="mex-w-full max-h-full object-contain" />}
{line === 2 && <img src="/assets/Docs/Telescopes/DailyMinorPlanet/Step2.png" alt="Step 2" className="mex-w-full max-h-full object-contain" />}
{line === 3 && <img src="/assets/Docs/Telescopes/DailyMinorPlanet/Step3.png" alt="Step 3" className="mex-w-full max-h-full object-contain" />}
Expand All @@ -94,11 +95,11 @@ export function StarterDailyMinorPlanet({
</>
)}

{part === 1 && (
{part === 2 && (
<>
{line === 1 && (
<p className="text-[#EEEAD1]">
Content

</p>
)}
</>
Expand Down

0 comments on commit e3d9c90

Please sign in to comment.