GroundForge is a library to generate tread diagrams from pair diagrams for bobbin lace. It is partly written in ScalaJS. The ScalaJS code runs on a JVM platform as well as in a JavaScript environment. Additional JavaScript functions create interaction between the web page components.

Current User Interfaces

Demonstrators

A few pages are the “hello world”-s of the basic components that work together in the user interfaces. These components can be tweaked, combined or inspire additional user interfaces for special use cases.

source examples see also query notes
proto.html spidersrosetest Pattern definition.
pair.html spiders, rose, max 4 colors per stitch.
thread.html spiders, rose 1 color per stitch pair diagram and thread diagram.
Comment in the source explains how to tweak the code for droste patterns.
sheet.html sheet.html Pattern families.
A simplified hardcoded variant of the page that takes a family of Tesselace patterns as parameter, you probably can make more and intermediate variations

Create your own variant

Steps to create your own variations of the demonstrator pages.

  • create a new directory with sub-directories api and js
  • download raw versions of the source(s) of your choice into the api directory
  • download raw versions of the referenced scripts into the js directory
  • your local page(s) should now behave like the public versions, you can grab other URL queries from the pattern editor.

Now you can fiddle around with your own knowledge of HTML, JavaScript, CSS, whatever framework you fancy to add or embed something on your own web pages.

Note that the functions called from GroundForge-opt.js are also available for a JVM environment on the server side. For that purpose you can look around in the releases for a jar asset. The downloads above then should be taken from the source code zip or tar of the same release.

IDE and build

An alternative to wait for an irregular release: create a local clone from the github project and run mvn clean install -DskipTests for an up to date jar in the target directory or one of the toJS scripts for GroundForge-opt.js.

When importing the project into an IDE (for example the community edition of Intellij) ignore the suggestion to import as an SBT project, do import as a maven project.

Note that plain Scala code only runs on a JVM environment while the GroundForge library is writtein in ScalJS with the purpose to run also in a JavaScipt environment. File access and plain Scala libraries are limited to the test classes. The tests run with Maven or by your IDE.

Exchanging complex data types between the library and Java or JavaScript can be complicated. So the methods are designed to exchange primitive data as much as possible, or the host language stores the data to be passed on to other library calls.

Note that Github builds the pattern editor with jekyll, instructions to test locally, see also how to publish your own fork on github.io.

Notes on the HTML/JS code

URL query

The diagram editor and some API pages for pairs and threads need the same set of query parameters. The query of the diagram editor is assembled by JavaScript via the link button. The query mimics what would be sent to a server when submitting the form. Many fields of the form are hidden to the user.

To avoid outdated documentation: look for the usage of TilesConfig.queryFields.

  • Droste patterns use additional parameters in the load function of tiles.js.
  • API/proto.html uses only some of the queryFields.
  • API/sheet.html does not use a query at all.

Inline SVG

The demonstrators assign SVG content to <div> elements. Let us compare two methods to assign the content:

d3.select('#someId').html(svg)`
document.getElementById("someId").innerHTML = svg

The first method requires the library js/d3.v4.min.js, which is primarily intended to take care of the animation alias nudging of nodes. The second is plain JavaScript but terminates the script with an exception if the id does not exist in the DOM of the page. The SVG content is generated with calls to the library js/GroundForge-opt.js. This library is compiled to JavaScript from ScalaJS code, look for @JSExport annotations.

Event handling

Except for the pattern families, the diagrams have out of the box event handling.

The SVG elements for stitches have an attribute onclick="clickedStitch(event)", bobbins and the starts of threads have onclick="clickedThread(event)". On proto.html we have onclick="resetStitch(event)" and hidden form fields with onchange="showProto()".

Animation alias nudging nodes

pair.html

The function PairSvg.render generates the SVG content for a pair diagram with 4-colors-per-stitch. The generated elements with class link have identifiers that concatenate the identifiers of the source/target elements with class node. The identifiers of the SVG elements are unique. The identifiers shown in pop-ups (titles) of the diagrams are only unique within the bold area of the pattern diagram. An example:

<path id="r0c4-r1c3" class="link" d="..." style="..."></path>
<g id="r0c4" class="node" transform="..."><title>ctc - a1</title>ct - a1</g>
<g id="r1c3" class="node" transform="..."><title>ctc - a1</title>ctct - b2</g>

The script js/nudgePairs.js uses the concatenated identifiers to find and bind the data required by the d3 library. The nudge script rewrites the values for the d and transform attributes as calculated by the d3 forces.

thread.html

The functionshowGraph in thread.html does both the rendering and the nudging of thread diagrams as well as old style pair diagrams. The latter are stepping stones for the first. ScalaJS data structures are paired up with generated SVG elements to compute the forces. A ScalaJS method uses this data to compute the d attribute of links with shortened starts or ends.

Download SVG

A download link can be created as follows:

var encoded = encodeURIComponent('<!--?xml version="1.0" encoding="UTF-8"?-->' + svg)
var el = document.getElementById("someId")
el.setAttribute('href', 'data:image/svg+xml,' + encoded)
el.setAttribute('download', 'some-file-name.svg')

The pattern editor is a very crowded user interface. Too many copies of too much data on the page might overwhelm browsers. Some detours are implemented that set the download content only when needed. For desktop browsers the href is set at onHover events, touch devices don’t have such an event.