alexjlockwood / ShapeShifter

SVG icon animation tool for Android, iOS, and the web
https://shapeshifter.design
Apache License 2.0
3.98k stars 204 forks source link

Transpiled library files is available in CDN such as CDNJS, jsDelivr, unpkg or etc...? #166

Closed dalisoft closed 7 years ago

dalisoft commented 7 years ago

Hey @alexjlockwood I see your demo at here and very amazed, really. I am interested in CDN js file for morph, but does everything for me, like GSAP, KUTE.js, Wilderness, etc... Amazing work, when have js cdn ver, we can work together for even better (maybe...?) work

alexjlockwood commented 7 years ago

Thanks for the compliments! What do you mean by a basic CDN js file?

dalisoft commented 7 years ago

CDN-js file (compiled): Just a reference to file, then use like this:

// Using prototype like method saves memory a lot
new ShapeShifter().morph({
from: '#path1',
to: '#path2',
reverse: true | false | auto,
shiftIndex: 0-999 | auto,
duration: 2000,
easing: ...
etc...
})

Look to kute.js svg plugin, wilderness.js, gsap morphsvg, etc to understand what i mean

dalisoft commented 7 years ago

I am interested in how you add the midpoint or correct/fix the points when unmatchs. Looked to any file, i not understand the TypeScript

alexjlockwood commented 7 years ago

The JS code for the demo animations in the blog post you linked to is here: https://github.com/alexjlockwood/AndroidDesignPatterns/blob/master/_js/src/posts/2016/11/29/animated-icon-demos.js

The code is pretty basic. I wrote it 6 months ago when I just started out learning Javascript. I used a web-animations-api polyfill. Some of them don't work in Safari and Edge though... if I recall correctly there are some bugs related to animating stroke-dash{array,offset} in those browsers.

ShapeShifter was never intended to be a library like Flubber or GSAP or Kute.js. It was always intended to be a web app for developers and designers. That said, if you think it would be useful I'd be open to suggestions. I am planning on improving the auto fix algorithm pretty soon to incorporate some of the triangulation ideas used in Flubber. But I doubt I will ever be able to compete with GSAP... I feel like if a web developer wanted to make a path morphing animation at runtime, they might as well just use GSAP because I'm sure their code is much better than mine. :P

alexjlockwood commented 7 years ago

Also, Typescript isn't too hard to understand to be honest. It is a superset of ES6, so any code that is valid ES6 is also valid TypeScript. If you remove the type declarations from the code, what you will be looking will probably be pretty close to ES6 in fact.

alexjlockwood commented 7 years ago

BTW, I wrote the blog post before I even started working on ShapeShifter. :) I only linked to it on shapeshifter.design because I haven't written any documentation for the tool yet. But I am probably going to replace it with a link to this pretty soon: https://webdesign.tutsplus.com/tutorials/quick-tip-easily-morph-svgs-using-shape-shifter--cms-29058

