thi-ng / umbrella

⛱ Broadly scoped ecosystem & mono-repository of 199 TypeScript projects (and ~180 examples) for general purpose, functional, data driven development
https://thi.ng
Apache License 2.0
3.35k stars 149 forks source link

[geom] [hiccup-canvas] draw elements on canvas - with bbox? #364

Closed pcace closed 1 year ago

pcace commented 1 year ago

hi there,

i am trying to find a solution for the following problem: i have a fairly complex svg wich takes way too long to render. so i tried hiccup-canvas instead with good results. Since it is way faster to draw IHiccupShapes i would like to go that way. The Problem i am facing is, that i cannot find a way to have some kind of boundingbox around my shapes. using svgs i did something like that:

    const doc = svg(
      {
        width: width ?? 100,
        height: height ?? 100,
        viewBox: `${bbox[0][0]} ${bbox[0][1]} ${bbox[1][0]} ${bbox[1][1]}`,
        'stroke-width': 0.25,
        convert: false,
      },
      ['defs', {}, ...getPatterns(), ...getPatternMasks(bbox)]
    )
    polys = [...polys, ...scaleBar, ...northArrow]
    for (let i = 0; i < polys.length; i++) {
      if (polys[i].hasOwnProperty('toHiccup')) {
        doc.push(polys[i].toHiccup())
      } else {
        doc.push(polys[i])
      }
    }
    doc[1].width = '100%'
    doc[1].height = '100%'
    const svgParsed = asSvg(doc)

when trying to do that with a canvas this is my way:

  const canvasShapes = group({}, shapes)
//shapes contains IHiccupShape[ ]

  useEffect(() => {
    if (canvasRef.current) {
      const canvas = canvasRef.current
      const context = canvas.getContext('2d')
      if (context) {
        draw(context, canvasShapes)
      }
    }
  }, [shapes, height, width])

  return (
    <canvas
      ref={canvasRef}
      height={height}
      width={width}
      style={{ width: `300px`, height: `300px` }} //only changes the dimensions of the canvas
    />
  )

is there any way to set a bounding Box within wich the shapes are drawn? Any idea would be great!

thank you so much

postspectacular commented 1 year ago

There's currently no built-in support for something like SVG's viewBox attrib, but it's easy enough to calculate a global transformation matrix & apply it. I've created a little codepen for you to illustrate the overall approach. I've been planning to integrate some of these steps, but haven't had bandwidth yet to get to that. It's on the todo list though!

https://codepen.io/postspectacular/pen/wvXdryp

Screen Shot 2022-11-12 at 11 35 21

Hope that helps & if not please let me know (and then maybe prep a small example yourself)

postspectacular commented 1 year ago

@pcace - just checking if the above example helped you and if we can close this issue?

postspectacular commented 1 year ago

@pcace - closing this, since no feedback & the above example shows a solution...