#cetz drawing in corner of box
52 messages · Page 1 of 1 (latest)
?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))
}))
])
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.
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)
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.
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
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
Unfortunately stroke makes diagonal cuts like this:
And this expands the canvas, which expands the box, which moves the location of the rounding error. You can get half of them, but not the other half.
So what I ended up doing is this...
?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),
)
})
})
})
?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),
)
})
})
})
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.
?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))
])
It works as a messy workaround 😉 but it does not exactly work for arbitrary pictures 🙂
So I just drew lines over the top.
And for some reason there's no rounding error this way.
what is the code that produces this? is it something that a modified cap or join could fix?
?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))
})
)
)
)
])
Looks like no.
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?
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.
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))
})
)
)
)
])
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
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.
?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),
)
})
})
})
Why not draw the big purple shape as one line and the other two as two rects?
Arbitrary text content and the canvas sizing.
?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.]))
})
Can you explain?
Just add two lines of text to that, and it's now outside the purple both above and below.
You can adjust the box to the text height? Or should the box stay fixed?
Adjust to the text height is preferable.
?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"))
})
Width is 100% of the page, so the preview here is too small.
Oh neat, I didn't know you could get that info out.
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.
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"))
})