Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
Mirador annotations
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package registry
Container registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Service Desk
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
GitLab community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
This is an archived project. Repository and other project resources are read-only.
Show more breadcrumbs
IIIF
Mirador
Mirador annotations
Commits
01db5124
Commit
01db5124
authored
Jan 26, 2024
by
Anthony
Browse files
Options
Downloads
Patches
Plain Diff
WIP reorganize
parent
f70454a3
Branches
Branches containing commit
No related tags found
1 merge request
!10
Draft: MigratingAnnotationCreation to MUI5.
Pipeline
#1798
failed
Jan 26, 2024
Stage: test
Changes
3
Pipelines
1
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
src/AnnotationCreation.js
+492
-594
492 additions, 594 deletions
src/AnnotationCreation.js
src/AnnotationDrawing.js
+1
-1
1 addition, 1 deletion
src/AnnotationDrawing.js
src/AnnotationForm/AnnotationFormDrawing.js
+138
-41
138 additions, 41 deletions
src/AnnotationForm/AnnotationFormDrawing.js
with
631 additions
and
636 deletions
src/AnnotationCreation.js
+
492
−
594
View file @
01db5124
import
React
,
{
useEffect
,
useLayoutEffect
,
useState
}
from
'
react
'
;
import
PropTypes
from
'
prop-types
'
;
import
{
Button
,
ClickAwayListener
,
Divider
,
Grid
,
MenuItem
,
MenuList
,
Paper
,
Popover
,}
from
'
@mui/material
'
;
import
ToggleButtonGroup
from
'
@mui/material/ToggleButtonGroup
'
;
import
{
SketchPicker
}
from
'
react-color
'
;
import
{
Button
,
ClickAwayListener
,
Divider
,
Grid
,
MenuItem
,
MenuList
,
Paper
,
Popover
,
}
from
'
@mui/material
'
;
import
{
styled
}
from
'
@mui/material/styles
'
;
import
{
v4
as
uuid
,
v4
as
uuidv4
}
from
'
uuid
'
;
import
{
exportStageSVG
}
from
'
react-konva-to-svg
'
;
...
...
@@ -37,10 +37,25 @@ function geomFromAnnoTarget(annotarget) {
return
r
[
1
];
}
/** Component for creating annotations.
* Display in companion window when a manifest is open and an annoation created or edited */
function
AnnotationCreation
(
props
)
{
const
[
toolState
,
setToolState
]
=
useState
({
activeTool
:
'
cursor
'
,
closedMode
:
'
closed
'
,
colorPopoverOpen
:
false
,
currentColorType
:
false
,
fillColor
:
'
black
'
,
image
:
{
id
:
null
},
imageEvent
:
null
,
lineWeightPopoverOpen
:
false
,
popoverAnchorEl
:
null
,
// ...(props.config.annotation.defaults || {}),
popoverLineWeightAnchorEl
:
null
,
strokeColor
:
'
green
'
,
strokeWidth
:
3
,
});
// Initial state setup
const
[
state
,
setState
]
=
useState
(()
=>
{
const
annoState
=
{};
...
...
@@ -89,18 +104,6 @@ function AnnotationCreation(props) {
}
}
// TODO add default values from config
const
toolState
=
{
activeTool
:
'
cursor
'
,
closedMode
:
'
closed
'
,
colorPopoverOpen
:
false
,
currentColorType
:
false
,
fillColor
:
'
black
'
,
strokeColor
:
'
green
'
,
strokeWidth
:
3
,
...(
props
.
config
.
annotation
.
defaults
||
{}),
};
const
timeState
=
props
.
currentTime
!==
null
?
{
tend
:
Math
.
floor
(
props
.
currentTime
)
+
10
,
tstart
:
Math
.
floor
(
props
.
currentTime
)
}
:
{
tend
:
null
,
tstart
:
null
};
...
...
@@ -108,22 +111,15 @@ function AnnotationCreation(props) {
return
{
...
toolState
,
...
timeState
,
activeTool
:
'
cursor
'
,
closedMode
:
'
closed
'
,
currentColorType
:
false
,
image
:
{
id
:
null
},
imageEvent
:
null
,
lineWeightPopoverOpen
:
false
,
mediaVideo
:
null
,
popoverAnchorEl
:
null
,
popoverLineWeightAnchorEl
:
null
,
textBody
:
''
,
...
annoState
,
textBody
:
''
,
textEditorStateBustingKey
:
0
,
valuetextTime
:
''
,
valueTime
:
[
0
,
1
],
};
});
const
[
scale
,
setScale
]
=
useState
(
1
);
const
{
height
,
width
}
=
VideosReferences
.
get
(
props
.
windowId
).
ref
.
current
;
...
...
@@ -148,31 +144,12 @@ function AnnotationCreation(props) {
/** */
const
handleImgChange
=
(
newUrl
,
imgRef
)
=>
{
setState
((
prevState
)
=>
({
set
Tool
State
((
prevState
)
=>
({
...
prevState
,
image
:
{
...
prevState
.
image
,
id
:
newUrl
},
}));
};
/** */
const
handleCloseLineWeight
=
(
e
)
=>
{
setState
((
prevState
)
=>
({
...
prevState
,
lineWeightPopoverOpen
:
false
,
popoverLineWeightAnchorEl
:
null
,
}));
};
/** */
const
handleLineWeightSelect
=
(
e
)
=>
{
setState
((
prevState
)
=>
({
...
prevState
,
lineWeightPopoverOpen
:
false
,
popoverLineWeightAnchorEl
:
null
,
strokeWidth
:
e
.
currentTarget
.
value
,
}));
};
/** set annotation start time to current time */
const
setTstartNow
=
()
=>
{
setState
((
prevState
)
=>
({
...
...
@@ -256,39 +233,36 @@ function AnnotationCreation(props) {
};
/** */
const
openChooseColor
=
(
e
)
=>
{
const
updateGeometry
=
({
svg
,
xywh
}
)
=>
{
setState
((
prevState
)
=>
({
...
prevState
,
colorPopoverOpen
:
true
,
currentColorType
:
e
.
currentTarget
.
value
,
popoverAnchorEl
:
e
.
currentTarget
,
svg
,
xywh
,
}));
};
/** */
const
openChooseLineWeight
=
(
e
)
=>
{
setState
((
prevState
)
=>
({
...
prevState
,
lineWeightPopoverOpen
:
true
,
popoverLineWeightAnchorEl
:
e
.
currentTarget
,
}));
};
const
setShapeProperties
=
(
options
)
=>
new
Promise
(()
=>
{
if
(
options
.
fill
)
{
state
.
fillColor
=
options
.
fill
;
}
/** Close color popover window */
const
closeChooseColor
=
(
e
)
=>
{
setState
((
prevState
)
=>
({
...
prevState
,
colorPopoverOpen
:
false
,
currentColorType
:
null
,
popoverAnchorEl
:
null
,
}));
};
if
(
options
.
strokeWidth
)
{
state
.
strokeWidth
=
options
.
strokeWidth
;
}
if
(
options
.
stroke
)
{
state
.
strokeColor
=
options
.
stroke
;
}
/** Update strokecolor */
const
updateStrokeColor
=
(
color
)
=>
{
setState
({
...
state
});
});
/** */
const
updateTextBody
=
(
textBody
)
=>
{
setState
((
prevState
)
=>
({
...
prevState
,
[
prevState
.
currentColorType
]:
color
.
hex
,
textBody
,
}));
};
...
...
@@ -386,74 +360,6 @@ function AnnotationCreation(props) {
});
};
/** */
const
changeTool
=
(
e
,
tool
)
=>
{
setState
((
prevState
)
=>
({
...
prevState
,
activeTool
:
tool
,
}));
};
/** */
const
changeClosedMode
=
(
e
)
=>
{
setState
((
prevState
)
=>
({
...
prevState
,
closedMode
:
e
.
currentTarget
.
value
,
}));
};
/** */
const
updateTextBody
=
(
textBody
)
=>
{
setState
((
prevState
)
=>
({
...
prevState
,
textBody
,
}));
};
/**
*
*/
const
addImage
=
()
=>
{
const
data
=
{
uuid
:
uuidv4
(),
id
:
image
?.
id
,
};
setState
((
prevState
)
=>
({
...
prevState
,
imageEvent
:
data
,
}));
};
/** */
const
setShapeProperties
=
(
options
)
=>
new
Promise
(()
=>
{
if
(
options
.
fill
)
{
state
.
fillColor
=
options
.
fill
;
}
if
(
options
.
strokeWidth
)
{
state
.
strokeWidth
=
options
.
strokeWidth
;
}
if
(
options
.
stroke
)
{
state
.
strokeColor
=
options
.
stroke
;
}
setState
({...
state
});
});
/** */
const
updateGeometry
=
({
svg
,
xywh
,
})
=>
{
setState
((
prevState
)
=>
({
...
prevState
,
svg
,
xywh
,
}));
};
/** */
const
{
annotation
,
...
...
@@ -462,6 +368,16 @@ function AnnotationCreation(props) {
windowId
,
}
=
props
;
const
{
textBody
,
tstart
,
tend
,
textEditorStateBustingKey
,
valueTime
,
mediaVideo
,
title
,
}
=
state
;
const
{
activeTool
,
colorPopoverOpen
,
...
...
@@ -473,15 +389,8 @@ function AnnotationCreation(props) {
lineWeightPopoverOpen
,
strokeWidth
,
closedMode
,
textBody
,
tstart
,
tend
,
textEditorStateBustingKey
,
image
,
valueTime
,
mediaVideo
,
title
,
}
=
state
;
}
=
toolState
;
// TODO : Vérifier ce code, c'est étrange de comprarer un typeof à une chaine de caractère.
const
mediaIsVideo
=
typeof
VideosReferences
.
get
(
windowId
)
!==
'
undefined
'
;
...
...
@@ -511,14 +420,8 @@ function AnnotationCreation(props) {
console
.
log
(
'
scale
'
,
scale
);
},
[
overlay
.
containerWidth
,
overlay
.
canvasWidth
]);
// stage.width(sceneWidth * scale);
// stage.height(sceneHeight * scale);
// stage.scale({ x: scale, y: scale });
return
(
// we need to get the width and height of the image to pass it to the annotation drawing component
<
CompanionWindow
title
=
{
title
?
title
.
value
:
'
New Annotation
'
}
windowId
=
{
windowId
}
...
...
@@ -551,7 +454,6 @@ function AnnotationCreation(props) {
setShapeProperties
=
{
setShapeProperties
}
updateScale
=
{
updateScale
}
imageEvent
=
{
state
.
imageEvent
}
// TODO Ajouter du style pour que le Konva et la vidéo se superpose
/
>
<
StyledForm
onSubmit
=
{
submitForm
}
...
...
@@ -575,20 +477,16 @@ function AnnotationCreation(props) {
setTendNow
=
{
setTendNow
}
tend
=
{
tend
}
updateTend
=
{
updateTend
}
/>
)
}
/
>
)}
<
AnnotationFormDrawing
value
=
{
activeTool
}
onChange
=
{
changeTool
}
onClick
=
{
openChooseColor
}
fill
=
{
strokeColor
}
onClick1
=
{
openChooseLineWeight
}
fill1
=
{
fillColor
}
activeTool
=
{
activeTool
}
value
=
{
closedMode
}
onChange
=
{
changeClosedMode
}
value1
=
{
image
}
onChange1
=
{
handleImgChange
}
onClick2
=
{
addImage
}
/
>
stroke
=
{
strokeColor
}
fill
=
{
fillColor
}
closedMode
=
{
closedMode
}
image
=
{
image
}
handleImgChange
=
{
handleImgChange
}
/
>
<
div
>
<
Button
onClick
=
{
closeCompanionWindow
}
>
Cancel
...
...
This diff is collapsed.
Click to expand it.
src/AnnotationDrawing.js
+
1
−
1
View file @
01db5124
...
...
@@ -12,7 +12,7 @@ import { v4 as uuidv4 } from 'uuid';
import
{
OSDReferences
}
from
'
mirador/dist/es/src/plugins/OSDReferences
'
;
// eslint-disable-next-line import/no-extraneous-dependencies
import
{
VideosReferences
}
from
'
mirador/dist/es/src/plugins/VideosReferences
'
;
import
ParentComponent
from
'
./KonvaDrawing/shapes/ParentComponent
'
;
import
ParentComponent
from
'
./
AnnotationForm/
KonvaDrawing/shapes/ParentComponent
'
;
/** All the stuff to draw on the canvas */
...
...
This diff is collapsed.
Click to expand it.
src/AnnotationForm/AnnotationFormDrawing.js
+
138
−
41
View file @
01db5124
import
{
Button
,
ClickAwayListener
,
Divider
,
Grid
,
MenuItem
,
MenuList
,
Paper
,
Popover
}
from
'
@mui/material
'
;
import
{
Button
,
ClickAwayListener
,
Divider
,
Grid
,
MenuItem
,
MenuList
,
Paper
,
Popover
,
}
from
'
@mui/material
'
;
import
Typography
from
'
@mui/material/Typography
'
;
import
ToggleButton
from
'
@mui/material/ToggleButton
'
;
import
TitleIcon
from
'
@mui/icons-material/Title
'
;
...
...
@@ -9,7 +11,7 @@ import RectangleIcon from '@mui/icons-material/CheckBoxOutlineBlank';
import
CircleIcon
from
'
@mui/icons-material/RadioButtonUnchecked
'
;
import
PolygonIcon
from
'
@mui/icons-material/Timeline
'
;
import
GestureIcon
from
'
@mui/icons-material/Gesture
'
;
import
React
from
'
react
'
;
import
React
,
{
useState
}
from
'
react
'
;
import
ToggleButtonGroup
from
'
@mui/material/ToggleButtonGroup
'
;
import
StrokeColorIcon
from
'
@mui/icons-material/BorderColor
'
;
import
ArrowDropDownIcon
from
'
@mui/icons-material/ArrowDropDown
'
;
...
...
@@ -19,12 +21,11 @@ import ClosedPolygonIcon from '@mui/icons-material/ChangeHistory';
import
OpenPolygonIcon
from
'
@mui/icons-material/ShowChart
'
;
import
AddPhotoAlternateIcon
from
'
@mui/icons-material/AddPhotoAlternate
'
;
import
PropTypes
from
'
prop-types
'
;
import
{
styled
}
from
'
@mui/material/styles
'
;
import
{
SketchPicker
}
from
'
react-color
'
;
import
{
v4
as
uuidv4
}
from
'
uuid
'
;
import
CursorIcon
from
'
../icons/Cursor
'
;
import
ImageFormField
from
'
./ImageFormField
'
;
import
CursorIcon
from
"
../icons/Cursor
"
;
import
{
styled
}
from
"
@mui/material/styles
"
;
import
{
SketchPicker
}
from
"
react-color
"
;
const
StyledToggleButtonGroup
=
styled
(
ToggleButtonGroup
)(({
theme
})
=>
({
'
&:first-of-type
'
:
{
...
...
@@ -41,7 +42,106 @@ const StyledDivider = styled(Divider)(({theme}) => ({
margin
:
theme
.
spacing
(
1
,
0.5
),
}));
function
AnnotationFormDrawing
(
props
)
{
function
AnnotationFormDrawing
({
activeTool
,
closedMode
,
...
props
})
{
/* const [state, setState] = useState({
activeTool: 'cursor',
closedMode: 'closed',
colorPopoverOpen: false,
currentColorType: false,
fillColor: 'black',
strokeColor: 'green',
strokeWidth: 3,
...(props.config.annotation.defaults || {}),
};*/
/** */
const
openChooseLineWeight
=
(
e
)
=>
{
setState
((
prevState
)
=>
({
...
prevState
,
lineWeightPopoverOpen
:
true
,
popoverLineWeightAnchorEl
:
e
.
currentTarget
,
}));
};
/** Close color popover window */
const
closeChooseColor
=
(
e
)
=>
{
setState
((
prevState
)
=>
({
...
prevState
,
colorPopoverOpen
:
false
,
currentColorType
:
null
,
popoverAnchorEl
:
null
,
}));
};
/** Update strokecolor */
const
updateStrokeColor
=
(
color
)
=>
{
setState
((
prevState
)
=>
({
...
prevState
,
[
prevState
.
currentColorType
]:
color
.
hex
,
}));
};
/** */
const
openChooseColor
=
(
e
)
=>
{
setState
((
prevState
)
=>
({
...
prevState
,
colorPopoverOpen
:
true
,
currentColorType
:
e
.
currentTarget
.
value
,
popoverAnchorEl
:
e
.
currentTarget
,
}));
};
/** */
const
handleCloseLineWeight
=
(
e
)
=>
{
setState
((
prevState
)
=>
({
...
prevState
,
lineWeightPopoverOpen
:
false
,
popoverLineWeightAnchorEl
:
null
,
}));
};
/** */
const
handleLineWeightSelect
=
(
e
)
=>
{
setState
((
prevState
)
=>
({
...
prevState
,
lineWeightPopoverOpen
:
false
,
popoverLineWeightAnchorEl
:
null
,
strokeWidth
:
e
.
currentTarget
.
value
,
}));
};
const
changeTool
=
(
e
,
tool
)
=>
{
setState
((
prevState
)
=>
({
...
prevState
,
activeTool
:
tool
,
}));
};
const
changeClosedMode
=
(
e
)
=>
{
setState
((
prevState
)
=>
({
...
prevState
,
closedMode
:
e
.
currentTarget
.
value
,
}));
};
/**
*
*/
const
addImage
=
()
=>
{
const
data
=
{
uuid
:
uuidv4
(),
id
:
image
?.
id
,
};
setState
((
prevState
)
=>
({
...
prevState
,
imageEvent
:
data
,
}));
};
return
(
<
div
>
<
div
>
...
...
@@ -60,13 +160,12 @@ function AnnotationFormDrawing(props) {
}}
>
<
StyledToggleButtonGroup
value
=
{
props
.
value
}
value
=
{
activeTool
}
// State or props ?
exclusive
onChange
=
{
props
.
onC
hange
}
onChange
=
{
c
hange
Tool
}
aria
-
label
=
"
tool selection
"
size
=
"
small
"
>
<
ToggleButton
value
=
"
text
"
aria
-
label
=
"
select text
"
>
<
TitleIcon
/>
<
/ToggleButton
>
...
...
@@ -126,7 +225,7 @@ function AnnotationFormDrawing(props) {
<
ToggleButton
value
=
"
strokeColor
"
aria
-
label
=
"
select color
"
onClick
=
{
props
.
onClick
}
onClick
=
{
openChooseColor
}
>
<
StrokeColorIcon
style
=
{{
fill
:
props
.
fill
}}
/
>
<
ArrowDropDownIcon
/>
...
...
@@ -134,7 +233,7 @@ function AnnotationFormDrawing(props) {
<
ToggleButton
value
=
"
strokeColor
"
aria
-
label
=
"
select line weight
"
onClick
=
{
props
.
onClick1
}
onClick
=
{
openChooseLineWeight
}
>
<
LineWeightIcon
/>
<
ArrowDropDownIcon
/>
...
...
@@ -142,9 +241,9 @@ function AnnotationFormDrawing(props) {
<
ToggleButton
value
=
"
fillColor
"
aria
-
label
=
"
select color
"
onClick
=
{
props
.
onClick
}
onClick
=
{
openChooseColor
}
>
<
FormatColorFillIcon
style
=
{{
fill
:
props
.
fill
1
}}
/
>
<
FormatColorFillIcon
style
=
{{
fill
:
props
.
fill
}}
/
>
<
ArrowDropDownIcon
/>
<
/ToggleButton
>
<
/ToggleButtonGroup
>
...
...
@@ -155,8 +254,8 @@ function AnnotationFormDrawing(props) {
?
(
<
ToggleButtonGroup
size
=
"
small
"
value
=
{
props
.
valu
e
}
onChange
=
{
props
.
onChang
e
}
value
=
{
closedMod
e
}
onChange
=
{
changeClosedMod
e
}
>
<
ToggleButton
value
=
"
closed
"
>
<
ClosedPolygonIcon
/>
...
...
@@ -172,10 +271,10 @@ function AnnotationFormDrawing(props) {
<
/Grid
>
<
Grid
container
>
<
Grid
item
xs
=
{
8
}
style
=
{{
marginBottom
:
10
}}
>
<
ImageFormField
xs
=
{
8
}
value
=
{
props
.
value1
}
onChange
=
{
props
.
on
Change
1
}
/
>
<
ImageFormField
xs
=
{
8
}
value
=
{
image
}
onChange
=
{
handleImg
Change
}
/
>
<
/Grid
>
<
Grid
item
xs
=
{
4
}
style
=
{{
marginBottom
:
10
}}
>
<
Button
variant
=
"
contained
"
onClick
=
{
props
.
onClick2
}
>
<
Button
variant
=
"
contained
"
onClick
=
{
addImage
}
>
<
AddPhotoAlternateIcon
/>
<
/Button
>
<
/Grid
>
...
...
@@ -211,7 +310,7 @@ function AnnotationFormDrawing(props) {
>
<
SketchPicker
// eslint-disable-next-line react/destructuring-assignment
color
=
{
state
[
currentColorType
]
||
{}
}
color
=
{
currentColorType
}
onChangeComplete
=
{
updateStrokeColor
}
/
>
<
/Popover
>
...
...
@@ -224,11 +323,9 @@ AnnotationFormDrawing.propTypes = {
onChange
:
PropTypes
.
func
,
onClick
:
PropTypes
.
func
,
fill
:
PropTypes
.
string
,
stroke
:
PropTypes
.
string
,
onClick1
:
PropTypes
.
func
,
fill1
:
PropTypes
.
string
,
activeTool
:
PropTypes
.
string
,
value
:
PropTypes
.
string
,
onChange
:
PropTypes
.
func
,
value1
:
PropTypes
.
shape
({
id
:
PropTypes
.
any
}),
onChange1
:
PropTypes
.
func
,
onClick2
:
PropTypes
.
func
,
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment