Created
November 6, 2022 03:44
-
-
Save ubuntor/758405e9a66c7f226181efc9df578a01 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from shapely.geometry import Polygon, MultiPoint, Point | |
from shapely.ops import voronoi_diagram | |
import matplotlib.pyplot as plt | |
import random | |
import math | |
NUM_EGGBUGS = 5 | |
cursors = [ | |
"nwse-resize", | |
"ns-resize", | |
"nesw-resize", | |
"ew-resize", | |
"nwse-resize", | |
"ns-resize", | |
"nesw-resize", | |
"ew-resize", | |
] | |
# generate cursor regions | |
# compute a voronoi diagram to get the regions closest to each point, then split them up into 8 sectors | |
cursor_regions = [] | |
square = Polygon([(0,0), (0,1), (1,1), (1,0), (0,0)]) | |
points = [(random.uniform(0.1, 0.9), random.uniform(0.1, 0.9)) for i in range(NUM_EGGBUGS)] | |
regions = voronoi_diagram(MultiPoint(points), envelope=square) | |
for region in regions.geoms: | |
for px,py in points: | |
if region.contains(Point(px,py)): | |
break | |
region = region.intersection(square) | |
for i in range(8): | |
a1 = (i+0.5)*2*math.pi/8 | |
a2 = (i+1.5)*2*math.pi/8 | |
subregion = region.intersection(Polygon([(px,py), (px+2*math.cos(a1),py+2*math.sin(a1)), (px+2*math.cos(a2),py+2*math.sin(a2)), (px,py)])) | |
plt.plot(*subregion.exterior.xy) | |
polygon = ', '.join(f'{x:.2%} {y:.2%}' for x,y in list(zip(*subregion.exterior.xy))[:-1]) | |
cursor_regions.append(f'<div style="width: 100%; height:100%; clip-path: polygon({polygon}); border-radius:10px; position:absolute; z-index:1; cursor:{cursors[i]}"></div>') | |
plt.plot(*region.exterior.xy) | |
plt.plot(px,py, marker="o") | |
tiny_eggbugs = [] | |
for x,y in points: | |
# using @nex3's vectorized eggbug: https://cohost.org/nex3/post/2554-i-went-ahead-and-vec | |
tiny_eggbugs.append(f'<img src="https://staging.cohostcdn.org/attachment/06bb2adb-ca3f-43dd-a4e7-5f2d2d5cb9ff/eggbug.svg" style="position: absolute; width: 3%; left: {x:.2%}; top: {y:.2%}; height: 3%; margin: 0; transform: translate(-50%, -50%)">') | |
print('<div style="width:100%; aspect-ratio:5/6; overflow:hidden; position:relative">') | |
print('<div style="aspect-ratio:1; position:relative; background: linear-gradient(135deg, #f6dbdb, #f6e4db, #f6f6db, #dbf6db, #dbdbf6, #e4dbf6, #f6dbf6); border-radius: 20px; box-shadow: inset 0px 0px 10px 0px #000a">') | |
print('\n'.join(cursor_regions)) | |
print('\n'.join(tiny_eggbugs)) | |
print('</div>') | |
# generate the buttons that cover the tiny eggbugs and the tabs that cover the big eggbugs and the "good job!" at the bottom | |
# technique adapted from @noa's explanation of two-way pagination: https://cohost.org/noa/post/139956-div-style-display#comment-77684084-e4a3-4a61-a078-7e4f7af66175 | |
for i,(x,y) in enumerate(points): | |
print('<div style="aspect-ratio: 1/3; display: flex; flex-direction: column; width: 100%; justify-content: end; position:absolute">') | |
print('<details style="display: contents;" open>') | |
x1 = i/NUM_EGGBUGS + 0.02 | |
x2 = (i+1)/NUM_EGGBUGS - 0.02 | |
# this polygon covers up one of the big eggbugs and the "good job!" message | |
print(f'<summary style="display: block; width: 100%; height: 33.33%; pointer-events: none; background: white; position: relative; z-index:1; clip-path: polygon(100% 0%, 100% -100%, 0% -100%, 0 100%, 100% 100%, 100% 13%, {x2:.2%} 13%, {x2:.2%} 1%, {x1:.2%} 1%, {x1:.2%} 13%, 1% 13%, 1% 0%);">') | |
# button that covers up a tiny eggbug | |
# when clicked, will close the <details> | |
print(f'<div style="background: linear-gradient(135deg, #f6dbdb, #f6e4db, #f6f6db, #dbf6db, #dbdbf6, #e4dbf6, #f6dbf6); width: 100%; height: 100%; position: absolute; top: -100%; pointer-events: all; cursor: pointer; z-index:2; clip-path: circle(2% at {x:.2%} {y:.2%})"></div>') | |
print('</summary>') | |
# spacer that pushes the summary and button up onto the screen when the <details> is open | |
print('<div style="width: 100%; height: 66.67%;">') | |
print('</div></details>') | |
print('</div>') | |
# big eggbugs and "good job!" | |
print('<div style="aspect-ratio: 5/1; width:100%; position:absolute">') | |
for i in range(NUM_EGGBUGS): | |
print(f'<img src="https://staging.cohostcdn.org/attachment/06bb2adb-ca3f-43dd-a4e7-5f2d2d5cb9ff/eggbug.svg" style="position: absolute; top: 35%; left: {(i+0.5)/NUM_EGGBUGS:.2%}; height: 50%; margin: 0; transform: translate(-50%, -50%);">') | |
print('<div style="width:100%; text-align: center; position:absolute; top:80%; transform: translateY(-50%)">good job!</div>') | |
print('</div>') | |
print('</div>') | |
plt.show() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment