It is possible to resize images in the client’s web browser using the canvas API. This eliminates the need for your server to do the work, and allows the client to upload the correct file directly to S3. We use the same simonh1000/file-reader module as the last two weeks, which allows us to pass native File
objects through ports
to a canvas for drawing.
app.js
main.ports.crop.subscribe(function (options) {
let img = new Image()
img.src = options.imgSrc
let canvas = document.createElement('canvas')
canvas.width = options.dim
canvas.height = options.dim
canvas.getContext('2d').drawImage(img, options.x, options.y, options.dim, options.dim, 0, 0, options.dim, options.dim)
canvas.toBlob(function (blob) {
main.ports.incomingCroppedFile.send(new File([blob], "cropped.jpg"))
})
})
Main.elm
update msg model =
case msg of
MouseUp ( upX, upY ) ->
let
-- …
cmd =
case model.encodedFile of
Just imgSrc ->
crop { imgSrc = imgSrc, x = downX, y = downY, dim = dim }
Nothing ->
Cmd.none
in
model ! [ cmd ]
IncomingCroppedFile blob ->
let
file =
JD.decodeValue nativeFileDecoder blob
|> Result.toMaybe
in
{ model | fileToUpload = file } ! []
port crop : { imgSrc : String, x : Float, y : Float, dim : Float } -> Cmd msg
port incomingCroppedFile : (JD.Value -> msg) -> Sub msg