-
Skwik
-
+
+
+
+
+ Skwik
+
+ Perspective Correction
+
+
@@ -32,5 +56,18 @@ const store = useAppStore()
+
+
+ Made by
+ Samuel Prevost
+
diff --git a/src/assets/index.css b/src/assets/index.css
index 95d3120..adfd569 100644
--- a/src/assets/index.css
+++ b/src/assets/index.css
@@ -1,4 +1,5 @@
-@import url("https://fonts.googleapis.com/css2?family=Geist:wght@400;500;600;700&display=swap");
+
+@import url('https://fonts.googleapis.com/css2?family=Geist:wght@400;500;600;700&display=swap');
@import "tailwindcss";
@@ -9,7 +10,8 @@
@custom-variant dark (&:is(.dark *));
@theme inline {
- --font-sans: "Geist Variable", sans-serif;
+ --font-sans: "Geist", "Geist Variable", ui-sans-serif, sans-serif;
+ --font-mono: "Geist Mono", ui-monospace, monospace;
--font-heading: var(--font-sans);
--color-sidebar-ring: var(--sidebar-ring);
--color-sidebar-border: var(--sidebar-border);
@@ -84,10 +86,10 @@
}
.dark {
- --background: oklch(0.145 0 0);
- --foreground: oklch(0.985 0 0);
- --card: oklch(0.205 0 0);
- --card-foreground: oklch(0.985 0 0);
+ --background: oklch(0.13 0 0);
+ --foreground: oklch(0.95 0 0);
+ --card: oklch(0.175 0 0);
+ --card-foreground: oklch(0.95 0 0);
--popover: oklch(0.205 0 0);
--popover-foreground: oklch(0.985 0 0);
--primary: oklch(0.922 0 0);
@@ -99,7 +101,7 @@
--accent: oklch(0.269 0 0);
--accent-foreground: oklch(0.985 0 0);
--destructive: oklch(0.704 0.191 22.216);
- --border: oklch(1 0 0 / 10%);
+ --border: oklch(1 0 0 / 12%);
--input: oklch(1 0 0 / 15%);
--ring: oklch(0.556 0 0);
--chart-1: oklch(0.87 0 0);
@@ -126,3 +128,63 @@
@apply font-sans;
}
}
+
+/* Fork-me ribbon — adapted from github-fork-ribbon-css */
+.github-fork-ribbon {
+ width: 12.1em;
+ height: 12.1em;
+ overflow: hidden;
+ position: fixed;
+ top: 0;
+ left: 0;
+ z-index: 100;
+ pointer-events: none;
+ text-decoration: none;
+ text-indent: -999em;
+ font-size: 0.85em;
+}
+
+.github-fork-ribbon::before,
+.github-fork-ribbon::after {
+ position: absolute;
+ display: block;
+ width: 15.38em;
+ height: 1.54em;
+ top: 3.23em;
+ right: 0.5em;
+ box-sizing: content-box;
+ transform: rotate(-45deg);
+}
+
+.github-fork-ribbon::before {
+ content: "";
+ padding: 0.38em 0;
+ background-color: #2d7a2e;
+ background-image: linear-gradient(
+ to bottom,
+ rgba(255, 255, 255, 0.05),
+ rgba(0, 0, 0, 0.15)
+ );
+ box-shadow:
+ 0 0.15em 0.23em 0 rgba(0, 0, 0, 0.5),
+ 0 0 0 1px #5cb85c,
+ inset 0 1px 0 rgba(255, 255, 255, 0.2),
+ inset 0 -1px 0 rgba(0, 0, 0, 0.2);
+ border-top: 1px dashed rgba(255, 255, 255, 0.25);
+ border-bottom: 1px dashed rgba(255, 255, 255, 0.25);
+ pointer-events: auto;
+}
+
+.github-fork-ribbon::after {
+ content: attr(data-ribbon);
+ color: #fff;
+ font: 700 0.9em "Helvetica Neue", Helvetica, Arial, sans-serif;
+ line-height: 1.54em;
+ text-decoration: none;
+ text-align: center;
+ text-indent: 0;
+ text-shadow:
+ 0 -1px 0 rgba(0, 0, 0, 0.5),
+ 0 1px 2px rgba(0, 0, 0, 0.3);
+ pointer-events: auto;
+}
diff --git a/src/components/DatumCanvas.vue b/src/components/DatumCanvas.vue
index 37ccd70..1b7a65f 100644
--- a/src/components/DatumCanvas.vue
+++ b/src/components/DatumCanvas.vue
@@ -49,19 +49,23 @@ function getPointConfigs(datum: Datum, dIdx: number) {
const color = getDatumColor(dIdx)
const isSelected = store.selectedDatumId === datum.id
const points = datum.type === "rectangle" ? datum.corners : datum.endpoints
- const radius = isSelected ? 10 : 7
+ const baseRadius = isSelected ? 6 : 4
+ const visualRadius = Math.max(
+ baseRadius / scale.value,
+ baseRadius * 0.5
+ )
return points.map((pt, pIdx) => ({
x: pt.x,
y: pt.y,
- radius: radius / scale.value,
+ radius: visualRadius,
fill: color,
stroke: isSelected ? "#fff" : color,
- strokeWidth: 2 / scale.value,
+ strokeWidth: 1.5 / scale.value,
draggable: true,
_datumId: datum.id,
_pointIndex: pIdx,
- hitStrokeWidth: 20 / scale.value,
+ hitStrokeWidth: 12 / scale.value,
}))
}
diff --git a/src/components/DatumEditor.vue b/src/components/DatumEditor.vue
index 9eed111..6d0c431 100644
--- a/src/components/DatumEditor.vue
+++ b/src/components/DatumEditor.vue
@@ -1,7 +1,9 @@
@@ -77,6 +89,16 @@ const nextTooltip = computed(() => {