cetz icon indicating copy to clipboard operation
cetz copied to clipboard

Powerpoint decorations

Open ntjess opened this issue 2 years ago • 7 comments

I aim to replace powerpoint with cetz + polylux, but the lack of shapes to insert is a critical roadblock. It would be wonderful if these existed as additional decorations. However, the internals of cetz are a bit tough to grasp, so I don't know whether I'm on the right track. I'm looking for (1) whether this idea is appreciated as belonging in the cetz library, and (2) whether the implementation + api is satisfactory. If the community/maintainers are receptive, I can proceed with adding additional shapes.

MWE:

#import "@preview/cetz:0.1.2"
#import cetz.draw: *
#import cetz.decorations: *

#cetz.canvas({
  cylinder(
    (0,0), 5, 3,
    fill: blue,
    top-fill: blue.lighten(40%),
    name: "cylinder",
    anchor: "right",
    content: align(center + horizon)[Hello, World!]
  )
  for-each-anchor("cylinder", anchor => {
    content((), angle: -45deg, box(fill: rgb("#fff6"), inset: 0.1em, text(size: 8pt, anchor)))
  })
})

image

Roadmap

I would implement a subset of powerpoint shapes and use that behavior to infer default control points etc: image

Questions

  • Should there be flowchart, block arrows, etc. submodules, or should all live under the decorations namespace?
  • Should content be a parameter, or should the user add this as an additional cetz element? I initially included content since it allows the cylinder itself to appropriately add margin, center the material, and so on. But this is not a common pattern for other cetz elements, so I am curious on a better implementation plan.
    • I also use content within a shape more often than not in ppt, so this would be an extremely common use case as I see it.
  • Are there cases where deviating from powerpoint control points / sizing defaults is preferred? (This question may be easier to answer as the PR is developed)
  • Should the PR be split up? It would be undesirable to require waiting until the whole library is full before making the shapes accessible
  • Is this functionality more suited to a separate typst package than a cetz contribution?

Thanks for the lovely typst package! It was easier than to get started with the contribution. The hard part is making sure the shapes API is robust against everything cetz is designed to support...

ntjess avatar Nov 28 '23 02:11 ntjess

Are you still interested in working on this PR @ntjess?

johannes-wolf avatar Jan 17 '24 16:01 johannes-wolf

@johannes-wolf Yes, coming back to this over the weekend. I tried to get anchors working before but ran into some issues, I'll see if these are resolved on the new branch

ntjess avatar Jan 20 '24 17:01 ntjess

I've migrated to 0.2.0, but am a little confused on the best way to reposition the object based on its anchor. Is there an easy way to translate an unnamed group by vector.sub(anchor, "north-west")

My thoughts were to draw the object regardless of the user-specified anchor, and apply a translate at the very end to treat pt as that anchor

ntjess avatar Jan 21 '24 04:01 ntjess

You can just pass it to anchor on the group, it'll reposition relative to the default anchor. Which for groups is the center anchor. Once #477 is merged (sometime today) you'll be able to override this for groups.

fenjalien avatar Jan 21 '24 11:01 fenjalien

Not sure what happened... I tried to rebase to master and it auto-closed the PR. Sorry for the noise, I'll reopen as a new PR with the fixes

ntjess avatar Feb 06 '24 02:02 ntjess

Alright, this should work now:

#cetz.canvas({
  cylinder(
    (5, 2),
    fill: blue,
    head-fill: blue.lighten(40%),
    name: "cylinder",
    anchor: "south",
    content: align(center + horizon)[Hello, World!],
    size: (5, 2),
    head-radius: 2,
  )
  for-each-anchor("cylinder", anchor => {
    content((), angle: -45deg, box(fill: rgb("#fff6"), inset: 0.1em, text(size: 8pt, anchor)))
  })
  circle((5,2), radius: 0.1, fill: red)
})

image

  • The shape mimics powerpoint behavior
  • Size is a style property
  • Group default anchor is respected
  • Default anchor is the center instead of north-west

To Do:

  • [ ] Expose through creating shapes.typ
  • [ ] Add documentation & examples
  • [ ] Add a few more simple shapes; others can wait for another PR to avoid overly complicating this one
    • [ ] arrow
    • [ ] triangle
    • [ ] cloud
  • [ ] Anything else identified by maintainers

ntjess avatar Feb 06 '24 02:02 ntjess

Any updates on this? Otherwise, I'd like to close this PR. I think we could have a separate repository cetz-shapes that implements some common shapes, like the one you've shown. What do you think @fenjalien?

johannes-wolf avatar May 18 '24 12:05 johannes-wolf

A separate repository would make sense to me

jamesrswift avatar Jul 29 '24 10:07 jamesrswift

Sorry for the extended AFK 😅

A separate repo is very reasonable. I wasn't sure to follow the pattern of other common shapes that were included out-of-box, which is why I initially designed it as a first-party PR.

But I'm happy to package it separately once I have the time. Feel free to close the PR 👍

ntjess avatar Jul 31 '24 18:07 ntjess