Also as for the "adding midpoint and correct/fix the points when unmatches"... this is still something I am looking to improve. Right now I use an application of the Needleman-Wunsch algorithm (https://en.wikipedia.org/wiki/Needleman%E2%80%93Wunsch_algorithm) to figure out how to align the SVGs and where to insert dummy points. But it is pretty slow, especially for paths that contain multiple shapes. Noah Veltman's work with Flubber has given me a lot of inspiration for areas of improvement though... I've already started writing a new and improved algorithm that I think will work a lot better. :)

dalisoft commented 7 years ago

I see your files, the not just TS. It is included something high quality code for reducing memory and increasing performance. I am also worked for morphing and etc animation tool, while my friend told my code looks like GSAP and i am removed repo. I am see algorithm, it is for letters working for me. Autofix your app so nice i am looking for API to normalise the path. Today i am maked simplified and light version morph which maybe closer good look like ShapeShifter and name is minimorph, i amazing your midpoint because it looks like really. Also your webapp shifting reverse etc works better. Maybe there has simplified AutoAwesome.ts and for js. I will watch the updates with interesting.

dalisoft commented 7 years ago

The demo looks like hacky. I can use your method when you commit new method for autofix?

dalisoft commented 7 years ago

I am used Wilderness.js (before been snapsvg, 2015) and d3js demo (later improved and added a lot features) for my app and size is 120kb which large for mobile app

alexjlockwood commented 7 years ago

Maybe if you give me an example I would understand better what you mean. Do you have an example SVG you would want to morph? I could probably split autofix into a separate repo and host it on npm... But I am not sure what the API should look like yet. Would hosting something on npm be what you are looking for?

Another thing I should mention... My code may not be 100% memory efficient. But I probably not that bad... Just would have to benchmark it I suppose.

One last thing... I'm not sure if you have used ShapeShifter yet but the reason I made it was because so many tools are out there that try to automatically make animations compatible. ShapeShifter allows you to autofix and also manually adjust the morphing animations like this: https://youtu.be/WjfXyxDC5Fw

dalisoft commented 7 years ago

I need just simple autofix function without dependecy and ligther size if possible.

Maybe Api looks like this?

Autofix ('M10,10L30...', 'M20,50C10,20,...')

dalisoft commented 7 years ago

@alexjlockwood Here link to my project part (now make public repo for it). Look at code and let me know where i can improve or fix, implementing AutoAwesome to this would be awesome. Note: my project is faster than any other, after fully fixing i am upload benchmark (1.2-x faster than MorphSVG, 1.8-x faster than SnapSVG, etc...)

dalisoft commented 7 years ago

@alexjlockwood I am did the CDN-version, part/split code everything for you understand what i mean. See for CDN or etc demo: https://github.com/dalisoft/minimorph See my morph too bad if shape not prepared: https://codepen.io/dalisoft/pen/OgaPqw (in comment i write your tool shape preparer/normalizer, if you not against)

Now you can help me implement auto-awesome aka shape normalizer to js?

alexjlockwood commented 7 years ago

I may be able to help at some point in the future, but right now I am prioritizing some other things related to improving ShapeShifter.

If you don't want to wait, I suggest taking a couple of hours to learn the basics of TypeScript. I honestly don't think it will take more than a couple of hours to understand... the AutoAwesome code is very basic TypeScript in its current form. Of course, feel free to ask me any questions if you don't understand a specific part of the code!

dalisoft commented 7 years ago

Ok, thanks @alexjlockwood

I am few hour ago think of convert from ts to js awesome-js (simple). I will use your Awesome file after i get

dalisoft commented 7 years ago

@alexjlockwood I am learned some basics of TS and some of these is i know (similar to es6). I am get AutoAwesome. But it has much reference cycle to other folders that parses SVG which no need for me because i have the parser. There are i have 2 problems:

  1. How to get auto awesome only file fix function without dependecy.
  2. What parametr should pass in subIdx in Autofix function?

Thanks for help

dalisoft commented 7 years ago

Or you can write me how it works. Example [M,5,6] [L,6,7]

and path 2 is [M,90,-10] [C,10,20,30,40,50,60]

There how algorithm works, basic explaining would be amazing

dalisoft commented 7 years ago

Your autofix works best for multipath as well as for singlepath and your midpoint function works amazing with auto matching closest point. i use points.js (npm) add function to add midpoint to match same number of points.

dalisoft commented 7 years ago

I am interestes in more than all. I have also some ideas for split single path to multi if to shape is multishape or reverse

alexjlockwood commented 7 years ago

Responding to your comments in order below:

I don't have too much time to explain, but let's say you wanted to use the algorithm to align the following two DNA sequences (this is the same example given in the wikipedia article above):

GCATGCU
GATTACA

As shown in the wikipedia article, running the algorithm on the above sequences might result in the following alignment:

GCA-TGCU
G-ATTACA

My auto fix algorithm behaves very similar, except instead of working with DNA base pairs (i.e. G/C/T/A), it works with SVG drawing commands (M/L/Q/C). So aligning these two SVG paths:

MLCLQCL
MLCQL

might result in an alignment like this:

MLCL-QCL
ML--CQ-L

The dashes represent "gaps" in the alignment... these are the places where I add dummy points to the SVG paths.

This may or may not be helpful, but here is a picture of some notes I have on my desk from a few months ago when I first wrote the algorithm. It should give you a good idea of how the 'dashes' in the alignment correspond to dummy points that are added to the SVG paths:

img_20170712_165417

dalisoft commented 7 years ago

Thanks for response and simplifiy. I use for midpoint https://github.com/colinmeinke/points. midpoint i mean is normalise less pointed points segments to longer by adding midpoint.

Your autofix automatic corrects subpath count.

I see algorithm and only letters. Not path 2d or commands so then asked from you.

Thanks

dalisoft commented 7 years ago

You helped me a lot. When i implement this. My idea is for subpaths like flubber.js

https://stackoverflow.com/questions/41609438/how-to-split-one-path-into-two-paths-in-svg

And little changed https://jsfiddle.net/ttk0sdh2/

This is just starting for my ideas.

Thanks again

dalisoft commented 7 years ago

Your algorithm works best because it automatic finds nearest point equal to another shape and very fast as well as looks like real morph. Not ugly.

Also i am find some good method from paperjs splitat method does same thing as triangulation+topojson but bit faster and cleaner code.

alexjlockwood commented 7 years ago

To be honest, the auto fix algorithm could probably be a lot faster. I have barely touched it since I first implemented it, so I have not optimized it very much. In fact, as I was typing this I just realized a way to speed things up by up to 2x, haha. Right now the algorithm reverses and shifts through each possible SVG path permutation (i.e. 2n permutations for a path with n draw commands). But if think I could cut it down to just n if I made sure all of the paths we're clockwise beforehand. Dunno... I'm typing this on my phone at the airport right now... I could be wrong. :P

And yeah, I have been trying out some of the flubber triangulation techniques as well. It seems promising! The only thing that I'm not too sure about is how flubber approximates all of its paths as polygons. Even cubic bezier curves need to be approximated as polygons with very short line segments, which results in paths with tons of points. The auto fix algorithm doesn't do this... which is probably better performance wise (less points to interpolate => better performance, right?). But again, I haven't really bench marked any of this yet.

dalisoft commented 7 years ago

I know about performance loss of getPointAtlength. Because of it i will researching the way of split paths

alexjlockwood commented 7 years ago

I've implemented that here:

https://github.com/alexjlockwood/ShapeShifter/blob/triangulate/src/app/model/paths/Path.ts#L119

alexjlockwood commented 7 years ago

I've also implemented the ability for splitting paths. I've written a lot of code for Shape Shifter since it is so GUI heavy. :)

