(node)
| 622 | } |
| 623 | |
| 624 | function render(node) { |
| 625 | const ed = node._ed; |
| 626 | const ctx = ed.ctx; |
| 627 | const c = ed.canvas; |
| 628 | |
| 629 | ctx.clearRect(0, 0, c.width, c.height); |
| 630 | |
| 631 | // Background image |
| 632 | if (ed.bgImg) { |
| 633 | const s = getScale(node); |
| 634 | ctx.globalAlpha = 0.85; |
| 635 | ctx.drawImage(ed.bgImg, 0, 0, ed.imgW * s, ed.imgH * s); |
| 636 | ctx.globalAlpha = 1.0; |
| 637 | } |
| 638 | |
| 639 | const samplesW = node.widgets.find((w) => w.name === "points_to_sample"); |
| 640 | const numSamples = samplesW ? samplesW.value : 121; |
| 641 | const dpr = window.devicePixelRatio || 1; |
| 642 | |
| 643 | // Draw each spline |
| 644 | for (let si = 0; si < ed.splines.length; si++) { |
| 645 | const isActive = si === ed.active; |
| 646 | const color = SPLINE_COLORS[si % SPLINE_COLORS.length]; |
| 647 | const spline = ed.splines[si]; |
| 648 | |
| 649 | // Interpolated curve |
| 650 | if (spline.length >= 2) { |
| 651 | const curve = interpolateSpline(spline, Math.max(numSamples, 60)); |
| 652 | ctx.beginPath(); |
| 653 | const p0 = imgToCanvas(node, curve[0]); |
| 654 | ctx.moveTo(p0.x, p0.y); |
| 655 | for (let i = 1; i < curve.length; i++) { |
| 656 | const p = imgToCanvas(node, curve[i]); |
| 657 | ctx.lineTo(p.x, p.y); |
| 658 | } |
| 659 | ctx.strokeStyle = color; |
| 660 | ctx.lineWidth = (isActive ? CURVE_LINE_WIDTH * 1.4 : CURVE_LINE_WIDTH) * dpr; |
| 661 | ctx.globalAlpha = isActive ? 1.0 : 0.5; |
| 662 | ctx.stroke(); |
| 663 | ctx.globalAlpha = 1.0; |
| 664 | } |
| 665 | |
| 666 | // Control points |
| 667 | for (let pi = 0; pi < spline.length; pi++) { |
| 668 | const cp = imgToCanvas(node, spline[pi]); |
| 669 | const isHov = ed.hover && ed.hover.si === si && ed.hover.pi === pi; |
| 670 | const isDrag = ed.drag && ed.drag.si === si && ed.drag.pi === pi; |
| 671 | const baseR = |
| 672 | isHov || isDrag |
| 673 | ? ACTIVE_POINT_RADIUS |
| 674 | : isActive |
| 675 | ? POINT_RADIUS |
| 676 | : POINT_RADIUS * 0.8; |
| 677 | const r = baseR * dpr; |
| 678 | |
| 679 | // Outer ring |
| 680 | ctx.beginPath(); |
| 681 | ctx.arc(cp.x, cp.y, r + 2 * dpr, 0, Math.PI * 2); |
no test coverage detected