blob: 4e186bb1b9dde97bc661199def4113ea255dbe27 [file] [log] [blame]
<!DOCTYPE html>
<title>TextEdit demo in CanvasKit</title>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script type="text/javascript" src="https://unpkg.com/canvaskit-wasm@0.34.1/bin/full/canvaskit.js"></script>
<script type="text/javascript" src="textapi_utils.js"></script>
<script type="text/javascript" src="spiralshader.js"></script>
<style>
canvas {
border: 1px dashed grey;
}
</style>
<body>
<h1>TextEdit in CanvasKit</h1>
<canvas id=para2 width=600 height=600 tabindex='-1'></canvas>
</body>
<script type="text/javascript" charset="utf-8">
let CanvasKit;
onload = async () => {
CanvasKit = await CanvasKitInit({ locateFile: (file) => 'https://unpkg.com/canvaskit-wasm@0.34.1/bin/full/'+file });
ParagraphAPI2();
};
function ParagraphAPI2() {
const surface = CanvasKit.MakeCanvasSurface('para2');
if (!surface) {
console.error('Could not make surface');
return;
}
const mouse = MakeMouse();
const cursor = MakeCursor(CanvasKit);
const canvas = surface.getCanvas();
const spiralEffect = MakeSpiralShaderEffect(CanvasKit);
const text0 = "In a hole in the ground there lived a hobbit. Not a nasty, dirty, " +
"wet hole full of worms and oozy smells. This was a hobbit-hole and " +
"that means good food, a warm hearth, and all the comforts of home.";
const LOC_X = 20,
LOC_Y = 20;
const bgPaint = new CanvasKit.Paint();
bgPaint.setColor([0.965, 0.965, 0.965, 1]);
const editor = MakeEditor(text0, {typeface:null, size:30}, cursor, 540);
editor.applyStyleToRange({size:130}, 0, 1);
editor.applyStyleToRange({italic:true}, 38, 38+6);
editor.applyStyleToRange({color:[1,0,0,1]}, 5, 5+4);
editor.setXY(LOC_X, LOC_Y);
function drawFrame(canvas) {
const lines = editor.getLines();
canvas.clear(CanvasKit.WHITE);
if (mouse.isActive()) {
const pos = mouse.getPos(-LOC_X, -LOC_Y);
const a = lines_pos_to_index(lines, pos[0], pos[1]);
const b = lines_pos_to_index(lines, pos[2], pos[3]);
if (a === b) {
editor.setIndex(a);
} else {
editor.setIndices(a, b);
}
}
canvas.drawRect(editor.bounds(), bgPaint);
{
// update our animated shaders
const rad_scale = Math.sin(Date.now() / 5000) / 2;
const shader0 = spiralEffect.makeShader([
rad_scale,
editor.width()/2, editor.width()/2,
1,0,0,1, // color0
0,0,1,1 // color1
]);
editor.draw(canvas, [shader0]);
shader0.delete();
}
surface.requestAnimationFrame(drawFrame);
}
surface.requestAnimationFrame(drawFrame);
function interact(e) {
const type = e.type;
if (type === 'pointerup') {
mouse.setUp(e.offsetX, e.offsetY);
} else if (type === 'pointermove') {
mouse.setMove(e.offsetX, e.offsetY);
} else if (type === 'pointerdown') {
mouse.setDown(e.offsetX, e.offsetY);
}
};
function keyhandler(e) {
switch (e.key) {
case 'ArrowLeft': editor.moveDX(-1); return;
case 'ArrowRight': editor.moveDX(1); return;
case 'ArrowUp':
e.preventDefault();
editor.moveDY(-1);
return;
case 'ArrowDown':
e.preventDefault();
editor.moveDY(1);
return;
case 'Backspace':
editor.deleteSelection(-1);
return;
case 'Delete':
editor.deleteSelection(1);
return;
case 'Shift':
return;
case 'Tab': // todo: figure out how to handle...
e.preventDefault();
return;
}
if (e.ctrlKey) {
e.preventDefault();
e.stopImmediatePropagation();
switch (e.key) {
case 'r': editor.applyStyleToSelection({color:[1,0,0,1]}); return;
case 'g': editor.applyStyleToSelection({color:[0,0.6,0,1]}); return;
case 'u': editor.applyStyleToSelection({color:[0,0,1,1]}); return;
case 'k': editor.applyStyleToSelection({color:[0,0,0,1]}); return;
case 's': editor.applyStyleToSelection({shaderIndex:0}); return;
case 'i': editor.applyStyleToSelection({italic:'toggle'}); return;
case 'b': editor.applyStyleToSelection({bold:'toggle'}); return;
case 'w': editor.applyStyleToSelection({wavy:'toggle'}); return;
case ']': editor.applyStyleToSelection({size_add:1}); return;
case '[': editor.applyStyleToSelection({size_add:-1}); return;
case '}': editor.applyStyleToSelection({size_add:10}); return;
case '{': editor.applyStyleToSelection({size_add:-10}); return;
}
}
if (!e.ctrlKey && !e.metaKey) {
if (e.key.length == 1) { // avoid keys like "Escape" for now
e.preventDefault();
e.stopImmediatePropagation();
editor.insert(e.key);
}
}
}
document.getElementById('para2').addEventListener('pointermove', interact);
document.getElementById('para2').addEventListener('pointerdown', interact);
document.getElementById('para2').addEventListener('pointerup', interact);
document.getElementById('para2').addEventListener('keydown', keyhandler);
return surface;
}
</script>