recipes/making-lists.md
Neater Lists
Let's reduce this chunky hunk of code to less:
Before
let midline = new Point(400, 400)
this.points = new PointList(
new Point({x:midline.x, y:150, radius:50, vx: .1, vy: 0, mass: 1, name: 'head' })
, new Point({x:400, y:180, radius:8, vx: .1, vy: 0, mass: 1, name: 'neck'})
, new Point({x:midline.x, y:200, radius:10, vx: .1, vy: 0, mass: 1, name:'shoulders' })
// arm
, new Point({x:midline.x-20, y:220, radius:8, vx: .1, vy: 0, mass: 1, name: 'elbow' })
, new Point({x:midline.x, y:230, radius:8, vx: .1, vy: 0, mass: 1, name: 'hand' })
// right arm
, new Point({x:midline.x+20, y:240, radius:8, vx: .1, vy: 0, mass: 1, name: 'elbow' })
, new Point({x:midline.x+40, y:250, radius:8, vx: .1, vy: 0, mass: 1, name: 'hand' })
// ledt leg
, new Point({x:midline.x-20, y:260, radius:15, vx: .1, vy: 0, mass: 1, name: 'hips' })
, new Point({x:midline.x-50, y:310, radius:8, vx: .1, vy: 0, mass: 1, name: 'leg' })
, new Point({x:midline.x, y:320, radius:8, vx: .1, vy: 0, mass: 1, name: 'foot'})
, new Point({x:midline.x, y:340, radius:8, vx: .1, vy: 0, mass: 1, name: 'leg' })
, new Point({x:400, y:520, radius:8, vx: .1, vy: 0, mass: 1, name: 'foot'})
)
PointList.cast
To save keystrokes we can use the cast() function on a PointList to convert all items to Point types.
After (with cast):
let midline = this.center.copy()
this.points = new PointList(
{x:midline.x, y:150, radius:50, vx: .1, vy: 0, mass: 1, name: 'head' }
, {x:400, y:180, radius:8, vx: .1, vy: 0, mass: 1, name: 'neck'}
, {x:midline.x, y:200, radius:10, vx: .1, vy: 0, mass: 1, name:'shoulders' }
// arm
, {x:midline.x-20, y:220, radius:8, vx: .1, vy: 0, mass: 1, name: 'elbow' }
, {x:midline.x, y:230, radius:8, vx: .1, vy: 0, mass: 1, name: 'hand' }
// right arm
, {x:midline.x+20, y:240, radius:8, vx: .1, vy: 0, mass: 1, name: 'elbow' }
, {x:midline.x+40, y:250, radius:8, vx: .1, vy: 0, mass: 1, name: 'hand' }
// ledt leg
, {x:midline.x-20, y:260, radius:15, vx: .1, vy: 0, mass: 1, name: 'hips' }
, {x:midline.x-50, y:310, radius:8, vx: .1, vy: 0, mass: 1, name: 'leg' }
, {x:midline.x, y:320, radius:8, vx: .1, vy: 0, mass: 1, name: 'foot'}
, {x:midline.x, y:340, radius:8, vx: .1, vy: 0, mass: 1, name: 'leg' }
, {x:400, y:520, radius:8, vx: .1, vy: 0, mass: 1, name: 'foot'}
).cast()
PointList.update
Then we havea lot of repeat vx, vy, mass. Luckily the point list has an update function, this updates each point:
let midline = this.center.copy()
this.points = new PointList(
{x:midline.x, y:150, radius:50, name: 'head' }
, {x:400, y:180, radius:8, name: 'neck'}
, {x:midline.x, y:200, radius:10, name:'shoulders' }
// arm
, {x:midline.x-20, y:220, radius:8, name: 'elbow' }
, {x:midline.x, y:230, radius:8, name: 'hand' }
// right arm
, {x:midline.x+20, y:240, radius:8, name: 'elbow' }
, {x:midline.x+40, y:250, radius:8, name: 'hand' }
// ledt leg
, {x:midline.x-20, y:260, radius:15, name: 'hips' }
, {x:midline.x-50, y:310, radius:8, name: 'leg' }
, {x:midline.x, y:320, radius:8, name: 'foot'}
, {x:midline.x, y:340, radius:8, name: 'leg' }
, {x:400, y:520, radius:8, name: 'foot'}
).cast()
this.points.update({
vx: .1, vy: 0, mass: 1
});
That's still a lot of repeat words.
Custom Point
In this example we'll exxtend the Point, and apply a default radius if undefined:
class BodyPoint extends Point {
created() {
if(this._opts.radius != undefined) return;
this.radius = 8
}
}
let midline = this.center.copy()
, mx = midline.x
;
this.points = new PointList(
{x: mx, y:150, radius:50, name: 'head' }
, {x: 400, y:180, name: 'neck'}
, {x: mx, y:200, radius:10, name:'shoulders' }
// arm
, {x: mx-20, y:220, name: 'elbow' }
, {x: mx, y:230, name: 'hand' }
// right arm
, {x: mx+20, y:240, name: 'elbow' }
, {x: mx+40, y:250, name: 'hand' }
// left leg
, {x: mx-20, y:260, radius:15, name: 'hips' }
, {x: mx-50, y:310, name: 'leg' }
, {x: mx, y:320, name: 'foot'}
, {x: mx, y:340, name: 'leg' }
, {x:400, y:520, name: 'foot'}
).cast(BodyPoint)
Better. But it would be nice to reduce further. Unfortunately because we're applying the name property to each point, it's not possible to simply convert each point to a list type; because a list type point accepts [x, y, radius, rotation].
points = new PointList(
// name, x, y, radius
['head', mx, 150, 50]
, ['neck', 400, 180]
, ['shoulders', mx, 200, 10]
// left arm
, ['elbow', mx-20, 220]
, ['hand' , mx, 230]
// right arm
, ['elbow', mx+20, 240]
, ['hand', mx+40, 250]
// ---
, ['hips', mx-20, 260, 15]
// left leg
, ['leg' , mx-50, 310]
, ['foot', mx, 320]
// right leg
, ['leg', mx, 340]
, ['foot', 400, 520]
).cast(BodyPoint, function(arrItem, type){
let [name, ...xyr] = arrItem
let o = (new type(xyr)).update({
vx: .1, vy: 0, mass: 1, name
})
return o
});
This requires a bit more code in the cast function, but saves a lot of repetition in the point list.
Info
keys: dict_keys(['exists', 'path', 'text', 'meta', 'rendered'])
path: recipes/making-lists.md
exists: True
meta: dict_keys(['filepath_exists', 'path', 'filepath', 'markdown'])