chessboard = (fenString = 'start', opts) => {
const {
size: maxSize,
responsive,
call,
theme,
} = Object.assign({
size: 440,
responsive: true,
call: () => {},
theme: {
lightSquareFill: '#FFF',
darkSquareFill: '#EEE',
borderStroke: '#CCC',
labelColor: '#CCC',
}
}, opts)
const size = responsive ? Math.min(maxSize, width) : maxSize
const marginSize = 20
const innerSize = size - marginSize * 2
const squareSize = innerSize / 8
const coords = fenToArray(fenString === 'start' ? START_FEN : fenString)
const output = html`
<svg class="chessboard" viewBox="0 0 ${size} ${size}" width=${size} height=${size}>
<defs>
${pieceSVG}
</defs>
<g class="labels file-labels">
${FILES.map((label, i) => svg`
<text
class="label file-label file-label-top"
x=${marginSize + i * squareSize + squareSize / 2}
y="12"
text-anchor="middle"
font-family="var(--sans-serif)"
font-size="14"
fill=${theme.labelColor}
>${label}</text>
<text
class="label file-label file-label-bottom"
x=${marginSize + i * squareSize + squareSize / 2}
y=${marginSize + innerSize + 16}
text-anchor="middle"
font-family="var(--sans-serif)"
font-size="14"
fill=${theme.labelColor}
>${label}</text>
`)}
</g>
<g class="labels rank-labels">
${RANKS.map((label, i) => svg`
labelText(label, 0, marginSize + i * squareSize + squareSize / 2 + 7, theme)
<text
class="label rank-label rank-label-left"
x="0"
y=${marginSize + i * squareSize + squareSize / 2 + 7}
text-anchor="right"
font-family="var(--sans-serif)"
font-size="14"
fill=${theme.labelColor}
>${label}</text>
<text
class="label rank-label rank-label-right"
x=${marginSize + innerSize + 12}
y=${marginSize + i * squareSize + squareSize / 2 + 7}
text-anchor="left"
font-family="var(--sans-serif)"
font-size="14"
fill=${theme.labelColor}
>${label}</text>
`)}
</g>
<g class="squares" transform="translate(${marginSize} ${marginSize})">
${coords.map(
(row, i) => svg`${row.map(
(square, j) => svg`
<rect
class="square ${(i + j) % 2 === 0 ? 'light-square' : 'dark-square'} square-${coordsToSquare([i, j])}"
x=${j * squareSize}
y=${i * squareSize}
width=${squareSize}
height=${squareSize}
fill=${(i + j) % 2 === 0 ? theme.lightSquareFill : theme.darkSquareFill}
/>
`
)}`
)}
</g>
<g class="pieces" transform="translate(${marginSize} ${marginSize})">
${coords.map(
(row, i) => svg`${
row.map(
(square, j) => square ? svg`<use
class="piece piece-${PIECE_MAP.get(square)}"
href="${new URL(`#${PIECE_MAP.get(square)}`, location)}"
x=${j * squareSize}
y=${i * squareSize}
width=${squareSize}
height=${squareSize}
/>` : null
).filter(d => d)
}`
)}
</g>
<rect
class="board-outline"
x=${marginSize}
y=${marginSize}
width=${innerSize}
height=${innerSize}
stroke=${theme.borderStroke}
fill="none"
/>
</svg>
`
// Call the passed in modifier function with helpful utilities
call(output, {
fenString,
squareSize,
squareCoords: (square) => squareToCoords(square).map(n => n * squareSize + marginSize),
squareCentroid: (square) => {
return squareToCoords(square).map(n => n * squareSize + 0.5 * squareSize + marginSize)
},
})
return output
}