UNPKG

css-doodle

Version:

A web component for drawing patterns with CSS

184 lines (167 loc) 4.92 kB
import parse_value_group from './parser/parse-value-group.js'; import parse_grid from './parser/parse-grid.js'; import generate_shape from './generator/shapes.js'; import { is_preset, get_preset } from './preset-size.js'; import { add_alias } from './utils/index.js'; import { memo } from './cache.js'; const iw = '--_cell-width'; const ih = '--_cell-height'; const map_left_right = { center: '50%', left: '0%', right: '100%', top: '50%', bottom: '50%' }; const map_top_bottom = { center: '50%', top: '0%', bottom: '100%', left: '50%', right: '50%', }; export default add_alias({ size(value, { is_special_selector, grid }) { let [w, h = w, ratio] = parse_value_group(value); if (is_preset(w)) { [w, h] = get_preset(w, h); } let styles = `width:${w};height:${h};`; if (w === 'auto' || h === 'auto') { if (ratio) { if (/^\(.+\)$/.test(ratio)) { ratio = ratio.substring(1, ratio.length - 1); } else if (!/^calc/.test(ratio)) { ratio = `calc(${ratio})`; } if (!is_special_selector) { styles += `aspect-ratio: ${ratio};`; } } if (is_special_selector) { styles += `aspect-ratio: ${ratio || grid.ratio};`; } } if (!is_special_selector) { styles += `${iw}:${w};${ih}:${h};`; } return styles; }, place(value, { extra }) { let [left, top = '50%'] = parse_value_group(value); left = map_left_right[left] || left; top = map_top_bottom[top] || top; let cw = `var(${iw}, 25%)`; let ch = `var(${ih}, 25%)`; return ` position: absolute; left: ${left}; top: ${top}; width: ${cw}; height: ${ch}; margin-left: calc(${cw} / -2); margin-top: calc(${ch} / -2); grid-area: unset; --plot-angle: ${extra || 0}; rotate: ${extra || 0}deg; `; }, grid(value, options) { let result = { clip: true, p3d: false, }; let temp = []; let pos = 0; for (let item of parse_value_group(value, {symbol: ' '})) { if (pos === 0 && (item === '|' || item === '-')) { result.flex = item === '|' ? 'column' : 'row'; temp.push('§'); } else if (/border:?/i.test(item)) { result.borderLegacy = item.split(':')[1] || ''; temp.push('§'); } else if (/^no\-*clip$/i.test(item)) { result.clip = false; temp.push('§'); } else if (/^p3d$/i.test(item)) { result.p3d = true; temp.push('§'); } else if (!result.grid) { result.grid = parse_grid(item, options.max_grid); temp.push(item); } else { temp.push(item); } pos += 1; } let groups = parse_value_group(temp.join(' '), { symbol: ['/ 2', '+', '^', '*', '~', '∆', '_', 'ß', '«', '§'], noSpace: true, verbose: true }); for (let { group, value } of groups) { if (group === '+') result.scale = value; if (group === '^') result.enlarge = value; if (group === '~') result.translate = value; if (group === '∆') result.persp = parse_value_group(value, {symbol: ' '}); if (group === '_') result.gap = value; if (group === '*') { let [head, ...rest] = parse_value_group(value, {symbol: ' '}); if (head == 'h') { result.hueRotate = rest.join(' ');; } else { result.rotate = value; } } if (group === '/') { if (result.size === undefined) result.size = this.size(value, options); else result.fill = value; } if (group === 'ß') { let values = parse_value_group(value, {symbol: ' '}); for (let i = 0; i < values.length; i++) { if (Number(values[i])) { values[i] += 'px'; break; } } // simplify the regex let v = values[0]; if (values.length === 1 && (/^\D/.test(v) && !/^\.\d/.test(v) && !/^(thin|thick|medium)$/.test(v) ) ) { values.push('1px'); } if (!/solid|dotted|dashed|double|groove|ridge|inset|outset/.test(value)) { values.push('solid'); } result.border = values.join(' '); } if (group === '«') { result.backdropFilter = value; } if (group === '' && !result.grid) { result.grid = parse_grid(value, options.max_grid); } } return result; }, gap(value) { return value; }, seed(value) { return value; }, shape: memo('shape-property', value => { let { points, preset} = generate_shape(value); if (!preset) return ''; return `clip-path: polygon(${points.join(',')});`; }), use(rules) { if (rules.length > 2) { return rules; } }, content(value) { return value; }, }, { // legacy names. 'place-cell': 'place', 'offset': 'place', 'position': 'place', });