1

I am creating a simple react app (HTML) that allows a user to browse to an image on their local pc, and then displays it in an image tag. I want to take a data-url and dynamically create a hidden canvas tag (open to a different approach, but I want to resize the image, not set size contraints on the tag displaying the image). Here is my resize code

MyComponent.res (offending code)

let resize = dataUrl => {
    let canvas = React.createElement(_ => React.string("canvas"), {"style": "display: none;"})
    canvas.getContext("2d");
    dataUrl
}

The error

  We've found a bug for you!
  /Users/n0321437/projects/rescript-react/from-local-template/src/Upload.res:14:12-21

  12 │     let canvas = React.createElement(_ => React.string("canvas"), {"sty
     │ le": "display: none;"})
  13 │     //let myCanvas = canvas([React.null])
  14 │     canvas.getContext("2d");
  15 │     dataUrl
  16 │ }

The record field getContext can't be found.

I haven't found a much documentation or postings on using createElement or createElementVariadic - so I am guessing here. It looks as though createElement returns an object of type element but there are no associated methods:

React.res

type element
external createElement: (component<'props>, 'props) => element = "createElement"

So I guess there are a couple of questions

  1. Have i infact created an element that would represent the HTML Object of Canvas?
  2. If I have done so, how do I call methods on that code?
  3. If I have not, how do I create a hidden Canvas object?
  4. FInally how might one navigate the documentation and source to discover this on their own?
akaphenom
  • 6,728
  • 10
  • 59
  • 109

1 Answers1

1

React is a library that provides a declarative API for creating, inserting and updating the DOM by way of a virtual DOM. React.createElement is an internal API used to create virtual DOM elements.

What you seem to want is to create an actual DOM element, and then NOT insert it into DOM. React is not designed to do this.

Instead what you want is bindings to the DOM API, which you could make yourself if you only need a few of its features, or you could use a full-blown set of DOM bindings such as rescript-webapi, which conveniently also includes bindings for Canvas.

This is how you'd create a canvas element:

open Webapi.Dom

let canvas = document->Document.createElement("canvas")

then to get the canvas context you'd use:

open Webapi.Canvas
let context = canvas->CanvasElement.getContext2d

then use the functions in Canvas2d to do what you want:

let image = context->Canvas2d.createImageDataCoords(~width=100, ~height=100)
...
context->Canvas2d.putImage(image, ~dx=0, ~dy=0)
glennsl
  • 28,186
  • 12
  • 57
  • 75
  • Ahhh - thank you. Will give this a shot after lunch. – akaphenom Nov 12 '21 at 12:44
  • This essentially "works" (I cannot get my image to resize properly, but thats on me). The Bs-WebAapi stuff is nice to have, but given the small scope of what I am working with, I don't like the amount of time it adds to the build process. I have ported the few interops I am using, and adopted to my preferences. It was great to learn the interop bits. I am accepting this - but will also post my solution once I have it functional, so there is an alternate solution to leveraging webapi. Thanks – akaphenom Nov 15 '21 at 14:34