Skip to content

Instantly share code, notes, and snippets.

@baku89
Last active September 26, 2021 15:22
Show Gist options
  • Save baku89/cfbcf44c0d2763bc4c3d6fbdf5495d6f to your computer and use it in GitHub Desktop.
Save baku89/cfbcf44c0d2763bc4c3d6fbdf5495d6f to your computer and use it in GitHub Desktop.
/*
{
"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'
}
/*
{
"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