Parse
File Parse pointpen.js
This tree is parsed live from the source file.
Classes
-
{{ item.name }}
- {{ key }}
Not Classes
{{ getTree() }}
Comments
{{ getTreeComments() }}
Source
/*
title: Point Pen
---
The `pen` provides a range of methods for visibly rendering the point.
Similar to how the draw tools _plot_ or _sketch_, the _pen_ renders the sketches.
This allows you to _draw_ many things and then _pen_ the drawing.
The available functions generally match the `draw` tools and in many cases use the
sibling function from the draw tools:
let p = new Point(100, 200)
p.pen.fill('red') // Calls p.draw.arc() then ctx.fill()
---
When imported, the `PointPen` auto-loads into the `Point.pen`.
Polypoint.head.lazyProp('Point', {
pen() { return new PointPen(this) }
}, 'pen')
let p = new Point;
p.pen // new instance of PointPen
*/
class PointPen {
// Draw functions for the Point.draw
// methods.
constructor(point) {
this.point = point;
}
_quickStroke(ctx, f, color, width=1, open=true, close=false) {
open && ctx.beginPath()
let r = f()
let origStroke = ctx.strokeStyle
, origWidth = ctx.lineWidth
;
if(color != undefined) {
ctx.strokeStyle = color == undefined? 'yellow': color
}
// if(width != undefined && ctx.lineWidth == undefined) {
// ctx.lineWidth = width == undefined? 1: width
// }
if(width != undefined) {
ctx.lineWidth = width
}
close && ctx.closePath()
ctx.stroke()
ctx.strokeStyle = origStroke
ctx.lineWidth = origWidth
return r
}
ngon(ctx, sides, radius, fromCenter=true, color, width=1, angle=0, open=true, close=true) {
return this._quickStroke(ctx, ()=>{
let points = this.point.draw.ngon(ctx, sides, radius, fromCenter, angle)
}, color, width, open, close)
}
circleGon(ctx, radius, lod=.3, fromCenter=true,color, width=1, open=true, close=true) {
let sides = Number((radius * lod).toFixed())
sides = Math.max(8, sides)
return this.ngon(ctx, sides, radius, fromCenter, color, width, open, close)
}
line(ctx, otherPoint, color, width) {
let al = arguments.length
// let data = unpack(arguments, {
// otherPoint: undefined
// , color: undefined
// , width: undefined
// })
this._quickStroke(ctx, ()=>{
if(otherPoint == undefined){
otherPoint = this.point.project()
}
return this.point.draw.lineTo(ctx, otherPoint)
}, color, width)
}
arc(ctx, otherPoint, color, distance=this.point.radius, width, direction=1) {
// draw.arc(ctx, radius=undefined, start=0, end=Math.PI2, direction=1)
this._quickStroke(ctx, ()=>{
if(otherPoint == undefined){
otherPoint = this.point.project()
}
let start = this.point.radians
let end = otherPoint.radians
this.point.draw.arc(ctx, distance, start, end, direction)
}, color, width)
}
ellipse(ctx, other, color, radRotation=this.point.radians, strokeWidth=1) {
let p = this.point
let start = other.start ?? 0
let end = other.end ?? 2 * Math.PI
start = start - (other.relative? 0: p.radians)
end = end - (other.relative? 0: p.radians)
this._quickStroke(ctx, ()=>{
this.point.draw.ellipse(ctx,
other.width, other.height,
r.radians,
start,
end)
// this.point.draw.arc(ctx, distance, start, end, direction)
}, color, strokeWidth)
}
stroke(ctx, radius=undefined) {
ctx.beginPath()
this.point.draw.arc(ctx, radius)
ctx.stroke()
}
circle(ctx, radius_or_conf=undefined, color, width) {
/*An arc, but complete with begin path and stoking */
let l = arguments.length
let opts = {
1: ()=>{
//no conf
this._quickStroke(ctx, ()=>{
this.point.draw.arc(ctx)
})
}
, 2: ()=>{
// ctx, dict
const _color = radius_or_conf.color || ctx.strokeStyle
const _width = radius_or_conf.width || ctx.lineWidth
const _radius = radius_or_conf.radius || this.point.radius
// quickStrokeWithCtx(ctx, _color, width)
this._quickStroke(ctx, ()=>{
this.point.draw.arc(ctx, _radius)
}, _color , _width)
}
, 3: ()=>{
// ctx, width, color ...
this._quickStroke(ctx, ()=>{
this.point.draw.arc(ctx, radius_or_conf)
}, color , width)
}
}
const extended = function(length) {
return (length > 3) && opts[3]
}
let c = (opts[l]==undefined?extended(l):opts[l])()
// this._quickStroke(ctx, ()=>{
// this.point.draw.arc(ctx, radius)
// }, _color , _width)
}
fill(ctx, fillStyle=undefined, radius=undefined) {
ctx.beginPath()
this.point.draw.arc(ctx, radius)
const getFillStyle = () => {
if(fillStyle.color != undefined) {
return fillStyle.color
}
if(fillStyle.fillStyle != undefined) {
return fillStyle.fillStyle
}
return fillStyle
};
let fs = fillStyle == undefined? this.fillStyle || this.point.color: getFillStyle()
if(fs) {
ctx.fillStyle = fs.call? fs(this): fs
}
// ctx.lineWidth = width == undefined? 1: width
ctx.fill()
}
box(ctx, size=this.point.radius, color, width, angle){
/*
A box is a rectangle on the outside of radius.
If an angle is given, the box cannot be a _rect_ and returns an ngon(4).
*/
if(angle != undefined) {
/* produce a ngon in the same location.*/
return this.ngon(ctx, 4, size * 1.4, true, color, width, angle)
}
let offset = {x: -size, y: -size}
return this.rect(ctx, size*2, undefined, color, width, offset)
}
rect(ctx, width=this.point.radius, height, color, strokeWidth, offset={x:0, y:0}) {
let xy = this.point.xy
if(height == undefined) {
height = width
}
this._quickStroke(ctx, ()=>{
ctx.rect(xy.x + offset.x, xy.y + offset.y, width, height)
// this.point.draw.pen(ctx, width, height)
}, color, strokeWidth)
}
indicator(ctx, miniConf={}) {
/*
Synonymous to:
weightedComPoint.project().pen.line(ctx, weightedComPoint, 'red', 2)
weightedComPoint.pen.circle(ctx, undefined, 'yellow', 1)
*/
// let def = {
// line: {color:'red', width: 2}
// , circle: {color:'yellow', width: 1}
// };
// Object.assign(def, miniConf)
let defaultCircleColor = '#66DD22'
let defaultLineColor = defaultCircleColor
let def = {
line: {/*color:'red',*/ width: 2}
, circle: {/*color:'yellow',*/ width: 1}
};
Object.assign(def, miniConf)
let lc = def?.line?.color || def.color || this.point.color || defaultLineColor
let lw = def?.line?.width || def.width
let cc = def?.circle?.color || def?.color || def?.line?.color || this.point.color || defaultCircleColor
let cw = def.width || def?.circle?.width
this.point.project().pen.line(ctx, this.point, lc, lw,)
this.circle(ctx, undefined,cc, cw,)
}
}
Polypoint.head.install(PointPen)
/*
Polypoint.head.lazyProp('Point', {
pen() {
let r = this._pen
if(r == undefined) {
r = new PointPen(this)
this._pen = r
}
return r
}
})
*/
Polypoint.head.lazyProp('Point', {
pen() { return new PointPen(this) }
}, 'pen')
copy