glyphr-studio / Glyphr-Studio-1

Now deprecated, Glyphr Studio v1 served us well from 2010 to 2023.
https://www.glyphrstudio.com
1.07k stars 94 forks source link

Glyphr Studio v2 #234

Closed mattlag closed 6 years ago

mattlag commented 8 years ago

It's time to start the v2 discussion!

For those who don't know, Glyphr Studio started as a relatively small side project for me, a non developer, over 5 years ago. It has since grown considerably, and has reached a much broader audience (bother users and developers/contributors) than I had every really imagined. This is kind of a problem, but it's really a fantastic problem to have :-)

Glyphr Studio v1 has a kinda-MVC framework I wrote from scratch, probably horrible code organization, no test system, and goes out of it's way to implement functionality that already exists in other well-established projects. Fun for me, but basically not fun for everybody else. V2 will change all this!

We need your help planning V2

@mechanicious started with contributing a fairly major Pen tool feature, but we started talking about a v2 re-write. With his input, and everyone else, I feel like I can comfortably get the help I need to pull Glyphr Studio into the next level. My vision, or decision/planning points, as of right now are as follows:

  1. Continue utilizing OpenType.js
  2. Use Paper.js for most interactive / GUI stuff
  3. Choose some JS framework (like React / Angular)
  4. Choose a better JS language (Babel-ES6 / Typescript)
  5. Choose a Test Framework and actually write unit tests
  6. Probably choose some other dev stack stuff (task runners, etc)
  7. Consider major UI / IA design changes (how pages / panels work)

@mechanicious is starting to look into the dev side (basically 3-6) and I'm thinking about design. But really, I wanted to get high level input from as many people as possible.

help us break it down

I'm @ including a bunch of you in this issue - you are folks who have either shown significant interest in Glyphr Studio, or have contributed / suggested major changes. We are in a planning phase, so this is the time to suggest big things. I want to keep Glyphr Studio's overall vision of being aimed at typeface design hobbyists / beginners - but besides that, is there something big that Glyphr Studio is missing? Is there some way that it's developed now that should be majorly changed? Is there some way it's designed now that should be majorly changed?

We've started a slack, because, you know, it's awesome. So email mail@glyphrstudio.com to be added to that conversation... or you can throw comments in this issue. Or tweet me. Or whatever. Tell everyone you know. Tell us anything that's on your mind. Let's do this, I know i'm excited :-)

Peoples

@ include others I may have missed, but this is the bit where I get people's attention: @davelab6 @louisremi @lukeb-uk @tomByrer @gambhiro @bpmccurdy @pathumego @raphaelbastide

:rocket:

davelab6 commented 8 years ago

is there something big that Glyphr Studio is missing?

7 is the most important thing, I think, and the rest is "merely" procedural, but of course to energise a developer community to execute on 7 is what the rest is for :)

Simply put: The UI is not useful for "real" type design work, because the context of other lettershapes is so critical to drawing any given letter but that context can not be made visible in the current UI. This is discussed in #6 #94 and #197 :)

All the rest are definitely good ideas. Angular, ES6, bower would be my picks, but I am not a developer, so whatever works for actual contributors is better :) Perhaps @graphicore has an opinion about testing.

In terms of 'engine' or 'core' things, the biggest thing missing for me is a 'proper' undo system: one that allows (like git or other version control systems) de-duplicated data representation to keep the tree size lean, being able to rewind/fastforward to any state in the tree, forking and merging, etc.

I want to keep Glyphr Studio's overall vision of being aimed at typeface design hobbyists / beginners

I am going to be a GSOC mentor this summer for the software project that emerged out of the old "One Laptop Per Child" thing - https://github.com/davelab6/gsoc/blob/master/2016-sugar-call-for-proposals.md - and I cc'd @llaske since he is the founder of http://sugarizer.org, the new web based children's-learning web app platform.

A "Sugar Activity" font editor is also squarely aimed at typeface design beginners, but has to work with the UX guidelines of Sugar itself. I am yet to dig them out, but that is on my April TODO list :)

