Last active
December 6, 2021 11:12
-
-
Save rarous/3b26b5e5346664deab1717b029bff14b to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* @copyright 2015-2016 TopMonks s.r.o. | |
* @flow weak | |
*/ | |
import React, {Children, cloneElement} from 'react'; | |
import component from '../component'; | |
import {Map} from 'immutable'; | |
type Crop = 'scale' | 'fill' | 'lfill' | 'fit' | 'mfit' | 'limit' | 'pad' | 'lpad' | 'mpad' | 'crop' | 'thumb'; | |
type Gravity = 'north' | 'east' | 'south' | 'west' | 'north_west' | 'south_west' | 'north_east' | 'south_east' | 'xy_center' | 'face' | 'faces' | 'face:center' | 'faces:center' | 'custom'; | |
type Quality = number | 'jpegmini'; | |
type Radius = number | 'max'; | |
type Format = 'auto' | 'jpg' | 'png' | 'webp' | 'jxr' | 'jp2'; | |
type Transformations = { | |
width: number, | |
height: number, | |
x: number, | |
y: number, | |
dpr: number | 'auto', | |
crop: Crop, | |
gravity: Gravity, | |
quality: Quality, | |
radius: Radius, | |
effect: string, | |
opacity: number, | |
density: number, | |
format: Format, | |
transformation: string | string[] | |
}; | |
type CloudinaryImgProps = { | |
alt: string, | |
src: string, | |
title: string, | |
width: string | number, | |
height: string | number, | |
transformations: Transformations | |
}; | |
const trans = Map([ | |
['width', x => `w_${x}`], | |
['height', x => `h_${x}`], | |
['x', x => `x_${x}`], | |
['y', x => `y_${x}`], | |
['dpr', x => `dpr_${x}`], | |
['crop', x => `c_${x}`], | |
['gravity', x => `g_${x}`], | |
['quality', x => `q_${x}`], | |
['radius', x => `r_${x}`], | |
['effect', x => `e_${x}`], | |
['opacity', x => `o_${x}`], | |
['density', x => `dn_${x}`], | |
['format', x => `f_${x}`], | |
['transformation', x => Array.isArray(x) ? `t_${x.join('.')}` : `t_${x}`] | |
]); | |
export function cloudinayImgUrl(url, transformations) { | |
const segment = Map(transformations).map((v, k) => trans.get(k)(v)).toArray().join(); | |
return (url && segment) ? url.replace('/upload/', `/upload/${segment}/`) : url; | |
} | |
export default component(function CloudinaryImg({alt, src, title, width, height, transformations, children: _ch, ...imgProps}: CloudinaryImgProps, _, children) { | |
const props = { | |
alt, title, width, height, | |
src: cloudinayImgUrl(src, transformations), | |
...imgProps | |
}; | |
if (!children) return <img {...props} />; | |
const sources = Children.toArray(children).map(x => cloneElement(x, {src})); | |
return ( | |
<picture> | |
{sources} | |
<img {...props} /> | |
</picture> | |
); | |
}); | |
type SourceProps = { | |
media: string, | |
type: string, | |
src: string, | |
transformations: Transformations | |
}; | |
export const Source = component(function Source({media, type, src, transformations}: SourceProps) { | |
const props = { | |
media, type, | |
srcSet: cloudinayImgUrl(src, transformations) | |
}; | |
return (<source {...props} />); | |
}); | |
const kTestImages = { | |
lossy: 'UklGRiIAAABXRUJQVlA4IBYAAAAwAQCdASoBAAEADsD+JaQAA3AAAAAA', | |
lossless: 'UklGRhoAAABXRUJQVlA4TA0AAAAvAAAAEAcQERGIiP4HAA==', | |
alpha: 'UklGRkoAAABXRUJQVlA4WAoAAAAQAAAAAAAAAAAAQUxQSAwAAAARBxAR/Q9ERP8DAABWUDggGAAAABQBAJ0BKgEAAQAAAP4AAA3AAP7mtQAAAA==', | |
animation: 'UklGRlIAAABXRUJQVlA4WAoAAAASAAAAAAAAAAAAQU5JTQYAAAD/////AABBTk1GJgAAAAAAAAAAAAAAAAAAAGQAAABWUDhMDQAAAC8AAAAQBxAREYiI/gcA' | |
}; | |
type Feature = 'lossy' | 'lossless' | 'alpha' | 'animation'; | |
/** | |
* Checks WebP support | |
* @param feature can be one of 'lossy', 'lossless', 'alpha' or 'animation'. | |
* @returns Promise<boolean> with the detection result (in an asynchronous way!) | |
*/ | |
export function checkWebpFeature(feature: Feature): Promise<boolean> { | |
const img = new Image(); | |
const promise = new Promise((resolve, _reject) => { | |
img.onload = function () { | |
var result = (img.width > 0) && (img.height > 0); | |
resolve(result); | |
}; | |
img.onerror = function () { | |
resolve(false); | |
}; | |
img.src = `data:image/webp;base64,${kTestImages[feature]}`; | |
}); | |
return promise; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment