Git Product home page Git Product logo

gallifreyo's Introduction

Gallifreyo

build test lint tested with jest made with bulma

An English-to-Gallifreyan transliterator, based on Sherman's Gallifreyan created by Loren Sherman.

Note that Sherman's Gallifreyan is a fan-made cipher and is not affiliated with the BBC show Doctor Who.

See it in action

Project status

The goal of Gallifreyo is to be able to recreate the first image from the official guide to Sherman's Gallifreyan — a transliteration of "hello sweetie" — to a reasonable degree of accuracy.

This target image is simple but complex. It is a good indication of how well Gallifreyo handles a range of requirements:

  • low-level requirements like word positioning and sizing, letters and vowels, and sentence formation
  • medium-level requirements like dots, lines, and variance between letter types
  • high-level requirements like double-letter and -vowel merging, sentence outlining, and word interlocking

It's just missing punctuation, paragraphs (multiple sentences), and numbers.

Theirs Ours (v0.2.0)

Obviously, Gallifreyo is incomplete.

Licensing

Gallifreyo is licensed under MIT.

Images produced by Gallifreyo are subject to the same licence of the text that created them — if you wrote the text yourself, you own the copyright.

gallifreyo's People

Contributors

rossjrw avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

gallifreyo's Issues

Store a letter's relative angular size on itself

Right now a letter's relative angular size is stored on its first subletter. Sure, that's where the value comes from, but does it make any sense to keep it there and then refer to letter.subletters[0] forevermore? Hint: it doesn't.

Handle case when a subphrase subtends > 180deg

When a subphrase occupies more than half of the circle, its radius is determined by the smaller of the two angles, resulting in lots of lots space.

I see two solutions:

Quick and hacky: The maximum angle a phrase can subtend is 180deg; the remaining words fill the space. Problem: will be much harder to calculate absolute angle sizes.

Long-term solution: The centre of the circle moves away from the larger letter to more effectively move the space. I do not if this is even possible with the current design of the system, and if it is, I have absolutely no idea how to begin implementing it.

Initial sample fails to appear

Sometimes when loading the page, the initial image does not render. A retransliteration must be prompted (e.g. by changing the input text) for the image to appear.