Perhaps the GSOC student could spend their summer working on Glyphr's core, if it was refactored to be easy to 'skin' for Sugar.

a slack, because, you know, it's awesome

No me gusta ;) I find real time chat rooms to be too time consuming, demanding too much attention, and being hard to catch up on. I hope you'll post whatever important ideas arise out of slack on this issue tracker :)

mattlag commented 8 years ago

@davelab6 I'm putting on my program mangement hat for this v2 effort, i'll definitely keep this issue up to date with major decisions from Slack.

As always, thank you for your input. Sugar seems very interesting... but i'm not sure how quickly v2 will progress. Keep us in the loop.

davelab6 commented 8 years ago

@mattlag :trophy:

Glyphr's code is today 100% JavaScript, and runs entirely in the browser. That's cool, because...

"There is no cloud, only other people's computers."

If in future you offer remote storage features, I recommend using the unhosted.org model, perhaps with the remotestorage.io standard, so that users will keep total control of who's computers their fonts are uploaded to.

You may also like to offer a 100% local version via nw.js.

I also suggest looking at @hoodiehq which makes using pouchdb easy.

@mechanicious what kind of schedule do you have in mind for this? :)

graphicore commented 8 years ago

Perhaps @graphicore has an opinion about testing.

Yeah, I'm currently not happy with my Metapolator/ufoJS situation.

ufoJS has a testing suite (d.o.h.) that is really old and a bit behind plus probably hard to update, but it runs nicely for my purposes from node and from a simple HTTP server in the browser.

Metapolator uses https://theintern.github.io/ which is more modern i.e. can include different testing apis (chai for me), does code coverage analysis, but is hard to run from e.g. a $ python -m SimpleHTTPServer and a pita to configure (because it is too bloated for me), it also had some minor quality and maintenance problems lately. I'm not saying it is bad, I'm just saying it's to much for my purpose.

I'm looking for a leaner test runner than the intern that takes arbitrary assertion libraries, like http://chaijs.com/ to be rolled out in a couple of sub-projects I'm preparing right now as offspring of Metapolator: Atem also: https://github.com/search?q=user%3Agraphicore+Atem

It's important to mention that I'm using AMD-modules (require.js) in all these projects, so my testing framework should do so, too. I'll add a new post in a second about modules and stuff.

mattlag commented 8 years ago

@davelab6 I still am really in love with the idea of Glyphr Studio being 100% client side... all 'compiled' nicely into a single .html file. It may be strange, but I think we'll keep that for v2.

graphicore commented 8 years ago

is there something big that Glyphr Studio is missing?

Modules! That is a point to be added to the 3-6 list. You got basically 3 good alternatives:

Despite of anything else being more popular I'm still very happy with AMD. Especially when you say "100% client side" it may be worth a look. You can load a big project, module by module locally in reasonable time when developing and build a one-file.js for distribution.

But much more important is that you use any module structure and stick with it. I.e. Never use any globally defined vars. Instead, each module must import it's dependencies at the top of the file. That's the way to stay sane when doing a rewrite. Also, patterns like dependency injection help (or to avoid defining "public" interfaces that you don't need at the moment, there's much more that helps ...).

Use jshint with a setup like this:

{
    "undef": true
}

To be informed when you use undefined variables in a file.

davelab6 commented 8 years ago

@mattlag yep, it is wonderful that it can be compiled like that! However, I think it is inevitable that users will want to be able to store their project "in the cloud" because it is so convenient. So I think it ought to be part of a v2 plan/vision, and that plan ought to include it being possible for us to do so using our own cloud servers, with a "Glyphr Server" program that can be integrated into the wider Sugar Server or ownCloud server frameworks.

@graphicore To confirm, using js modules will not prevent Glyphr Studio being compiled into a single .html file (by bower)?

gambhiro commented 8 years ago

Glyphr all the things!

