|
| 1 | +import React, {useRef, useEffect} from 'react' |
| 2 | + |
| 3 | +export const CubicBezier = ({bezier}: {bezier: [number, number, number, number]}) => { |
| 4 | + const canvasRef = useRef(null) |
| 5 | + const padding = 20 |
| 6 | + const lineWidth = '6' |
| 7 | + const fillStart = 'purple' |
| 8 | + const fillEnd = 'blue' |
| 9 | + |
| 10 | + // Convert CSS cubic-bezier array to control points |
| 11 | + const [x1, y1, x2, y2] = bezier |
| 12 | + const p0 = {x: padding, y: 500 - padding} |
| 13 | + const p1 = { |
| 14 | + x: x1 * (500 - 2 * padding) + padding, |
| 15 | + y: 500 - (y1 * (500 - 2 * padding) + padding), |
| 16 | + } |
| 17 | + const p2 = { |
| 18 | + x: x2 * (500 - 2 * padding) + padding, |
| 19 | + y: 500 - (y2 * (500 - 2 * padding) + padding), |
| 20 | + } |
| 21 | + const p3 = {x: 500 - padding, y: padding} |
| 22 | + |
| 23 | + useEffect(() => { |
| 24 | + const canvas = canvasRef.current |
| 25 | + const ctx = canvas.getContext('2d') |
| 26 | + ctx.clearRect(0, 0, canvas.width, canvas.height) |
| 27 | + |
| 28 | + // Create gradient |
| 29 | + const gradient = ctx.createLinearGradient(p0.x, p0.y, p3.x, p3.y) |
| 30 | + gradient.addColorStop(0, fillStart) |
| 31 | + gradient.addColorStop(1, fillEnd) |
| 32 | + |
| 33 | + // Draw bezier curve |
| 34 | + ctx.strokeStyle = gradient |
| 35 | + ctx.lineWidth = lineWidth |
| 36 | + ctx.lineCap = 'round' |
| 37 | + ctx.beginPath() |
| 38 | + ctx.moveTo(p0.x, p0.y) |
| 39 | + ctx.bezierCurveTo(p1.x, p1.y, p2.x, p2.y, p3.x, p3.y) |
| 40 | + ctx.stroke() |
| 41 | + }, [p0, p1, p2, p3]) |
| 42 | + |
| 43 | + return <canvas ref={canvasRef} width={500} height={500} /> |
| 44 | +} |
0 commit comments