I can only reproduce this using the dev server (#66) - in production, or using the production build on local, it doesn't seem to happen - although a small version of the initial image is visible for a frame in the top left of the image, presumably before the second transliteration in the mounted hook:

gallifreyo/src/index.ts

Lines 17 to 21 in 6c44763

mounted () {
this.store.modifyInput("Gallifreyo Test")
// Needs an extra transliteration to fix the initial bounding box
this.store.transliterate()
},

The latter can be 'fixed' by adding a CSS animation or similar to the image that fades it in on page load.

I don't know what to do about the former, or if it's even worth fixing.

Refine geometry-related properties

relativeAngularSize, absoluteAngularSize, angularLocation etc. are all stored on the phrase objects. I don't think they should be.

The value being stored implies that it's going to be referred back to frequently. That's not necessarily the case. (#35 implies that this actually is the case, though.) I suspect they're being called for just once or twice, and in the same function.

Critically, these properties aren't needed by all the positioning algorithms, which implies to me that they're only required by the positioning algorithm. If that's the case, they should be generated during the geometry calculation and then discarded afterwards.

Don't differentiate between paragraphs/sentences/words/letters

Everything is a sentence. A sentence is series of smaller units. Those units are words.

A "word" becomes a sentence of words, where each word is one letter.

A "paragraph" becomes a sentence of words, where each word is one sentence.

I should be able to make a generic system that doesn't care what level it's working at.

Don't rotate letters

Right now letters are all drawn at an angular location of 0 relative to their word, and rotated afterwards.

This is not ideal for positioning things on top of those letters down the line, as those positions will also have to be rotated. Ideally I would like everything to be in the right place without transformations.

That being said, this would add a lot of complexity to letter rendering, and it might be better to stick with the current method. I will have to see.

Incremental type transitions

Right now, the structure types have all the progressively-added properties as optional types. This means I have to keep assuring TypeScript that they exist, when I know for sure that they do, but the type system doesn't indicate that.

That needs to change - I need to make Typescript work for me.

StackOverflow thread

Squeezing and/or nesting

Nesting:

It would be nice if letters, especially those in the d block, were able to recept a nearby word. They should be able to rotate and reshape within a threshold to better accomodate this.

Note that a d-site should be able to hold not only another word, but also an f-block letter:

Squeezing:

Failing that, letters could be made to settle into place by reducing/increasing their angular subtension according to how much space they take up. For example, "tt" is a very flat word and takes up very little angular space if it's on the left or right side of the final image. It should be able to reduce its space requirements and let other letters fill the space.

Buffer size does not increase on size-scaled mode

Simple mode asserts that the relative angle of each word is 1, so the buffer value is a proportion of that.

However, the relative angle of size-scaled words is almost always more than 1 (it is equal to the length of the word), but the buffer value is not increased to counter that. This results in disproportionately small buffers and unintentionally dense words.

To counter this, the relative angle of words should not be set to the word's length, but to the word's length divided by the sentence's length (to maintain an average relative angle of 1).

Subsentences

When writing a long sentence using the simple renderer, there is a lot of space space in the middle of the circle. There could be an option to place a small sentence inside it.

There should be some character combination that declares the start of a subsentence. For example:

This is a long sentence. It has a gap in the middle.
#subsentence#Smaller sentence!

The #subsentence# letter could be a single-letter alphabet. The same syntax could be used for other experimental modifiers.

Web workers

I've got an awful lot of functionality happening in the main thread, and with #51, that's only going to increase.

I should start the habit of using the main thread as the UI thread only, and using web workers for everything else.

https://github.com/GoogleChromeLabs/comlink

Split structures into sizes and positions

Simple / Size-Scaled / Spiral aren't three kinds of the same thing. Simple and Size-Scaled refer to the size calculation algorithm for phrases, but Spiral is a positioning algorithm. They should be broken into different categories (even though size-scaled and spiral will look terrible under the current system).

Circular debug line is not correct

The circular line on the word "yes" is not drawn where it should be. The subtension of s is greater than half the circumference; I suspect a flag needs to be flipped. This could be related to how single letters are drawn.

Crash when starting a new line with a space

The following input crashes the page:

a a a a
<space>

Starting a new line with a space when there are less than 4 words on the previous line does not crash the page.

It's fine when the algorithm is set to radial, indicating that the reason 4 words are needed is to create enough disparity to invoke the organic algorithm.

In 68358ac I added an override in the tokeniser that scraps creating a word if it would be empty, but I don't think it does the same for phrases. I suspect that that's the cause.

Animate the logo

I think an initially-stroked set of characters that become filled shortly after loading would be pretty neat. They could fill via transparency, but I think a wipe with a differing direction and timing for each letter would be neater. The order of letters should run left to right.

Organic using spiral as base

An organic algorithm that extends the spiral algorithm could look pretty neat, provided that the starting frame doesn't have any overlapping phrases.

I'd probably need to extract out organic into its own setting.

OOP

Could an object-oriented structure work?

I'm running very similar processes for both sentences and words - in fact there's even some code duplication. This could be slapped onto an abstract class with the more specific stuff on the actual classes. Might even be able to have letters extend that.

I'm sort of doing that already - I'm just passing a bunch of huge objects around a functional procedure. Maybe I'm swimming against the current.

Not worth a refactor right now, but for sure something to think about.

Double vowels

Double vowels can be represented by a double circle where the vowel's circle would normally be.

This could probably be another alphabet in the alphabet file:

[ShermanDoubleVowels]
priority = 2
letters = [
  { value = "AA", block = "vv", vert = -1, line = 0 },
  # ...
]

Do not break on punctuation

If sentences are delimited by ., then one of two situations will happen:

  1. A sentence cannot contain .
  2. All sentences must end with .

What if I want a two sentences, the first of which does not end with .?

Phrases should be delimited by whitespace only. One newline for sentences and two for paragraphs.

Curved lines

adrian17/Gallifreyan#10

This project has a feature that lets the user toggle a spline for a single line. Would be nice to have the ability to toggle curves on all drawn lines - this'd allow me to reach much greater angular thresholds for line connections. I could even have splines enabled only for connections that exceed the threshold.

One thing I don't particularly like about adrian17's splines is that they normally end up being little squiggles rather than the sweeping curves that I crave. I wonder how I'd go about implementing that.

Unlike adrian17 I don't want individual lines to be editable. Just one setting that affects everything.

Limit the angular subtension of a letter

An angle is drawn as if it were on account of some quirk in the radial renderer. With the new organic algorithm, this doesn't really matter for phrases, but for letters it does:

image

The letter is too small.

The easiest thing to do is to limit the angular subtension of a letter. This should only be invoked when there is only one letter in a word, so it shouldn't cause any problems, hopefully. In this example, a d-block letter should be huge and dominate that word.

Allow multiple paths in a single element

Using the debug mode on v0.1.0, which just draws a line between each letter, it frustrates me that these lines have to be drawn exactly the same as the rest of the lines in the image.

It'd be lovely to be able to have multiple paths in a single letter. A main one, drawn in default; a debug one, perhaps in 1px blue... that's about it for now, but it'd leave functionality open for later.

Possible optimisation: don't rerender if only one word has been changed

Rendering everything can take a hot second when there's a lot of text.

If only one word has been changed, only that word in the picture needs to be adjusted. Equally, if only one sentence has been changed, the whole paragraph doesn't need to be redrawn.

Until inter-sentence and inter-paragraph integration is done, these changes won't affect the things around them. Even then, it won't matter unless integration is done automatically instead of being mapped to a button.

Use unique keys to identify nodes

Right now I'm using the text immediately contained by a node to identify it. That's not good enough - in just the word "Gallifrey", for example, there would be two nodes with an ID of "l".

I need a new, totally unique way of ID-ing nodes, but still something that is deterministic i.e. not based on randomness. Critically, the IDs must be unique amongst siblings.

I could do this by having the ID be the concatenation of itself and all nodes before it. That would probably be fine.

Use canvas for drawing

Canvas is probably a lot faster to draw than SVG. I think I should have been using it all along, honestly.

I should save SVG for the export. The preview should be canvas.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.