Skip to content
This repository has been archived by the owner on Oct 9, 2019. It is now read-only.

Add the ability to render HTML Elements to Texture #45

Closed
wants to merge 6 commits into from

Conversation

shamansir
Copy link

@shamansir shamansir commented Jun 18, 2017

...such as canvas, video, svg, even with animation.

Adds

  • Texture.fromElement elementId: load the DOM element content once and use it as a texture;
  • Texture.fromElementWith options elementId: same as above, but with options;
  • Texture.fromDynamicElement <UseRAF | UseInterval interval> elementId: load content from the DOM element and use requestAnimationFrame or setInterval interval to ask for the content again and update the texture;
  • introduces ElementNotFound error;

Adds dynamic-texture.elm example, which is just a copy of crate.elm, with few changes:

init : ( Model, Cmd Msg )
init =
    ( { texture = Nothing, theta = 0 }
    , Task.attempt TextureLoaded
        (Texture.fromDynamicElement UseRAF "my-element")
    )

view : Model -> Html Msg
view { texture, theta } =
    div
        [ ]
        [ Element.toHtml
            <| tag "my-element"
            <| collage 128 128
                [ (circle 64) |> filled blue
                , (rect 3 60) |> filled black
                              |> rotate theta
                ]
        , WebGL.toHtmlWith
            [ WebGL.alpha True
            , WebGL.antialias
            , WebGL.depth 1
            , WebGL.stencil 0
            ]
            [ width 400
            , height 400
            , style [ ( "display", "block" ) ]
            ]
            (texture
                |> Maybe.map (scene (perspective theta))
                |> Maybe.withDefault []
            )
        ]

Caveats

  • requires the ID of the wrapper, not the canvas, video itself... The reason is: collage from evancz/elm-graphics is not allowing to set ID to the canvas itself, but its wrapper;
  • for dynamic textures, minify = linear options is currently forced to be set, or else WebGL fails to render such elements (actually it just shouldn't be the default Resize Smaller);
  • user probably should not overuse requestAnimationFrame / setInterval in large amounts;
  • element could be not suitable to be a texture source (i.e. just div), then the error is just reported to console and not returned to the Elm code, since it is fired during createTexture call;
  • if the texture is dynamic, for the moment it is not possible to stop requestAnimationFrame / setInterval calls used to update it.

Motivation

Usually the source element is hidden, so it’s quite a useful method. For example, I need to show a video in a texture, others also use this method to display text in 3D with almost no hardware tension. Or to add shader-based effects to HTML components, see http://htmlgl.com/.

@shamansir shamansir closed this Jun 18, 2017
@shamansir
Copy link
Author

This functionality is not reviewed by community, not needed for now and could be too exclusive for my case.

@w0rm
Copy link
Member

w0rm commented Mar 4, 2018

@shamansir just had an idea, it may be possible to send a blob url through ports to Elm and then load it as a texture. This may partially cover this use case.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants