Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Option to eliminate randomness #27

Closed
novoselrok opened this issue Mar 15, 2018 · 18 comments
Closed

Option to eliminate randomness #27

novoselrok opened this issue Mar 15, 2018 · 18 comments
Assignees

Comments

@novoselrok
Copy link

It would be great if there was an option to eliminate randomness when drawing shapes. So basically that the first time it would be random, and then the same shape would be drawn again.

For example drawing lines on canvas and then redrawing the entire canvas causes the lines to flicker due to randomness.
roughjs

I would be willing to work on this as a PR, if you think it's a good idea.

@ghost
Copy link

ghost commented Mar 15, 2018

This would be useful.
How about a generate function that returns an instance. Something like the below.

// returns instance of rectangle
const rec = rc.generate.rectangle(120, 15, 80, 80, { roughness: 2.8, fill: 'blue' }) 
// draws rectangle using above instance, will always be same no randomness
rc.draw(rec)

@novoselrok
Copy link
Author

Yep, something like that would be great 👍

@pshihn
Copy link
Collaborator

pshihn commented Mar 15, 2018

This is great. In fact underneath the main API, there are already methods to do this; and my version 1 of this lib already supported this - it was more object oriented and a lot of people preferred the current simpler api.

Having said that that I'm planning an update that creates a raw SVG renderer along with the current Canvas render. So, any API change has to be forward compatible, and this is right along the lines with where I'm going.

I'll add this in in the next couple of days.

@pshihn pshihn self-assigned this Mar 15, 2018
@AriaFallah
Copy link

@pshihn Would definitely appreciate having this feature. I made a snake game using roughjs, and it looks great. However, it currently updates the drawings too fast, and having control over the randomness would help me fix it.

snake

Thanks a lot for making the library!

@pshihn
Copy link
Collaborator

pshihn commented Mar 15, 2018

@AriaFallah This is really cool! I think I should create a gallery page where people submit creations using Rough.js

@ShonFrazier
Copy link

Not sure this warrants a new issue, so I'm adding here.

I suggest using a seedable RNG to support 'squigglevision' allowing the coder to limit the change in randomness to just a few iterations. For example: setting to seed A, drawing a square; setting to seed B, redrawing the same square; now back to seed A, etc.

I suppose the same functionality can be gained with the generator function - I'd just need to generate two or more instances of an object with the same settings, then alternate which is placed on-screen.

@novoselrok
Copy link
Author

@ShonFrazier That's exactly what I had in mind :)

@pshihn
Copy link
Collaborator

pshihn commented Mar 19, 2018

Here you go: https://github.com/pshihn/rough/wiki/RoughGenerator
It's available in the latest build: 2.0.1
This should handle your use cases. Let me know what you think @novoselrok, @AriaFallah, @BrianDGLS

Regarding the 'squigglevision', @ShonFrazier, I suppose it could be written on top of roughjs/generators easily.
I'm a bit reluctant to add animation related effects in the core draw platform.
Perhaps an animation helper lib that used roughjs would be nice later on.

@ShonFrazier
Copy link

I meant "support others' efforts to use roughjs when animating" - I wouldn't expect any kind of animation helpers to be provided by this lib. Just giving more control to the consumer of your API is all that's required. I think generators gives me exactly the control I'd expect. thanks!

@AriaFallah
Copy link

AriaFallah commented Mar 20, 2018

@pshihn with this new API is there any way to have

roughCanvas.rectangle(0, 0, 25, 25);
roughCanvas.rectangle(10, 10, 25, 25);

the two above calls, draw the same exact shape? Basically, have the library draw the same thing even when the x and y coordinates change. Right now I'm not sure how to use the generators for a moving object like the snake, which always has segments of the same dimensions but not with the same x and y coordinates.

@pshihn
Copy link
Collaborator

pshihn commented Mar 20, 2018

@AriaFallah It does not directly solve your scenario, but you can use generator in combination with context.translate/setTransform
Here's an example: https://jsfiddle.net/woubwqv0/3/

@rymohr
Copy link

rymohr commented Mar 20, 2018

@AriaFallah I ran into this yesterday too. The best solution I've found is to generate the shapes anchored around 0,0 and then translate each shape into place using your x and y coordinates as @pshihn recommended. The context.save() and context.restore() helpers may come in handy if you're animating a lot of objects.

Still not sure what to do for curves (such as an edge between two nodes that are allowed to move independently).

@pshihn
Copy link
Collaborator

pshihn commented Mar 20, 2018

When RoughSVG renderer is in place, you can get a SVG node with the shape - would be much easier to animate without re-rendering using CSS/Style transform
(Re-rendering has its own cool effect though)

@pshihn
Copy link
Collaborator

pshihn commented Mar 22, 2018

Generators were added in #36 Closing issue

@vjeux
Copy link

vjeux commented Jan 3, 2020

In my project, I needed the ability to have a custom seed in order to have a stable rendering across serialization boundaries. Since it's not going to be supported directly by roughjs, I had to workaround by overriding Math.random with a pseudo random number generator that supports a seed before calling roughjs.

Here's the code if you want to replicate it on your use case.

// Before
const shape = generator.rectangle(10, 10, 50, 50);

// After
const shape = withCustomMathRandom(123456 /* seed */, () =>
  generator.rectangle(10, 10, 50, 50)
);
// https://stackoverflow.com/questions/521295/seeding-the-random-number-generator-in-javascript/47593316#47593316
const LCG = seed => () =>
  ((2 ** 31 - 1) & (seed = Math.imul(48271, seed))) / 2 ** 31;

// Unfortunately, roughjs doesn't support a seed attribute (https://github.com/pshihn/rough/issues/27).
// We can achieve the same result by overriding the Math.random function with a
// pseudo random generator that supports a random seed and swapping it back after.
function withCustomMathRandom(seed, cb) {
  const random = Math.random;
  Math.random = LCG(seed);
  const result = cb();
  Math.random = random;
  return result;
}

@pshihn, I would encourage to make it part of the official API. I don't believe that generators are solving this use case of serializing and deserializing the shapes.

@pshihn pshihn reopened this Jan 9, 2020
@pshihn
Copy link
Collaborator

pshihn commented Jan 9, 2020

@vjeux do you imagine seeding each shape or a global seed or both?

@vjeux
Copy link

vjeux commented Jan 9, 2020

My use case us each generate command would have an individual seed managed by the caller.

I don’t have a use case for a global seed

@pshihn
Copy link
Collaborator

pshihn commented Jan 13, 2020

Resolved by #121

@pshihn pshihn closed this as completed Jan 13, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants