@ -1,103 +1,18 @@
import PureRenderMixin from 'react-addons-pure-render-mixin' ;
import PureRenderMixin from 'react-addons-pure-render-mixin' ;
/ / F r o m : h t t p : / / s t a c k o v e r f l o w . c o m / a / 1 8 3 2 0 6 6 2
const resample = ( canvas , width , height , resize _canvas ) => {
let width _source = canvas . width ;
let height _source = canvas . height ;
width = Math . round ( width ) ;
height = Math . round ( height ) ;
let ratio _w = width _source / width ;
let ratio _h = height _source / height ;
let ratio _w _half = Math . ceil ( ratio _w / 2 ) ;
let ratio _h _half = Math . ceil ( ratio _h / 2 ) ;
let ctx = canvas . getContext ( "2d" ) ;
let img = ctx . getImageData ( 0 , 0 , width _source , height _source ) ;
let img2 = ctx . createImageData ( width , height ) ;
let data = img . data ;
let data2 = img2 . data ;
for ( let j = 0 ; j < height ; j ++ ) {
for ( let i = 0 ; i < width ; i ++ ) {
let x2 = ( i + j * width ) * 4 ;
let weight = 0 ;
let weights = 0 ;
let weights _alpha = 0 ;
let gx _r = 0 ;
let gx _g = 0 ;
let gx _b = 0 ;
let gx _a = 0 ;
let center _y = ( j + 0.5 ) * ratio _h ;
let yy _start = Math . floor ( j * ratio _h ) ;
let yy _stop = Math . ceil ( ( j + 1 ) * ratio _h ) ;
for ( let yy = yy _start ; yy < yy _stop ; yy ++ ) {
let dy = Math . abs ( center _y - ( yy + 0.5 ) ) / ratio _h _half ;
let center _x = ( i + 0.5 ) * ratio _w ;
let w0 = dy * dy ; / / p r e - c a l c p a r t o f w
let xx _start = Math . floor ( i * ratio _w ) ;
let xx _stop = Math . ceil ( ( i + 1 ) * ratio _w ) ;
for ( let xx = xx _start ; xx < xx _stop ; xx ++ ) {
let dx = Math . abs ( center _x - ( xx + 0.5 ) ) / ratio _w _half ;
let w = Math . sqrt ( w0 + dx * dx ) ;
if ( w >= 1 ) {
/ / p i x e l t o o f a r
continue ;
}
/ / h e r m i t e f i l t e r
weight = 2 * w * w * w - 3 * w * w + 1 ;
let pos _x = 4 * ( xx + yy * width _source ) ;
/ / a l p h a
gx _a += weight * data [ pos _x + 3 ] ;
weights _alpha += weight ;
/ / c o l o r s
if ( data [ pos _x + 3 ] < 255 )
weight = weight * data [ pos _x + 3 ] / 250 ;
gx _r += weight * data [ pos _x ] ;
gx _g += weight * data [ pos _x + 1 ] ;
gx _b += weight * data [ pos _x + 2 ] ;
weights += weight ;
}
}
data2 [ x2 ] = gx _r / weights ;
data2 [ x2 + 1 ] = gx _g / weights ;
data2 [ x2 + 2 ] = gx _b / weights ;
data2 [ x2 + 3 ] = gx _a / weights _alpha ;
}
}
/ / c l e a r a n d r e s i z e c a n v a s
if ( resize _canvas === true ) {
canvas . width = width ;
canvas . height = height ;
} else {
ctx . clearRect ( 0 , 0 , width _source , height _source ) ;
}
/ / d r a w
ctx . putImageData ( img2 , 0 , 0 ) ;
} ;
const Avatar = React . createClass ( {
const Avatar = React . createClass ( {
propTypes : {
propTypes : {
src : React . PropTypes . string . isRequired ,
src : React . PropTypes . string . isRequired ,
staticSrc : React . PropTypes . string ,
size : React . PropTypes . number . isRequired ,
size : React . PropTypes . number . isRequired ,
style : React . PropTypes . object ,
style : React . PropTypes . object ,
animate d : React . PropTypes . bool
animate : React . PropTypes . bool
} ,
} ,
getDefaultProps ( ) {
getDefaultProps ( ) {
return {
return {
animate d: tru e
animate : false
} ;
} ;
} ,
} ,
@ -117,38 +32,30 @@ const Avatar = React.createClass({
this . setState ( { hovering : false } ) ;
this . setState ( { hovering : false } ) ;
} ,
} ,
handleLoad ( ) {
this . canvas . width = this . image . naturalWidth ;
this . canvas . height = this . image . naturalHeight ;
this . canvas . getContext ( '2d' ) . drawImage ( this . image , 0 , 0 ) ;
resample ( this . canvas , this . props . size * window . devicePixelRatio , this . props . size * window . devicePixelRatio , true ) ;
} ,
setImageRef ( c ) {
this . image = c ;
} ,
setCanvasRef ( c ) {
this . canvas = c ;
} ,
render ( ) {
render ( ) {
const { src , size , staticSrc , animate } = this . props ;
const { hovering } = this . state ;
const { hovering } = this . state ;
if ( this . props . animated ) {
const style = {
return (
... this . props . style ,
< div style = { { ... this . props . style , width : ` ${ this . props . size } px ` , height : ` ${ this . props . size } px ` } } >
width : ` ${ size } px ` ,
< img src = { this . props . src } width = { this . props . size } height = { this . props . size } alt = '' style = { { borderRadius : '4px' } } / >
height : ` ${ size } px ` ,
< / div >
backgroundSize : ` ${ size } px ${ size } px `
) ;
} ;
if ( hovering || animate ) {
style . backgroundImage = ` url( ${ src } ) ` ;
} else {
style . backgroundImage = ` url( ${ staticSrc } ) ` ;
}
}
return (
return (
< div onMouseEnter = { this . handleMouseEnter } onMouseLeave = { this . handleMouseLeave } style = { { ... this . props . style , width : ` ${ this . props . size } px ` , height : ` ${ this . props . size } px ` , position : 'relative' } } >
< div
< img ref = { this . setImageRef } onLoad = { this . handleLoad } src = { this . props . src } width = { this . props . size } height = { this . props . size } alt = '' style = { { position : 'absolute' , top : '0' , left : '0' , opacity : hovering ? '1' : '0' , borderRadius : '4px' } } / >
className = 'avatar'
< canvas ref = { this . setCanvasRef } style = { { borderRadius : '4px' , width : this . props . size , height : this . props . size , opacity : hovering ? '0' : '1' } } / >
onMouseEnter = { this . handleMouseEnter }
< / div >
onMouseLeave = { this . handleMouseLeave }
style = { style }
/ >
) ;
) ;
}
}