I'll share my recent experience about choosing a JS framework. TL,DR: go React, for the rendering speed. Don't go Angular, go ClojureScript and fly into the Sun. It took me less time to learn writing Clojure(Script) than the time I spent figuring out the idiosyncrasies of sails.js and angular.js.

The rest of this is about how I ended up with ClojureScript.

I have been wanting to write this wiki app for office data-organizing for the people around me. One day I started, and after the research I started to write it with sails.js as back-end, and angular.js as front-end. For a while, all was well.

What had got to me eventually was the amount of time spent with fighting the frameworks and drilling in the discipline each one has, i.e. that sail.js has a way of doing JS you must follow, angular.js has a way of doing JS, then underscore.js, then etc. has one, you just keep trying to hold everything in the right angle to write this one function. Then that is done, and you do it again for the next. Exhausting! And completely distances you from thinking about the app you are building, or the problem you are solving in the code.

Each of these tools introduces great ideas, and it is testament to the flexibility of modern JS that they can even do this. But they can only do it with adding more conventions and discipline on top of the language.

ClojureScript compiles to JS. You deliver the application to the user the same way. It addresses the above situation with implementing the best of modern JS practices right in the language. There are two react.js wrappers, Reagent and Om. Other people have presented this better:

ClojureScript + React.js

ClojureScript Release - Rich Hickey

Clojure Made Simple

gambhiro commented 8 years ago

Sorry, that was a bit evangelizing, but the talks are cool nonetheless :)

graphicore commented 8 years ago

@graphicore To confirm, using js modules will not prevent Glyphr Studio being compiled into a single .html file (by bower)?

With AMD-Modules you can put all modules into a file (using r.js) and add almond on top, which is like require.js but can't load from external. The contents of that single js file you can copy into a <script> script tag. (Note: r.js, require.js and almond are all from the requirejs project, so they work well together and the stuff is mature, http://requirejs.org/ is a good resource)

With commonjs modules, I think you would use something like Browserify. Browserify will also package a single js file for you and add it's own loader. It's in the end very similar to the result of r.js + almond.js

I'm not sure about ES6 modules. But it should be something out there I guess. Would be a point to check before going with ES6 modules though.

graphicore commented 8 years ago

@gambhiro

I'm personally more conservative in terms of using other languages that compile to JavaScript. But that's not because I dislike well made functional programming languages or such. It's rather that my focus is on building libraries for the broader web platform, and the single common language there is JavaScript.

Using these compiled-to-js languages raise some questions, like

I could spend hours iterating over questions like these. That's why I'm conservative there, unless I have good reasons for going to something else, I'll just try to write the best possible plain JavaScript es5/es6 compatible.

graphicore commented 8 years ago

go React, for the rendering speed. Don't go Angular

Metapolator is using Angular(-1 I did not evaluate Angular-2). I agree that it may not be the best choice. React gets a lot of praise since a while. Also, I wonder if/how polymer could be used with either, and if there's any gain.

In the meantime I try to separate the business logic as far as possible from the frontend/framework logic and for some simpler cases it may be just enough to do it directly with the DOM—one big dependency less, yay!

mattlag commented 8 years ago

@graphicore Yes, some sort of modules, I forgot to mention it, but definitely this. In v1 I assumed the entire global scope was mine to play with, which is a horrible practice :-)

@gambhiro Thank you for your writeup! I'm in a bit of a weird spot, because I have no experience using compile-to-js languages... but none the less I think I agree with @graphicore, i'm worried about barrier of entry. Other languages may be relatively easy to learn, but vanilla js is the shared language, which is very attractive from a contributions standpoint. I also don't want a language choice to preclude using other projects / components written in vanilla js - having to do extra work to make regular javascript work sounds kind of silly.

Does anyone have experience with TypeScript? It does "compile to javascript" - but it's also just a superset, so regular javascript is also TypeScript. On the surface this seems like a good compromise to me (again, having zero experience in the matter :-))

gambhiro commented 8 years ago

@mattlag On a quest like this, one should love the experience of writing the code. And re-writing it too, as it usually happens.

