Skip to content

Commit

Permalink
Initial version of quiver
Browse files Browse the repository at this point in the history
A graphical editor for commutative diagrams that exports to tikzcd. This
version contains the following features:
- 0-cell (object), 1-cell (morphism) and 2-cell (natural transformation)
  placement.
- Repositioning cells.
- Connecting cells.
- MathJax labels.
- Smart label alignment.
- tikzcd output.
  • Loading branch information
varkor committed Dec 28, 2018
0 parents commit 194a455
Show file tree
Hide file tree
Showing 4 changed files with 1,796 additions and 0 deletions.
1 change: 1 addition & 0 deletions MathJax
Submodule MathJax added at 419b0a
13 changes: 13 additions & 0 deletions index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>quiver</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" type="text/css" media="screen" href="main.css" />
<script type="text/javascript" src="ui.js"></script>
<script type="text/javascript" async src="MathJax/MathJax.js"></script>
</head>
<body>
</body>
</html>
280 changes: 280 additions & 0 deletions main.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,280 @@
/* Root styles */

*, *::before, *::after {
box-sizing: border-box;
}

:root {
/* Cell attributes. */
--cell-size: 64px;
/* Cell states. */
--cell-hover: hsla(0, 0%, 0%, 0.1);
--cell-selected: hsla(0, 0%, 0%, 0.2);
--cell-source: hsla(0, 0%, 0%, 0.2);
--cell-target: hsla(0, 0%, 0%, 0.2);
}

body {
position: absolute;
width: 100%; height: 100%;
margin: 0;

background-color: white;
background-size: var(--cell-size) var(--cell-size);
}

/* Special elements */

.MathJax_SVG {
outline: none;
}

/* Grid interaction */

.insertion-point {
display: block;
position: absolute;
width: var(--cell-size); height: var(--cell-size);
transform: translate(-50%, -50%);

background: hsla(0, 0%, 0%, 0);

text-align: center;
font: 16px sans-serif;
line-height: var(--cell-size);
color: hsla(0, 0%, 0%, 0.4);
}

.insertion-point.revealed {
background: hsla(0, 0%, 0%, 0.1);
}

.insertion-point::before {
content: "Add vertex";
visibility: hidden;
}

.insertion-point.revealed::before {
visibility: visible;
}

/* Vertices */

.vertex {
position: absolute;
width: var(--cell-size); height: var(--cell-size);
transform: translate(-50%, -50%);
}

.ui:not(.connect) .vertex {
cursor: move;
}

.vertex .content {
position: absolute;
width: calc(var(--cell-size) / 2); height: calc(var(--cell-size) / 2);
left: calc(var(--cell-size) / 2); top: calc(var(--cell-size) / 2);
transform: translate(-50%, -50%);

border-radius: 100%;

line-height: calc(var(--cell-size) / 2);
text-align: center;

cursor: default;
}

/* This is so explicit because of the CSS specificity rules. */
.ui:not(.connect):not(.move) .vertex:not(.selected):not(.source):not(.target) .content:hover {
background: var(--cell-hover);
}

.vertex.source .content {
background: var(--cell-source);
}

.vertex.target .content {
background: var(--cell-target);
}

.vertex.selected .content {
background: var(--cell-selected);
}

.label {
display: block;
position: absolute;
left: 50%; top: 50%;
transform: translate(-50%, -50%);

text-align: center;
font-size: 26px;

pointer-events: none;

transition: opacity 0.2s;
}

.label.buffer {
visibility: hidden;
}

/* Edges */

.edge {
position: absolute;
}

.edge > svg {
position: absolute;
left: 50%; top: 50%;
transform: translate(-50%, -50%);
}

/* The overlay edge drawn while connecting cells. */
.overlay {
pointer-events: none;
}

/* This is so explicit because of the CSS specificity rules. */
.ui:not(.connect):not(.move) .edge:hover:not(.selected):not(.source):not(.target) {
background: var(--cell-hover);
}

.edge.source {
background: var(--cell-source);
}

.edge.target {
background: var(--cell-target);
}

.edge.selected {
background: var(--cell-selected);
}

.edge .label {
font-size: 20px;
text-align: right;
}

/* The side panel */

.panel {
position: fixed;
width: 20%; height: 100%;
right: 0;
z-index: 1;
padding: 24px 16px;

background: hsl(0, 0%, 20%);

font: 14px sans-serif;
color: hsl(0, 0%, 80%);
}

.panel input[type="text"] {
padding: 2px 4px;

background: hsl(0, 0%, 16%);
border: hsl(0, 0%, 28%) solid 1px;
border-radius: 2px;
outline: none;

font-size: inherit;
font-family: monospace;
color: hsl(0, 0%, 96%);
}

.panel input[type="text"]:hover {
background: hsl(0, 0%, 18%);
}

.panel input[type="text"]:focus {
background: hsl(0, 0%, 96%);
border-color: hsl(200, 100%, 40%);

color: hsl(0, 0%, 16%);
}

.panel input[type="text"]:disabled {
background: hsl(0, 0%, 20%);
}

.panel .options {
margin: 8px 0;

text-align: center;
}

.panel input[type="radio"] {
-webkit-appearance: none;
display: inline-block;
width: 48px; height: 48px;

background-color: hsl(0, 0%, 16%);
background-repeat: no-repeat;
background-position: center;
/* We use stacked backgrounds for the background image, */
/* to allow us to change the image directly via CSS. */
background-size: 0%, 100%;
border: hsl(0, 0%, 28%) solid 1px;
border-radius: 2px;
outline: none;
}

.panel input[type="radio"]:hover {
background-color: hsl(0, 0%, 18%);
}

.panel input[type="radio"]:checked {
background-color: hsl(0, 0%, 96%);
background-size: 100%, 0%;
border-color: hsl(200, 100%, 40%);
}

.panel input[type="radio"]:disabled {
background-size: 0%, 100%;
background-color: hsl(0, 0%, 20%);
border-color: hsl(0, 0%, 28%);
}

.panel button {
display: block;
position: absolute;
width: calc(100% - 8px * 2); height: 30px;
left: 8px; bottom: 8px;

background: transparent;
border: transparent solid 1px;
border-radius: 2px;
outline: none;

font: inherit;
color: hsl(0, 0%, 96%);
}

.panel button:hover {
background: hsl(0, 0%, 24%);
border-color: hsl(0, 0%, 36%);
}

.panel button:active {
background: hsl(0, 0%, 16%);
border-color: hsl(0, 0%, 36%);
}

.export {
position: fixed;
width: 80%; height: 100%;
left: 0;
z-index: 1;
padding: 20px 24px;

background: hsla(0, 0%, 10%, 0.8);
white-space: pre-wrap;
tab-size: 4;

font: 16px monospace;
color: white;
}
Loading

0 comments on commit 194a455

Please sign in to comment.