#cetz drawing in corner of box

52 messages · Page 1 of 1 (latest)

trail dock
#

I want to carve out a corner of a box and draw a picture on it, but there are subtle rendering issues.
As you can see, the boundaries show bits of color through the layers above. This is visible in the final pdf, even zoomed to 100%

#

?r theme=light

#import "@preview/cetz:0.3.1"
#box(fill:purple, width:2cm, height:1cm, 
[
  #box([Test\
  Test2])
  #h(1fr)
  #box(height:auto, width:2em, fill:white, cetz.canvas(length:100%, {
  import cetz.draw: *
  // rect((0,0),(1,1), fill:white, stroke:none)
  set-style(fill:purple, stroke:none)
  rect((0,0),(0.5,0.5))
  rect((0.5,0.5),(0.8,0.8))
  rect((0.8,0.8),(1,1))
}))
])
trail dock
#

I've tried drawing the white corner as part of both the box, the cetz canvas background, and a rect, to the same issue with all of them.

#

I'm willing to accept messy work arounds, but I couldn't get the alignment to the corner right on any of them.
The final outer purple box will be width:100% with a height determined by the text.

lone pollen
#

why don't you use a grid with the desired rows/columns and then color the background the way you want? (this is the idea of a non-specialist)

trail dock
#

I can use a grid for the white corner, and that would probably get rid of the outer line of purple, but the drawing is arbitrary. Which means the inner boundary where the white shows through is still a problem.

lone pollen
#

sorry i don't fully understand your intentions, but if you play with the backgroundcolor of the cells and the stroke property (the lines of the table) with the same color you should get it

pallid narwhal
#

Its probably due rounding errors, you could change the starting point of the rect to be (-0.01, -0.01) or draw some lines over it

trail dock
trail dock
#

So what I ended up doing is this...

split helm
#

?r ```
#set page(width: 5cm, height: auto, margin: 0.4cm)

#import "@preview/cetz:0.3.1"
#box(fill:purple, width: 100%, {
box[Test\ Test2]
h(1fr)
let len = 0.6cm
place(top+right, dx: len/10, dy: -len/10, {
cetz.canvas(length: len, {
import cetz.draw: *
// rect((0,0),(1,1), fill:white, stroke:none)
set-style(fill:white, stroke:none)
line(
(0.0, 0.5),
(0.5, 0.5),
(0.5, 0.8),
(0.8, 0.8),
(0.8, 1.1),
(0.0, 1.1),
)
line(
(0.5, 0.0),
(0.5, 0.5),
(0.8, 0.5),
(0.8, 0.8),
(1.1, 0.8),
(1.1, 0.0),
)
})
})
})

split helm
#

?r t=l ```
#set page(width: 5cm, height: auto, margin: 0.4cm)

#import "@preview/cetz:0.3.1"
#box(fill:purple, width: 100%, {
box[Test\ Test2]
h(1fr)
let len = 0.6cm
place(top+right, dx: len/10, dy: -len/10, {
cetz.canvas(length: len, {
import cetz.draw: *
// rect((0,0),(1,1), fill:white, stroke:none)
set-style(fill:white, stroke:none)
line(
(0.0, 0.5),
(0.5, 0.5),
(0.5, 0.8),
(0.8, 0.8),
(0.8, 1.1),
(0.0, 1.1),
)
line(
(0.5, 0.0),
(0.5, 0.5),
(0.8, 0.5),
(0.8, 0.8),
(1.1, 0.8),
(1.1, 0.0),
)
})
})
})

split helm
#

I basically did the same "extend out of the canvas" trick, but also applied dx and dy in a place() to counteract the resulting shift.

trail dock
#

?r t=l

#import "@preview/cetz:0.3.1"
#box(fill:purple, width:2cm, height:1cm, 
[
  #box([Test\
  Test2])
  #place(top+right, 
    box(height:auto, width:2em,baseline:-1.25em, fill:white, stroke:(top:white,right:white,bottom:purple, left:purple),
      align(top+right, 
        cetz.canvas(length:100%, {
          import cetz.draw: *
          // rect((0,0),(1,1), fill:white, stroke:none)
          set-style(fill:purple, stroke:none)
          rect((0,0),(0.5,0.5))
          rect((0.5,0.5),(0.8,0.8))
          rect((0.8,0.8),(1,1))
          })
        )
      )
    )

    #place(top+right, dx:-2em, line(angle:90deg,length:2.1em,stroke:purple))
    #place(top+right, dx:0.5pt, line(angle:90deg,length:2.1em,stroke:white))
    #place(top+right, dy:2em, line(angle:0deg,length:2.1em,stroke:purple))
    #place(top+right, dy:-0.5pt, line(angle:0deg,length:2.1em,stroke:white))
])
split helm
#

