Ideally possible on any page; browser extension / bookmarklet (part of the K-Web Tools extension).
Ultimately you should be able to do all of it freely, but at the same time choose to stay within helpful borders etc, example: default to put comments in the margin next to the selection (move it only if you really want to).
Comment on a selection of text, like in Google Docs.
Comment on the document.
Minimal drawing on top of page that is useful?
Boring, but asking why might help. It could be for:
This is surely too simple but you may: try the crudest version possible, a craying should appear bottom right, just click it and draw!
[ Note for Kalle https://chatgpt.com/c/681d12ba-b7dc-8008-8d77-552481f0aafb ]
/draw demo aboveWritten by ChatGPT 4o (not their strongest coder).
PS. This code is just inlined in this Google Docs document, pretty cool huh?
// crayon.js
const draw = () => {
const id = '🖍️'
const toggle = document.createElement('div')
Object.assign(toggle.style, {
position: 'fixed', bottom: '10px', right: '10px',
fontSize: '24px', cursor: 'pointer', opacity: '0.25',
zIndex: 99999, userSelect: 'none'
})
toggle.textContent = id
document.body.appendChild(toggle)
const canvas = document.createElement('canvas')
Object.assign(canvas.style, {
position: 'fixed', top: 0, left: 0, width: '100vw', height: '100vh',
zIndex: 99998, pointerEvents: 'none'
})
canvas.width = window.innerWidth
canvas.height = window.innerHeight
document.body.appendChild(canvas)
const ctx = canvas.getContext('2d')
ctx.lineJoin = ctx.lineCap = 'round'
ctx.strokeStyle = 'rgba(255,0,0,0.7)'
ctx.lineWidth = 4
let drawing = false, enabled = false
let points = JSON.parse(localStorage.crayonDraw || '[]')
const redraw = () => {
ctx.clearRect(0, 0, canvas.width, canvas.height)
for (const line of points) {
ctx.beginPath()
for (let i = 0; i < line.length; i++) {
const p = line[i]
i ? ctx.lineTo(p.x, p.y) : ctx.moveTo(p.x, p.y)
}
ctx.stroke()
}
}
redraw()
const newLine = () => { points.push([]) }
const addPoint = e => {
const x = e.clientX, y = e.clientY
points.at(-1).push({x, y})
ctx.lineTo(x, y)
ctx.stroke()
}
canvas.addEventListener('mousedown', e => {
if (!enabled) return
drawing = true
ctx.beginPath()
ctx.moveTo(e.clientX, e.clientY)
newLine()
addPoint(e)
})
canvas.addEventListener('mousemove', e => {
if (!enabled || !drawing) return
addPoint(e)
})
window.addEventListener('mouseup', () => {
if (drawing) {
drawing = false
localStorage.crayonDraw = JSON.stringify(points)
}
})
toggle.onclick = () => {
enabled = !enabled
canvas.style.pointerEvents = enabled ? 'auto' : 'none'
toggle.style.opacity = enabled ? '1.0' : '0.25'
if (!enabled) redraw()
}
}