I suppose that was more the point of the message above, not so much what language or tools that means. By the time I was beyond the boilerplate, things were growing numerous, writing the more complex parts, I really felt mentally burdened with having to do this juggle all the time, but the marketing is very good and I thought that was the only way.

@graphicore Barrier of entry, certainly. But pain is very motivating, I was going to go all the way even if that was into a LISP :)

I did enjoy learning Angular actually, a lot of power is packed into it. But do think what is Glyphr going to need? It is not manipulating a lot of HTML pages or complex user input forms, for example. The scopes and data-binding is still big though. Still, if all you want is the routing and hashtag navigation, Backbone.js would be enough.

TypeScript, as I understand, is about the syntactic sugar. Type less, look at cleaner code, have some type safety. Which is a good thing, but you are still in JS.

Clojure and -Script goes for the deeper root, gives you this very well thought-out language with keeping modern demands in mind, and you basically forget this is going be JS in the end.

The result is that most things are solved with the primary elements of the language, not with extra stuff from frameworks. To me the experience is very creative. I do recommend the talks I linked above. They express the sort of qualitative difference.

mattlag commented 8 years ago

Hi All

We have a collection of specs that we're working on - they are in varying states of iteration and done-ness, but here they are if you're curious:

https://github.com/glyphr-studio/glyphr-studio-2-specs

I just finished one up today about Panels: https://github.com/glyphr-studio/glyphr-studio-2-specs/blob/master/design/Panels.md

davelab6 commented 8 years ago

@mattlag great to see the progress on this in https://github.com/glyphr-studio/glyphr-studio-2-specs/commits/master :D

cc @eliheuer @YashAgarwal

davelab6 commented 8 years ago

Last week www.metapolator.com/v0.4.0/full/ was released and now it works out of the box in Chrome and its VERY fast :D I encourage you to take a look at the "Atem" codebase @graphicore has spun out of Metapolator, and ufoJS, for v2

graphicore commented 8 years ago

look at the "Atem" codebase

It's badly documented, but there's an overview at https://github.com/graphicore/Atem-Project#atem-project

