120 lines
3.6 KiB
Plaintext
120 lines
3.6 KiB
Plaintext
import { defaultIconProps } from '../icon/defaults.mjs';
|
|
import { defaultIconCustomisations } from '../customisations/defaults.mjs';
|
|
import { calculateSize } from './size.mjs';
|
|
import { wrapSVGContent } from './defs.mjs';
|
|
|
|
const isUnsetKeyword = (value) => value === "unset" || value === "undefined" || value === "none";
|
|
function iconToSVG(icon, customisations) {
|
|
const fullIcon = {
|
|
...defaultIconProps,
|
|
...icon
|
|
};
|
|
const fullCustomisations = {
|
|
...defaultIconCustomisations,
|
|
...customisations
|
|
};
|
|
const box = {
|
|
left: fullIcon.left,
|
|
top: fullIcon.top,
|
|
width: fullIcon.width,
|
|
height: fullIcon.height
|
|
};
|
|
let body = fullIcon.body;
|
|
[fullIcon, fullCustomisations].forEach((props) => {
|
|
const transformations = [];
|
|
const hFlip = props.hFlip;
|
|
const vFlip = props.vFlip;
|
|
let rotation = props.rotate;
|
|
if (hFlip) {
|
|
if (vFlip) {
|
|
rotation += 2;
|
|
} else {
|
|
transformations.push(
|
|
"translate(" + (box.width + box.left).toString() + " " + (0 - box.top).toString() + ")"
|
|
);
|
|
transformations.push("scale(-1 1)");
|
|
box.top = box.left = 0;
|
|
}
|
|
} else if (vFlip) {
|
|
transformations.push(
|
|
"translate(" + (0 - box.left).toString() + " " + (box.height + box.top).toString() + ")"
|
|
);
|
|
transformations.push("scale(1 -1)");
|
|
box.top = box.left = 0;
|
|
}
|
|
let tempValue;
|
|
if (rotation < 0) {
|
|
rotation -= Math.floor(rotation / 4) * 4;
|
|
}
|
|
rotation = rotation % 4;
|
|
switch (rotation) {
|
|
case 1:
|
|
tempValue = box.height / 2 + box.top;
|
|
transformations.unshift(
|
|
"rotate(90 " + tempValue.toString() + " " + tempValue.toString() + ")"
|
|
);
|
|
break;
|
|
case 2:
|
|
transformations.unshift(
|
|
"rotate(180 " + (box.width / 2 + box.left).toString() + " " + (box.height / 2 + box.top).toString() + ")"
|
|
);
|
|
break;
|
|
case 3:
|
|
tempValue = box.width / 2 + box.left;
|
|
transformations.unshift(
|
|
"rotate(-90 " + tempValue.toString() + " " + tempValue.toString() + ")"
|
|
);
|
|
break;
|
|
}
|
|
if (rotation % 2 === 1) {
|
|
if (box.left !== box.top) {
|
|
tempValue = box.left;
|
|
box.left = box.top;
|
|
box.top = tempValue;
|
|
}
|
|
if (box.width !== box.height) {
|
|
tempValue = box.width;
|
|
box.width = box.height;
|
|
box.height = tempValue;
|
|
}
|
|
}
|
|
if (transformations.length) {
|
|
body = wrapSVGContent(
|
|
body,
|
|
'<g transform="' + transformations.join(" ") + '">',
|
|
"</g>"
|
|
);
|
|
}
|
|
});
|
|
const customisationsWidth = fullCustomisations.width;
|
|
const customisationsHeight = fullCustomisations.height;
|
|
const boxWidth = box.width;
|
|
const boxHeight = box.height;
|
|
let width;
|
|
let height;
|
|
if (customisationsWidth === null) {
|
|
height = customisationsHeight === null ? "1em" : customisationsHeight === "auto" ? boxHeight : customisationsHeight;
|
|
width = calculateSize(height, boxWidth / boxHeight);
|
|
} else {
|
|
width = customisationsWidth === "auto" ? boxWidth : customisationsWidth;
|
|
height = customisationsHeight === null ? calculateSize(width, boxHeight / boxWidth) : customisationsHeight === "auto" ? boxHeight : customisationsHeight;
|
|
}
|
|
const attributes = {};
|
|
const setAttr = (prop, value) => {
|
|
if (!isUnsetKeyword(value)) {
|
|
attributes[prop] = value.toString();
|
|
}
|
|
};
|
|
setAttr("width", width);
|
|
setAttr("height", height);
|
|
const viewBox = [box.left, box.top, boxWidth, boxHeight];
|
|
attributes.viewBox = viewBox.join(" ");
|
|
return {
|
|
attributes,
|
|
viewBox,
|
|
body
|
|
};
|
|
}
|
|
|
|
export { iconToSVG, isUnsetKeyword };
|