Skip to content
Snippets Groups Projects
Commit 80494a3f authored by Yuriy Maksymets's avatar Yuriy Maksymets
Browse files

New cursor style, addOrUpdatePathElem refactoring

parent d3582653
Branches
No related tags found
2 merge requests!57Erasure intervals,!48Intuitive erasing
Pipeline #102731 passed
<svg viewBox="-2 -2 6 6" xmlns="http://www.w3.org/2000/svg">
<circle cx="2" cy="2" r="2"/>
<svg viewBox="-10 -10 30 30" xmlns="http://www.w3.org/2000/svg">
<circle cx="10" cy="10" r="10"/>
</svg>
\ No newline at end of file
html,
body {
height: 100%;
cursor: crosshair;
cursor: url(cursor.svg) 15 15, pointer;
/* /crosshair; */
}
body {
......
......@@ -25,13 +25,13 @@ const STROKECOLOUR = "blue"
const STROKERADIUS = 2
const ERASERRADIUS = STROKERADIUS * 10
function interpolatedCoordinate(start, end, length) {
const dx = end[0] - start[0]
const dy = end[1] - start[1]
const dist = getDistance(start, end)
const ratio = length / dist
return [start[0] + dx * ratio, start[1] + dy * ratio]
}
// function interpolatedCoordinate(start, end, length) {
// const dx = end[0] - start[0]
// const dy = end[1] - start[1]
// const dist = getDistance(start, end)
// const ratio = length / dist
// return [start[0] + dx * ratio, start[1] + dy * ratio]
// }
function eraseAt(x, y, room) {
let mousePos = [x, y]
......@@ -47,11 +47,10 @@ function eraseAt(x, y, room) {
detail: { id: pathID, points },
}),
)
points.forEach((point, i) => {
points.forEach((point) => {
const distanceToPoint = getDistance(mousePos, point)
if (distanceToPoint <= ERASERRADIUS) {
room.erasePoint(pathID, i)
// room.erasePoint(pathID, i)
// let prev, next
// if (i > 0) {
// prev = i - 1
......@@ -59,7 +58,6 @@ function eraseAt(x, y, room) {
// if (i < points.length - 1) {
// next = i + 1
// }
// if (prev !== undefined) {
// const interpolatedPoint = interpolatedCoordinate(
// point,
......@@ -68,7 +66,6 @@ function eraseAt(x, y, room) {
// )
// room.insertIntoPath(pathID, prev, interpolatedPoint)
// }
// if (next !== undefined) {
// const interpolatedPoint = interpolatedCoordinate(
// point,
......@@ -93,9 +90,9 @@ const SVG = {
},
}
let TEST_ERASE_INTERVAL = {} // { 0: [[0.1, 0.3], [0.4, 0.8]] }
let TEST_ERASE_INTERVAL = {}
function erasurePoints(pointA, pointB, start, fin) {
function erasurePoints(pointA, pointB, [start, fin]) {
if (start >= fin) return
if (start <= 0) start = 0
if (fin >= 1) fin = 1
......@@ -110,7 +107,7 @@ function erasurePoints(pointA, pointB, start, fin) {
return [start, fin].map(pointOnLine)
}
const addOrUpdatePathElem = (pathElems, id, points) => {
function getOrAddPathElem(pathElems, id) {
let pathElem = pathElems.get(id)
if (pathElem == null) {
......@@ -128,92 +125,101 @@ const addOrUpdatePathElem = (pathElems, id, points) => {
}
pathElem.innerHTML = ""
return pathElem
}
if (points.length == 0) {
return pathElem
}
function generateSvgPoint(subPath) {
const subpathElem = SVG.create.circle()
subpathElem.setAttribute("stroke", "none")
subpathElem.setAttribute("fill", STROKECOLOUR)
subpathElem.setAttribute("cx", subPath[0][0])
subpathElem.setAttribute("cy", subPath[0][1])
subpathElem.setAttribute("r", STROKERADIUS)
return subpathElem
}
function generateSvgPath(subPath) {
const subpathElem = SVG.create.path()
subpathElem.setAttribute("d", lineFn(subPath))
return subpathElem
}
function generateSvgForSubpath(subPath) {
return subPath.length === 1
? generateSvgPoint(subPath)
: generateSvgPath(subPath)
}
function isInvalidPoint(point) {
return point[0] === undefined
}
function isEndPoint(point) {
return point[2] === "end"
}
function getEraseIntervals(pathID, pointID) {
const eraseIntervalsForPath = TEST_ERASE_INTERVAL[pathID]
if (!eraseIntervalsForPath) return undefined
return eraseIntervalsForPath[pointID]
}
function generatePointsForPathElem(pathElem, pathID, dataPoints) {
const points = dataPoints
// Push a fake path split to generate the last path
points.push([-1, -1, false])
points.push([-1, -1, "end"])
let subPath = []
let toAdd = undefined
for (let i = 0; i < points.length; i++) {
const point = points[i]
if (toAdd) {
subPath.push(toAdd)
toAdd = undefined
}
if (point[0] === undefined) {
if (isInvalidPoint(point)) {
continue
}
if (point[2] === false) {
if (isEndPoint(point)) {
// End of subpath
if (subPath.length == 1) {
const subpathElem = SVG.create.circle()
subpathElem.setAttribute("stroke", "none")
subpathElem.setAttribute("fill", STROKECOLOUR)
subpathElem.setAttribute("cx", subPath[0][0])
subpathElem.setAttribute("cy", subPath[0][1])
subpathElem.setAttribute("r", STROKERADIUS)
pathElem.appendChild(subpathElem)
} else if (subPath.length > 0) {
const subpathElem = SVG.create.path()
subpathElem.setAttribute("d", lineFn(subPath))
if (subPath.length) {
const subpathElem = generateSvgForSubpath(subPath)
pathElem.appendChild(subpathElem)
subPath = []
}
subPath = []
continue
}
// Valid point inside a subpath
subPath.push(point)
const eraseIntervalsForPath = TEST_ERASE_INTERVAL[id]
if (!eraseIntervalsForPath) continue
const eraseIntervals = TEST_ERASE_INTERVAL[id][i]
if (!eraseIntervals) continue
if (i === points.length - 1) {
continue
}
const nextPoint = points[i + 1]
const eraseIntervals = getEraseIntervals(pathID, i)
if (!eraseIntervals || nextPoint === undefined) continue
for (const eraseInterval of eraseIntervals) {
if (eraseInterval) {
if (toAdd) {
subPath.push(toAdd)
toAdd = undefined
}
const erp = erasurePoints(
point,
nextPoint,
eraseInterval[0],
eraseInterval[1],
)
if (!(erp && erp.length)) continue
const [start, fin] = erp
subPath.push(start)
const subpathElem = SVG.create.path()
subpathElem.setAttribute("d", lineFn(subPath))
pathElem.appendChild(subpathElem)
subPath = []
if (!eraseInterval) continue
toAdd = fin
}
const erasedIntervalBounds = erasurePoints(
point,
nextPoint,
eraseInterval,
)
if (!(erasedIntervalBounds && erasedIntervalBounds.length)) continue
const [endOfDrawnSegment, startOfNewSegment] = erasedIntervalBounds
subPath.push(endOfDrawnSegment)
const subpathElem = generateSvgPath(subPath)
pathElem.appendChild(subpathElem)
subPath = [startOfNewSegment]
}
}
}
const addOrUpdatePathElem = (pathElems, id, points) => {
const pathElem = getOrAddPathElem(pathElems, id)
if (!points.length) {
return pathElem
}
generatePointsForPathElem(pathElem, id, points)
return pathElem
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment