Initial commit
This commit is contained in:
54
canvas/initial.js
Normal file
54
canvas/initial.js
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
// Reset transform
|
||||||
|
C.setTransform(1, 0, 0, 1, 0, 0);
|
||||||
|
|
||||||
|
// Clear canvas
|
||||||
|
C.clearRect(0, 0, W, H);
|
||||||
|
|
||||||
|
// Reset common properties
|
||||||
|
C.globalCompositeOperation = 'source-over';
|
||||||
|
C.fillStyle = 'rgba(255,200,100,1)';
|
||||||
|
C.strokeStyle = 'rgba(0,0,0,1)';
|
||||||
|
|
||||||
|
|
||||||
|
// Set up transform to map -1,-1..1,1 to canvas with aspect fit
|
||||||
|
const aspect = W / H;
|
||||||
|
const scale = aspect >= 1 ? H / 2 : W / 2;
|
||||||
|
const offsetX = W / 2;
|
||||||
|
const offsetY = H / 2;
|
||||||
|
|
||||||
|
//Apply transform
|
||||||
|
C.translate(offsetX, offsetY);
|
||||||
|
C.scale(scale, -scale);
|
||||||
|
|
||||||
|
|
||||||
|
function drawShapeSetOperation(op) {
|
||||||
|
// Define shapes in normalized space
|
||||||
|
const shape1 = new Path2D();
|
||||||
|
const shape2 = new Path2D();
|
||||||
|
|
||||||
|
// Shape 1: Circle centered left
|
||||||
|
shape1.arc(-0.3, 0, 0.5, 0, Math.PI * 2);
|
||||||
|
|
||||||
|
// Shape 2: Circle centered right
|
||||||
|
shape2.arc(0.3, 0, 0.5, 0, Math.PI * 2);
|
||||||
|
|
||||||
|
// Fill shapes with set operation
|
||||||
|
C.fillStyle = 'rgb(0, 128, 255)';
|
||||||
|
C.fill(shape1);
|
||||||
|
|
||||||
|
C.globalCompositeOperation = op; // e.g., 'source-in', 'xor', etc.
|
||||||
|
C.fillStyle = 'rgb(255, 0, 128)';
|
||||||
|
C.fill(shape2);
|
||||||
|
|
||||||
|
C.globalCompositeOperation = 'source-over';
|
||||||
|
|
||||||
|
// Scale lineWidth based on transform scale
|
||||||
|
const lineScale = 2 / scale;
|
||||||
|
C.lineWidth = lineScale;
|
||||||
|
C.strokeStyle = 'black';
|
||||||
|
C.stroke(shape1);
|
||||||
|
C.stroke(shape2);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
drawShapeSetOperation('xor');
|
||||||
134
canvas/test1.html
Normal file
134
canvas/test1.html
Normal file
@@ -0,0 +1,134 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<title>Test</title>
|
||||||
|
<script src="../lib/cm6.bundle.min.js"></script>
|
||||||
|
<!-- https://github.com/RPGillespie6/codemirror-quickstart -->
|
||||||
|
|
||||||
|
<script type="module">
|
||||||
|
|
||||||
|
document.addEventListener('DOMContentLoaded', async () => {
|
||||||
|
|
||||||
|
const initial_code = await (await fetch('initial.js')).text();
|
||||||
|
const initialState = cm6.createEditorState(initial_code);
|
||||||
|
const editor = document.getElementById("editor");
|
||||||
|
const view = cm6.createEditorView(initialState, editor);
|
||||||
|
|
||||||
|
const run_button = document.getElementById("run");
|
||||||
|
|
||||||
|
const canvas = document.getElementById("canvas");
|
||||||
|
const context = canvas.getContext('2d');
|
||||||
|
const auto_run_cb = document.getElementById("auto_run");
|
||||||
|
|
||||||
|
|
||||||
|
function run_experiment() {
|
||||||
|
const code = view.state.doc.toString();
|
||||||
|
const code_to_run = `(canvas, context, code) => {
|
||||||
|
const C = context;
|
||||||
|
const W = canvas.width;
|
||||||
|
const H = canvas.height;
|
||||||
|
|
||||||
|
${code}
|
||||||
|
}`;
|
||||||
|
eval(code_to_run)(canvas, context, code);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
document.addEventListener('keydown', (event) => {
|
||||||
|
if (event.altKey && event.key.toLowerCase() === 'r') {
|
||||||
|
event.preventDefault(); // Prevent any default behavior
|
||||||
|
run_experiment();
|
||||||
|
}
|
||||||
|
if (event.altKey && event.key.toLowerCase() === 'a') {
|
||||||
|
event.preventDefault(); // Prevent any default behavior
|
||||||
|
auto_run_cb.checked = !auto_run_cb.checked;
|
||||||
|
auto_run_cb.dispatchEvent(new Event("change"));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
run_button.addEventListener('click', (event) => {
|
||||||
|
run_experiment();
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
const observer = new MutationObserver(() => {
|
||||||
|
run_experiment();
|
||||||
|
});
|
||||||
|
|
||||||
|
auto_run_cb.addEventListener("change", (e) => {
|
||||||
|
const enabled = e.target.checked;
|
||||||
|
if (enabled) {
|
||||||
|
observer.observe(editor, { characterData: true, attributes: false, childList: false, subtree: true });
|
||||||
|
} else {
|
||||||
|
observer.disconnect();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
run_experiment();
|
||||||
|
|
||||||
|
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
<style>
|
||||||
|
kbd {
|
||||||
|
border: 1px #CCC outset;
|
||||||
|
padding: 0em 0.2em;
|
||||||
|
border-radius: 0.3em;
|
||||||
|
margin: 0.2em;
|
||||||
|
background-color: #EEE;
|
||||||
|
box-shadow: 0.2em 0.2em 0.5em rgba(0,0,0,0.5);
|
||||||
|
}
|
||||||
|
.toolbar {
|
||||||
|
padding: .5em 0em;
|
||||||
|
background-color: #EEF;
|
||||||
|
}
|
||||||
|
#run {
|
||||||
|
border-radius: 0.5em;
|
||||||
|
padding: 0.25em .5em;
|
||||||
|
margin-right: 1em;
|
||||||
|
background-color: #CFC;
|
||||||
|
}
|
||||||
|
|
||||||
|
html, body {
|
||||||
|
height: 100%;
|
||||||
|
margin: 0;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
#canvas {
|
||||||
|
margin: 0.5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
body > .top {
|
||||||
|
flex: 0 0 auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
body > .view {
|
||||||
|
flex: 1 1 auto;
|
||||||
|
overflow-y: auto;
|
||||||
|
min-height: 0; /* prevents flex from over-expanding */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="top">
|
||||||
|
<canvas id="canvas" style="border: 3px #BBF solid;"></canvas>
|
||||||
|
<div class="toolbar">
|
||||||
|
<button id="run">Run</button>(<kbd>Alt</kbd><kbd>R</kbd>)
|
||||||
|
<input type="checkbox" id="auto_run"><label for="auto_run">Auto run <kbd>Alt</kbd><kbd>A</kbd></label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="view">
|
||||||
|
<div id="editor"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
13
index.html
Normal file
13
index.html
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>Simple tools</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
<a href="canvas/test1.html">Simple canvas playground</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
1
lib/cm6.bundle.min.js
vendored
Normal file
1
lib/cm6.bundle.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user