Merge pull request #1413 from gavin-ts/scale-flag
use scale flag for no-fit and customizing zoom
This commit is contained in:
commit
5829f26082
6 changed files with 84 additions and 34 deletions
|
|
@ -1,6 +1,7 @@
|
||||||
#### Features 🚀
|
#### Features 🚀
|
||||||
|
|
||||||
- Configure timeout value with D2_TIMEOUT env var. [#1392](https://github.com/terrastruct/d2/pull/1392)
|
- 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 🧹
|
#### Improvements 🧹
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -80,6 +80,9 @@ Renders the diagram to look like it was sketched by hand
|
||||||
.It Fl -center Ar flag
|
.It Fl -center Ar flag
|
||||||
Center the SVG in the containing viewbox, such as your browser screen
|
Center the SVG in the containing viewbox, such as your browser screen
|
||||||
.Ns .
|
.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
|
.It Fl -font-regular
|
||||||
Path to .ttf file to use for the regular font. If none provided, Source Sans Pro Regular is used
|
Path to .ttf file to use for the regular font. If none provided, Source Sans Pro Regular is used
|
||||||
.Ns .
|
.Ns .
|
||||||
|
|
|
||||||
|
|
@ -107,6 +107,10 @@ func Run(ctx context.Context, ms *xmain.State) (err error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
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.")
|
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.")
|
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)
|
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)
|
plugin, err := d2plugin.FindPlugin(ctx, ps, *layoutFlag)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -282,6 +290,7 @@ func Run(ctx context.Context, ms *xmain.State) (err error) {
|
||||||
Center: *centerFlag,
|
Center: *centerFlag,
|
||||||
ThemeID: *themeFlag,
|
ThemeID: *themeFlag,
|
||||||
DarkThemeID: darkThemeFlag,
|
DarkThemeID: darkThemeFlag,
|
||||||
|
Scale: scale,
|
||||||
}
|
}
|
||||||
|
|
||||||
if *watchFlag {
|
if *watchFlag {
|
||||||
|
|
@ -665,6 +674,12 @@ 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) {
|
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
|
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{
|
svg, err := d2svg.Render(diagram, &d2svg.RenderOpts{
|
||||||
Pad: opts.Pad,
|
Pad: opts.Pad,
|
||||||
Sketch: opts.Sketch,
|
Sketch: opts.Sketch,
|
||||||
|
|
@ -672,7 +687,7 @@ func _render(ctx context.Context, ms *xmain.State, plugin d2plugin.Plugin, opts
|
||||||
ThemeID: opts.ThemeID,
|
ThemeID: opts.ThemeID,
|
||||||
DarkThemeID: opts.DarkThemeID,
|
DarkThemeID: opts.DarkThemeID,
|
||||||
MasterID: opts.MasterID,
|
MasterID: opts.MasterID,
|
||||||
SetDimensions: toPNG,
|
Scale: scale,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
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
|
// make the bg fill within the png transparent so that the pdf bg fill is the only bg color present
|
||||||
diagram.Root.Fill = "transparent"
|
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{
|
svg, err = d2svg.Render(diagram, &d2svg.RenderOpts{
|
||||||
Pad: opts.Pad,
|
Pad: opts.Pad,
|
||||||
Sketch: opts.Sketch,
|
Sketch: opts.Sketch,
|
||||||
Center: opts.Center,
|
Center: opts.Center,
|
||||||
SetDimensions: true,
|
Scale: scale,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
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
|
// make the bg fill within the png transparent so that the pdf bg fill is the only bg color present
|
||||||
diagram.Root.Fill = "transparent"
|
diagram.Root.Fill = "transparent"
|
||||||
|
|
||||||
|
var scale *float64
|
||||||
|
if opts.Scale != nil {
|
||||||
|
scale = opts.Scale
|
||||||
|
} else {
|
||||||
|
scale = go2.Pointer(1.)
|
||||||
|
}
|
||||||
|
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
svg, err = d2svg.Render(diagram, &d2svg.RenderOpts{
|
svg, err = d2svg.Render(diagram, &d2svg.RenderOpts{
|
||||||
Pad: opts.Pad,
|
Pad: opts.Pad,
|
||||||
Sketch: opts.Sketch,
|
Sketch: opts.Sketch,
|
||||||
Center: opts.Center,
|
Center: opts.Center,
|
||||||
SetDimensions: true,
|
Scale: scale,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
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) {
|
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 {
|
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{
|
svg, err = d2svg.Render(diagram, &d2svg.RenderOpts{
|
||||||
Pad: opts.Pad,
|
Pad: opts.Pad,
|
||||||
Sketch: opts.Sketch,
|
Sketch: opts.Sketch,
|
||||||
Center: opts.Center,
|
Center: opts.Center,
|
||||||
SetDimensions: true,
|
Scale: scale,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
|
|
|
||||||
|
|
@ -35,6 +35,9 @@ function init(reconnectDelay) {
|
||||||
let width = parseInt(svgEl.getAttribute("width"), 10);
|
let width = parseInt(svgEl.getAttribute("width"), 10);
|
||||||
let height = parseInt(svgEl.getAttribute("height"), 10);
|
let height = parseInt(svgEl.getAttribute("height"), 10);
|
||||||
if (isInit) {
|
if (isInit) {
|
||||||
|
if (msg.scale) {
|
||||||
|
ratio = msg.scale;
|
||||||
|
} else {
|
||||||
if (width > height) {
|
if (width > height) {
|
||||||
if (width > window.innerWidth) {
|
if (width > window.innerWidth) {
|
||||||
ratio = window.innerWidth / width;
|
ratio = window.innerWidth / width;
|
||||||
|
|
@ -42,6 +45,7 @@ function init(reconnectDelay) {
|
||||||
} else if (height > window.innerHeight) {
|
} else if (height > window.innerHeight) {
|
||||||
ratio = window.innerHeight / height;
|
ratio = window.innerHeight / height;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
// Scale svg fit to zoom
|
// Scale svg fit to zoom
|
||||||
isInit = false;
|
isInit = false;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -84,6 +84,7 @@ type watcher struct {
|
||||||
|
|
||||||
type compileResult struct {
|
type compileResult struct {
|
||||||
SVG string `json:"svg"`
|
SVG string `json:"svg"`
|
||||||
|
Scale *float64 `json:"scale,omitEmpty"`
|
||||||
Err string `json:"err"`
|
Err string `json:"err"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -373,6 +374,7 @@ func (w *watcher) compileLoop(ctx context.Context) error {
|
||||||
}
|
}
|
||||||
w.broadcast(&compileResult{
|
w.broadcast(&compileResult{
|
||||||
SVG: string(svg),
|
SVG: string(svg),
|
||||||
|
Scale: w.renderOpts.Scale,
|
||||||
Err: errs,
|
Err: errs,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -75,8 +75,8 @@ type RenderOpts struct {
|
||||||
ThemeID int64
|
ThemeID int64
|
||||||
DarkThemeID *int64
|
DarkThemeID *int64
|
||||||
Font string
|
Font string
|
||||||
// disables the fit to screen behavior and ensures the exported svg has the exact dimensions
|
// the svg will be scaled by this factor, if unset the svg will fit to screen
|
||||||
SetDimensions bool
|
Scale *float64
|
||||||
|
|
||||||
// MasterID is passed when the diagram should use something other than its own hash for unique targeting
|
// 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
|
// Currently, that's when multi-boards are collapsed
|
||||||
|
|
@ -1654,7 +1654,7 @@ func Render(diagram *d2target.Diagram, opts *RenderOpts) ([]byte, error) {
|
||||||
pad := DEFAULT_PADDING
|
pad := DEFAULT_PADDING
|
||||||
themeID := DEFAULT_THEME
|
themeID := DEFAULT_THEME
|
||||||
darkThemeID := DEFAULT_DARK_THEME
|
darkThemeID := DEFAULT_DARK_THEME
|
||||||
setDimensions := false
|
var scale *float64
|
||||||
if opts != nil {
|
if opts != nil {
|
||||||
pad = opts.Pad
|
pad = opts.Pad
|
||||||
if opts.Sketch {
|
if opts.Sketch {
|
||||||
|
|
@ -1666,7 +1666,7 @@ func Render(diagram *d2target.Diagram, opts *RenderOpts) ([]byte, error) {
|
||||||
}
|
}
|
||||||
themeID = opts.ThemeID
|
themeID = opts.ThemeID
|
||||||
darkThemeID = opts.DarkThemeID
|
darkThemeID = opts.DarkThemeID
|
||||||
setDimensions = opts.SetDimensions
|
scale = opts.Scale
|
||||||
}
|
}
|
||||||
|
|
||||||
buf := &bytes.Buffer{}
|
buf := &bytes.Buffer{}
|
||||||
|
|
@ -1857,8 +1857,11 @@ func Render(diagram *d2target.Diagram, opts *RenderOpts) ([]byte, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
var dimensions string
|
var dimensions string
|
||||||
if setDimensions {
|
if scale != nil {
|
||||||
dimensions = fmt.Sprintf(` width="%d" height="%d"`, w, h)
|
dimensions = fmt.Sprintf(` width="%d" height="%d"`,
|
||||||
|
int(math.Ceil((*scale)*float64(w))),
|
||||||
|
int(math.Ceil((*scale)*float64(h))),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
alignment := "xMinYMin"
|
alignment := "xMinYMin"
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue