Skip to content
This repository has been archived by the owner on Aug 10, 2022. It is now read-only.

Commit

Permalink
Add Gradient
Browse files Browse the repository at this point in the history
  • Loading branch information
schmidsi committed Mar 17, 2021
1 parent f884202 commit 5cbd858
Show file tree
Hide file tree
Showing 3 changed files with 189 additions and 18 deletions.
86 changes: 86 additions & 0 deletions gradient-path.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
<!DOCTYPE html>
<meta charset="utf-8">
<svg width="960" height="500">
<path fill="none" stroke-width="10" stroke="black" d="
M86,388
L203,330
C320,272,554,156,673.8333333333334,165.83333333333334
C793.6666666666666,175.66666666666666,799.3333333333334,311.3333333333333,683.5,316.6666666666667
C567.6666666666666,322,330.3333333333333,197,211.66666666666666,134.5
L93,72"></path>
</svg>
<script src="http://d3js.org/d3.v4.min.js"></script>
<script>

var color = d3.interpolateRainbow;

var path = d3.select("path").remove();

d3.select("svg").selectAll("path")
.data(quads(samples(path.node(), 8)))
.enter().append("path")
.style("fill", function(d) { console.log(d); return color(d.t); })
.style("stroke", function(d) { return color(d.t); })
.attr("d", function(d) { return lineJoin(d[0], d[1], d[2], d[3], 32); });

// Sample the SVG path uniformly with the specified precision.
function samples(path, precision) {
var n = path.getTotalLength(), t = [0], i = 0, dt = precision;
while ((i += dt) < n) t.push(i);
t.push(n);
return t.map(function(t) {
var p = path.getPointAtLength(t), a = [p.x, p.y];
a.t = t / n;
return a;
});
}

// Compute quads of adjacent points [p0, p1, p2, p3].
function quads(points) {
return d3.range(points.length - 1).map(function(i) {
var a = [points[i - 1], points[i], points[i + 1], points[i + 2]];
a.t = (points[i].t + points[i + 1].t) / 2;
return a;
});
}

// Compute stroke outline for segment p12.
function lineJoin(p0, p1, p2, p3, width) {
var u12 = perp(p1, p2),
r = width / 2,
a = [p1[0] + u12[0] * r, p1[1] + u12[1] * r],
b = [p2[0] + u12[0] * r, p2[1] + u12[1] * r],
c = [p2[0] - u12[0] * r, p2[1] - u12[1] * r],
d = [p1[0] - u12[0] * r, p1[1] - u12[1] * r];

if (p0) { // clip ad and dc using average of u01 and u12
var u01 = perp(p0, p1), e = [p1[0] + u01[0] + u12[0], p1[1] + u01[1] + u12[1]];
a = lineIntersect(p1, e, a, b);
d = lineIntersect(p1, e, d, c);
}

if (p3) { // clip ab and dc using average of u12 and u23
var u23 = perp(p2, p3), e = [p2[0] + u23[0] + u12[0], p2[1] + u23[1] + u12[1]];
b = lineIntersect(p2, e, a, b);
c = lineIntersect(p2, e, d, c);
}

return "M" + a + "L" + b + " " + c + " " + d + "Z";
}

// Compute intersection of two infinite lines ab and cd.
function lineIntersect(a, b, c, d) {
var x1 = c[0], x3 = a[0], x21 = d[0] - x1, x43 = b[0] - x3,
y1 = c[1], y3 = a[1], y21 = d[1] - y1, y43 = b[1] - y3,
ua = (x43 * (y1 - y3) - y43 * (x1 - x3)) / (y43 * x21 - x43 * y21);
return [x1 + ua * x21, y1 + ua * y21];
}

// Compute unit vector perpendicular to p01.
function perp(p0, p1) {
var u01x = p0[1] - p1[1], u01y = p1[0] - p0[0],
u01d = Math.sqrt(u01x * u01x + u01y * u01y);
return [u01x / u01d, u01y / u01d];
}

</script>
2 changes: 0 additions & 2 deletions storefront/components/Layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,6 @@ const Layout = (props) => {
balance,
} = useAppContext();

console.log(balance);