dalisoft commented 7 years ago

Without getPointAtLength? It is really nice news. Thanks for a lot work. I have better idea. Maybe i provide the CDN version under some expieremental branch insteadof create my own if have done project why another. If we work together we will be something good

dalisoft commented 7 years ago

You path split code is not live yet?

dalisoft commented 7 years ago

Why point, path constructors? I really spend 2 day for this and still cant get. Maybe i should learn more about adaptation of code

alexjlockwood commented 7 years ago

Have you messed around with https://shapeshifter.design yet? Here is an example of how it is used: https://www.youtube.com/watch?v=YtYDEezpmpU

In the video, the user is splitting the play button icon into two separate shapes. In order to do this, I had to write a lot of path splitting code. A lot of that code begins inside of this file: https://github.com/alexjlockwood/ShapeShifter/blob/master/src/app/model/paths/PathMutator.ts

An example of how you would use it:

const path = new Path('M 0 0 L 10 10 L 20 20');

// Split command #1 in subpath #0 at `t=0.5`.
const splitPath = path.mutate().splitCommand(0, 1, 0.5).build();

console.log(splitPath.getPathString()); // outputs M 0 0 L 5 5 L 10 10 L 20 20

There are a bunch of tests here that might make it easier for you to understand how things work: https://github.com/alexjlockwood/ShapeShifter/blob/master/src/app/model/paths/Path.spec.ts

I have only been writing javascript/typescript for about 6 months, so when I started writing some of this code I designed a lot of it similar to Java (which is probably the language I know best). So that's why Point and Path have constructors right now probably. I've been meaning to remove the constructor from Point because I realized later it wasn't necessary, but haven't gotten around to refactoring things. If you have any suggestions on how to better design it, I'm open to suggestions. But it would be easier for me to understand if you gave me some examples of what you would change.

Writing things in an experimental branch sounds good to me. I am open to hosting the code you need in a separate npm library or something. But I have never done that before, so if you have a link on where to learn how to do that, it would be great!

The getPointAtLength() isn't in master yet, but I could pretty easily cherry pick it in.

dalisoft commented 7 years ago

