Skip to content

Commit f2b7048

Browse files
committed
finish dynamic border sizing and sort files
1 parent 14cbba6 commit f2b7048

11 files changed

+103
-222
lines changed

package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/external/bobspace:html-colors.js

Lines changed: 8 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
File renamed without changes.

src/generator.js

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -45,10 +45,8 @@ export default function generateSvgSquircle(height, width, radius) {
4545
mapRange(maxRadius, (x / 2) * .90, x / 2, 0, 1),
4646
1
4747
)) * 200 / maxRadius,
48-
hyOffset = yOffsetF(height),
49-
wyOffset = yOffsetF(width)
50-
51-
console.log(hyOffset, wyOffset)
48+
hyOffset = yOffsetF(height) || 0,
49+
wyOffset = yOffsetF(width) || 0
5250

5351
const startPoint = `${a0xw},${wyOffset}`
5452

@@ -91,5 +89,5 @@ export default function generateSvgSquircle(height, width, radius) {
9189
C0,${a1x[0]},0,${a2x[0]},${a3y[0]},${a3x[0]}
9290
C${b1y[0]},${b1x[0]},${b1x[0]},${b1y[0]},${b0x[0]},${b0y[0]}
9391
C${a2x[0]},0,${a1x[0]},0,${startPoint}
94-
Z`.replace(/\n */g, '');
92+
Z`.replace(/\n */g, '').replace(/NaN/g, '0');
9593
}

src/html-colors.js

Lines changed: 0 additions & 159 deletions
This file was deleted.

src/main.js

Lines changed: 29 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -45,26 +45,23 @@ export default function RoundDiv({style, children, ...props}) {
4545
}, [updateStatesWithArgs])
4646

4747
const path = generateSvgSquircle(height, width, radius)
48-
const maxBorderWidth = Math.max(...borderWidth)
49-
const diffBorderMaxWidthLeftWidth = maxBorderWidth - borderWidth[3]
50-
const diffBorderMaxWidthTopWidth = maxBorderWidth - borderWidth[0]
51-
// const verticalBorderWidthDelta = maxWidth - borderWidth[2];
52-
// const horizontalBorderWidthDelta = maxWidth - borderWidth[1];
53-
const borderPath = generateSvgSquircle(
54-
height + diffBorderMaxWidthTopWidth + (maxBorderWidth - borderWidth[2]),
55-
width + diffBorderMaxWidthLeftWidth + (maxBorderWidth - borderWidth[1]),
56-
[
57-
radius[0] + maxBorderWidth - Math.min(borderWidth[3], borderWidth[0]),
58-
radius[1] + maxBorderWidth - Math.min(borderWidth[0], borderWidth[1]),
59-
radius[2] + maxBorderWidth - Math.min(borderWidth[1], borderWidth[2]),
60-
radius[3] + maxBorderWidth - Math.min(borderWidth[2], borderWidth[3])
61-
])
48+
const innerPath = generateSvgSquircle(
49+
height - (borderWidth[0] + borderWidth[2]),
50+
width - (borderWidth[1] + borderWidth[3]),
51+
radius.map((val, i) =>
52+
Math.max(0,
53+
val - Math.max(borderWidth[i], borderWidth[i === 0 ? 3 : i - 1])
54+
)
55+
)
56+
).replace(
57+
/(\d+(\.\d+)?),(\d+(\.\d+)?)/g,
58+
match => match.split(',').map((number, i) =>
59+
Number(number) + (i === 0 ? borderWidth[3] : borderWidth[0])
60+
).join(',')
61+
)
6262

6363
const maskPaths = getMaskPaths(borderWidth, height, width)
6464

65-
// console.log(borderWidth, borderColor, borderOpacity)
66-
// console.log(isFlex)
67-
6865
const svgTransform = isFlex
6966
? `translate(${(borderWidth[1] - borderWidth[3]) / 2}px,${(borderWidth[2] - borderWidth[0]) / 2}px)`
7067
: `translate(${(borderWidth[1] - borderWidth[3]) / 2}px,-${borderWidth[0]}px)`
@@ -86,19 +83,22 @@ export default function RoundDiv({style, children, ...props}) {
8683
transform: svgTransform
8784
}} xmlnsXlink="http://www.w3.org/1999/xlink" preserveAspectRatio={'xMidYMid slice'}>
8885
<defs>
89-
{Object.keys(maskPaths).map(key => (
90-
<clipPath id={key + '-mask'} key={key}>
91-
<path d={maskPaths[key]}
92-
transform={`translate(${diffBorderMaxWidthLeftWidth},${diffBorderMaxWidthTopWidth})`}/>
93-
</clipPath>
94-
))}
95-
<path d={borderPath} fill="none" id="border"/>
86+
<clipPath id="inner">
87+
<path d={`M0,0V${height}H${width}V0Z` + innerPath} fillRule={'evenodd'}/>
88+
</clipPath>
9689
</defs>
97-
{Object.keys(maskPaths).map((key, i) => (
98-
<use href="#border" clipPath={`url(#${key}-mask)`} key={key}
99-
strokeWidth={maxBorderWidth * 2} stroke={borderColor[i]} opacity={borderOpacity[i]}
100-
transform={`translate(${-diffBorderMaxWidthLeftWidth},${-diffBorderMaxWidthTopWidth})`}/>
101-
))}
90+
{Object.keys(maskPaths).map((key, i) => {
91+
if (borderColor[i] === borderColor[i - 1]) return ''
92+
93+
let path = maskPaths[key]
94+
while (borderColor[i] === borderColor[i + 1]) {
95+
path += maskPaths[Object.keys(maskPaths)[i + 1]]
96+
i++
97+
}
98+
99+
return <path d={path} clipPath={'url(#inner)'} key={key}
100+
fill={borderColor[i]} opacity={borderOpacity[i]}/>
101+
})}
102102
</svg>
103103
<slot/>
104104
</ShadowRoot>