It works as a messy workaround 😉 but it does not exactly work for arbitrary pictures 🙂

trail dock
#

So I just drew lines over the top.

#

And for some reason there's no rounding error this way.

split helm
trail dock
#

?r t=l

#import "@preview/cetz:0.3.1"
#box(fill:purple, width:2cm, height:1cm, 
[
  #box([Test\
  Test2])
  #place(top+right, 
    box(height:auto, width:2em,baseline:-1.25em, fill:white, stroke:(top:stroke(paint:white,cap:"square",join:"bevel"),right:stroke(paint:white,cap:"square",join:"bevel"),bottom:stroke(paint:purple,cap:"square",join:"bevel"),left:stroke(paint:purple,cap:"square",join:"bevel")),
      align(top+right, 
        cetz.canvas(length:100%, {
          import cetz.draw: *
          // rect((0,0),(1,1), fill:white, stroke:none)
          set-style(fill:purple, stroke:none)
          rect((0,0),(0.5,0.5))
          rect((0.5,0.5),(0.8,0.8))
          rect((0.8,0.8),(1,1))
          })
        )
      )
    )
])
split helm
#

ah, yes. it's not the shape of the stroke that is the problem but the changing of color. I don't think you can change that behavior...

is the approach I showed suitable, or does it not fit your needs?

trail dock
#

It mostly works, but you have to have something going to 1.1, instead of 1 or the canvas shrinks oddly. Since I want this to be something others can use, probably better to just draw lines over the border.

split helm
#

drawing lines over the border also just extends the size of what you're drawing:

#

