UNPKG

react-carousel-query

Version:

A infinite carousel component made with react that handles the pagination for you.

334 lines (288 loc) 8.48 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.drawFloatingLabel = drawFloatingLabel; exports.labelStacks = labelStacks; require("core-js/modules/es.array.fill.js"); require("core-js/modules/es.object.to-string.js"); require("core-js/modules/web.dom-collections.for-each.js"); /* eslint-disable operator-assignment */ /* eslint-disable no-param-reassign */ var colors = { margin: '#f6b26b', border: '#ffe599', padding: '#93c47d', content: '#6fa8dc', text: '#232020' }; var labelPadding = 6; function roundedRect(context, _ref) { var x = _ref.x, y = _ref.y, w = _ref.w, h = _ref.h, r = _ref.r; x = x - w / 2; y = y - h / 2; if (w < 2 * r) r = w / 2; if (h < 2 * r) r = h / 2; context.beginPath(); context.moveTo(x + r, y); context.arcTo(x + w, y, x + w, y + h, r); context.arcTo(x + w, y + h, x, y + h, r); context.arcTo(x, y + h, x, y, r); context.arcTo(x, y, x + w, y, r); context.closePath(); } function positionCoordinate(position, _ref2) { var padding = _ref2.padding, border = _ref2.border, width = _ref2.width, height = _ref2.height, top = _ref2.top, left = _ref2.left; var contentWidth = width - border.left - border.right - padding.left - padding.right; var contentHeight = height - padding.top - padding.bottom - border.top - border.bottom; var x = left + border.left + padding.left; var y = top + border.top + padding.top; if (position === 'top') { x += contentWidth / 2; } else if (position === 'right') { x += contentWidth; y += contentHeight / 2; } else if (position === 'bottom') { x += contentWidth / 2; y += contentHeight; } else if (position === 'left') { y += contentHeight / 2; } else if (position === 'center') { x += contentWidth / 2; y += contentHeight / 2; } return { x: x, y: y }; } /** * Offset the label based on how many layers appear before it * For example: * margin labels will shift further outwards if there are * padding labels */ function offset(type, position, _ref3, labelPaddingSize, external) { var margin = _ref3.margin, border = _ref3.border, padding = _ref3.padding; var shift = function shift(dir) { return 0; }; var offsetX = 0; var offsetY = 0; // If external labels then push them to the edge of the band // else keep them centred var locationMultiplier = external ? 1 : 0.5; // Account for padding within the label var labelPaddingShift = external ? labelPaddingSize * 2 : 0; if (type === 'padding') { shift = function shift(dir) { return padding[dir] * locationMultiplier + labelPaddingShift; }; } else if (type === 'border') { shift = function shift(dir) { return padding[dir] + border[dir] * locationMultiplier + labelPaddingShift; }; } else if (type === 'margin') { shift = function shift(dir) { return padding[dir] + border[dir] + margin[dir] * locationMultiplier + labelPaddingShift; }; } if (position === 'top') { offsetY = -shift('top'); } else if (position === 'right') { offsetX = shift('right'); } else if (position === 'bottom') { offsetY = shift('bottom'); } else if (position === 'left') { offsetX = -shift('left'); } return { offsetX: offsetX, offsetY: offsetY }; } function collide(a, b) { return Math.abs(a.x - b.x) < Math.abs(a.w + b.w) / 2 && Math.abs(a.y - b.y) < Math.abs(a.h + b.h) / 2; } function overlapAdjustment(position, currentRect, prevRect) { if (position === 'top') { currentRect.y = prevRect.y - prevRect.h - labelPadding; } else if (position === 'right') { currentRect.x = prevRect.x + prevRect.w / 2 + labelPadding + currentRect.w / 2; } else if (position === 'bottom') { currentRect.y = prevRect.y + prevRect.h + labelPadding; } else if (position === 'left') { currentRect.x = prevRect.x - prevRect.w / 2 - labelPadding - currentRect.w / 2; } return { x: currentRect.x, y: currentRect.y }; } function textWithRect(context, type, _ref4, text) { var x = _ref4.x, y = _ref4.y, w = _ref4.w, h = _ref4.h; roundedRect(context, { x: x, y: y, w: w, h: h, r: 3 }); context.fillStyle = "".concat(colors[type], "dd"); context.fill(); context.strokeStyle = colors[type]; context.stroke(); context.fillStyle = colors.text; context.fillText(text, x, y); roundedRect(context, { x: x, y: y, w: w, h: h, r: 3 }); context.fillStyle = "".concat(colors[type], "dd"); context.fill(); context.strokeStyle = colors[type]; context.stroke(); context.fillStyle = colors.text; context.fillText(text, x, y); return { x: x, y: y, w: w, h: h }; } function configureText(context, text) { context.font = '600 12px monospace'; context.textBaseline = 'middle'; context.textAlign = 'center'; var metrics = context.measureText(text); var actualHeight = metrics.actualBoundingBoxAscent + metrics.actualBoundingBoxDescent; var w = metrics.width + labelPadding * 2; var h = actualHeight + labelPadding * 2; return { w: w, h: h }; } function drawLabel(context, measurements, _ref5, prevRect) { var type = _ref5.type, _ref5$position = _ref5.position, position = _ref5$position === void 0 ? 'center' : _ref5$position, text = _ref5.text; var external = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : false; var _positionCoordinate = positionCoordinate(position, measurements), x = _positionCoordinate.x, y = _positionCoordinate.y; var _offset = offset(type, position, measurements, labelPadding + 1, external), offsetX = _offset.offsetX, offsetY = _offset.offsetY; // Shift coordinate to center within // the band of measurement x += offsetX; y += offsetY; var _configureText = configureText(context, text), w = _configureText.w, h = _configureText.h; // Adjust for overlap if (prevRect && collide({ x: x, y: y, w: w, h: h }, prevRect)) { var adjusted = overlapAdjustment(position, { x: x, y: y, w: w, h: h }, prevRect); x = adjusted.x; y = adjusted.y; } return textWithRect(context, type, { x: x, y: y, w: w, h: h }, text); } function floatingOffset(alignment, _ref6) { var w = _ref6.w, h = _ref6.h; var deltaW = w * 0.5 + labelPadding; var deltaH = h * 0.5 + labelPadding; return { offsetX: (alignment.x === 'left' ? -1 : 1) * deltaW, offsetY: (alignment.y === 'top' ? -1 : 1) * deltaH }; } function drawFloatingLabel(context, measurements, _ref7) { var type = _ref7.type, text = _ref7.text; var floatingAlignment = measurements.floatingAlignment, extremities = measurements.extremities; var x = extremities[floatingAlignment.x]; var y = extremities[floatingAlignment.y]; var _configureText2 = configureText(context, text), w = _configureText2.w, h = _configureText2.h; var _floatingOffset = floatingOffset(floatingAlignment, { w: w, h: h }), offsetX = _floatingOffset.offsetX, offsetY = _floatingOffset.offsetY; x += offsetX; y += offsetY; return textWithRect(context, type, { x: x, y: y, w: w, h: h }, text); } function drawStack(context, measurements, stack, external) { var rects = []; stack.forEach(function (l, idx) { // Move the centred label to floating in external mode var rect = external && l.position === 'center' ? drawFloatingLabel(context, measurements, l) : drawLabel(context, measurements, l, rects[idx - 1], external); rects[idx] = rect; }); } function labelStacks(context, measurements, labels, externalLabels) { var stacks = labels.reduce(function (acc, l) { if (!Object.prototype.hasOwnProperty.call(acc, l.position)) { acc[l.position] = []; } acc[l.position].push(l); return acc; }, {}); if (stacks.top) { drawStack(context, measurements, stacks.top, externalLabels); } if (stacks.right) { drawStack(context, measurements, stacks.right, externalLabels); } if (stacks.bottom) { drawStack(context, measurements, stacks.bottom, externalLabels); } if (stacks.left) { drawStack(context, measurements, stacks.left, externalLabels); } if (stacks.center) { drawStack(context, measurements, stacks.center, externalLabels); } }