From afba5797e1a1602f129b0c69ed4e7f264400c6e7 Mon Sep 17 00:00:00 2001 From: Bryan Housel Date: Tue, 17 Dec 2019 14:50:34 -0500 Subject: [PATCH] es6 preset_icon.js --- modules/ui/preset_icon.js | 752 ++++++++++++++++++++------------------ 1 file changed, 388 insertions(+), 364 deletions(-) diff --git a/modules/ui/preset_icon.js b/modules/ui/preset_icon.js index fc1cd9582..e4b8dfb4e 100644 --- a/modules/ui/preset_icon.js +++ b/modules/ui/preset_icon.js @@ -3,385 +3,409 @@ import { select as d3_select } from 'd3-selection'; import { svgIcon, svgTagClasses } from '../svg'; import { utilFunctor } from '../util'; + export function uiPresetIcon(context) { - var preset, geometry, sizeClass = 'medium'; + let _preset; + let _geometry; + let _sizeClass = 'medium'; - function isSmall() { - return sizeClass === 'small'; + + function isSmall() { + return _sizeClass === 'small'; + } + + + function presetIcon(selection) { + selection.each(render); + } + + + function getIcon(p, geom) { + if (isSmall() && p.isFallback && p.isFallback()) + return 'iD-icon-' + p.id; + else if (p.icon) + return p.icon; + else if (geom === 'line') + return 'iD-other-line'; + else if (geom === 'vertex') + return p.isFallback() ? '' : 'temaki-vertex'; + else if (isSmall() && geom === 'point') + return ''; + else + return 'maki-marker-stroked'; + } + + + function renderPointBorder(enter) { + const w = 40; + const h = 40; + + enter + .append('svg') + .attr('class', 'preset-icon-fill preset-icon-point-border') + .attr('width', w) + .attr('height', h) + .attr('viewBox', `0 0 ${w} ${h}`) + .append('path') + .attr('transform', 'translate(11.5, 8)') + .attr('d', 'M 17,8 C 17,13 11,21 8.5,23.5 C 6,21 0,13 0,8 C 0,4 4,-0.5 8.5,-0.5 C 13,-0.5 17,4 17,8 z'); + } + + + function renderCircleFill(fillEnter) { + const w = 60; + const h = 60; + const d = 40; + + fillEnter + .append('svg') + .attr('class', 'preset-icon-fill preset-icon-fill-vertex') + .attr('width', w) + .attr('height', h) + .attr('viewBox', `0 0 ${w} ${h}`) + .append('circle') + .attr('cx', w / 2) + .attr('cy', h / 2) + .attr('r', d / 2); + } + + + function renderSquareFill(fillEnter) { + const d = isSmall() ? 40 : 60; + const w = d; + const h = d; + const l = d * 2/3; + const c1 = (w-l) / 2; + const c2 = c1 + l; + + fillEnter = fillEnter + .append('svg') + .attr('class', 'preset-icon-fill preset-icon-fill-area') + .attr('width', w) + .attr('height', h) + .attr('viewBox', `0 0 ${w} ${h}`); + + ['fill', 'stroke'].forEach(klass => { + fillEnter + .append('path') + .attr('d', `M${c1} ${c1} L${c1} ${c2} L${c2} ${c2} L${c2} ${c1} Z`) + .attr('class', `line area ${klass}`); + }); + + const rVertex = 2.5; + const coordinates = [c1, c2]; + for (let xIndex in coordinates) { + for (let yIndex in coordinates) { + fillEnter + .append('circle') + .attr('class', 'vertex') + .attr('cx', coordinates[xIndex]) + .attr('cy', coordinates[yIndex]) + .attr('r', rVertex); + } + } + + if (!isSmall()) { + const rMidpoint = 1.25; + const midCoordinates = [[c1, w/2], [c2, w/2], [h/2, c1], [h/2, c2]]; + for (let index in midCoordinates) { + const loc = midCoordinates[index]; + fillEnter + .append('circle') + .attr('class', 'midpoint') + .attr('cx', loc[0]) + .attr('cy', loc[1]) + .attr('r', rMidpoint); + } + } + } + + + function renderLine(lineEnter) { + const d = isSmall() ? 40 : 60; + // draw the line parametrically + const w = d; + const h = d; + const y = Math.round(d * 0.72); + const l = Math.round(d * 0.6); + const r = 2.5; + const x1 = (w - l) / 2; + const x2 = x1 + l; + + lineEnter = lineEnter + .append('svg') + .attr('class', 'preset-icon-line') + .attr('width', w) + .attr('height', h) + .attr('viewBox', `0 0 ${w} ${h}`); + + ['casing', 'stroke'].forEach(klass => { + lineEnter + .append('path') + .attr('d', `M${x1} ${y} L${x2} ${y}`) + .attr('class', `line ${klass}`); + }); + + [[x1-1, y], [x2+1, y]].forEach(loc => { + lineEnter + .append('circle') + .attr('class', 'vertex') + .attr('cx', loc[0]) + .attr('cy', loc[1]) + .attr('r', r); + }); + } + + + function renderRoute(routeEnter) { + const d = isSmall() ? 40 : 60; + // draw the route parametrically + const w = d; + const h = d; + const y1 = Math.round(d * 0.80); + const y2 = Math.round(d * 0.68); + const l = Math.round(d * 0.6); + const r = 2; + const x1 = (w - l) / 2; + const x2 = x1 + l / 3; + const x3 = x2 + l / 3; + const x4 = x3 + l / 3; + + routeEnter = routeEnter + .append('svg') + .attr('class', 'preset-icon-route') + .attr('width', w) + .attr('height', h) + .attr('viewBox', `0 0 ${w} ${h}`); + + ['casing', 'stroke'].forEach(klass => { + routeEnter + .append('path') + .attr('d', `M${x1} ${y1} L${x2} ${y2}`) + .attr('class', `segment0 line ${klass}`); + routeEnter + .append('path') + .attr('d', `M${x2} ${y2} L${x3} ${y1}`) + .attr('class', `segment1 line ${klass}`); + routeEnter + .append('path') + .attr('d', `M${x3} ${y1} L${x4} ${y2}`) + .attr('class', `segment2 line ${klass}`); + }); + + [[x1, y1], [x2, y2], [x3, y1], [x4, y2]].forEach(loc => { + routeEnter + .append('circle') + .attr('class', 'vertex') + .attr('cx', loc[0]) + .attr('cy', loc[1]) + .attr('r', r); + }); + } + + + const routeSegments = { + bicycle: ['highway/cycleway', 'highway/cycleway', 'highway/cycleway'], + bus: ['highway/unclassified', 'highway/secondary', 'highway/primary'], + detour: ['highway/tertiary', 'highway/residential', 'highway/unclassified'], + ferry: ['route/ferry', 'route/ferry', 'route/ferry'], + foot: ['highway/footway', 'highway/footway', 'highway/footway'], + hiking: ['highway/path', 'highway/path', 'highway/path'], + horse: ['highway/bridleway', 'highway/bridleway', 'highway/bridleway'], + light_rail: ['railway/light_rail', 'railway/light_rail', 'railway/light_rail'], + monorail: ['railway/monorail', 'railway/monorail', 'railway/monorail'], + pipeline: ['man_made/pipeline', 'man_made/pipeline', 'man_made/pipeline'], + piste: ['piste/downhill', 'piste/hike', 'piste/nordic'], + power: ['power/line', 'power/line', 'power/line'], + road: ['highway/secondary', 'highway/primary', 'highway/trunk'], + subway: ['railway/subway', 'railway/subway', 'railway/subway'], + train: ['railway/rail', 'railway/rail', 'railway/rail'], + tram: ['railway/tram', 'railway/tram', 'railway/tram'], + waterway: ['waterway/stream', 'waterway/stream', 'waterway/stream'] + }; + + + function render() { + let p = _preset.apply(this, arguments); + let geom = _geometry ? _geometry.apply(this, arguments) : null; + if (geom === 'relation' && p.tags && ((p.tags.type === 'route' && p.tags.route && routeSegments[p.tags.route]) || p.tags.type === 'waterway')) { + geom = 'route'; + } + const isFallback = isSmall() && p.isFallback && p.isFallback(); + const imageURL = p.imageURL; + const picon = getIcon(p, geom); + const isMaki = picon && /^maki-/.test(picon); + const isTemaki = picon && /^temaki-/.test(picon); + const isFa = picon && /^fa[srb]-/.test(picon); + const isTnp = picon && /^tnp-/.test(picon); + const isiDIcon = picon && !(isMaki || isTemaki || isFa || isTnp); + const isCategory = !p.setTags; + const drawPoint = picon && geom === 'point' && isSmall() && !isFallback; + const drawVertex = picon !== null && geom === 'vertex' && (!isSmall() || !isFallback); + const drawLine = picon && geom === 'line' && !isFallback && !isCategory; + const drawArea = picon && geom === 'area' && !isFallback; + const drawRoute = picon && geom === 'route'; + const isFramed = (drawVertex || drawArea || drawLine || drawRoute); + + let tags = !isCategory ? p.setTags({}, geom) : {}; + for (let k in tags) { + if (tags[k] === '*') { + tags[k] = 'yes'; + } + } + + let tagClasses = svgTagClasses().getClassesString(tags, ''); + let selection = d3_select(this); + + let container = selection.selectAll('.preset-icon-container') + .data([0]); + + container = container.enter() + .append('div') + .attr('class', `preset-icon-container ${_sizeClass}`) + .merge(container); + + container.classed('fallback', isFallback); + + + let pointBorder = container.selectAll('.preset-icon-point-border') + .data(drawPoint ? [0] : []); + + pointBorder.exit() + .remove(); + + let pointBorderEnter = pointBorder.enter(); + renderPointBorder(pointBorderEnter); + pointBorder = pointBorderEnter.merge(pointBorder); + + + let vertexFill = container.selectAll('.preset-icon-fill-vertex') + .data(drawVertex ? [0] : []); + + vertexFill.exit() + .remove(); + + let vertexFillEnter = vertexFill.enter(); + renderCircleFill(vertexFillEnter); + vertexFill = vertexFillEnter.merge(vertexFill); + + + let fill = container.selectAll('.preset-icon-fill-area') + .data(drawArea ? [0] : []); + + fill.exit() + .remove(); + + let fillEnter = fill.enter(); + renderSquareFill(fillEnter); + fill = fillEnter.merge(fill); + + fill.selectAll('path.stroke') + .attr('class', `area stroke ${tagClasses}`); + fill.selectAll('path.fill') + .attr('class', `area fill ${tagClasses}`); + + + let line = container.selectAll('.preset-icon-line') + .data(drawLine ? [0] : []); + + line.exit() + .remove(); + + let lineEnter = line.enter(); + renderLine(lineEnter); + line = lineEnter.merge(line); + + line.selectAll('path.stroke') + .attr('class', `line stroke ${tagClasses}`); + line.selectAll('path.casing') + .attr('class', `line casing ${tagClasses}`); + + + let route = container.selectAll('.preset-icon-route') + .data(drawRoute ? [0] : []); + + route.exit() + .remove(); + + let routeEnter = route.enter(); + renderRoute(routeEnter); + route = routeEnter.merge(route); + + if (drawRoute) { + let routeType = p.tags.type === 'waterway' ? 'waterway' : p.tags.route; + const segmentPresetIDs = routeSegments[routeType]; + for (let i in segmentPresetIDs) { + const segmentPreset = context.presets().item(segmentPresetIDs[i]); + const segmentTagClasses = svgTagClasses().getClassesString(segmentPreset.tags, ''); + route.selectAll(`path.stroke.segment${i}`) + .attr('class', `segment${i} line stroke ${segmentTagClasses}`); + route.selectAll(`path.casing.segment${i}`) + .attr('class', `segment${i} line casing ${segmentTagClasses}`); + } } - function presetIcon(selection) { - selection.each(render); - } + let icon = container.selectAll('.preset-icon') + .data(picon ? [0] : []); + icon.exit() + .remove(); - function getIcon(p, geom) { - if (isSmall() && p.isFallback && p.isFallback()) - return 'iD-icon-' + p.id; - else if (p.icon) - return p.icon; - else if (geom === 'line') - return 'iD-other-line'; - else if (geom === 'vertex') - return p.isFallback() ? '' : 'temaki-vertex'; - else if (isSmall() && geom === 'point') - return ''; - else - return 'maki-marker-stroked'; - } + icon = icon.enter() + .append('div') + .attr('class', 'preset-icon') + .call(svgIcon('')) + .merge(icon); - function renderPointBorder(enter) { - var w = 40, h = 40; - enter = enter - .append('svg') - .attr('class', 'preset-icon-fill preset-icon-point-border') - .attr('width', w) - .attr('height', h) - .attr('viewBox', '0 0 ' + w + ' ' + h); + icon + .attr('class', 'preset-icon ' + (geom ? geom + '-geom' : '')) + .classed('framed', isFramed) + .classed('preset-icon-iD', isiDIcon); - enter.append('path') - .attr('transform', 'translate(11.5, 8)') - .attr('d', 'M 17,8 C 17,13 11,21 8.5,23.5 C 6,21 0,13 0,8 C 0,4 4,-0.5 8.5,-0.5 C 13,-0.5 17,4 17,8 z'); - } + icon.selectAll('svg') + .attr('class', 'icon ' + picon + ' ' + (!isiDIcon && geom !== 'line' ? '' : tagClasses)); - function renderCircleFill(fillEnter) { - var w = 60, h = 60, d = 40; - fillEnter = fillEnter - .append('svg') - .attr('class', 'preset-icon-fill preset-icon-fill-vertex') - .attr('width', w) - .attr('height', h) - .attr('viewBox', '0 0 ' + w + ' ' + h); + icon.selectAll('use') + .attr('href', '#' + picon + (isMaki ? (isSmall() && geom === 'point' ? '-11' : '-15') : '')); - fillEnter.append('circle') - .attr('cx', w/2) - .attr('cy', h/2) - .attr('r', d/2); - } + let imageIcon = container.selectAll('img.image-icon') + .data(imageURL ? [0] : []); - function renderSquareFill(fillEnter) { - var d = isSmall() ? 40 : 60; - var w = d, h = d, l = d*2/3, c1 = (w-l)/2, c2 = c1 + l; - fillEnter = fillEnter - .append('svg') - .attr('class', 'preset-icon-fill preset-icon-fill-area') - .attr('width', w) - .attr('height', h) - .attr('viewBox', '0 0 ' + w + ' ' + h); + imageIcon.exit() + .remove(); - var data = 'M' + c1 + ' ' + c1 + ' L' + c1 + ' ' + c2 + ' L' + c2 + ' ' + c2 + ' L' + c2 + ' ' + c1 + ' Z'; + imageIcon = imageIcon.enter() + .append('img') + .attr('class', 'image-icon') + .on('load', () => container.classed('showing-img', true) ) + .on('error', () => container.classed('showing-img', false) ) + .merge(imageIcon); - fillEnter.append('path') - .attr('d', data) - .attr('class', 'line area fill'); + imageIcon + .attr('src', imageURL); + } - fillEnter.append('path') - .attr('d', data) - .attr('class', 'line area stroke'); - - var r = 2.5; - var coordinates = [c1, c2]; - for (var xIndex in coordinates) { - for (var yIndex in coordinates) { - fillEnter.append('circle') - .attr('class', 'vertex') - .attr('cx', coordinates[xIndex]) - .attr('cy', coordinates[yIndex]) - .attr('r', r); - } - } - - if (!isSmall()) { - var midCoordinates = [[c1, w/2], [c2, w/2], [h/2, c1], [h/2, c2]]; - for (var index in midCoordinates) { - var loc = midCoordinates[index]; - fillEnter.append('circle') - .attr('class', 'midpoint') - .attr('cx', loc[0]) - .attr('cy', loc[1]) - .attr('r', 1.25); - } - } - - } - - function renderLine(lineEnter) { - var d = isSmall() ? 40 : 60; - // draw the line parametrically - var w = d, h = d, y = Math.round(d*0.72), l = Math.round(d*0.6), r = 2.5; - var x1 = (w - l)/2, x2 = x1 + l; - - lineEnter = lineEnter - .append('svg') - .attr('class', 'preset-icon-line') - .attr('width', w) - .attr('height', h) - .attr('viewBox', '0 0 ' + w + ' ' + h); - - ['casing', 'stroke'].forEach(function(klass) { - lineEnter.append('path') - .attr('d', 'M' + x1 + ' ' + y + ' L' + x2 + ' ' + y) - .attr('class', 'line ' + klass); - }); - - [[x1 - 1, y], [x2 + 1, y]].forEach(function(loc) { - lineEnter.append('circle') - .attr('class', 'vertex') - .attr('cx', loc[0]) - .attr('cy', loc[1]) - .attr('r', r); - }); - } - - function renderRoute(routeEnter) { - var d = isSmall() ? 40 : 60; - // draw the route parametrically - var w = d, - h = d, - y1 = Math.round(d*0.80), - y2 = Math.round(d*0.68), - l = Math.round(d*0.6), - r = 2; - var x1 = (w - l)/2, x2 = x1 + l/3, x3 = x2 + l/3, x4 = x3 + l/3; - - routeEnter = routeEnter - .append('svg') - .attr('class', 'preset-icon-route') - .attr('width', w) - .attr('height', h) - .attr('viewBox', '0 0 ' + w + ' ' + h); - - ['casing', 'stroke'].forEach(function(klass) { - routeEnter.append('path') - .attr('d', 'M' + x1 + ' ' + y1 + ' L' + x2 + ' ' + y2) - .attr('class', 'segment0 line ' + klass); - routeEnter.append('path') - .attr('d', 'M' + x2 + ' ' + y2 + ' L' + x3 + ' ' + y1) - .attr('class', 'segment1 line ' + klass); - routeEnter.append('path') - .attr('d', 'M' + x3 + ' ' + y1 + ' L' + x4 + ' ' + y2) - .attr('class', 'segment2 line ' + klass); - }); - - [[x1, y1], [x2, y2], [x3, y1], [x4, y2]].forEach(function(loc) { - routeEnter.append('circle') - .attr('class', 'vertex') - .attr('cx', loc[0]) - .attr('cy', loc[1]) - .attr('r', r); - }); - } - - var routeSegements = { - bicycle: ['highway/cycleway', 'highway/cycleway', 'highway/cycleway'], - bus: ['highway/unclassified', 'highway/secondary', 'highway/primary'], - detour: ['highway/tertiary', 'highway/residential', 'highway/unclassified'], - ferry: ['route/ferry', 'route/ferry', 'route/ferry'], - foot: ['highway/footway', 'highway/footway', 'highway/footway'], - hiking: ['highway/path', 'highway/path', 'highway/path'], - horse: ['highway/bridleway', 'highway/bridleway', 'highway/bridleway'], - light_rail: ['railway/light_rail', 'railway/light_rail', 'railway/light_rail'], - monorail: ['railway/monorail', 'railway/monorail', 'railway/monorail'], - pipeline: ['man_made/pipeline', 'man_made/pipeline', 'man_made/pipeline'], - piste: ['piste/downhill', 'piste/hike', 'piste/nordic'], - power: ['power/line', 'power/line', 'power/line'], - road: ['highway/secondary', 'highway/primary', 'highway/trunk'], - subway: ['railway/subway', 'railway/subway', 'railway/subway'], - train: ['railway/rail', 'railway/rail', 'railway/rail'], - tram: ['railway/tram', 'railway/tram', 'railway/tram'], - waterway: ['waterway/stream', 'waterway/stream', 'waterway/stream'] - }; - - function render() { - - var p = preset.apply(this, arguments); - var isFallback = isSmall() && p.isFallback && p.isFallback(); - var geom = geometry ? geometry.apply(this, arguments) : null; - if (geom === 'relation' && p.tags && ((p.tags.type === 'route' && p.tags.route && routeSegements[p.tags.route]) || p.tags.type === 'waterway')) { - geom = 'route'; - } - var imageURL = p.imageURL; - var picon = getIcon(p, geom); - var isMaki = picon && /^maki-/.test(picon); - var isTemaki = picon && /^temaki-/.test(picon); - var isFa = picon && /^fa[srb]-/.test(picon); - var isTnp = picon && /^tnp-/.test(picon); - var isiDIcon = picon && !(isMaki || isTemaki || isFa || isTnp); - var isCategory = !p.setTags; - var drawPoint = picon && geom === 'point' && isSmall() && !isFallback; - var drawVertex = picon !== null && geom === 'vertex' && (!isSmall() || !isFallback); - var drawLine = picon && geom === 'line' && !isFallback && !isCategory; - var drawArea = picon && geom === 'area' && !isFallback; - var drawRoute = picon && geom === 'route'; - var isFramed = (drawVertex || drawArea || drawLine || drawRoute); - - var tags = !isCategory ? p.setTags({}, geom) : {}; - for (var k in tags) { - if (tags[k] === '*') { - tags[k] = 'yes'; - } - } - var tagClasses = svgTagClasses().getClassesString(tags, ''); - - var selection = d3_select(this); - - var container = selection.selectAll('.preset-icon-container') - .data([0]); - - container = container.enter() - .append('div') - .attr('class', 'preset-icon-container ' + sizeClass) - .merge(container); - - container.classed('fallback', isFallback); - - var pointBorder = container.selectAll('.preset-icon-point-border') - .data(drawPoint ? [0] : []); - - pointBorder.exit() - .remove(); - - var pointBorderEnter = pointBorder.enter(); - renderPointBorder(pointBorderEnter); - pointBorder = pointBorderEnter.merge(pointBorder); - - - var vertexFill = container.selectAll('.preset-icon-fill-vertex') - .data(drawVertex ? [0] : []); - - vertexFill.exit() - .remove(); - - var vertexFillEnter = vertexFill.enter(); - renderCircleFill(vertexFillEnter); - vertexFill = vertexFillEnter.merge(vertexFill); - - - var fill = container.selectAll('.preset-icon-fill-area') - .data(drawArea ? [0] : []); - - fill.exit() - .remove(); - - var fillEnter = fill.enter(); - renderSquareFill(fillEnter); - fill = fillEnter.merge(fill); - - fill.selectAll('path.stroke') - .attr('class', 'area stroke ' + tagClasses); - fill.selectAll('path.fill') - .attr('class', 'area fill ' + tagClasses); - - - var line = container.selectAll('.preset-icon-line') - .data(drawLine ? [0] : []); - - line.exit() - .remove(); - - var lineEnter = line.enter(); - renderLine(lineEnter); - - line = lineEnter.merge(line); - - line.selectAll('path.stroke') - .attr('class', 'line stroke ' + tagClasses); - line.selectAll('path.casing') - .attr('class', 'line casing ' + tagClasses); - - var route = container.selectAll('.preset-icon-route') - .data(drawRoute ? [0] : []); - - route.exit() - .remove(); - - var routeEnter = route.enter(); - renderRoute(routeEnter); - - route = routeEnter.merge(route); - - if (drawRoute) { - var routeType = p.tags.type === 'waterway' ? 'waterway' : p.tags.route; - var segmentPresetIDs = routeSegements[routeType]; - for (var segmentIndex in segmentPresetIDs) { - var segmentPreset = context.presets().item(segmentPresetIDs[segmentIndex]); - var segmentTagClasses = svgTagClasses().getClassesString(segmentPreset.tags, ''); - route.selectAll('path.stroke.segment' + segmentIndex) - .attr('class', 'segment' + segmentIndex + ' line stroke ' + segmentTagClasses); - route.selectAll('path.casing.segment' + segmentIndex) - .attr('class', 'segment' + segmentIndex + ' line casing ' + segmentTagClasses); - } - - } - - var icon = container.selectAll('.preset-icon') - .data(picon ? [0] : []); - - icon.exit() - .remove(); - - icon = icon.enter() - .append('div') - .attr('class', 'preset-icon') - .call(svgIcon('')) - .merge(icon); - - icon - .attr('class', 'preset-icon ' + (geom ? geom + '-geom' : '')) - .classed('framed', isFramed) - .classed('preset-icon-iD', isiDIcon); - - icon.selectAll('svg') - .attr('class', function() { - return 'icon ' + picon + ' ' + (!isiDIcon && geom !== 'line' ? '' : tagClasses); - }); - - icon.selectAll('use') - .attr('href', '#' + picon + (isMaki ? (isSmall() && geom === 'point' ? '-11' : '-15') : '')); - - var imageIcon = container.selectAll('img.image-icon') - .data(imageURL ? [0] : []); - - imageIcon.exit() - .remove(); - - imageIcon = imageIcon.enter() - .append('img') - .attr('class', 'image-icon') - .on('load', function() { - container.classed('showing-img', true); - }) - .on('error', function() { - container.classed('showing-img', false); - }) - .merge(imageIcon); - - imageIcon - .attr('src', imageURL); - - } - - - presetIcon.preset = function(val) { - if (!arguments.length) return preset; - preset = utilFunctor(val); - return presetIcon; - }; - - - presetIcon.geometry = function(val) { - if (!arguments.length) return geometry; - geometry = utilFunctor(val); - return presetIcon; - }; - - - presetIcon.sizeClass = function(val) { - if (!arguments.length) return sizeClass; - sizeClass = val; - return presetIcon; - }; + presetIcon.preset = (val) => { + if (!arguments.length) return _preset; + _preset = utilFunctor(val); return presetIcon; + }; + + + presetIcon.geometry = (val) => { + if (!arguments.length) return _geometry; + _geometry = utilFunctor(val); + return presetIcon; + }; + + + presetIcon.sizeClass = (val) => { + if (!arguments.length) return _sizeClass; + _sizeClass = val; + return presetIcon; + }; + + return presetIcon; }