?r ```
#import "@preview/cetz:0.3.1"
#box(fill:purple, width:2cm, height:1cm,
[
#box([Test
Test2])
#place(top+right,
box(height:auto, width:2em,baseline:-1.25em, fill:white, stroke:(top:stroke(paint:white,cap:"square",join:"bevel"),right:stroke(paint:white,cap:"square",join:"bevel"),bottom:stroke(paint:purple,cap:"square",join:"bevel"),left:stroke(paint:purple,cap:"square",join:"bevel")),
align(top+right,
cetz.canvas(length:100%, {
import cetz.draw: *
// rect((0,0),(1,1), fill:white, stroke:none)
set-style(fill:purple, stroke:none)
rect((0,0),(0.5,0.5))
rect((0.5,0.5),(0.8,0.8))
rect((0.8,0.8),(1,1))
})
)
)
)
])

split helm
#

on the dark background you can see how the default stroke extends out from the box

#

so it's really just a matter of where this extent originates

trail dock
#

Yeah. I think this is okay, it should be on a white background 99+% of the time.

... Technically in the style I'm imitating the drawing is transparent (as in see through to the page background). But that sounds like an awful lot more work.

split helm
#

?r you can at least get really small with the overextent:

#import "@preview/cetz:0.3.1"
#box(fill:purple, width: 100%, {
  box[Test\ Test2]
  h(1fr)
  let len = 0.6cm
  let over = 0.005
  place(top+right, dx: len*over, dy: -len*over, {
    cetz.canvas(length: len, {
      import cetz.draw: *
      // rect((0,0),(1,1), fill:white, stroke:none)
      set-style(fill:white, stroke:none)
      line(
        (0.0, 0.5), 
        (0.5, 0.5),
        (0.5, 0.8),
        (0.8, 0.8),
        (0.8, 1.0 + over),
        (0.0, 1.0 + over),
      )
      line(
        (0.5, 0.0), 
        (0.5, 0.5),
        (0.8, 0.5),
        (0.8, 0.8),
        (1.0 + over, 0.8),
        (1.0 + over, 0.0),
      )
    })
  }) 
})
valid trench
#

Why not draw the big purple shape as one line and the other two as two rects?

trail dock
#

Arbitrary text content and the canvas sizing.

valid trench
#

?r

#import "@preview/cetz:0.3.1"
#import cetz: *

#canvas(length: 100%, {
  import draw:* 

  let special-rect(w, h, name: none) = group(ctx => {
    let w = cetz.util.resolve-number(ctx, w)
    let h = cetz.util.resolve-number(ctx, h)
    let a = h/3
    fill(purple)
    stroke(none)
    line((0,0), (w,0), (w,a),
      (w - a, a),
      (w - a, 2*a),
      (w - 2*a, 2*a),
      (w - 2*a, 3*a),
      (0, h))
    rect((w - a, h - a), (rel: (2*a/3, 2*a/3)))
    rect((w - a/3, h - a/3), (rel: (a/3, a/3)))
  }, name: name)
  
  special-rect(1, 3cm, name: "my-rect")
  content((rel: (.2cm, .2cm), to: "my-rect.south-west"),
          (rel: (-.2cm, -.2cm), to: "my-rect.north-east"),
          align(left + horizon, text(size: 1cm)[Hello, I am Text!\ Test, test.]))
})
valid trench
trail dock
valid trench
#

You can adjust the box to the text height? Or should the box stay fixed?

trail dock
#

Adjust to the text height is preferable.

valid trench
#

?r

#import "@preview/cetz:0.3.1"
#import cetz: *

#canvas(length: 100%, {
  import draw:* 

  let special-rect(element, name: none) = group(ctx => {
    let w = cetz.util.resolve-number(ctx, 1)
    let (_, n, s) = cetz.coordinate.resolve(ctx, element + ".north", element + ".south")
    let h = cetz.vector.dist(n,s)
    let a = h/3
    fill(purple)
    stroke(none)
    line((0,0), (w,0), (w,a),
      (w - a, a),
      (w - a, 2*a),
      (w - 2*a, 2*a),
      (w - 2*a, 3*a),
      (0, h))
    rect((w - a, h - a), (rel: (2*a/3, 2*a/3)))
    rect((w - a/3, h - a/3), (rel: (a/3, a/3)))
  }, name: name)
  
  
  content((0, 0), anchor: "south-west",
          align(left + horizon, text(size: 1cm)[Hello, I am Text!\ Test, test\ Another line, \ and another  one\ ohno ]),
          name: "content")
  on-layer(-1, special-rect("content", name: "my-rect"))
})
valid trench
#

Width is 100% of the page, so the preview here is too small.

trail dock
#

Oh neat, I didn't know you could get that info out.

split helm
#

I'm pretty sure the corner graphic should keep its size though, so you'd have to replace length: 100%. Not horrible, but it makes stuff a bit less convenient.

trail dock
#

No, that's easy enough to fix.

#

?r

#import "@preview/cetz:0.3.1"
#let drawing = {
      import cetz.draw: *
      rect((0,0),(0.5,0.5))
      rect((0.5,0.5),(0.75,0.75))
      rect((0.75,0.75),(1,1))
    }
#let txt = box(inset:0.5em, text(size: 10pt)[Hello, I am Text!\ Test, test\ Another line, \ and another  one\ ohno ])

#cetz.canvas(length: 100%, {
  import cetz.draw:* 

  let special-rect(element, name: none) = group(ctx => {
    let w = cetz.util.resolve-number(ctx, 1)
    let (_, n, s) = cetz.coordinate.resolve(ctx, element + ".north", element + ".south")
    let h = cetz.vector.dist(n,s)
    if(h < cetz.util.resolve-number(ctx,1cm)){
      h = cetz.util.resolve-number(ctx,1cm)
    }
    let a = cetz.util.resolve-number(ctx,0.75cm)
    fill(purple)
    stroke(none)
    line((0,0), (w,0), (w,h - a),
      (w - a + 0.001, h - a + 0.001),
      (w - a + 0.001, h),
      (0, h))
    set-origin((w - a,h - a))
    scale(a)
    drawing
  }, name: name)
  
  
  content((0, 0), anchor: "south-west",
          align(left + horizon, txt),
          name: "content")
  on-layer(-1, special-rect("content", name: "my-rect"))
})