The Atem-MOM module is the origin for typography related code while [https://github.com/graphicore/Atem-CPS] is responsible for more generic basics of the system.

Autre31415 commented 8 years ago

Hey @mattlag, this project was just crying out to be a desktop application with a real taskbar entry / dock icon... so @kethinov and I made one out of it! https://github.com/Autre31415/Glyphr-Studio-Desktop/releases

We'd of course be happy to give you push powers to our repo or we could just move the code to a GitHub Organization for all Glyphr projects if that's more your style. However you want to manage it. It's your project. We just want to make it a bit more awesome.

We of course both agree with what you wrote above that Glyphr Studio being 100% client side is a great idea - it's the principal reason it works so well as a desktop application when wrapped with electron.

One big caveat: we spent a solid week trying to adapt popOut to electron and it just isn't possible due to how intertwined the business logic is with the UI layer.

For popOut to work in electron, you'd have to refactor Glyphr's UI rendering code into something more modular so that you're not directly altering the DOM from window A to window B or vice versa.

This is because electron's security model prevents two windows from altering each other's DOM directly. Two windows can send messages / data payloads / emit custom events to each other, but transferring objects wholesale (e.g. the document object) is not possible.

As such, we would need a more sophsticated abstraction around the UI drawing than the rather simplistic getEditDocument() function which abstracts the document object of whichever window the drawing canvas is located in.

Instead of merely abstracting the document object, we'd need the whole of the UI drawing and all its DOM manipulation encapsulated in whichever window needs to be drawn to, rather than having window A try to manipulate the DOM of window B directly and vice versa.

We figured we'd mention that here in this issue thread, since if you're working on a 2.0 version of Glyphr, then greater abstractions around the UI code in pursuit of making it easier support the popOut feature in electron would be a terrific nice to have. Anyway, thanks for making this and we hope you like the electron version we made! 😃

davelab6 commented 8 years ago

Awesome work @Autre31415 :D

mattlag commented 8 years ago

Yes, this is fantastic! I started, briefly, to play around with NW.js, but dropped it since I'm way over capacity for this 'little project' as it is :-) I'm very happy that you took the initiative!

This brings up something else i've been meaning to do - transition Glyphr Studio V1 over to the Glyphr Studio organization (right now the main project is still under mattlag) I think having a V1 desktop version as a repo under the Glyphr Studio org makes total sense, and we'll invite you to be admins or whatever on that.

And, also, I agree with your simple fix now of just hiding / ignoring the Pop-out functionality for the desktop app is the right move. Probably just keep it that way till we 'fix' it in V2. I don't want to say V1 is in maintenance mode... but I am trying to put more effort into V2 at the moment.

As for V2, I totally agree a desktop version would also be awesome. @mechanicious and I are still in the very early stages of V2, so citing new requirements is still totally within timeframe. In addition to desktop version, we'd also love help getting V2 off the ground, if that's something you'd be interested in.

Here are some action items for me:

Let me know if this makes sense, and/or if there is anything else!

mechanicious commented 8 years ago

We'll take the need of these abstractions into the account while working on v2. A standalone app is a feature which many users have been looking forward to and we absolutely want to support it into the future. Feedback from the desktop repo is therefore of great value. Great work!

As @mattlag has already mentioned, we're working hard to get the right level of abstraction to ensure the best evolutionary path of the project according to the community. At this stage we're very happy to welcome any feedback/ideas to dabble with; as much as any help with implementation of these ideas.

Merging it with the organization is a good idea. Those who want to get even more involved are welcome to join our Slack to discuss about features in realtime.

kethinov commented 8 years ago

I think @Autre31415 and I would both be happy to maintain the desktop version, as we both have some experience tinkering with native apps and electron, but I don't think either of us are terribly qualified to offer advice on how best to structure the architecture of the main project, as we're not font or design experts. From what I'm seeing in the thread, you guys seem to have it handled.

But if/when you've got an alpha/beta stage version of 2.0 going with better abstractions around popOut, we'd be happy to take another stab implementing support for how electron does multi window management so we can support 100% of the features of the main project. In general though, any business logic / UI layer abstraction you guys come up with that allows each window to do its own UI drawing based on simple, one-line messaging should be sufficient.

I'm imagining some kind of system that allows us to do something like this:

The current codebase does stuff like this:

var el = getEditDocument().getElementById(etc).moreDomStuff.etc;
el.yetMoreDomStuff;
el.moreDomStuffYetStill;

We'd refactor all the UI drawing to be more like:

doInterfaceThingy(someDataPayload);

Condensing it all to one line is a really big deal for the electron execution environment. It lets us tell the other window to do its own UI drawing, rather than having window A do window B's drawing for it.

Inside all the functions like doInterfaceThingy would be the code like this:

function doInterfaceThingy(someDataPayload, isTargetWindow) {
  if (isTargetWindow || !popOut) {
    // the popOut window is either not open, or this function wants to draw to its own window
    // [insert DOM manipulation code here]
  }
  else if (isElectron && popOut && !isTargetWindow) {
    // the execution environment is electron, popOut is open,
    // and it wants to draw to the other window
    nativeElectronApi.executeJavascriptOnSecondWindow('doInterfaceThingy('
    + someDataPayload + ', true);');
  }
  else {
    // popOut is open, we're not in the electron execution environment,
    // and we want to draw to the other window
    // [either insert DOM manipulation code here]
    // [or insert JS commands to the other window here using browser API instead of electron API]
  }
}

Ideally, in a best case scenario, we'd develop a further abstraction to do this check automatically on every instance of UI drawing, rather than littering every function that does UI drawing with the popOut and electron execution environment checks.

That's pretty much the conclusion we came to when struggling with figuring out how popOut could be adapted to the electron execution environment. I hope that additional level of detail is helpful. 😀

mattlag commented 6 years ago

Closing this down - we're going to continue adding features on with the GS1 code base.