src/mask-generator.js

Lines changed: 60 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,67 @@
11
export default function getMaskPaths(borderWidth, height, width) {
2-
const n = 10;
3-
// todo: make adaptive
4-
5-
const maskPointsA = {
6-
to: -borderWidth[0],
7-
ti: borderWidth[0] * n,
8-
ro: width + borderWidth[1],
9-
ri: width - borderWidth[1] * n,
10-
bo: height + borderWidth[2],
11-
bi: height - borderWidth[2] * n,
12-
lo: -borderWidth[3],
13-
li: borderWidth[3] * n,
2+
const allSides = ['top', 'right', 'bottom', 'left']
3+
const max = allSides.length - 1
4+
const next = i => i === max ? 0 : i + 1
5+
const prev = i => i === 0 ? max : i - 1
6+
7+
/**
8+
* @constant
9+
* @type {Array<number>}
10+
* */
11+
const allRatios = allSides.map((side, i) =>
12+
((i % 2 === 0 ? height : width) - borderWidth[next(next(i))])
13+
/ borderWidth[i]
14+
)
15+
16+
/**
17+
* @param {string} posY
18+
* @param {string} posX
19+
* @param {boolean} [inside]
20+
* @param {string} [borderPos] needed if inside=true
21+
* */
22+
const makePoint = (posY, posX, inside, borderPos) => {
23+
return makeValue(posX, inside, borderPos) + ',' + makeValue(posY, inside, borderPos)
1424
}
1525

16-
const maskPoints = {
17-
tlo: maskPointsA.lo + ',' + maskPointsA.to,
18-
tli: maskPointsA.li + ',' + maskPointsA.ti,
19-
tro: maskPointsA.ro + ',' + maskPointsA.to,
20-
tri: maskPointsA.ri + ',' + maskPointsA.ti,
21-
blo: maskPointsA.lo + ',' + maskPointsA.bo,
22-
bli: maskPointsA.li + ',' + maskPointsA.bi,
23-
bro: maskPointsA.ro + ',' + maskPointsA.bo,
24-
bri: maskPointsA.ri + ',' + maskPointsA.bi,
26+
/**
27+
* @param {string} pos
28+
* @param {boolean} [inside]
29+
* @param {string} [borderPos] needed if inside=true
30+
* */
31+
const makeValue = (pos, inside, borderPos) => {
32+
let v = -borderWidth[allSides.indexOf(pos)]
33+
34+
if (inside) {
35+
const i = allSides.indexOf(borderPos)
36+
v *= -Math.min(allRatios[prev(i)], allRatios[i], allRatios[next(i)])
37+
}
38+
39+
if (pos === 'right')
40+
v = -v + Number(width)
41+
else if (pos === 'bottom')
42+
v = -v + Number(height)
43+
44+
return v
2545
}
2646

27-
return {
28-
top: `M${maskPoints.tli}H${maskPointsA.ri}L${maskPoints.tro}H${maskPointsA.lo}Z`,
29-
right: `M${maskPoints.tri}V${maskPointsA.bi}L${maskPoints.bro}V${maskPointsA.to}Z`,
30-
bottom: `M${maskPoints.bri}H${maskPointsA.li}L${maskPoints.blo}H${maskPointsA.ro}Z`,
31-
left: `M${maskPoints.bli}V${maskPointsA.ti}L${maskPoints.tlo}V${maskPointsA.bo}Z`,
47+
const makeMaskPath = (side) => {
48+
const i = allSides.indexOf(side)
49+
const isH = i % 2 === 0 // is "top" or "bottom"
50+
const T = isH ? 'H' : 'V'
51+
const nextSide = allSides[next(i)]
52+
const prevSide = allSides[prev(i)]
53+
const prevIfH = isH ? prevSide : side
54+
const prevIfV = !isH ? prevSide : side
55+
const nextIfH = isH ? nextSide : side
56+
const nextIfV = !isH ? nextSide : side
57+
58+
return 'M' + makePoint(prevIfV, prevIfH, true, side) +
59+
T + makeValue(nextSide, true, side) +
60+
'L' + makePoint(nextIfV, nextIfH) +
61+
T + makeValue(prevSide) + 'Z'
3262
}
63+
64+
return Object.fromEntries(
65+
allSides.map(side => [side, makeMaskPath(side)])
66+
)
3367
}

0 commit comments

Comments
 (0)