Skip to content

Instantly share code, notes, and snippets.

@phloe
Created August 14, 2017 12:15
Show Gist options
  • Save phloe/f1b70ce07a89867fbe49923f292c1288 to your computer and use it in GitHub Desktop.
Save phloe/f1b70ce07a89867fbe49923f292c1288 to your computer and use it in GitHub Desktop.
import URL from "url-parse";
import ratioHelper from "./ratioHelper";
import { quantize, interpolate, normalize, clamp } from "./math";
var dprMin = 1; // min dpr to get highest quality
var dprMax = 2; // max dpr to get lowest quality
var dprRanges = [
/*{
min: 3,
quality: getQuality(3)
},*/
{
min: 2,
//max: 3,
quality: getQuality(2)
},
// default dpr (below 2) setting
{
quality: qualityMax
}
];
export const defaultWidths = [120, 240, 360, 720, 1080, 1440, 1800, 2160, 2520];
export const ratios = ratioHelper(["16-9", "4-3", "3-2", "2-1", "1-1", "3-4"]);
function prefixMediaDpr (media) {
var result = [media];
var mdprReg = /(\()(min|max)-resolution(: \d+(?:\.\d*)?)dppx/g;
["$1-webkit-$2-device-pixel-ratio$3", "$1$2-device-pixel-ratio$3"].forEach(
(pattern) => {
var prefixed = media.replace(mdprReg, pattern);
if (prefixed !== media) {
result.unshift(prefixed);
}
}
);
return result.join(", ");
}
function mediaDpr (media, dprMin, dprMax) {
var result = [];
if (media) {
result.push(media);
}
if (dprMin) {
result.push(`(min-resolution: ${dprMin}dppx)`);
}
if (dprMax) {
result.push(`(max-resolution: ${dprMax}dppx)`);
}
return prefixMediaDpr(result.join(" and "));
}
function expandDprRanges (result, media, params, sizes, widths) {
dprRanges.forEach(
({min, max, quality}, index) => {
const srcSet = prescaleSrcSet(params, min, quality, widths);
result.push({
media: mediaDpr(media, min, max),
sizes,
srcSet
});
}
);
}
export function sourcePropsFromMediaSizes (params, mediaSizes = { default: "" }, widths) {
var propSet = [];
Object.entries(mediaSizes).reduce(
(result, [media, sizes]) => {
if (media !== "default") {
expandDprRanges(result, media, params, sizes, widths);
}
return result;
},
propSet
);
expandDprRanges(propSet, null, params, mediaSizes.default, widths);
return propSet;
}
export function responsiveSources (url, w, h, ratioLabel, mediaSizes, widths = defaultWidths) {
if (/\.(png|gif)$/.test(url)) {
return {
src: url,
sources: []
};
}
var params = getParams(url, w, h, ratioLabel);
return {
src: scalerUrl({...params, w: 640, h: null}),
sources: sourcePropsFromMediaSizes(params, mediaSizes, widths)
};
}
export function getParams (url, w, h, ratioLabel) {
ratioLabel = ratioLabel || (w && h ? ratios.getLabelFromSize(w, h) : null);
return { url, w, h, ratio: ratioLabel };
}
export function prescaleSrcSet (params, dpr, quality, widths) {
return widths.reduce(
(result, size, index) => {
var _size = (dpr > 1) ? Math.round(size * dpr) : size;
// always output first width
// always output if no width was provided
// else only output if needed size is smaller than/equal source
if (!index || !params.w || _size <= params.w ) {
var _params = {
...params,
quality,
w: _size,
h: (params.h) ? Math.round(params.h * (_size / params.w)) : null
};
result.push(`${scalerUrl(_params)} ${_size}w`);
}
return result;
},
[]
).join(", ");
}
/*
{
"(min-width: 640px)": {
"1x": "image.jpg 240w, image_640.jpg 640w",
"2x": "image_480.jpg 480w, image_1280.jpg 1280w"
},
"default": {
"1x": "image.jpg 240w, image_640.jpg 640w"
}
}
*/
export default function (data) {
if (typeof data === "string") {
return [{
srcSet: data
}];
}
return Object.entries(data).reduce(
(result, [media, mediaData]) => {
var source = {};
if (typeof mediaData === "string") {
if (media !== "default") {
source.media = media;
}
source.srcSet = mediaData;
result.push(source);
}
else {
var dprs = Object.keys(mediaData).map(
(dpr) => parseFloat(dpr, 10)
).sort().reverse();
}
return result;
},
[]
);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment