1- import * as React from 'react' ;
21import { FunctionComponent , useCallback , useRef , useMemo } from 'react' ;
3- import { Card as MUICard , CardHeader , Grid , MenuItem } from '@material-ui/core' ;
2+ import { Card as MUICard , CardHeader , Grid , MenuItem , Typography } from '@material-ui/core' ;
43import { Medium } from './Medium' ;
54import { observer , useObservable } from 'mobx-react-lite' ;
65import { Fetcher } from '../../store/fetcher' ;
@@ -9,6 +8,7 @@ import {headers} from '../../services/auth';
98import { useObserver } from '../../services/use-observer' ;
109import { CommentsLoader } from './CommentsLoader' ;
1110import { ActionMenu } from './ActionMenu' ;
11+ import { render } from 'react-dom' ;
1212
1313type AlbumResponse = APIResponse < GalleryAlbumResponse > ;
1414
@@ -60,29 +60,66 @@ export const Card: FunctionComponent<Props> = observer(({item}) => {
6060 canvas . width = Math . max ( ...stillImages . map ( ( image ) => image . width ) ) ;
6161 canvas . height = stillImages . reduce ( ( acc , curr ) => acc + curr . height , 0 ) ;
6262 const ctx = canvas . getContext ( '2d' ) ;
63+ if ( ! ctx ) return ;
64+
65+ const { font, lineHeight} = await ( async ( ) => {
66+
67+ const root = document . createElement ( "div" ) ;
68+ document . body . appendChild ( root ) ;
69+ await new Promise < any > ( resolve =>
70+ render ( < Typography variant = { 'body1' } > text</ Typography > as any , root , ( ) => resolve ( null ) ) ) ;
71+
72+ const map = root . querySelector < any > ( "p" ) ! . computedStyleMap ( ) ;
73+ const fontSize = + map . get ( "font-size" ) ! . toString ( ) . replace ( "px" , "" ) ;
74+ const lineHeight = + map . get ( "line-height" ) ! . toString ( ) . replace ( "px" , "" ) ;
75+ const style = {
76+ font : map . get ( "font" ) ! . toString ( ) ,
77+ lineHeight : fontSize * lineHeight ,
78+ } ;
79+ root . remove ( ) ;
80+ return style ;
81+ } ) ( ) ;
82+ ctx . font = font ;
6383
6484 await Promise . all (
6585 stillImages
6686 . reduce ( ( acc , curr ) => {
67- if ( acc . length === 0 ) {
68- return [ { y : 0 , image : curr } ] ;
87+ let height = curr . height ;
88+ let description = [ ] as string [ ] ;
89+ if ( curr . description ) {
90+ description = curr . description . split ( " " ) . reduce ( ( acc , curr ) => {
91+ const withNewWord = `${ acc [ acc . length - 1 ] } ${ curr } ` ;
92+ if ( ctx . measureText ( withNewWord ) . width > canvas . width ) {
93+ return [ ...acc , curr ]
94+ }
95+ return [ ...acc . slice ( 0 , acc . length - 1 ) , withNewWord ] ;
96+ } , [ "" ] ) ;
97+ height += description . length * lineHeight ;
6998 }
70- return [ ...acc , { y : acc [ acc . length - 1 ] . y + acc [ acc . length - 1 ] . image . height , image : curr } ] ;
71- } , [ ] as { y : number , image : any } [ ] )
72- . map ( async ( { y, image} ) => {
99+ let y = 0 ;
100+ if ( acc . length > 0 ) {
101+ y = acc [ acc . length - 1 ] . y + acc [ acc . length - 1 ] . height
102+ }
103+
104+ return [ ...acc , { height, y, image : curr , description} ] ;
105+ } , [ ] as { height : number , y : number , image : ImageResponse , description : string [ ] } [ ] )
106+ . map ( async ( { y, image, description} ) => {
73107 const img = new Image ( ) ;
74108 img . setAttribute ( 'crossorigin' , 'anonymous' ) ;
75109 const promise = new Promise ( resolve => img . onload = resolve ) ;
76110 img . src = image . link ;
77111 await promise ;
78- console . log ( )
79- if ( ctx )
80- ctx . drawImage ( img , 0 , y ) ;
112+ ctx . drawImage ( img , 0 , y ) ;
113+ if ( description . length ) {
114+ const leading = ctx . measureText ( description [ 0 ] ) . fontBoundingBoxAscent ;
115+ for ( let i = 0 ; i < description . length ; i ++ )
116+ ctx . fillText ( description [ i ] , 0 , y + image . height + leading + i * lineHeight )
117+ }
81118 } )
82119 )
83120
84121 const a = document . createElement ( 'a' ) ;
85- const blob = await new Promise < Blob > ( ( resolve , reject ) => canvas . toBlob ( ( blob ) => blob ? resolve ( blob ) : reject ( blob ) ) ) ;
122+ const blob = await new Promise < Blob > ( ( resolve , reject ) => canvas . toBlob ( ( ( blob ) => blob ? resolve ( blob ) : reject ( ) ) ) ) ;
86123 a . href = window . URL . createObjectURL ( blob ) ;
87124 a . download = item . id ;
88125 a . click ( ) ;
0 commit comments