Last active
September 26, 2021 15:22
-
-
Save baku89/cfbcf44c0d2763bc4c3d6fbdf5495d6f to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
{ | |
"id": "9cwrv2kxip", | |
"label": "Polyline + Arc", | |
"icon": "【", | |
"parameters": [ | |
{ | |
"name": "strokeColor", | |
"type": "color", | |
"default": "#282a2e" | |
}, | |
{ | |
"name": "strokeWidth", | |
"type": "float", | |
"default": 2 | |
} | |
] | |
} | |
*/ | |
let path | |
let from, corner, to, t0, t1 | |
let guide, guideT0, guideT1 | |
let guideExtend, guideExtendPt | |
let state = 'begin' | |
function clamp(v, a, b) { | |
return Math.min(Math.max(v, a), b) | |
} | |
function getT(a, b, m) { | |
const dir = b.subtract(a) | |
const maxLen = dir.length | |
const diff = m.subtract(b) | |
const n = dir.normalize() | |
const diffLen = n.dot(diff) | |
const t = clamp(diffLen / maxLen, 0, 1) | |
const pt = a.add(dir.multiply(t)) | |
return pt | |
} | |
function createNewPath() { | |
p = new Path() | |
p.strokeWidth = strokeWidth | |
p.strokeColor = strokeColor | |
p.fillColor = strokeColor | |
return p | |
} | |
function press() { | |
if (state === 'begin') { | |
path = createNewPath() | |
path.moveTo(mouse) | |
from = mouse | |
} else if (state === 'corner') { | |
path.lineTo(mouse) | |
corner = mouse | |
t0 = from | |
} else if (state === 'end') { | |
to = mouse | |
t1 = to | |
} | |
} | |
function drag() { | |
if (state === 'corner') { | |
t0 = getT(from, corner, mouse) | |
if (guideT0) guideT0.remove() | |
guideT0 = Guide.addPoint(t0, 'stroke') | |
const pt = corner.add(t0.subtract(from)) | |
if (guideExtend) guideExtend.remove() | |
guideExtend = Guide.addLine(corner, pt) | |
if (guideExtendPt) guideExtendPt.remove() | |
guideExtendPt = Guide.addPoint(pt) | |
} else if (state === 'end') { | |
t1 = getT(corner, to, mouse) | |
if (guideT1) guideT1.remove() | |
guideT1 = Guide.addPoint(t1, 'stroke') | |
const pt = to.add(t1.subtract(corner)) | |
if (guideExtend) guideExtend.remove() | |
guideExtend = Guide.addLine(to, pt) | |
if (guideExtendPt) guideExtendPt.remove() | |
guideExtendPt = Guide.addPoint(pt) | |
} | |
if (guide) guide.remove() | |
guide = path.clone() | |
if (state === 'end') { | |
guide.lineTo(to) | |
guide.lineTo(t1) | |
guide.quadraticCurveTo(corner, t0) | |
guide.closePath() | |
} | |
} | |
function release() { | |
if (state === 'begin') { | |
state = 'corner' | |
} else if (state === 'corner') { | |
state = 'end' | |
} else if (state === 'end') { | |
path.lineTo(to) | |
path.lineTo(t1) | |
path.quadraticCurveTo(corner, t0) | |
path.closePath() | |
if (guide) guide.remove() | |
if (guideT0) guideT0.remove() | |
if (guideT1) guideT1.remove() | |
state = 'corner' | |
path = createNewPath() | |
path.moveTo(to) | |
from = to | |
} | |
if (guideExtend) guideExtend.remove() | |
if (guideExtendPt) guideExtendPt.remove() | |
} | |
function move() { | |
if (!path) return | |
if (state === 'begin') return | |
if (guide) guide.remove() | |
guide = path.clone() | |
if (state === 'corner') { | |
guide.lineTo(mouse) | |
} else if (state === 'end') { | |
guide.lineTo(mouse) | |
guide.lineTo(corner) | |
guide.closePath() | |
} | |
} | |
function end() { | |
if (guide) guide.remove() | |
if (guideT0) guideT0.remove() | |
if (guideT1) guideT1.remove() | |
if (guideExtend) guideExtend.remove() | |
if (guideExtendPt) guideExtendPt.remove() | |
path = null | |
state = 'begin' | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
{ | |
"id": "9cwrv2kxip", | |
"label": "Polyline + Arc", | |
"icon": "【", | |
"parameters": [ | |
{ | |
"name": "strokeColor", | |
"type": "color", | |
"default": "#282a2e" | |
}, | |
{ | |
"name": "strokeWidth", | |
"type": "float", | |
"default": 2 | |
} | |
] | |
} | |
*/ | |
let path | |
let from, to, t0, t1 | |
let guide, guideT | |
let guideExtend, guideExtendPt | |
let state = 'begin' | |
function clamp(v, a, b) { | |
return Math.min(Math.max(v, a), b) | |
} | |
function getT(a, b, m) { | |
const dir = b.subtract(a) | |
const maxLen = dir.length | |
const diff = m.subtract(b) | |
const n = dir.normalize() | |
const diffLen = n.dot(diff) | |
const t = clamp(diffLen / maxLen, 0, 1) | |
const pt = a.add(dir.multiply(t)) | |
return pt | |
} | |
function createNewPath() { | |
p = new Path() | |
p.strokeWidth = strokeWidth | |
p.strokeColor = strokeColor | |
p.fillColor = strokeColor | |
return p | |
} | |
function press() { | |
if (state === 'begin') { | |
path = createNewPath() | |
path.moveTo(mouse) | |
from = mouse | |
} else if (state === 'corner') { | |
path.lineTo(mouse) | |
to = mouse | |
t0 = from | |
} else if (state === 'end') { | |
from = to | |
to = mouse | |
t1 = mouse | |
} | |
drag() | |
} | |
function drag() { | |
if (state === 'corner') { | |
t0 = getT(from, to, mouse) | |
if (guideT) guideT.remove() | |
guideT = Guide.addPoint(t0, 'stroke') | |
const pt = to.add(t0.subtract(from)) | |
if (guideExtend) guideExtend.remove() | |
guideExtend = Guide.addLine(to, pt) | |
if (guideExtendPt) guideExtendPt.remove() | |
guideExtendPt = Guide.addPoint(pt) | |
} else if (state === 'end') { | |
t1 = getT(from, to, mouse) | |
if (guideT) guideT.remove() | |
guideT = Guide.addPoint(t1, 'stroke') | |
const pt = to.add(t1.subtract(from)) | |
if (guideExtend) guideExtend.remove() | |
guideExtend = Guide.addLine(to, pt) | |
if (guideExtendPt) guideExtendPt.remove() | |
guideExtendPt = Guide.addPoint(pt) | |
} | |
if (guide) guide.remove() | |
if (state === 'end') { | |
guide = createNewPath() | |
guide.moveTo(from) | |
guide.lineTo(to) | |
guide.lineTo(t1) | |
if (t1.getDistance(from) < 0.0001) { | |
guide.lineTo(t0) | |
} else { | |
guide.quadraticCurveTo(from, t0) | |
} | |
} | |
} | |
function release() { | |
if (state === 'begin') { | |
state = 'corner' | |
} else if (state === 'corner') { | |
state = 'end' | |
from = to | |
} else if (state === 'end') { | |
path = createNewPath() | |
path.moveTo(from) | |
path.lineTo(to) | |
path.lineTo(t1) | |
path.quadraticCurveTo(from, t0) | |
if (guide) guide.remove() | |
if (guideT) guideT.remove() | |
from = to | |
t0 = t1 | |
} | |
if (guideExtend) guideExtend.remove() | |
if (guideExtendPt) guideExtendPt.remove() | |
} | |
function move() { | |
if (!path) return | |
if (state === 'begin') return | |
if (guide) guide.remove() | |
if (state !== 'begin') { | |
guide = createNewPath() | |
guide.moveTo(from) | |
guide.lineTo(mouse) | |
} | |
} | |
function end() { | |
if (guide) guide.remove() | |
if (guideT) guideT.remove() | |
if (guideExtend) guideExtend.remove() | |
if (guideExtendPt) guideExtendPt.remove() | |
path = null | |
state = 'begin' | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment