77724af76c
Change-Id: I337f4dff10f30aa248ebc520449f3b763ede0ed8 Reviewed-on: https://skia-review.googlesource.com/c/skia/+/414096 Reviewed-by: Mike Reed <reed@google.com>
166 lines
5.9 KiB
HTML
166 lines
5.9 KiB
HTML
<!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://particles.skia.org/dist/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://particles.skia.org/dist/'+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>
|