return (
<div className="page-layout">
<div className="container">
Expand Down
119 changes: 103 additions & 16 deletions storefront/components/LissajousSvg.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,81 @@ import React, { useEffect, useRef } from 'react';
import * as d3 from 'd3';
import type { LissajousArgs } from '@private/contracts';

// Sample the SVG path uniformly with the specified precision.
function samples(path, precision) {
let n = path.getTotalLength(),
t = [0],
i = 0,
dt = precision;
while ((i += dt) < n) t.push(i);
t.push(n);
return t.map(function (t) {
const p = path.getPointAtLength(t),
a = [p.x, p.y];
a.t = t / n;
return a;
});
}

// Compute quads of adjacent points [p0, p1, p2, p3].
function quads(points) {
return d3.range(points.length - 1).map(function (i) {
const a = [points[i - 1], points[i], points[i + 1], points[i + 2]];
a.t = (points[i].t + points[i + 1].t) / 2;
return a;
});
}

// Compute stroke outline for segment p12.
function lineJoin(p0, p1, p2, p3, width) {
let u12 = perp(p1, p2),
r = width / 2,
a = [p1[0] + u12[0] * r, p1[1] + u12[1] * r],
b = [p2[0] + u12[0] * r, p2[1] + u12[1] * r],
c = [p2[0] - u12[0] * r, p2[1] - u12[1] * r],
d = [p1[0] - u12[0] * r, p1[1] - u12[1] * r];

if (p0) {
// clip ad and dc using average of u01 and u12
var u01 = perp(p0, p1),
e = [p1[0] + u01[0] + u12[0], p1[1] + u01[1] + u12[1]];
a = lineIntersect(p1, e, a, b);
d = lineIntersect(p1, e, d, c);
}

if (p3) {
// clip ab and dc using average of u12 and u23
var u23 = perp(p2, p3),
e = [p2[0] + u23[0] + u12[0], p2[1] + u23[1] + u12[1]];
b = lineIntersect(p2, e, a, b);
c = lineIntersect(p2, e, d, c);
}

return 'M' + a + 'L' + b + ' ' + c + ' ' + d + 'Z';
}

// Compute intersection of two infinite lines ab and cd.
function lineIntersect(a, b, c, d) {
const x1 = c[0],
x3 = a[0],
x21 = d[0] - x1,
x43 = b[0] - x3,
y1 = c[1],
y3 = a[1],
y21 = d[1] - y1,
y43 = b[1] - y3,
ua = (x43 * (y1 - y3) - y43 * (x1 - x3)) / (y43 * x21 - x43 * y21);
return [x1 + ua * x21, y1 + ua * y21];
}

// Compute unit vector perpendicular to p01.
function perp(p0, p1) {
const u01x = p0[1] - p1[1],
u01y = p1[0] - p0[0],
u01d = Math.sqrt(u01x * u01x + u01y * u01y);
return [u01x / u01d, u01y / u01d];
}

const LissajousSvg = ({
frequenceX,
frequenceY,
Expand Down Expand Up @@ -31,8 +106,8 @@ const LissajousSvg = ({
const absoluteStartStep = (stepsUntilFull / numberOfSteps) * startStep;
const absoluteTotalSteps = (stepsUntilFull / numberOfSteps) * totalSteps;

const figureHeight = 512 - lineWidth - 4;
const figureWidht = 512 - lineWidth - 4;
const figureHeight = canvasHeight - lineWidth - 4;
const figureWidht = canvasWidth - lineWidth - 4;

const amplitudeX = width / 16 / 2;
const amplitudeY = height / 16 / 2;
Expand Down Expand Up @@ -67,22 +142,34 @@ const LissajousSvg = ({
const valueline = d3
.line()
.curve(d3.curveCatmullRomOpen)
.x((d: any) => d.x)
.x((d: any) => {
return d.x;
})
.y((d: any) => d.y);

svg
.append('path')
.datum(points)
.attr('d', valueline as any)
.attr('stroke', strokeColor)
.attr('stroke-width', lineWidth + 1)
.attr('fill', 'none')
.attr(
'transform',
`scale(${boundingRect.height / canvasHeight} ${
boundingRect.width / canvasWidth
})`,
);
const hslStart = d3.hsl(strokeColor);
const hslEnd = d3.hsl(hslStart.h - 120, hslStart.s, hslStart.l - 0.1);

console.log(hslStart);

console.log(hslEnd.formatHex(), strokeColor);

const interpolateHsl = d3.interpolateHslLong(hslEnd, strokeColor);
points.map((point, i) =>
svg
.append('path')
.datum(points.slice(i, i + 4))
.attr('d', valueline as any)
.style('stroke', interpolateHsl(i / absoluteTotalSteps))
.attr('stroke-width', lineWidth + 1)
.style('fill', interpolateHsl(i / absoluteTotalSteps))
.attr(
'transform',
`scale(${(boundingRect.height - 2) / canvasHeight} ${
(boundingRect.width - 2) / canvasWidth
})`,
),
);
}, [
frequenceX,
frequenceY,
Expand Down

0 comments on commit 5cbd858

Please sign in to comment.