􀀂􀀟􀀍􀀄 􀀂􀀘􀀋 Failed Experiment: Svg Tweets: Third attempt: Bounding rects, bboxes, ...

(This is part 3 in a set of failed experiments trying to generate SVG tweets in Hugo. I eventually abandoned this goal, and generate HTML archives of tweets instead.)

Tried to use bbox and bounding rect but no success. You could see it measuring something but the result was always wrong.

single.html:

{{- partial "header.html" . -}}
{{- $formattedDate := .Date.Format .Site.Params.dateform -}}
{{- $tweet := index .Site.Data.tweets .Params.tweetid -}}

<style>

</style>

<section id="content" class="single-tweet">
  <p><a href='{{ ref . "/archive/tweets" }}'>About archived tweets</a></p>

  </div>

  <h1 id="single-tweet-page-h1">Tweet from @{{ $tweet.username}} on {{ .Date.Format .Site.Params.dateform }}</h1>

  <p id="single-tweet-dimensions"></p>

  <!-- <object class="tweet-object-svg" data="index.svg" type="image/svg+xml"></object> -->

  <svg
  xmlns="http://www.w3.org/2000/svg"
  xmlns:xlink="http://www.w3.org/1999/xlink"
  style="box-sizing: border-box;"
  >
  <!-- <g class="foreign-object-wrapper"> -->
    <foreignObject
      fill="#eade52"
      width="20em"
      height="100%"
      style="box-sizing: border-box; overflow: visible;"
    >
      <style>
        {{- $inlineTweetStandalone := resources.Get "inlineTweetStandalone.scss" | resources.ToCSS | minify -}}
        {{- $inlineTweetStandalone.Content | safeCSS -}}
      </style>
      {{- partial "inlineTweet.html" (dict "ctx" . "tweetId" .Params.tweetid) -}}
    </foreignObject>
  <!-- </g> -->
</svg>

</section>

<script>


// let svgObjects = document.getElementsByClassName('tweet-object-svg');
// for (let svgObj of svgObjects) {
//   let svg = svgObj.contentDocument.getElementsByTagName('svg')[0];
//   if (!svg) {
//     console.log("Skipping...")
//     continue
//   }
//   console.log("Working...")
//   let { xMin, xMax, yMin, yMax } = svg.children.reduce((acc, el) => {
//     let { x, y, width, height } = el.getBBox();
//     if (!acc.xMin || x < acc.xMin) acc.xMin = x;
//     if (!acc.xMax || x + width > acc.xMax) acc.xMax = x + width;
//     if (!acc.yMin || y < acc.yMin) acc.yMin = y;
//     if (!acc.yMax || y + height > acc.yMax) acc.yMax = y + height;
//     return acc;
//   }, {});
//   let viewbox = `${xMin} ${yMin} ${xMax - xMin} ${yMax - yMin}`;
//   svg.setAttribute('viewBox', viewbox);
// }


const metaElem = document.getElementById("single-tweet-dimensions");
metaElem.innerHTML = ""
let svgObjects = document.getElementsByTagName('svg');
for (let svg of svgObjects) {
  let { xMin, xMax, yMin, yMax } = [...svg.children].reduce((acc, el) => {
    if (el.tagName === "foreignObject") {
      console.log("foreignObject")
      for (const foreignChild of el.children) {
        const { x, y, width, height } = foreignChild.getBoundingClientRect();
        if (!acc.xMin || x < acc.xMin) acc.xMin = x;
        if (!acc.xMax || x + width > acc.xMax) acc.xMax = x + width;
        if (!acc.yMin || y < acc.yMin) acc.yMin = y;
        if (!acc.yMax || y + height > acc.yMax) acc.yMax = y + height;
      }
    } else {
      console.log(`processing a ${el.tagName} tag`)
      let { x, y, width, height } = el.getBBox();
      if (!acc.xMin || x < acc.xMin) acc.xMin = x;
      if (!acc.xMax || x + width > acc.xMax) acc.xMax = x + width;
      if (!acc.yMin || y < acc.yMin) acc.yMin = y;
      if (!acc.yMax || y + height > acc.yMax) acc.yMax = y + height;
    }
    return acc;
  }, {});
  // const viewbox = `0 0 ${xMax} ${yMax}`;
  const viewbox = `0 0 ${xMax} ${yMax-yMin + 10}`;
  // const viewbox = `${xMin} ${yMin} ${xMax - xMin} ${yMax - yMin}`;
  // const viewbox = `${xMin} ${yMin} ${xMax} ${yMax}`;
  console.log(`xMin ${xMin} xMax ${xMax} diff ${xMax-xMin}`);
  console.log(`yMin ${yMin} yMax ${yMax} diff ${yMax-yMin}`);
  console.log(`New svg viewbox: ${viewbox}`)
  metaElem.innerHTML += `<br/> new svg viewbox: ${viewbox}`;
  svg.setAttribute('viewBox', viewbox);

  // svg.height = yMax-yMin;
  // svg.width = xMax-xMin;

  // foreignObj = svg.getElementsByTagName("foreignObject");
  // foreignObj.height = yMax-yMin;
  // foreignObj.width = xMax-xMin;
}



</script>

{{ partial "taxonomyList.html" . }}
{{ partial "footer.html" . }}
  • tried to measure SVG with .getBBox()
  • Found that foreignObject needed getBoundingClientRect()
  • BOTH of these returned… stuff… but I couldn’t just set the height to that value and have it be happy.

eg I tried all of these (see above for context) and all of them were wrong in one way or another:

  // const viewbox = `0 0 ${xMax} ${yMax}`;
  const viewbox = `0 0 ${xMax} ${yMax-yMin + 10}`;
  // const viewbox = `${xMin} ${yMin} ${xMax - xMin} ${yMax - yMin}`;
  // const viewbox = `${xMin} ${yMin} ${xMax} ${yMax}`;

Also, NONE of this is responsive to document changes with the tweet button.

  • You can wrap an SVG’s foreignObject in a g element and measure the g with getBBox(), but the numbers are still wrong.

Responses

Comments are hosted on this site and powered by Remark42 (thanks!).

Webmentions are hosted on remote sites and syndicated via Webmention.io (thanks!).