This repository has been archived on 2023-08-30. You can view files and clone it, but cannot push or open issues/pull-requests.
bytedo
/
wcui
Archived
1
0
Fork 0
wcui/src/avatar/index.wc

202 lines
3.6 KiB
Plaintext

<template>
<slot></slot>
<img />
</template>
<style lang="scss">
:host {
overflow: hidden;
display: flex;
align-items: center;
justify-content: center;
width: var(--size, 32px);
height: var(--size, 32px);
line-height: 1;
font-size: var(--size, 32px);
border-radius: 4px;
color: #fff;
user-select: none;
-moz-user-select: none;
img {
display: none;
width: 100%;
height: 100%;
}
slot {
display: block;
transform: scale(0.8);
}
}
:host([src]),
:host([hash]) {
slot {
display: none;
}
img {
display: block;
}
}
:host([color='red']) {
background: #ff5061;
}
:host([color='teal']) {
background: #3fc2a7;
}
:host([color='purple']) {
background: #ac61ce;
}
:host([color='green']) {
background: #58d68d;
}
:host([color='orange']) {
background: #ffb618;
}
:host([color='dark']) {
background: #62778d;
}
:host([color='blue']) {
background: #66b1ff;
}
:host([size='large']) {
width: 50px;
height: 50px;
font-size: 36px;
}
:host([size='medium']) {
width: 40px;
height: 40px;
font-size: 28px;
}
:host([size='mini']) {
width: 24px;
height: 24px;
font-size: 16px;
}
:host([circle]) {
border-radius: 50%;
}
</style>
<script>
const COLORS = [
'#3fc2a7', //teal
'#58d68d', //green
'#ac61ce', // purple
'#66b1ff', //blue
'#ff5061', //red
'#ffb618', // orange
'#62778d' //dark
]
const COLOR_NAME = ['teal', 'green', 'purple', 'blue', 'red', 'orange', 'dark']
var canvas = document.createElement('canvas')
var ctx = canvas.getContext('2d')
var size = 500
canvas.width = size
canvas.height = size
function sum(arr) {
var n = 0
arr.forEach(a => (n += a))
return n
}
function createImage(hash) {
if (!hash) {
return './def.jpg'
}
var bg = COLORS[parseInt(hash.slice(-1), 16) % 7]
var color = '#fff'
var fixColor = color
var lens = hash.slice(0, 8).split('')
var pos1 = hash.slice(8, 16).split('')
var pos2 = hash.slice(16, 24).split('')
var step = size / 10
lens = lens.map(c => {
c = parseInt(c, 16)
return c % 8
})
pos1 = pos1.map(c => {
c = parseInt(c, 16)
return c % 4
})
pos2 = pos2.map(c => {
c = parseInt(c, 16)
return c % 4
})
fixColor = sum(lens) > 32 ? bg : color
ctx.fillStyle = bg
ctx.fillRect(0, 0, size, size)
for (var i = 1; i < 9; i++) {
var xl = lens[i - 1]
var xp1 = pos1[i - 1]
var xp2 = pos2[i - 1]
if (xl + xp1 > 8) {
xl = 8 - xp1
}
ctx.fillStyle = color
ctx.fillRect((xp1 + 1) * step, i * step, xl * step, step)
ctx.fillStyle = color
ctx.fillRect((9 - xp1 - xl) * step, i * step, xl * step, step)
ctx.fillStyle = fixColor
ctx.fillRect((xp2 + 1) * step, i * step, step, step)
ctx.fillStyle = fixColor
ctx.fillRect((8 - xp2) * step, i * step, step, step)
}
return canvas.toDataURL('image/webp')
}
export default class Avatar {
props = {
hash: '', //哈希头像
src: '', // 地址头像
fit: '' // 头像填充方式 fill, contain, cover, scale-down
}
constructor() {
/* render */
this.__IMG__ = this.root.lastElementChild
var text = this.textContent.slice(0, 1)
this.setAttribute('color', COLOR_NAME[text.charCodeAt(0) % 7])
this.textContent = text
}
watch(name, old, val) {
if (old === val) {
return
}
switch (name) {
case 'src':
this.removeAttribute('hash')
this.__IMG__.src = val || './def.jpg'
break
case 'hash':
this.removeAttribute('src')
this.__IMG__.src = createImage(val)
break
case 'fit':
if (val) {
this.__IMG__.style['object-fit'] = val
}
break
}
}
}
</script>
wcui是一套基于`Web Components`的UI组件库, 宗旨是追求简单、实用、不花哨。
JavaScript 95.2%
CSS 4.8%