Merge pull request #1413 from gavin-ts/scale-flag

use scale flag for no-fit and customizing zoom
This commit is contained in:
gavin-ts 2023-06-26 13:54:57 -07:00 committed by GitHub
commit 5829f26082
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 84 additions and 34 deletions

View file

@ -1,6 +1,7 @@
#### Features 🚀
- Configure timeout value with D2_TIMEOUT env var. [#1392](https://github.com/terrastruct/d2/pull/1392)
- Scale renders and disable fit to screen with `--scale` flag. [#1413](https://github.com/terrastruct/d2/pull/1413)
#### Improvements 🧹

View file

@ -80,6 +80,9 @@ Renders the diagram to look like it was sketched by hand
.It Fl -center Ar flag
Center the SVG in the containing viewbox, such as your browser screen
.Ns .
.It Fl -scale Ar -1
Scale the output. E.g., 0.5 to halve the default size. Default -1 means that SVG's will fit to screen and all others will use their default render size. Setting to 1 turns off SVG fitting to screen
.Ns .
.It Fl -font-regular
Path to .ttf file to use for the regular font. If none provided, Source Sans Pro Regular is used
.Ns .

View file

@ -107,6 +107,10 @@ func Run(ctx context.Context, ms *xmain.State) (err error) {
if err != nil {
return err
}
scaleFlag, err := ms.Opts.Float64("SCALE", "scale", "", -1, "scale the output. E.g., 0.5 to halve the default size. Default -1 means that SVG's will fit to screen and all others will use their default render size. Setting to 1 turns off SVG fitting to screen.")
if err != nil {
return err
}
fontRegularFlag := ms.Opts.String("D2_FONT_REGULAR", "font-regular", "", "", "path to .ttf file to use for the regular font. If none provided, Source Sans Pro Regular is used.")
fontItalicFlag := ms.Opts.String("D2_FONT_ITALIC", "font-italic", "", "", "path to .ttf file to use for the italic font. If none provided, Source Sans Pro Regular-Italic is used.")
@ -232,6 +236,10 @@ func Run(ctx context.Context, ms *xmain.State) (err error) {
}
ms.Log.Debug.Printf("using dark theme %s (ID: %d)", match.Name, *darkThemeFlag)
}
var scale *float64
if scaleFlag != nil && *scaleFlag > 0. {
scale = scaleFlag
}
plugin, err := d2plugin.FindPlugin(ctx, ps, *layoutFlag)
if err != nil {
@ -282,6 +290,7 @@ func Run(ctx context.Context, ms *xmain.State) (err error) {
Center: *centerFlag,
ThemeID: *themeFlag,
DarkThemeID: darkThemeFlag,
Scale: scale,
}
if *watchFlag {
@ -665,14 +674,20 @@ func render(ctx context.Context, ms *xmain.State, compileDur time.Duration, plug
func _render(ctx context.Context, ms *xmain.State, plugin d2plugin.Plugin, opts d2svg.RenderOpts, outputPath string, bundle, forceAppendix bool, page playwright.Page, ruler *textmeasure.Ruler, diagram *d2target.Diagram) ([]byte, error) {
toPNG := getExportExtension(outputPath) == PNG
var scale *float64
if opts.Scale != nil {
scale = opts.Scale
} else if toPNG {
scale = go2.Pointer(1.)
}
svg, err := d2svg.Render(diagram, &d2svg.RenderOpts{
Pad: opts.Pad,
Sketch: opts.Sketch,
Center: opts.Center,
ThemeID: opts.ThemeID,
DarkThemeID: opts.DarkThemeID,
MasterID: opts.MasterID,
SetDimensions: toPNG,
Pad: opts.Pad,
Sketch: opts.Sketch,
Center: opts.Center,
ThemeID: opts.ThemeID,
DarkThemeID: opts.DarkThemeID,
MasterID: opts.MasterID,
Scale: scale,
})
if err != nil {
return nil, err
@ -746,11 +761,18 @@ func renderPDF(ctx context.Context, ms *xmain.State, plugin d2plugin.Plugin, opt
// make the bg fill within the png transparent so that the pdf bg fill is the only bg color present
diagram.Root.Fill = "transparent"
var scale *float64
if opts.Scale != nil {
scale = opts.Scale
} else {
scale = go2.Pointer(1.)
}
svg, err = d2svg.Render(diagram, &d2svg.RenderOpts{
Pad: opts.Pad,
Sketch: opts.Sketch,
Center: opts.Center,
SetDimensions: true,
Pad: opts.Pad,
Sketch: opts.Sketch,
Center: opts.Center,
Scale: scale,
})
if err != nil {
return nil, err
@ -837,12 +859,20 @@ func renderPPTX(ctx context.Context, ms *xmain.State, presentation *pptx.Present
// make the bg fill within the png transparent so that the pdf bg fill is the only bg color present
diagram.Root.Fill = "transparent"
var scale *float64
if opts.Scale != nil {
scale = opts.Scale
} else {
scale = go2.Pointer(1.)
}
var err error
svg, err = d2svg.Render(diagram, &d2svg.RenderOpts{
Pad: opts.Pad,
Sketch: opts.Sketch,
Center: opts.Center,
SetDimensions: true,
Pad: opts.Pad,
Sketch: opts.Sketch,
Center: opts.Center,
Scale: scale,
})
if err != nil {
return nil, err
@ -1076,11 +1106,18 @@ func buildBoardIDToIndex(diagram *d2target.Diagram, dictionary map[string]int, p
func renderPNGsForGIF(ctx context.Context, ms *xmain.State, plugin d2plugin.Plugin, opts d2svg.RenderOpts, ruler *textmeasure.Ruler, page playwright.Page, diagram *d2target.Diagram) (svg []byte, pngs [][]byte, err error) {
if !diagram.IsFolderOnly {
var scale *float64
if opts.Scale != nil {
scale = opts.Scale
} else {
scale = go2.Pointer(1.)
}
svg, err = d2svg.Render(diagram, &d2svg.RenderOpts{
Pad: opts.Pad,
Sketch: opts.Sketch,
Center: opts.Center,
SetDimensions: true,
Pad: opts.Pad,
Sketch: opts.Sketch,
Center: opts.Center,
Scale: scale,
})
if err != nil {
return nil, nil, err

View file

@ -35,12 +35,16 @@ function init(reconnectDelay) {
let width = parseInt(svgEl.getAttribute("width"), 10);
let height = parseInt(svgEl.getAttribute("height"), 10);
if (isInit) {
if (width > height) {
if (width > window.innerWidth) {
ratio = window.innerWidth / width;
if (msg.scale) {
ratio = msg.scale;
} else {
if (width > height) {
if (width > window.innerWidth) {
ratio = window.innerWidth / width;
}
} else if (height > window.innerHeight) {
ratio = window.innerHeight / height;
}
} else if (height > window.innerHeight) {
ratio = window.innerHeight / height;
}
// Scale svg fit to zoom
isInit = false;

View file

@ -83,8 +83,9 @@ type watcher struct {
}
type compileResult struct {
SVG string `json:"svg"`
Err string `json:"err"`
SVG string `json:"svg"`
Scale *float64 `json:"scale,omitEmpty"`
Err string `json:"err"`
}
func newWatcher(ctx context.Context, ms *xmain.State, opts watcherOpts) (*watcher, error) {
@ -372,8 +373,9 @@ func (w *watcher) compileLoop(ctx context.Context) error {
w.ms.Log.Error.Print(errs)
}
w.broadcast(&compileResult{
SVG: string(svg),
Err: errs,
SVG: string(svg),
Scale: w.renderOpts.Scale,
Err: errs,
})
if firstCompile {

View file

@ -75,8 +75,8 @@ type RenderOpts struct {
ThemeID int64
DarkThemeID *int64
Font string
// disables the fit to screen behavior and ensures the exported svg has the exact dimensions
SetDimensions bool
// the svg will be scaled by this factor, if unset the svg will fit to screen
Scale *float64
// MasterID is passed when the diagram should use something other than its own hash for unique targeting
// Currently, that's when multi-boards are collapsed
@ -1654,7 +1654,7 @@ func Render(diagram *d2target.Diagram, opts *RenderOpts) ([]byte, error) {
pad := DEFAULT_PADDING
themeID := DEFAULT_THEME
darkThemeID := DEFAULT_DARK_THEME
setDimensions := false
var scale *float64
if opts != nil {
pad = opts.Pad
if opts.Sketch {
@ -1666,7 +1666,7 @@ func Render(diagram *d2target.Diagram, opts *RenderOpts) ([]byte, error) {
}
themeID = opts.ThemeID
darkThemeID = opts.DarkThemeID
setDimensions = opts.SetDimensions
scale = opts.Scale
}
buf := &bytes.Buffer{}
@ -1857,8 +1857,11 @@ func Render(diagram *d2target.Diagram, opts *RenderOpts) ([]byte, error) {
}
var dimensions string
if setDimensions {
dimensions = fmt.Sprintf(` width="%d" height="%d"`, w, h)
if scale != nil {
dimensions = fmt.Sprintf(` width="%d" height="%d"`,
int(math.Ceil((*scale)*float64(w))),
int(math.Ceil((*scale)*float64(h))),
)
}
alignment := "xMinYMin"