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

Updates #13

Merged
merged 5 commits into from
Apr 16, 2020
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Add blockie
gesseekur committed Apr 16, 2020
commit 8787c0b231908dbc6df460162a313b22b711539d
23 changes: 22 additions & 1 deletion src/components/AddressSelect/AddressSelect.vue
Original file line number Diff line number Diff line change
@@ -16,7 +16,7 @@
<template v-slot:prepend-inner>
<div v-if="!isValidAddress" class="blockie-placeholder"></div>
<div v-if="isValidAddress" class="blockie-container">
<slot name="blockie" />
<blockie :address="addressValue" width="30px" height="30px" />
</div>
</template>

@@ -42,6 +42,12 @@
<template v-slot:item="data">
<div class="item-container" @click="selectAddress(data.item)">
<div class="address-container">
<blockie
class="blockie"
:address="data.item.address"
width="30px"
height="30px"
/>
<div class="address">{{ data.item.address }}</div>
</div>
<div class="nickname">{{ data.item.nickname }}</div>
@@ -50,7 +56,10 @@
</v-combobox>
</div>
</template>

<script>
import Blockie from "@/components/Blockie/Blockie.vue";

export default {
name: "AddressSelector",
props: {
@@ -92,6 +101,9 @@ export default {
default: function() {}
}
},
components: {
blockie: Blockie
},
data() {
return {
addressValue: "",
@@ -134,6 +146,13 @@ export default {
width: 100%;

.address-container {
align-items: center;
display: flex;
justify-content: space-between;

.blockie {
margin-right: 5px;
}
.address {
color: var(--v-basic-base);
}
@@ -158,6 +177,8 @@ export default {
}

.blockie-container {
margin-bottom: 17px;
margin-right: 5px;
max-height: 25px;
}

78 changes: 78 additions & 0 deletions src/components/Blockie/Blockie.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
<template lang="html">
<div ref="identicon" class="address-identicon" />
</template>
<script>
import Blockies from "@/helpers/blockies.js";
export default {
name: "Blockie",
props: {
address: {
type: String,
default: ""
},
width: {
type: String,
default: "64px"
},
height: {
type: String,
default: "64px"
},
size: {
type: Number,
default: 8
},
scale: {
type: Number,
default: 16
}
},
data() {
return {};
},
watch: {
address() {
this.setBlockie();
},
width() {
this.setBlockie();
},
height() {
this.setBlockie();
},
scale() {
this.setBlockie();
},
size() {
this.setBlockie();
}
},
mounted() {
this.setBlockie();
},
methods: {
setBlockie() {
console.error('this', this.address)
const data = Blockies({
seed: this.address ? this.address.toLowerCase() : "",
size: this.size,
scale: this.scale
}).toDataURL();
this.$refs.identicon.style.width = this.width;
this.$refs.identicon.style.height = this.height;
this.$refs.identicon.style.backgroundImage = `url('${data}')`;
}
}
};
</script>
<style lang="scss" scoped>
.address-identicon {
background-repeat: no-repeat;
background-size: cover;
border-radius: 50%;
box-shadow: inset rgba(255, 255, 255, 0.25) 0 2px 2px,
inset rgba(0, 0, 0, 0.6) 0 -1px 8px;
height: 100%;
width: 100%;
}
</style>
File renamed without changes.
File renamed without changes.
99 changes: 99 additions & 0 deletions src/helpers/blockies.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
const randseed = new Array(4); // Xorshift: [x, y, z, w] 32 bit values

function seedrand(seed) {
for (let i = 0; i < randseed.length; i++) {
randseed[i] = 0;
}
for (let j = 0; j < seed.length; j++) {
randseed[j % 4] =
(randseed[j % 4] << 5) - randseed[j % 4] + seed.charCodeAt(j);
}
}

function rand() {
// based on Java's String.hashCode(), expanded to 4 32bit values
const t = randseed[0] ^ (randseed[0] << 11);

randseed[0] = randseed[1];
randseed[1] = randseed[2];
randseed[2] = randseed[3];
randseed[3] = randseed[3] ^ (randseed[3] >> 19) ^ t ^ (t >> 8);

return (randseed[3] >>> 0) / ((1 << 31) >>> 0);
}

function createColor() {
// saturation is the whole color spectrum
const h = Math.floor(rand() * 360);
// saturation goes from 40 to 100, it avoids greyish colors
const s = rand() * 60 + 40 + "%";
// lightness can be anything from 0 to 100, but probabilities are a bell curve around 50%
const l = (rand() + rand() + rand() + rand()) * 25 + "%";

const color = "hsl(" + h + "," + s + "," + l + ")";
return color;
}

function createImageData(size) {
const width = size; // Only support square icons for now
const height = size;

const dataWidth = Math.ceil(width / 2);
const mirrorWidth = width - dataWidth;

const data = [];
for (let y = 0; y < height; y++) {
let row = [];
for (let x = 0; x < dataWidth; x++) {
// this makes foreground and background color to have a 43% (1/2.3) probability
// spot color has 13% chance
row[x] = Math.floor(rand() * 2.3);
}
const r = row.slice(0, mirrorWidth);
r.reverse();
row = row.concat(r);

for (let i = 0; i < row.length; i++) {
data.push(row[i]);
}
}

return data;
}

function createCanvas(imageData, color, scale, bgcolor, spotcolor) {
const width = Math.sqrt(imageData.length);
const c = document.createElement("canvas");
c.width = c.height = width * scale;
const cc = c.getContext("2d");
cc.fillStyle = bgcolor;
cc.fillRect(0, 0, c.width, c.height);
cc.fillStyle = color;

for (let i = 0; i < imageData.length; i++) {
const row = Math.floor(i / width);
const col = i % width;
cc.fillStyle = imageData[i] === 1 ? color : spotcolor;
if (imageData[i]) {
cc.fillRect(col * scale, row * scale, scale, scale);
}
}
return c;
}

function createIcon(opts) {
opts = opts || {};
const size = opts.size || 8;
const scale = opts.scale || 4;
const seed =
opts.seed || Math.floor(Math.random() * Math.pow(10, 16)).toString(16);
seedrand(seed);
const color = opts.color || createColor();
const bgcolor = opts.bgcolor || createColor();
const spotcolor = opts.spotcolor || createColor();
const imageData = createImageData(size);
const canvas = createCanvas(imageData, color, scale, bgcolor, spotcolor);

return canvas;
}
export default createIcon;
11 changes: 7 additions & 4 deletions stories/AddressSelector/AddressSelector.stories.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { withKnobs, text, array } from "@storybook/addon-knobs";
import { withKnobs, text, array, boolean } from "@storybook/addon-knobs";
import mewAddressSelector from "@/components/AddressSelect/AddressSelect.vue";

export default {
@@ -11,10 +11,10 @@ export default {

const addressesArray = [
{
address: "123",
address: "0xDECAF9CD2367cdbb726E904cD6397eDFcAe6068D",
currency: "ETH",
nickname: "nickname",
resolverAddr: "123"
resolverAddr: "0xDECAF9CD2367cdbb726E904cD6397eDFcAe6068D"
}
];

@@ -29,12 +29,15 @@ export const AddressSelector = () => ({
},
placeholder: {
default: text("placeholder", "Please enter an address")
},
isValidAddress: {
default: boolean("is-valid-address", false)
}
},
template: `
<div>
<br />
<address-selector @emitSelectedValue="getSelectedValue" :label="label" :items="items">
<address-selector @emitSelectedValue="getSelectedValue" :is-valid-address="isValidAddress" :label="label" :items="items">
<template v-slot:blockie>
</template>
</address-selector>