dist/directory statically, with gzip compression since the generated
Main.jsfile by the client application is roughly 1.2 MB raw but 150 KB gzipped.
Model. It contains all and every information about our application state. The visual aspect of our application is called the
Viewis generated from and only from the
Model. Meaning there is a function called
viewwhich takes a
Model, and returns a
View(basically an HTML document). And finally, all events generate messages, of type
Msg. We have a function called
update, changing the model by reacting to those messages, closing the loop.
Cmd) generated by the update function, like making http requests.
Sub) to outside world events like the time ticking.
Msgof our choosing and route it to the update function.
viewParametersfield contains cached parameters precomputed for the view function, like the current device type (phone, tablet, computer) depending on window dimension, or other view-related parameters.
statefield contains the main state of our application i.e. the images loaded, the configuration chosen, the annotations performed etc. We will describe this further.
viewerfield contains the entity recording movements coordinates relative to the image frame and zoom ratio, in order to display correctly the annotations on the image.
dragStateis constantly tracking the state of the pointer. Whether it is currently up or down and dragging from a given initial position.
stateis of type
Statedefined as follows:
NothingProvided) and provides a button to load images. In doing so, you reach state 1a (
ImagesProvided), and then by providing a configuration you finally reach the state 2 (
AllProvided). It is the state in which we can annotate images. State 1b (
ConfigProvided) should only be reachable by providing a config in startup flags (see last section) and no image. Two messages called
ConfigLoadedproduce transitions in the state machine. They are detailed soon.
Zipper(wikipedia, lyahfgg) is a very usefull collection. In our case, it is more or less a non empty list, in which at all times, there is one element selected. Since there is always a tool selected (movement or annotation tool) and always an image selected, it is the perfect collection type for this job.
updatefunction then performs the modifications of the model described by such a message.
WindowResizesmessage is triggered when the application is resized. In the update function, it takes the new size and recomputes some view parameters and the annotation viewer.
PointerMsgmessage is triggered by pointer events (mouse, touch, etc.). In the update function, this is the message activating all the annotations logic code of our application.
SelectClasswith their corresponding integer ids are generated when clicking on images, tools and classes in their respective bars.
imgtag since this is not possible within Elm. For every image correctly loaded into an
ImageLoadedmessage, providing a local url, corresponding to the image in memory.
Exportmessage causes the application to serialize into Json all the annotations, and asks the user to save the generated file. It is triggered by clicking on the export button of the top action bar.
ZoomMsgmessage should be generated. The update function will update relevant model fields according to the message.
RemoveLatestAnnotationmessage is stating that we should remove latest annotation of the current tool selected. The update function takes care of doing it, if possible.
emptyView : Parameters msg -> Element ...: provides a bar with only one button to load images, in order to transition to the
viewImages : Parameters msg -> Element ...: provides an additional button to load a config, in order to transition to the
viewAll : Parameters msg -> Zipper Tool -> Element ...: provides a fully functional action bar, with the tools as specified in the configuration Json file.
viewConfig : Parameters msg -> Zipper Tool -> Element ...: provides a preview of the configuration loaded but not yet actionable. This is not visible in the "normal" app transitions, only if start flags (see next section) provided in the
index.htmlfile provide a config but no image.
index.htmlfile with initial values called flags. Currently, flags contain four objects.
deviceSizeprovides the initial size of the area allocated to the application in the html page.
mturkModetoggles a mode in which the action bar view does not show the buttons to load images or load a config. It also replaces the icon button to export annotation by a textual "Submit" button.
imagescontains a list of images (url, width, height) with an already available url, without having to locally load them in memory from the disk.
configcan provide an already defined configuration, to avoid having to load a Json file later.
NothingProvidedstate. In order to reach the
ConfigProvidedstate (1b), one should use flags with a valid config, and an empty images array.
src/Ports.elmin Elm side.
Ports.elmfile is explicit so I will just comment on the return types of those ports. Each port returns either a
Cmd(command) or a
ports.jsfile. Ports usually come in outgoing-incoming pairs but not necessarily. The
resizesincomming port has no outgoing counterpart, and the reverse is true for the