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

Deterministic CSS styling based on profile public key. The component blueprint. #37

Open
vladiuz1 opened this issue Feb 19, 2021 · 1 comment

Comments

@vladiuz1
Copy link
Contributor

vladiuz1 commented Feb 19, 2021

Background Generator

Background generator component must generate an SVG code that will be used as background and (may be as default avatar) for the profile derived style.

This is not as hard as it seems, we can do it in 4 steps.

Step 1. Random rectangles.

First we create a few random rectangles that go over the borders of the SVG view area:

1-random-rectangles-with-random-colors

The colors are also picked randomly, but they should have the same brightness, color range, and the distance of the color form one rectangle to the other should not be great to avoid too much difference. The right ranges need to be picked manually to result in beautiful sequence of colours every other time.

Step 2. Random ovals with some opacity on top

2-random-ovals-with-random-colors-and-30-opacity

The ovals also have colors and some level of opacity to be transparent. May be transparency is optional, need to experiment.

Step 3. Random skew

We slightly turn the whole area left or right within some ranges.

3-random-rotation

Step 4. Final blur

Now we blur the resulting SVG

4-blur-new

I changed the initial rectangles a bit, turned them into trapezoids, gave a different colour and skew, and here is what i got:

4-blur-alternative

One more:

4-blur-alternative-2

Active/select color

To pick the active color, we can take the dominant color (the color of the widest of the initial rectangles). If the color is not dark enough, we can darken it a little to fit our active color darkness limits.

The selected background color can be the same as active color but with low opacity.

deterministic-colors-2

Source of randomness

There is no randomness of course when we are picking the angle of skew, color within range, etc...

The source of randomness is different parts of the hash of the public key derived from mnemonic phrase of the user profile.

Most likely we will be using bitcoinjs-lib as crypto base for our profiles. The public key will be unpacked into a few values 0-15 (half bytes) or 0-255 (bytes), and these values will be the random source for our colors, angles, sizes.

For now you can just use this class to get random values:

class Randomness {
    constructor(source) {
        this.source = source;
        this.index = 0;
    }
    pop(min, max) {
        var min = Math.ceil(min);
        var max = Math.floor(max);
        return Math.floor(Math.random() * (max - min)) + min; //Максимум не включается, минимум включается
    }
};
var profile = "doesn't matter what for now, as long as you declare an instance once per profile.";
var rand = new Randomness(profile);

// this is how you get random values:
console.log('value 1', rand.pop(128,256));
console.log('value 2', rand.pop(16,128));
console.log('value 3', rand.pop(128,256));

// remember the maximum number is not included, 
// so rand.pop(128,255) will return a number from 128 to 255
@vladiuz1 vladiuz1 changed the title Background component Deterministic CSS styling based on profile public key. The component blueprint. Feb 19, 2021
@vladiuz1
Copy link
Contributor Author

vladiuz1 commented Apr 9, 2021

Ok just made a simple class to get deterministic random derived from an array buffer:

class DerivedRandom {
    constructor(source) {
        this.source = source.reduce((str, source) => str + source.toString(2).padStart(8, '0'), '').substr(8);
    }
    pop(bits) {
        var ret = parseInt(this.source.substr(0, bits),2);
        this.source = this.source.substr(bits) + this.source.substr(0, bits);
        return ret;
    }
}

First you need to create the DerivedRandom object, for example like this:

var rnd = new DerivedRandom(window.crypto.getRandomValues(new Uint8Array(16)));

Now this object will give you pseudo-random Int values from 0 to 2^N - 1. For example if you want a value from
0 to 31 you will call rnd.pop(5). Because 2^5 = 32.

Conveniently you can use this method:

console.log(rnd.pop(Math.log2(128)));

Working example here:

https://jsfiddle.net/u87g2Lw4/2/

This now has a bitcoinjs-lib example.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant