purescript-p5 icon indicating copy to clipboard operation
purescript-p5 copied to clipboard

Make the `image` function draw `Graphics`

Open m-bock opened this issue 6 years ago • 5 comments

The function P5.Image.LoadingAndDisplaying.image currently has this signature:

image :: P5 -> ElementOrImage -> Number -> Number -> (Maybe Number) -> (Maybe Number) -> (Effect Unit)

This aligns with the P5 documentation: p5.Image|p5.Element: the image to display

However, it's also possible to draw 'Graphics' to the canvas with this function.

In P5 Graphics are subsumed under the 'base class' Element. Looks weird to me because as far as I understand, a 'graphics' object is not an HTML object, rather some internal representation of a layer on the canvas.

The suggestion would be to have a type GraphicsOrImageOrElement and change the above image function to accept this as argument.

m-bock avatar Jul 06 '19 18:07 m-bock

That sounds good to me. It looks like it's an oversight in the p5.js API doc for image.

derektmueller avatar Jul 15 '19 01:07 derektmueller

Another a bit more difficult part of the problem is: How to actually draw things on the Graphics. All the drawing functions currently take a P5 as the first argument. Following the approach of sum types, we'd end up with things like:

rect :: P5OrGraphics -> Number -> Number -> Number -> Number -> (Maybe Int) -> (Maybe Int) -> (Effect Unit)

which would mean a tremendous API change and would probably not look so nice anymore.

Instead I thought of some

graphicsToP5 :: Graphics -> P5
graphicsToP5 = unsafeCoerce

But this would only be correct, if really all of the P5 functions can be used on graphics. This seems not to be the case, so in the end I think it's not a good approach.

m-bock avatar Jul 22 '19 19:07 m-bock

Generally I thought of this, instead of the union types:

class CanDrawOn a

data P5
data Graphics

instance canDrawOnGraphics :: CanDrawOn Graphics
instance canDrawOnP5 :: CanDrawOn P5      

-- So e.g. rect could be used with both
rect :: CanDrawOn a => a -> ...

-- But this one only with P5
createGraphics :: P5 -> ...

However, also a huge API change. But maybe worth thinking about as alternative also for the other quite wordy sum types...

m-bock avatar Jul 22 '19 19:07 m-bock

see https://blog.ndk.io/purescript-ffi.html (section "How do I wrap a class hierarchy?")

m-bock avatar Jul 23 '19 21:07 m-bock

I'm not sure the linked approach of using phantom types would work, since it appears to only support single inheritance. Graphics has methods from both p5.Element and p5.prototype. Adding the type class might be the best option.

derektmueller avatar Aug 04 '19 04:08 derektmueller