I basically use CDN (almost 3month ago started, before it my all request was declined). now even cdn got better. I suggest you learn npm first with their docs. I am too few month ago started. I use simple steps

  1. Once download node.
  2. Run bash/cmd in your favorite workspace and type 'npm init' answer in few question. After you put files then run 'npm publish'.

I am still junior developer as havent done yet something great. You is advanced developer as i see, because learning AngularJS is harder than basic ES6 and ReactJS.

About CDNize the repo. I will create repo on npm with shapeshifter, you can make me moderator to your repo? I then made another branch (or you will name it and create). I use your some API for simplifiy actions. Much of users are can be get via npm (nodejs package registry)

dalisoft commented 7 years ago

Note: i will be on laptop in next week then i can do something good. I am still using phone to PR, Issues, etc.

dalisoft commented 7 years ago

If you have this split method why you need triangulate? I am need that for split single moveto based paths

alexjlockwood commented 7 years ago

Triangulation is necessary in order to determine how to split the shape into multiple shapes, correct?

p.s. I just cherry picked getPointAtLength() into master. I use the bezier-js library to calculate the length of bezier curves, and then some simple math for calculating the length of lines etc. There are ways to optimize it further if necessary. Not sure if it is more efficient than what flubber uses or not as I haven't benchmarked it.

dalisoft commented 7 years ago

In tests i see unexcepted path command. It is how being parsed and how about dummy point. Still i take care of this.

dalisoft commented 7 years ago

Hey please dont use getPointAtLength. It kills performance. Do you checked points library? See link on top. It offers bounding box, length, motion path. I will help because i have my deprecated project used this and works like charm. I need only point equalisation and split path. Everything was done.

dalisoft commented 7 years ago

Everything else done. I will help to improve API and performance as well as clean, compatibility relates problems. I will help to fix these issues

dalisoft commented 7 years ago

This library would be best. You continue implement TS files update after i port. I am update code to JS

dalisoft commented 7 years ago

Triangulation is slow at first. Second, it needs to match how count subpaths should made. We will match it via Array.reduce

alexjlockwood commented 7 years ago

Thanks for your enthusiasm! Just want to say though, if you could keep your changes small and focused that would be great. Or if you plan on making major API changes run it by me first. I wrote Path.ts over a period of several months and it went through a ton of refactoring over time, so a lot of thought went into it. I'm sure it could be improved but it would be good to benchmark the inefficient parts first before changing too many things. I don't want to accidentally introduce a change that breaks something... That is my worst fear. :)

dalisoft commented 7 years ago

No. I do not want braking change Just transpile and use CDN solution i offer

dalisoft commented 7 years ago

Really the code should be refactored. There much of performance improvements & fixes requires. E.g. for every mutate constructor creates another constructor that uses browser memory and slow downs the tab. We need create less and reuse as much as possible for best performance

dalisoft commented 7 years ago

We no need break the current API, we need refactor the code

alexjlockwood commented 7 years ago

The entire code base assumes that Path objects are immutable, so refactoring things to make them mutable won't be as easy as it sounds. You'd probably have to create a new MutablePath class or something. And then maybe Path could be an immutable wrapper class around it or something.

Bottom line though is that immutability was an intentional design decision in many parts of the Shape Shifter core base.

dalisoft commented 7 years ago

Great. Immutabe is good for most thing

dalisoft commented 7 years ago

I am now made some script like algorithm that finds unequal commands. I have solution for convert command, but for missing point i bit like noob. Older used as i told points.js add, but it not looking nice like ShapeShifter

dalisoft commented 7 years ago

I now have network on mobile only. When i will on laptop i will show code and it also faster than my old thing

dalisoft commented 7 years ago

I fixed my library to good, but when i trying to implement your path splitting code, requires a lot of other code parts which size larger than my library. Can you have some links that can be implement to my library. I see and research splitting aka division/divide. But it is used for add missed point, splitting path to 2 subpath is much harder. I likd your code and library. But i building library for mobile app that uses js, not supports svg. I will first do everything fixes and convert to canvas curves for mobile app. So is any library or guide there? Thanks.

alexjlockwood commented 7 years ago

Can you have some links that can be implement to my library. I see and research splitting aka division/divide. But it is used for add missed point, splitting path to 2 subpath is much harder.

I'm not sure what you mean by this.