diff --git a/src/components/tools/PortraitGenerator/Preview.tsx b/src/components/tools/PortraitGenerator/Preview.tsx index 92434103..3e23b10b 100644 --- a/src/components/tools/PortraitGenerator/Preview.tsx +++ b/src/components/tools/PortraitGenerator/Preview.tsx @@ -16,7 +16,10 @@ const noteHeight = 45 const noteFont = "bold 25px \"Arial\"" const nameFont = "bold 17px \"Arial\"" -export default function Preview({ active, remove, background, secondaryBackground, portraitPadding, changedWidth, names, tripleSplit, artifactSplit }: { active: PortraitIcon[], remove: (i: number) => void, background: boolean, secondaryBackground: string, portraitPadding: boolean, changedWidth: number, names: boolean, tripleSplit: boolean, artifactSplit: boolean }) { +export default function Preview({ active, remove, background, secondaryBackground, portraitPadding, changedWidth, names, + tripleSplit, artifactSplit, twoWeapons, twoWeaponsDistance, threeWeapons, threeWeaponsDistance }: + { active: PortraitIcon[], remove: (i: number) => void, background: boolean, secondaryBackground: string, portraitPadding: boolean, changedWidth: number, names: boolean, + tripleSplit: boolean, artifactSplit: boolean, twoWeapons: string, twoWeaponsDistance: number, threeWeapons: string, threeWeaponsDistance: number }) { const canvasRef = useRef(null as HTMLCanvasElement) const [hovering, setHovering] = useState(false) @@ -28,7 +31,7 @@ export default function Preview({ active, remove, background, secondaryBackgroun function getName(x: PortraitIcon) { // Filter out Skin or Version number - var filteredName = filterName(x.name); + var filteredName = filterName(x.name) return `${filteredName}${x.others ? "+" + x.others.map(x => getName(x)).join("+") : ""}` } const list = active.map(x => getName(x)).join(" - ") @@ -71,9 +74,10 @@ export default function Preview({ active, remove, background, secondaryBackgroun // https://stackoverflow.com/questions/6011378/how-to-add-image-to-canvas const x = leftBorder + effectivePortraitPad + portraitSize * (changedWidth - 1) / 2 const y = effectiveFramePad + effectivePortraitPad - await drawIcon(ctx, icon, x, y, portraitSize, names, tripleSplit, artifactSplit) + await drawIcon(ctx, icon, x, y, portraitSize, names, tripleSplit, artifactSplit, twoWeapons, twoWeaponsDistance, threeWeapons, threeWeaponsDistance) } - })(), [active, background, secondaryBackground, effectivePortraitPad, changedWidth, names, tripleSplit, artifactSplit]) + })(), [active, background, secondaryBackground, effectivePortraitPad, changedWidth, names, + tripleSplit, artifactSplit, twoWeapons, twoWeaponsDistance, threeWeapons, threeWeaponsDistance]) return
{ }) } -async function drawIcon(ctx: CanvasRenderingContext2D, icon: PortraitIcon, x: number, y: number, size: number, names: boolean, tripleSplit: boolean, artifactSplit: boolean) { +async function drawIcon(ctx: CanvasRenderingContext2D, icon: PortraitIcon, x: number, y: number, size: number, names: boolean, + tripleSplit: boolean, artifactSplit: boolean, twoWeapons: string, twoWeaponsDistance: number, threeWeapons: string, threeWeaponsDistance: number) { const baseImage = await loadImage(icon.path) const firstIconType = imageType(icon.path) @@ -121,20 +126,30 @@ async function drawIcon(ctx: CanvasRenderingContext2D, icon: PortraitIcon, x: nu if (icon.others) { if (icon.others.length == 1) { - // 2 images - await drawTopHalf(ctx, icon, baseImage, x, y, size) - const secondIconType = imageType(icon.others[0].path) if (secondIconType == "Artifact") { icon.others[0].full = artifactSplit } const secondIcon = icon.others[0] const second = await loadImage(secondIcon.path) - await drawBottomHalf(ctx, secondIcon, second, x, y, size) + + if (twoWeapons != "Split" && firstIconType == "Weapon" && secondIconType == "Weapon") { + // 2 images (1st Weapon + 2nd Weapon overlapped or side-by-side) + if (twoWeapons == "Overlap") { + await drawImg(ctx, icon, baseImage, x, y, size) + await drawMirroredImg(ctx, secondIcon, second, x, y, size) + } else if (twoWeapons == "SideBySide") { + await drawSlightlyLeft(ctx, icon, baseImage, x, y, size, twoWeaponsDistance * 0.8) + await drawSlightlyRight(ctx, secondIcon, second, x, y, size, twoWeaponsDistance * 0.8) + } + } else { + // 2 images + await drawTopHalf(ctx, icon, baseImage, x, y, size) + await drawBottomHalf(ctx, secondIcon, second, x, y, size) - drawDiagonal(ctx, x, y, size) + drawDiagonal(ctx, x, y, size) + } } else { - // 3/4 images const secondIconType = imageType(icon.others[0].path) if (secondIconType == "Artifact") { icon.others[0].full = artifactSplit @@ -156,43 +171,50 @@ async function drawIcon(ctx: CanvasRenderingContext2D, icon: PortraitIcon, x: nu icon.others[2].full = artifactSplit } } - - if (fourthIconType == "None" && tripleSplit) { - await drawTopLeft(ctx, icon, baseImage, x, y, size) - await drawTopRight(ctx, secondIcon, second, x, y, size) + + if (threeWeapons == "SideBySide" && firstIconType == "Weapon" && secondIconType == "Weapon" && thirdIconType == "Weapon" && fourthIconType == "None") { + // 3 images (1st Weapon + 2nd Weapon + 3nd Weapon side-by-side) + await drawSlightlyLeft(ctx, icon, baseImage, x, y, size, threeWeaponsDistance) + await drawImg(ctx, secondIcon, second, x, y, size) + await drawSlightlyRight(ctx, thirdIcon, third, x, y, size, threeWeaponsDistance) } else { - await drawTopCenter(ctx, icon, baseImage, x, y, size) - await drawLeftCenter(ctx, secondIcon, second, x, y, size) - } + // 3/4 images + if (fourthIconType == "None" && tripleSplit) { + await drawTopLeft(ctx, icon, baseImage, x, y, size) + await drawTopRight(ctx, secondIcon, second, x, y, size) + } else { + await drawTopCenter(ctx, icon, baseImage, x, y, size) + await drawLeftCenter(ctx, secondIcon, second, x, y, size) + } - if (fourthIconType == "None") { - // 3 images - if (tripleSplit) { - await drawBottomCenter2(ctx, thirdIcon, third, x, y, size) - - drawHalfMiddleSplit(ctx, x, y, size) - drawHalfFirstTripleDiagonal(ctx, x, y, size) - drawHalfSecondTripleDiagonal(ctx, x, y, size) + if (fourthIconType == "None") { + // 3 images + if (tripleSplit) { + await drawBottomCenter2(ctx, thirdIcon, third, x, y, size) + + drawHalfMiddleSplit(ctx, x, y, size) + drawHalfFirstTripleDiagonal(ctx, x, y, size) + drawHalfSecondTripleDiagonal(ctx, x, y, size) + } else { + await drawBottomHalf(ctx, thirdIcon, third, x, y, size) + + drawDiagonal(ctx, x, y, size) + drawTLHalfDiagonal(ctx, x, y, size) + } } else { - await drawBottomHalf(ctx, thirdIcon, third, x, y, size) + // 4 images + await drawRightCenter(ctx, thirdIcon, third, x, y, size) + + const fourthIcon = icon.others[2] + const fourth = await loadImage(fourthIcon.path) + + await drawBottomCenter(ctx, fourthIcon, fourth, x, y, size) drawDiagonal(ctx, x, y, size) - drawTLHalfDiagonal(ctx, x, y, size) + drawTLDiagonal(ctx, x, y, size) } - } else { - // 4 images - await drawRightCenter(ctx, thirdIcon, third, x, y, size) - - const fourthIcon = icon.others[2] - const fourth = await loadImage(fourthIcon.path) - - await drawBottomCenter(ctx, fourthIcon, fourth, x, y, size) - - drawDiagonal(ctx, x, y, size) - drawTLDiagonal(ctx, x, y, size) } } - } else { // Draw singular drawImg(ctx, icon, baseImage, x, y, size) @@ -219,7 +241,7 @@ async function drawIcon(ctx: CanvasRenderingContext2D, icon: PortraitIcon, x: nu ctx.fillStyle = "#FFFFFF" ctx.textBaseline = "alphabetic" // Filter out Skin or Version number - var filteredName = filterName(icon.name); + var filteredName = filterName(icon.name) // ctx.fillText(icon.name, x + size / 2, y + size + 34) wrapText(ctx, filteredName, x + size / 2, y + size + 34, 180, 20) .forEach(([text, x, y]) => ctx.fillText(text, x, y)) @@ -235,6 +257,21 @@ async function drawImg(ctx: CanvasRenderingContext2D, icon: PortraitIcon, baseIm } } +async function drawMirroredImg(ctx: CanvasRenderingContext2D, icon: PortraitIcon, img: HTMLImageElement, x: number, y: number, size: number) { + ctx.save() + ctx.scale(-1, 1) + await drawImg(ctx, icon, img, -x -size, y, size) + ctx.restore() +} + +async function drawSlightlyLeft(ctx: CanvasRenderingContext2D, icon: PortraitIcon, img: HTMLImageElement, x: number, y: number, size: number, distance: number) { + await drawImg(ctx, icon, img, x - ((size / 6) * distance), y, size) +} + +async function drawSlightlyRight(ctx: CanvasRenderingContext2D, icon: PortraitIcon, img: HTMLImageElement, x: number, y: number, size: number, distance: number) { + await drawImg(ctx, icon, img, x + ((size / 6) * distance), y, size) +} + async function drawBottomHalf(ctx: CanvasRenderingContext2D, icon: PortraitIcon, img: HTMLImageElement, x: number, y: number, size: number) { const half = size / 2 ctx.save() @@ -448,7 +485,7 @@ function drawHalfSecondTripleDiagonal(ctx: CanvasRenderingContext2D, x: number, function filterName(name: string) { // Filter out Skin or Version number - return name.replace(/ Skin[0-9]+| Alt[0-9]+/g, ""); + return name.replace(/ Skin[0-9]+| Alt[0-9]+/g, "") } function imageType(path: string) { diff --git a/src/components/tools/PortraitGenerator/index.tsx b/src/components/tools/PortraitGenerator/index.tsx index 471b3207..b887f4fc 100644 --- a/src/components/tools/PortraitGenerator/index.tsx +++ b/src/components/tools/PortraitGenerator/index.tsx @@ -84,6 +84,10 @@ export default function PortraitGenerator({ const [tripleSplit, setTripleSplit] = useState(true) const [artifactSplit, setArtifactSplit] = useState(true) + const [twoWeapons, setTwoWeapons] = useState("Split") + const [twoWeaponsDistance, setTwoWeaponsDistance] = useState(1) + const [threeWeapons, setThreeWeapons] = useState("Split") + const [threeWeaponsDistance, setThreeWeaponsDistance] = useState(1) const [search, setSearch] = useState("") @@ -249,6 +253,10 @@ export default function PortraitGenerator({ setTripleSplit(true) setArtifactSplit(true) + setTwoWeapons("Split") + setTwoWeaponsDistance(1) + setThreeWeapons("Split") + setThreeWeaponsDistance(1) } }}> Reset to default settings @@ -290,7 +298,42 @@ export default function PortraitGenerator({ +
+ + {twoWeapons == "SideBySide" && }
+ + {threeWeapons == "SideBySide" && }