Skip to content

Commit 4e67095

Browse files
committed
toggle vv bonds
1 parent 37a334b commit 4e67095

1 file changed

Lines changed: 179 additions & 21 deletions

File tree

index.html

Lines changed: 179 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,22 @@
4242
return lerp(a, b, alpha)
4343
}
4444

45+
let rvec = (x, y, dx, dy, a) => {
46+
let ca = cos(a), sa = sin(a)
47+
return [
48+
x + ca * dx - sa * dy,
49+
y + sa * dx + ca * dy,
50+
]
51+
}
52+
53+
let point_onto_line = (x, y, x1, y1, x2, y2) => {
54+
let d = dist(x1, y1, x2, y2) || 1
55+
let dx = (x2 - x1) / d, dy = (y2 - y1) / d
56+
let p_dx = x - x1, p_dy = y - y1
57+
let f = clamp(dx * p_dx + dy * p_dy, 0, d)
58+
return [x1 + dx * f, y1 + dy * f]
59+
}
60+
4561
let ease = {
4662
outQuart: t => 1 - pow(1 - t, 4),
4763
outBounce: t => {
@@ -56,6 +72,7 @@
5672
}
5773

5874
let cursor = v => document.body.style.cursor = v
75+
let hand = () => cursor("pointer")
5976

6077
let mouse = {
6178
x: 0, y: 0,
@@ -244,18 +261,21 @@
244261
let canvas = document.querySelector("canvas")
245262
let ctx = canvas.getContext("2d")
246263

247-
let line = (x1, y1, x2, y2, strokeStyle) => {
248-
ctx.strokeStyle = strokeStyle || ctx.strokeStyle
264+
let line = (x1, y1, x2, y2, color) => {
265+
ctx.strokeStyle = color || ctx.strokeStyle
249266
ctx.beginPath()
250267
ctx.moveTo(x1, y1)
251268
ctx.lineTo(x2, y2)
252269
ctx.stroke()
253270
}
254271

255-
let circle = (x, y, r, color = "SteelBlue", mode = "fill") => {
256-
ctx.lineWidth = 4
257-
if (mode == "fill") ctx.fillStyle = color
258-
else ctx.strokeStyle = color
272+
let circle = (x, y, r, mode = "fill", color) => {
273+
if (mode == "fill") {
274+
ctx.fillStyle = color || ctx.fillStyle
275+
} else {
276+
ctx.strokeStyle = color || ctx.strokeStyle
277+
ctx.lineWidth = 4
278+
}
259279
ctx.beginPath()
260280
ctx.ellipse(
261281
x, y, r, r,
@@ -265,6 +285,15 @@
265285
else ctx.stroke()
266286
}
267287

288+
let polygon = (...pts) => {
289+
ctx.beginPath()
290+
ctx.moveTo(pts[0], pts[1])
291+
for (let i = 2; i < pts.length; i += 2)
292+
ctx.lineTo(pts[i], pts[i + 1])
293+
ctx.closePath()
294+
ctx.fill()
295+
}
296+
268297
let _mats = []
269298
let push = () => _mats.push(ctx.getTransform())
270299
let pop = () => ctx.setTransform(_mats.pop())
@@ -385,16 +414,16 @@
385414
if (my == undefined) my = wmy
386415
let a = this
387416
let r = a.r || 25
388-
if (a.fill) circle(a.x, a.y, r, a.fill)
389-
else circle(a.x, a.y, r, "#122", "line")
417+
if (a.fill) circle(a.x, a.y, r, "fill", a.fill)
418+
else circle(a.x, a.y, r, "line", "#122")
390419
if (bonding.includes(a)) {
391-
circle(a.x, a.y, r * 1.3, "#122", "line")
420+
circle(a.x, a.y, r * 1.3, "line", "#122")
392421
}
393422
if (no_hover) return
394423
if (dist(a.x, a.y, mx, my) < r && !touch_left()) {
395-
cursor("pointer")
424+
hand()
396425
ctx.globalAlpha = 0.5
397-
circle(a.x, a.y, r, "#444")
426+
circle(a.x, a.y, r, "fill", "#444")
398427
ctx.globalAlpha = 1
399428
}
400429
}
@@ -465,6 +494,8 @@
465494
vv.atoms = []
466495
for (let i = 0; i < 6; i++)
467496
vv.atoms.push(new Atom())
497+
498+
vv.bonds = [0, 1, 1, 0, 1, 1]
468499
}
469500

470501
update(dt) {
@@ -496,19 +527,76 @@
496527
ctx.rotate(vv.a)
497528
ctx.scale(vv.s, vv.s)
498529

530+
let slide_t = (vv.open
531+
? ease.outBounce(vv.open_t)
532+
: 1 - ease.outBounce(1 - vv.open_t)
533+
)
534+
let roll_t = 1 - slide_t
499535
let btn_slide_t = (vv.open
500536
? ease.outQuart(vv.open_t)
501537
: 1 - ease.outQuart(1 - vv.open_t)
502538
)
503539
let btn_roll_t = 1 - btn_slide_t
504540

541+
let m, mx, my
542+
if (vv.open && vv.open_t == 1) {
543+
let h = tan(pi / 3) * 200
544+
let mid = tan(pi / 6) * 200
545+
546+
push()
547+
ctx.translate(300 * slide_t, 0)
548+
ctx.rotate(-pi / 2 * roll_t)
549+
ctx.translate(0, -mid)
550+
m = ctx.getTransform().inverse()
551+
;({ x: mx, y: my } = m.transformPoint(mouse))
552+
let in_ca = dist(mx, my, ...point_onto_line(
553+
mx, my, 200, 0, -200, 0
554+
)) < 50
555+
let in_ab = dist(mx, my, ...point_onto_line(
556+
mx, my, -200, 0, 0, h
557+
)) < 50
558+
let in_bc = dist(mx, my, ...point_onto_line(
559+
mx, my, 0, h, 200, 0
560+
)) < 50
561+
if (in_ca && !in_ab && !in_bc)
562+
{ vv.bonds[3] = 1 - vv.bonds[3] }
563+
if (in_ab && !in_ca && !in_bc)
564+
{ vv.bonds[4] = 1 - vv.bonds[4] }
565+
if (in_bc && !in_ab && !in_ca)
566+
{ vv.bonds[5] = 1 - vv.bonds[5] }
567+
pop()
568+
569+
push()
570+
ctx.translate(-300 * slide_t, 0)
571+
ctx.rotate(pi / 2 * roll_t)
572+
ctx.translate(0, -mid)
573+
m = ctx.getTransform().inverse()
574+
;({ x: mx, y: my } = m.transformPoint(mouse))
575+
in_ca = dist(mx, my, ...point_onto_line(
576+
mx, my, 200, 0, -200, 0
577+
)) < 50
578+
in_ab = dist(mx, my, ...point_onto_line(
579+
mx, my, -200, 0, 0, h
580+
)) < 50
581+
in_bc = dist(mx, my, ...point_onto_line(
582+
mx, my, 0, h, 200, 0
583+
)) < 50
584+
if (in_ca && !in_ab && !in_bc)
585+
{ vv.bonds[0] = 1 - vv.bonds[0] }
586+
if (in_ab && !in_ca && !in_bc)
587+
{ vv.bonds[1] = 1 - vv.bonds[1] }
588+
if (in_bc && !in_ab && !in_ca)
589+
{ vv.bonds[2] = 1 - vv.bonds[2] }
590+
pop()
591+
}
592+
505593
ctx.translate(0, 120 * btn_slide_t)
506594
ctx.rotate(-pi * btn_roll_t)
507595
let s = lerp(1, 1.6, btn_slide_t)
508596
ctx.scale(s, s)
509597

510-
let m = ctx.getTransform().inverse()
511-
let { x: mx, y: my } = m.transformPoint(mouse)
598+
m = ctx.getTransform().inverse()
599+
;({ x: mx, y: my } = m.transformPoint(mouse))
512600

513601
for (let b of Object.values(vv.btns))
514602
if (dist(b.x, b.y, mx, my) < 25) b.fn()
@@ -543,10 +631,47 @@
543631
ctx.translate(300 * slide_t, 0)
544632
ctx.rotate(-pi / 2 * roll_t)
545633
ctx.translate(0, -mid)
634+
let m = ctx.getTransform().inverse()
635+
let { x: mx, y: my } = m.transformPoint(mouse)
636+
let in_ca = dist(mx, my, ...point_onto_line(
637+
mx, my, 200, 0, -200, 0
638+
)) < 50
639+
let in_ab = dist(mx, my, ...point_onto_line(
640+
mx, my, -200, 0, 0, h
641+
)) < 50
642+
let in_bc = dist(mx, my, ...point_onto_line(
643+
mx, my, 0, h, 200, 0
644+
)) < 50
546645
ctx.lineWidth = 100
547-
line(-200, 0, 200, 0, "#4d3b34")
548-
line(-200, 0, 0, h, "#47352f")
549-
line(0, h, 200, 0)
646+
let bcol = ["#4d3b34", "#47352f"]
647+
line(200, 0, -200, 0, bcol[vv.bonds[3]])
648+
line(-200, 0, 0, h, bcol[vv.bonds[4]])
649+
line(0, h, 200, 0, bcol[vv.bonds[5]])
650+
ctx.fillStyle = bcol[1]
651+
circle(-200, 0, 50)
652+
circle(0, h, 50)
653+
circle(200, 0, 50)
654+
let pt = rvec(-200, 0, 50, 0, -pi / 6)
655+
let d1 = dist(-200, 50, ...pt)
656+
let d2 = dist(-200, 0, -200 + d1, 50)
657+
polygon(-200, 50, ...pt, -200 + d1, 50)
658+
polygon(
659+
...rvec(0, h, 50, 0, -pi / 6),
660+
...rvec(0, h, 50, 0, -5 * pi / 6),
661+
0, h - d2,
662+
)
663+
polygon(200, 50, -pt[0], pt[1], 200 - d1, 50)
664+
if (vv.open && vv.open_t == 1 && !touch_left()) {
665+
ctx.globalAlpha = 0.2
666+
ctx.strokeStyle = "#222"
667+
if (in_ca && !in_ab && !in_bc)
668+
{ hand(), line(200, 0, -200, 0) }
669+
if (in_ab && !in_ca && !in_bc)
670+
{ hand(), line(-200, 0, 0, h) }
671+
if (in_bc && !in_ab && !in_ca)
672+
{ hand(), line(0, h, 200, 0) }
673+
ctx.globalAlpha = 1
674+
}
550675

551676
if (vv.atoms[3].fill)
552677
ad.call({ ...vv.atoms[3], x: -200, y: 0, r: 50 }, true)
@@ -560,10 +685,43 @@
560685
ctx.translate(-300 * slide_t, 0)
561686
ctx.rotate(pi / 2 * roll_t)
562687
ctx.translate(0, -mid)
688+
m = ctx.getTransform().inverse()
689+
;({ x: mx, y: my } = m.transformPoint(mouse))
690+
in_ca = dist(mx, my, ...point_onto_line(
691+
mx, my, 200, 0, -200, 0
692+
)) < 50
693+
in_ab = dist(mx, my, ...point_onto_line(
694+
mx, my, -200, 0, 0, h
695+
)) < 50
696+
in_bc = dist(mx, my, ...point_onto_line(
697+
mx, my, 0, h, 200, 0
698+
)) < 50
563699
ctx.lineWidth = 100
564-
line(-200, 0, 200, 0, "#4d3b34")
565-
line(-200, 0, 0, h, "#47352f")
566-
line(0, h, 200, 0)
700+
line(200, 0, -200, 0, bcol[vv.bonds[0]])
701+
line(-200, 0, 0, h, bcol[vv.bonds[1]])
702+
line(0, h, 200, 0, bcol[vv.bonds[2]])
703+
ctx.fillStyle = bcol[1]
704+
circle(-200, 0, 50)
705+
circle(0, h, 50)
706+
circle(200, 0, 50)
707+
polygon(-200, 50, ...pt, -200 + d1, 50)
708+
polygon(
709+
...rvec(0, h, 50, 0, -pi / 6),
710+
...rvec(0, h, 50, 0, -5 * pi / 6),
711+
0, h - d2,
712+
)
713+
polygon(200, 50, -pt[0], pt[1], 200 - d1, 50)
714+
if (vv.open && vv.open_t == 1 && !touch_left()) {
715+
ctx.globalAlpha = 0.2
716+
ctx.strokeStyle = "#222"
717+
if (in_ca && !in_ab && !in_bc)
718+
{ hand(), line(200, 0, -200, 0) }
719+
if (in_ab && !in_ca && !in_bc)
720+
{ hand(), line(-200, 0, 0, h) }
721+
if (in_bc && !in_ab && !in_ca)
722+
{ hand(), line(0, h, 200, 0) }
723+
ctx.globalAlpha = 1
724+
}
567725

568726
if (vv.atoms[0].fill)
569727
ad.call({ ...vv.atoms[0], x: -200, y: 0, r: 50 }, true)
@@ -578,8 +736,8 @@
578736
let s = lerp(1, 1.6, btn_slide_t)
579737
ctx.scale(s, s)
580738

581-
let m = ctx.getTransform().inverse()
582-
let { x: mx, y: my } = m.transformPoint(mouse)
739+
m = ctx.getTransform().inverse()
740+
;({ x: mx, y: my } = m.transformPoint(mouse))
583741

584742
for (let b of Object.values(vv.btns))
585743
ad.call(b, false, mx, my)

0 commit comments

Comments
 (0)