1cb93a386Sopenharmony_ci<!DOCTYPE html> 2cb93a386Sopenharmony_ci<title>TextEdit demo in CanvasKit</title> 3cb93a386Sopenharmony_ci<meta charset="utf-8" /> 4cb93a386Sopenharmony_ci<meta http-equiv="X-UA-Compatible" content="IE=edge"> 5cb93a386Sopenharmony_ci<meta name="viewport" content="width=device-width, initial-scale=1.0"> 6cb93a386Sopenharmony_ci<script type="text/javascript" src="https://particles.skia.org/dist/canvaskit.js"></script> 7cb93a386Sopenharmony_ci<script type="text/javascript" src="textapi_utils.js"></script> 8cb93a386Sopenharmony_ci<script type="text/javascript" src="spiralshader.js"></script> 9cb93a386Sopenharmony_ci 10cb93a386Sopenharmony_ci<style> 11cb93a386Sopenharmony_cicanvas { 12cb93a386Sopenharmony_ci border: 1px dashed grey; 13cb93a386Sopenharmony_ci} 14cb93a386Sopenharmony_ci</style> 15cb93a386Sopenharmony_ci 16cb93a386Sopenharmony_ci<body> 17cb93a386Sopenharmony_ci <h1>TextEdit in CanvasKit</h1> 18cb93a386Sopenharmony_ci 19cb93a386Sopenharmony_ci <canvas id=para2 width=600 height=600 tabindex='-1'></canvas> 20cb93a386Sopenharmony_ci</body> 21cb93a386Sopenharmony_ci 22cb93a386Sopenharmony_ci<script type="text/javascript" charset="utf-8"> 23cb93a386Sopenharmony_ci let CanvasKit; 24cb93a386Sopenharmony_ci onload = async () => { 25cb93a386Sopenharmony_ci CanvasKit = await CanvasKitInit({ locateFile: (file) => 'https://particles.skia.org/dist/'+file }); 26cb93a386Sopenharmony_ci ParagraphAPI2(); 27cb93a386Sopenharmony_ci }; 28cb93a386Sopenharmony_ci 29cb93a386Sopenharmony_ci function ParagraphAPI2() { 30cb93a386Sopenharmony_ci const surface = CanvasKit.MakeCanvasSurface('para2'); 31cb93a386Sopenharmony_ci if (!surface) { 32cb93a386Sopenharmony_ci console.error('Could not make surface'); 33cb93a386Sopenharmony_ci return; 34cb93a386Sopenharmony_ci } 35cb93a386Sopenharmony_ci 36cb93a386Sopenharmony_ci const mouse = MakeMouse(); 37cb93a386Sopenharmony_ci const cursor = MakeCursor(CanvasKit); 38cb93a386Sopenharmony_ci const canvas = surface.getCanvas(); 39cb93a386Sopenharmony_ci const spiralEffect = MakeSpiralShaderEffect(CanvasKit); 40cb93a386Sopenharmony_ci 41cb93a386Sopenharmony_ci const text0 = "In a hole in the ground there lived a hobbit. Not a nasty, dirty, " + 42cb93a386Sopenharmony_ci "wet hole full of worms and oozy smells. This was a hobbit-hole and " + 43cb93a386Sopenharmony_ci "that means good food, a warm hearth, and all the comforts of home."; 44cb93a386Sopenharmony_ci const LOC_X = 20, 45cb93a386Sopenharmony_ci LOC_Y = 20; 46cb93a386Sopenharmony_ci 47cb93a386Sopenharmony_ci const bgPaint = new CanvasKit.Paint(); 48cb93a386Sopenharmony_ci bgPaint.setColor([0.965, 0.965, 0.965, 1]); 49cb93a386Sopenharmony_ci 50cb93a386Sopenharmony_ci const editor = MakeEditor(text0, {typeface:null, size:30}, cursor, 540); 51cb93a386Sopenharmony_ci 52cb93a386Sopenharmony_ci editor.applyStyleToRange({size:130}, 0, 1); 53cb93a386Sopenharmony_ci editor.applyStyleToRange({italic:true}, 38, 38+6); 54cb93a386Sopenharmony_ci editor.applyStyleToRange({color:[1,0,0,1]}, 5, 5+4); 55cb93a386Sopenharmony_ci 56cb93a386Sopenharmony_ci editor.setXY(LOC_X, LOC_Y); 57cb93a386Sopenharmony_ci 58cb93a386Sopenharmony_ci function drawFrame(canvas) { 59cb93a386Sopenharmony_ci const lines = editor.getLines(); 60cb93a386Sopenharmony_ci 61cb93a386Sopenharmony_ci canvas.clear(CanvasKit.WHITE); 62cb93a386Sopenharmony_ci 63cb93a386Sopenharmony_ci if (mouse.isActive()) { 64cb93a386Sopenharmony_ci const pos = mouse.getPos(-LOC_X, -LOC_Y); 65cb93a386Sopenharmony_ci const a = lines_pos_to_index(lines, pos[0], pos[1]); 66cb93a386Sopenharmony_ci const b = lines_pos_to_index(lines, pos[2], pos[3]); 67cb93a386Sopenharmony_ci if (a === b) { 68cb93a386Sopenharmony_ci editor.setIndex(a); 69cb93a386Sopenharmony_ci } else { 70cb93a386Sopenharmony_ci editor.setIndices(a, b); 71cb93a386Sopenharmony_ci } 72cb93a386Sopenharmony_ci } 73cb93a386Sopenharmony_ci 74cb93a386Sopenharmony_ci canvas.drawRect(editor.bounds(), bgPaint); 75cb93a386Sopenharmony_ci 76cb93a386Sopenharmony_ci { 77cb93a386Sopenharmony_ci // update our animated shaders 78cb93a386Sopenharmony_ci const rad_scale = Math.sin(Date.now() / 5000) / 2; 79cb93a386Sopenharmony_ci const shader0 = spiralEffect.makeShader([ 80cb93a386Sopenharmony_ci rad_scale, 81cb93a386Sopenharmony_ci editor.width()/2, editor.width()/2, 82cb93a386Sopenharmony_ci 1,0,0,1, // color0 83cb93a386Sopenharmony_ci 0,0,1,1 // color1 84cb93a386Sopenharmony_ci ]); 85cb93a386Sopenharmony_ci editor.draw(canvas, [shader0]); 86cb93a386Sopenharmony_ci shader0.delete(); 87cb93a386Sopenharmony_ci } 88cb93a386Sopenharmony_ci 89cb93a386Sopenharmony_ci surface.requestAnimationFrame(drawFrame); 90cb93a386Sopenharmony_ci } 91cb93a386Sopenharmony_ci surface.requestAnimationFrame(drawFrame); 92cb93a386Sopenharmony_ci 93cb93a386Sopenharmony_ci function interact(e) { 94cb93a386Sopenharmony_ci const type = e.type; 95cb93a386Sopenharmony_ci if (type === 'pointerup') { 96cb93a386Sopenharmony_ci mouse.setUp(e.offsetX, e.offsetY); 97cb93a386Sopenharmony_ci } else if (type === 'pointermove') { 98cb93a386Sopenharmony_ci mouse.setMove(e.offsetX, e.offsetY); 99cb93a386Sopenharmony_ci } else if (type === 'pointerdown') { 100cb93a386Sopenharmony_ci mouse.setDown(e.offsetX, e.offsetY); 101cb93a386Sopenharmony_ci } 102cb93a386Sopenharmony_ci }; 103cb93a386Sopenharmony_ci 104cb93a386Sopenharmony_ci function keyhandler(e) { 105cb93a386Sopenharmony_ci switch (e.key) { 106cb93a386Sopenharmony_ci case 'ArrowLeft': editor.moveDX(-1); return; 107cb93a386Sopenharmony_ci case 'ArrowRight': editor.moveDX(1); return; 108cb93a386Sopenharmony_ci case 'ArrowUp': 109cb93a386Sopenharmony_ci e.preventDefault(); 110cb93a386Sopenharmony_ci editor.moveDY(-1); 111cb93a386Sopenharmony_ci return; 112cb93a386Sopenharmony_ci case 'ArrowDown': 113cb93a386Sopenharmony_ci e.preventDefault(); 114cb93a386Sopenharmony_ci editor.moveDY(1); 115cb93a386Sopenharmony_ci return; 116cb93a386Sopenharmony_ci case 'Backspace': 117cb93a386Sopenharmony_ci editor.deleteSelection(-1); 118cb93a386Sopenharmony_ci return; 119cb93a386Sopenharmony_ci case 'Delete': 120cb93a386Sopenharmony_ci editor.deleteSelection(1); 121cb93a386Sopenharmony_ci return; 122cb93a386Sopenharmony_ci case 'Shift': 123cb93a386Sopenharmony_ci return; 124cb93a386Sopenharmony_ci case 'Tab': // todo: figure out how to handle... 125cb93a386Sopenharmony_ci e.preventDefault(); 126cb93a386Sopenharmony_ci return; 127cb93a386Sopenharmony_ci } 128cb93a386Sopenharmony_ci if (e.ctrlKey) { 129cb93a386Sopenharmony_ci e.preventDefault(); 130cb93a386Sopenharmony_ci e.stopImmediatePropagation(); 131cb93a386Sopenharmony_ci switch (e.key) { 132cb93a386Sopenharmony_ci case 'r': editor.applyStyleToSelection({color:[1,0,0,1]}); return; 133cb93a386Sopenharmony_ci case 'g': editor.applyStyleToSelection({color:[0,0.6,0,1]}); return; 134cb93a386Sopenharmony_ci case 'u': editor.applyStyleToSelection({color:[0,0,1,1]}); return; 135cb93a386Sopenharmony_ci case 'k': editor.applyStyleToSelection({color:[0,0,0,1]}); return; 136cb93a386Sopenharmony_ci 137cb93a386Sopenharmony_ci case 's': editor.applyStyleToSelection({shaderIndex:0}); return; 138cb93a386Sopenharmony_ci 139cb93a386Sopenharmony_ci case 'i': editor.applyStyleToSelection({italic:'toggle'}); return; 140cb93a386Sopenharmony_ci case 'b': editor.applyStyleToSelection({bold:'toggle'}); return; 141cb93a386Sopenharmony_ci case 'w': editor.applyStyleToSelection({wavy:'toggle'}); return; 142cb93a386Sopenharmony_ci 143cb93a386Sopenharmony_ci case ']': editor.applyStyleToSelection({size_add:1}); return; 144cb93a386Sopenharmony_ci case '[': editor.applyStyleToSelection({size_add:-1}); return; 145cb93a386Sopenharmony_ci case '}': editor.applyStyleToSelection({size_add:10}); return; 146cb93a386Sopenharmony_ci case '{': editor.applyStyleToSelection({size_add:-10}); return; 147cb93a386Sopenharmony_ci } 148cb93a386Sopenharmony_ci } 149cb93a386Sopenharmony_ci if (!e.ctrlKey && !e.metaKey) { 150cb93a386Sopenharmony_ci if (e.key.length == 1) { // avoid keys like "Escape" for now 151cb93a386Sopenharmony_ci e.preventDefault(); 152cb93a386Sopenharmony_ci e.stopImmediatePropagation(); 153cb93a386Sopenharmony_ci editor.insert(e.key); 154cb93a386Sopenharmony_ci } 155cb93a386Sopenharmony_ci } 156cb93a386Sopenharmony_ci } 157cb93a386Sopenharmony_ci 158cb93a386Sopenharmony_ci document.getElementById('para2').addEventListener('pointermove', interact); 159cb93a386Sopenharmony_ci document.getElementById('para2').addEventListener('pointerdown', interact); 160cb93a386Sopenharmony_ci document.getElementById('para2').addEventListener('pointerup', interact); 161cb93a386Sopenharmony_ci document.getElementById('para2').addEventListener('keydown', keyhandler); 162cb93a386Sopenharmony_ci return surface; 163cb93a386Sopenharmony_ci } 164cb93a386Sopenharmony_ci 165cb93a386Sopenharmony_ci</script> 166