diff --git a/ci/release/changelogs/next.md b/ci/release/changelogs/next.md index 3899ec4f7..272cd726b 100644 --- a/ci/release/changelogs/next.md +++ b/ci/release/changelogs/next.md @@ -7,3 +7,4 @@ #### Bugfixes ⛑️ - Appendix seperator line no longer added to PNG export when appendix doesn't exist. [#582](https://github.com/terrastruct/d2/pull/582) +- Watch mode only fits to screen on initial load. [#582](https://github.com/terrastruct/d2/pull/582) diff --git a/d2renderers/d2svg/d2svg.go b/d2renderers/d2svg/d2svg.go index 2f7f931f0..9f5dddbe2 100644 --- a/d2renderers/d2svg/d2svg.go +++ b/d2renderers/d2svg/d2svg.go @@ -1096,6 +1096,9 @@ func embedFonts(buf *bytes.Buffer, fontFamily *d2fonts.FontFamily) { buf.WriteString(`]]>`) } +//go:embed fitToScreen.js +var fitToScreenScript string + // TODO minify output at end func Render(diagram *d2target.Diagram, opts *RenderOpts) ([]byte, error) { var sketchRunner *d2sketch.Runner @@ -1124,6 +1127,8 @@ func Render(diagram *d2target.Diagram, opts *RenderOpts) ([]byte, error) { ]]> `, styleCSS, styleCSS2)) + buf.WriteString(fmt.Sprintf(``, fitToScreenScript)) + hasMarkdown := false for _, s := range diagram.Shapes { if s.Label != "" && s.Type == d2target.ShapeText { diff --git a/d2renderers/d2svg/fitToScreen.js b/d2renderers/d2svg/fitToScreen.js new file mode 100644 index 000000000..98a3272bd --- /dev/null +++ b/d2renderers/d2svg/fitToScreen.js @@ -0,0 +1,19 @@ +window.addEventListener("DOMContentLoaded", () => { + const svgEl = document.querySelector("svg"); + let width = parseInt(svgEl.getAttribute("width"), 10); + let height = parseInt(svgEl.getAttribute("height"), 10); + let ratio; + if (width > height) { + if (width > window.innerWidth) { + ratio = window.innerWidth / width; + } + } else if (height > window.innerHeight) { + ratio = window.innerHeight / height; + } + // Scale svg fit to zoom + if (ratio) { + // body padding is 8px + svgEl.setAttribute("width", width * ratio - 16); + svgEl.setAttribute("height", height * ratio - 16); + } +}); diff --git a/static/watch.js b/static/watch.js index 0ebeddeeb..0034b2fe3 100644 --- a/static/watch.js +++ b/static/watch.js @@ -11,6 +11,7 @@ function init(reconnectDelay) { const ws = new WebSocket( `ws://${window.location.host}${window.location.pathname}watch` ); + let isInit = true; ws.onopen = () => { reconnectDelay = 1000; console.info("watch websocket opened"); @@ -32,22 +33,25 @@ function init(reconnectDelay) { // out the width, height and viewbox out of the top level SVG tag and update those manually. d2SVG.innerHTML = msg.svg; - const svgEl = d2SVG.querySelector("svg"); - let width = parseInt(svgEl.getAttribute("width"), 10); - let height = parseInt(svgEl.getAttribute("height"), 10); - let ratio; - if (width > height) { - if (width > window.innerWidth) { - ratio = window.innerWidth / width; + if (isInit) { + const svgEl = d2SVG.querySelector("svg"); + let width = parseInt(svgEl.getAttribute("width"), 10); + let height = parseInt(svgEl.getAttribute("height"), 10); + let ratio; + 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 - if (ratio) { - // body padding is 8px - svgEl.setAttribute("width", width * ratio - 16); - svgEl.setAttribute("height", height * ratio - 16); + // Scale svg fit to zoom + if (ratio) { + // body padding is 8px + svgEl.setAttribute("width", width * ratio - 16); + svgEl.setAttribute("height", height * ratio - 16); + } + isInit = false; } d2ErrDiv.style.display = "none";