mass-pointer.js

total 0
used 0
limit 0
/* categories: springs files: ../point_src/core/head.js ../point_src/pointpen.js ../point_src/pointdraw.js ../point_src/math.js ../point_src/extras.js ../point_src/point-content.js ../point_src/pointlistpen.js ../point_src/pointlist.js ../point_src/events.js ../point_src/point.js ../point_src/distances.js ../point_src/dragging.js ../point_src/stage.js ../point_src/stagepen.js ../point_src/automouse.js ../point_src/setunset.js ../point_src/text/styler.js ../point_src/functions/springs.js ../point_src/functions/clamp.js ../point_src/setunset.js ../point_src/stroke.js ../point_src/rope.js ../point_src/collisionbox.js ../point_src/gravity.js ../point_src/random.js */ const stringLength = 200 const heavyStep = function(followPoint, mouse, gravity, damping=.9, dotDamping=.2, forceMultiplier=.1, forceValue=undefined) { // Apply gravity to the follow point's vertical velocity // Calculate the vector from the mouse to the follow point // let dx = followPoint.x - mouse.x ; // let dy = followPoint.y - mouse.y ; let dx = mouse.x - followPoint.x; let dy = mouse.y - followPoint.y; // Calculate the current distance between the follow point and the mouse let distance = Math.sqrt(dx * dx + dy * dy); // Set the follow point's position to be exactly on the circumference of the string length // const force = (distance - stringLength) * 0.01; // Tweak this factor as needed // If the distance exceeds the string length, we need to constrain the follow point if (distance > stringLength) { // Normalize the direction vector dx /= distance; dy /= distance; if(dotDamping!==false) { // Adjust the velocity so that it reflects the string tension let dotProduct = (followPoint.vx * dx + followPoint.vy * dy) * dotDamping; followPoint.vx -= dotProduct * dx; followPoint.vy -= dotProduct * dy; } if(forceMultiplier!==false){ const force = forceValue? forceValue: (distance - stringLength) * forceMultiplier; // Tweak this factor as needed followPoint.vx += force * dx; followPoint.vy += force * dy; } } // Apply gravity if(gravity){ followPoint.vy += gravity.y; followPoint.vx += gravity.x; } // Update the follow point's position based on its velocity followPoint.x += followPoint.vx; followPoint.y += followPoint.vy; if(damping) { // Apply damping continuously to smooth the motion followPoint.vx *= damping; followPoint.vy *= damping; } }; const flutter = ()=>{ stage.cable.visibleRopeGravity.y = -.05 + (random.float(-1, 1) * .1) setTimeout(flutter, random.float(2, 5)) }; setTimeout(flutter, random.float(0.5, 2)) class Cable { defaults = { // gravity: .2 gravity: {x:.05, y: 0} , visibleRopeGravity: {x:0, y:0.2} // gravity: undefined // , visibleRopeGravity: undefined , ropePointLength: 20 , segmentLength: 10 , invMass: .3 , color: '#990000' , knotColor: '#225555' , ropeColor: '#AAA' , radius: 2 , reactorMultiplier: .4 // , position: [1,1] } constructor(settings={}){ Object.assign(this, this.defaults, settings) this.points = PointList.generate.random(10, [100, 200], [0, 0, 2, 0]) this.points.forEach((p)=>{ p.update({vx: 0, vy:0, radius: 2 }) }); if(this.position) { this.mounted() } } mounted(initPos=this.position) { // this.ropePointLength = 20; // this.segmentLength = 10; // this.gravity = -.31; // this.gravity2D = gravity2D // let initPos = this.center.copy() this.points = this.ropePoints(initPos, this.ropePointLength * this.reactorMultiplier) this.points2 = this.ropePoints(initPos, this.ropePointLength) this.points.each.radius = 2 // let penUlt = this.points[this.points.length - 3] // penUlt.invMass = 200 let lastPoint = this.points.last() lastPoint.invMass = this.invMass lastPoint.radius = this.radius this.ropeReactor = new RopeReactor() this.visibleRopeReactor = new RopeReactor() this.points[0].copy(initPos.add(1,1)) this.points2[0].copy(initPos.add(1,1)) // this.visibleRopeReactor.pin(0) this.ropeReactor.pin(0) this.visibleRopeReactor.pin( this.points2.length-1 , this.points[this.points.length - 1] ) // this.visibleRopeReactor.pin(5) } ropePoints(initPos, ropePointLength){ let points = Array.from({ length: ropePointLength }, () => ({ x: initPos.x, y: initPos.y, oldX: initPos.x, oldY: initPos.y, })); // points[9].invMass = .01 return new PointList(...points).cast() } get head() { return this.points.last() } get handle() { return this.points[0] } step(){ /* A viscous fluid, applied through 2d invMass*/ // this.applyPhysics2(this.points, this.gravity2D, [1, this.points.length-1]); let ropeReactor = this.ropeReactor let visibleRopeReactor = this.visibleRopeReactor /* Rope like mass physics.*/ /* If not enabled, the ball on a string, without gravity acting upon the head. */ if(this.gravity !== undefined) { ropeReactor.applyPhysics(this.points, this.gravity); } /* If not enabled, the points wont fall, but simply sit in place. The constraints solves the bindings between nodes. */ if(this.visibleRopeGravity !== undefined) { visibleRopeReactor.applyPhysics(this.points2, this.visibleRopeGravity) } // ropeReactor.applyPhysics2(this.points, this.gravity) /* Different solving methods These should occur else the points won't connect like a rope. */ // this.solveConstraints1(this.points, this.segmentLength); // this.solveConstraints2(this.points, this.segmentLength); ropeReactor.solveConstraints3(this.points, this.segmentLength * 2.5); visibleRopeReactor.solveConstraints3(this.points2, this.segmentLength); } draw(ctx) { // this.clear(ctx); this.points2[0].xy = this.points[0].xy this.step() // ctx.fillStyle = '#999' // ctx.font = 'normal 30px lexend deca' // ctx.textAlign = 'center' // this.points.pen.indicator(ctx); // this.points.pen.line(ctx, {color:'#444'}); this.points2.pen.quadCurve(ctx, {color: this.ropeColor, lineWidth: 4}); // this.points2.pen.line(ctx, {color:'#AAA'}); // this.points[0].pen.indicator(ctx) this.points[0].pen.fill(ctx) // last.lookAt(penUlt)//, Math.PI *.5) // last.pen.indicator(ctx) // penUlt.pen.indicator(ctx) // last.pen.indicator(ctx, {color: '#770000'}) // let penUlt = this.points[this.points.length - 3] // penUlt.pen.fill(ctx, this.knotColor) /* Render the real physics rope*/ // this.points.pen.fill(ctx, this.knotColor) let last = this.points.last() last.pen.fill(ctx, {'color': this.color}) // last.text.label(ctx, 'Polypoint') } } class MainStage extends Stage { // canvas = document.getElementById('playspace'); canvas = 'playspace' mounted(){ this.cable = new Cable() this.cable.mounted(this.center.copy().add(0)) this.cable.handle.radius = 8 this.dragging.addPoints( this.cable.handle , this.cable.head ) let gp = new Point(0, 3) // this.collisionBox = new CollisionBox(this.points) // this.gravityBox = new GravityReactor(gp, this.points) // this.gravityBox.points.push(this.pinpo) } draw(ctx){ this.clear(ctx) ctx.font = `500 20px lexend deca`; // this.collisionBox.shuffle() this.cable.draw(ctx) this.cable.head.text.label(ctx, 'Poly Pointer!', {x:10, y:0}) } } stage = MainStage.go(/*{ loop: true }*/)
Run
Meta Data
imports ()
files ('../point_src/core/head.js', '../point_src/pointpen.js', '../point_src/pointdraw.js', '../point_src/math.js', '../point_src/extras.js', '../point_src/point-content.js', '../point_src/pointlistpen.js', '../point_src/pointlist.js', '../point_src/events.js', '../point_src/point.js', '../point_src/distances.js', '../point_src/dragging.js', '../point_src/stage.js', '../point_src/stagepen.js', '../point_src/automouse.js', '../point_src/setunset.js', '../point_src/text/styler.js', '../point_src/functions/springs.js', '../point_src/functions/clamp.js', '../point_src/setunset.js', '../point_src/stroke.js', '../point_src/rope.js', '../point_src/collisionbox.js', '../point_src/gravity.js', '../point_src/random.js')
unused_keys ('title',)
unknown_keys ('categories',)
categories ['springs']
filepath_exists True
path mass-pointer.js
filepath mass-pointer.js
clean_files ('../point_src/core/head.js', '../point_src/pointpen.js', '../point_src/pointdraw.js', '../point_src/math.js', '../point_src/extras.js', '../point_src/compass.js', '../point_src/center.js', '../point_src/point-content.js', '../point_src/pointlistpen.js', '../point_src/pointlistdraw.js', '../point_src/pointlistgradient.js', '../point_src/pointlistshape.js', '../point_src/pointlistgenerator.js', '../point_src/unpack.js', '../point_src/pointlist.js', '../point_src/events.js', '../point_src/relative-xy.js', '../point_src/pointcast.js', '../point_src/point.js', '../point_src/distances.js', '../point_src/protractor.js', '../point_src/text/beta.js', '../point_src/dragging.js', '../point_src/stage-resize.js', '../point_src/functions/resolve.js', '../point_src/stage.js', '../point_src/stagepen.js', '../point_src/automouse.js', '../point_src/setunset.js', '../point_src/text/styler.js', '../point_src/functions/springs.js', '../point_src/functions/clamp.js', '../point_src/stroke.js', '../point_src/rope.js', '../point_src/collisionbox.js', '../point_src/gravity.js', '../point_src/random.js')
markdown {'html': '', 'content': 'categories: springs\nfiles:\n ../point_src/core/head.js\n ../point_src/pointpen.js\n ../point_src/pointdraw.js\n ../point_src/math.js\n ../point_src/extras.js\n ../point_src/point-content.js\n ../point_src/pointlistpen.js\n ../point_src/pointlist.js\n ../point_src/events.js\n ../point_src/point.js\n ../point_src/distances.js\n ../point_src/dragging.js\n ../point_src/stage.js\n ../point_src/stagepen.js\n ../point_src/automouse.js\n ../point_src/setunset.js\n ../point_src/text/styler.js\n ../point_src/functions/springs.js\n ../point_src/functions/clamp.js\n ../point_src/setunset.js\n ../point_src/stroke.js\n ../point_src/rope.js\n ../point_src/collisionbox.js\n ../point_src/gravity.js\n ../point_src/random.js'}