diff --git a/CHANGELOG.md b/CHANGELOG.md index be7ee95..0ba71bb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,9 +5,21 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## v1.2.1 - 11-07-2019 + +### Added + +- better landing page +- improved examples + +### Fixed + +- bug in clamp function + ## v1.2.0 - 08-07-2019 ### Added + - Hidden Sticks with hidden parameter to Stick class - Setters API for easy use of Point and Stick constructors - Method chaining for Point and Stick diff --git a/dist/verly.bundle.js b/dist/verly.bundle.js index bd1d73c..5494d5c 100644 --- a/dist/verly.bundle.js +++ b/dist/verly.bundle.js @@ -1,2 +1,2 @@ -!function(t){var i={};function s(e){if(i[e])return i[e].exports;var n=i[e]={i:e,l:!1,exports:{}};return t[e].call(n.exports,n,n.exports,s),n.l=!0,n.exports}s.m=t,s.c=i,s.d=function(t,i,e){s.o(t,i)||Object.defineProperty(t,i,{enumerable:!0,get:e})},s.r=function(t){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},s.t=function(t,i){if(1&i&&(t=s(t)),8&i)return t;if(4&i&&"object"==typeof t&&t&&t.__esModule)return t;var e=Object.create(null);if(s.r(e),Object.defineProperty(e,"default",{enumerable:!0,value:t}),2&i&&"string"!=typeof t)for(var n in t)s.d(e,n,function(i){return t[i]}.bind(null,n));return e},s.n=function(t){var i=t&&t.__esModule?function(){return t.default}:function(){return t};return s.d(i,"a",i),i},s.o=function(t,i){return Object.prototype.hasOwnProperty.call(t,i)},s.p="",s(s.s=1)}([function(t,i){window.normalizedRandom=function(){return 2*Math.random()-1},window.degreesToRad=function(t){return t*(Math.PI/180)},window.clamp=function(t,i,s){return Math.min(Math.max(t,Math.min(i,s),Math.max(i,s)))},window.random=function(t,i,s){return 1===arguments.length?Math.random()*arguments[0]:(2==arguments.length&&(s=i,i=t,t=Math.random),i||s?s?t()*(s-i)+i:(s=i,t()*s):Math.random())},window.lerp=function(t,i,s){return(i-t)*s+t}},function(t,i,s){"use strict";s.r(i);class e{constructor(t,i,s){this.entities=t,this.draggedPoint=null,this.down=!1,this.coord=new Vector,this.offset=new Vector,this.offsetCoord=new Vector,this.canvas=i,this.ctx=s,this.canvas.addEventListener("mousedown",t=>{this.down=!0,this.draggedPoint&&(this.offset.setXY(t.offsetX-this.draggedPoint.pos.x,t.offsetY-this.draggedPoint.pos.y),this.offsetCoord=Vector.sub(this.coord,this.offset))}),this.canvas.addEventListener("mouseup",t=>{this.draggedPoint&&this.draggedPoint.resetVelocity(),this.down=!1,this.draggedPoint=null}),this.canvas.addEventListener("mousemove",t=>{this.coord.setXY(t.offsetX,t.offsetY),this.offsetCoord=Vector.sub(this.coord,this.offset)}),this.canvas.addEventListener("touchstart",t=>{let i=t.touches[0];this.down=!0,this.draggedPoint&&(this.offset.setXY(i.clientX-this.draggedPoint.pos.x,i.clientY-this.draggedPoint.pos.y),this.offsetCoord=Vector.sub(this.coord,this.offset))}),this.canvas.addEventListener("touchend",t=>{this.draggedPoint&&this.draggedPoint.resetVelocity(),this.down=!1,this.draggedPoint=null}),this.canvas.addEventListener("touchmove",t=>{let i=t.touches[0];this.coord.setXY(i.pageX,i.pageY),this.offsetCoord=Vector.sub(this.coord,this.offset)})}dragPoint(){this.down&&this.draggedPoint.pos.setXY(this.offsetCoord.x,this.offsetCoord.y)}drag(){this.down||(this.draggedPoint=this.getNearestPoint()),this.draggedPoint&&(this.renderDraggedPoint(this.draggedPoint),this.dragPoint())}renderDraggedPoint(t){this.ctx.beginPath(),this.ctx.strokeStyle="black",this.ctx.arc(t.pos.x,t.pos.y,1.5*t.radius,0,2*Math.PI),this.ctx.stroke(),this.ctx.closePath()}getNearestPoint(){let t=null;for(let i=0;i0&&d.addStick(r*n+o,r*n+o-1),r>0&&d.addStick(r*n+o,(r-1)*n+o)}for(d.tear=function(t){for(let i=0;i(t||20)&&d.removeSticks(d.sticks[i].startPoint)},o=0;o0&&this.div(t),this}normalizeTo(t){var i=this.mag();return i>0&&(i=t/i,this.mult(i)),this}limit(t){return this.mag()>t&&(this.normalize(),this.mult(t)),this}heading(){return-Math.atan2(-this.y,this.x)}dist(t){let i=this.x-t.x,s=this.y-t.y;return Math.sqrt(i*i+s*s)}distSq(t){let i=this.x-t.x,s=this.y-t.y;return i*i+s*s}copy(){return new h(this.x,this.y)}negative(){return this.x=-this.x,this.y=-this.y,this}array(){return[this.x,this.y]}toString(){return"["+this.x+", "+this.y+", "+this.z+"]"}project(t){var i=(this.x*t.x+this.y*t.y)/(t.x*t.x+t.y*t.y);return this.x=i*t.x,this.y=i*t.y,this}rotate(t){var i=this.heading()+t,s=this.mag();this.x=Math.cos(i)*s,this.y=Math.sin(i)*s}}var o=h;var r=class{constructor(t,i,s,e,n){this.pos=new Vector(t,i),this.oldpos=new Vector(t+(s||0),i+(e||0)),this.bounce=.99,this.friction=.97,this.groundFriction=.7,this.gravity=new Vector(0,1),this.pinned=!1,this.radius=n||5,this.color="#e62a4f",this.mass=1,this.sticks=[],this.forceAcc=1}setGravity(t){return this.gravity=t,this}setFriction(t){return this.friction=t,this}setGroundFriction(t){return this.groundFriction=t,this}setBounce(t){return this.bounce=t,this}setForceAcc(t){return this.forceAcc=t,this}setMass(t){return this.mass=t,this}setRadius(t){return this.radius=t,this}setColor(t){return this.color=t,this}setVelocity(t){return this.oldpos.setXY(t.x,t.y),this}pin(){return this.pinned=!0,this}unpin(){return this.pinned=!1,this}resetVelocity(){this.oldpos.setXY(this.pos.x,this.pos.y)}rotate(t,i){let s=i.x+(this.pos.x-i.x)*Math.cos(t)-(this.pos.y-i.y)*Math.sin(t),e=i.y+(this.pos.x-i.x)*Math.sin(t)+(this.pos.y-i.y)*Math.cos(t);this.pos.setXY(s,e)}resolveBehaviors(t,i=this.radius,s=this.forceAcc){var e=Vector.sub(this.pos,t.pos),n=e.magSq();let h=i*i;if(nt.WIDTH-this.radius&&(this.pos.x=t.WIDTH-this.radius),this.pos.xt.HEIGHT-this.radius&&(this.pos.y=t.HEIGHT-this.radius),this.pos.y=t.HEIGHT-this.radius&&i.magSq()>1e-6){var s=i.mag();i.x/=s,i.y/=s,i.mult(s*this.groundFriction)}this.oldpos.setXY(this.pos.x,this.pos.y),this.pos.add(i),this.pos.add(this.gravity)}render(t){t.beginPath(),t.fillStyle=this.color,t.arc(this.pos.x,this.pos.y,this.radius,0,2*Math.PI),t.fill(),t.closePath()}};var d=class{constructor(t,i,s,e,n){this.startPoint=t,this.endPoint=i,this.stiffness=e||2,this.color="#f5476a",this.hidden=n,this.length=s||this.startPoint.pos.dist(this.endPoint.pos),this.startPoint.sticks.push(this),this.endPoint.sticks.push(this)}update(t){let i=this.endPoint.pos.x-this.startPoint.pos.x,s=this.endPoint.pos.y-this.startPoint.pos.y,e=Math.sqrt(i*i+s*s),n=(this.length-e)/e*this.stiffness,h=i*n*.5,o=s*n*.5,r=this.startPoint.mass+this.endPoint.mass,d=this.startPoint.mass/r;r=this.endPoint.mass/r,this.startPoint.pinned||(this.startPoint.pos.x-=h*r,this.startPoint.pos.y-=o*r),this.endPoint.pinned||(this.endPoint.pos.x+=h*d,this.endPoint.pos.y+=o*d)}setColor(t){return this.color=t,this}setLength(t){return this.length=t,this}setStiffness(t){return this.stiffness=t,this}setHidden(t){return this.hidden=t,this}render(t){this.hidden||(t.beginPath(),t.strokeStyle=this.color,t.moveTo(this.startPoint.pos.x,this.startPoint.pos.y),t.lineTo(this.endPoint.pos.x,this.endPoint.pos.y),t.stroke(),t.closePath())}};var a=class{constructor(t,i){this.points=[],this.sticks=[],this.verlyInstance=i,this.iterations=t||16}setGravity(t){for(let i=0;i{s.oldpos.x+=t,s.oldpos.y+=i})}addPoint(t,i,s,e,n){let h;return h=t instanceof Point?t:new Point(t,i,s,e,n),this.points.push(h),h}addStick(t,i,s,e,n){let h;return h=t instanceof Stick?t:new Stick(this.points[t],this.points[i],s,e,n),this.sticks.push(h),h}updatePoints(){for(let t=0;t0&&s{this.down=!0,this.draggedPoint&&(this.offset.setXY(t.offsetX-this.draggedPoint.pos.x,t.offsetY-this.draggedPoint.pos.y),this.offsetCoord=Vector.sub(this.coord,this.offset))}),this.canvas.addEventListener("mouseup",t=>{this.draggedPoint&&this.draggedPoint.resetVelocity(),this.down=!1,this.draggedPoint=null}),this.canvas.addEventListener("mousemove",t=>{this.coord.setXY(t.offsetX,t.offsetY),this.offsetCoord=Vector.sub(this.coord,this.offset)}),this.canvas.addEventListener("touchstart",t=>{let i=t.touches[0];this.down=!0,this.draggedPoint&&(this.offset.setXY(i.clientX-this.draggedPoint.pos.x,i.clientY-this.draggedPoint.pos.y),this.offsetCoord=Vector.sub(this.coord,this.offset))}),this.canvas.addEventListener("touchend",t=>{this.draggedPoint&&this.draggedPoint.resetVelocity(),this.down=!1,this.draggedPoint=null}),this.canvas.addEventListener("touchmove",t=>{let i=t.touches[0];this.coord.setXY(i.pageX,i.pageY),this.offsetCoord=Vector.sub(this.coord,this.offset)})}dragPoint(){this.down&&this.draggedPoint.pos.setXY(this.offsetCoord.x,this.offsetCoord.y)}drag(){this.down||(this.draggedPoint=this.getNearestPoint()),this.draggedPoint&&(this.renderDraggedPoint(this.draggedPoint),this.dragPoint())}renderDraggedPoint(t){this.ctx.beginPath(),this.ctx.strokeStyle="black",this.ctx.arc(t.pos.x,t.pos.y,1.5*t.radius,0,2*Math.PI),this.ctx.stroke(),this.ctx.closePath()}getNearestPoint(){let t=null;for(let i=0;i0&&d.addStick(r*n+o,r*n+o-1),r>0&&d.addStick(r*n+o,(r-1)*n+o)}for(d.tear=function(t){for(let i=0;i(t||20)&&d.removeSticks(d.sticks[i].startPoint)},o=0;o0&&this.div(t),this}normalizeTo(t){var i=this.mag();return i>0&&(i=t/i,this.mult(i)),this}limit(t){return this.mag()>t&&(this.normalize(),this.mult(t)),this}heading(){return-Math.atan2(-this.y,this.x)}dist(t){let i=this.x-t.x,s=this.y-t.y;return Math.sqrt(i*i+s*s)}distSq(t){let i=this.x-t.x,s=this.y-t.y;return i*i+s*s}copy(){return new h(this.x,this.y)}negative(){return this.x=-this.x,this.y=-this.y,this}array(){return[this.x,this.y]}toString(){return"["+this.x+", "+this.y+", "+this.z+"]"}project(t){var i=(this.x*t.x+this.y*t.y)/(t.x*t.x+t.y*t.y);return this.x=i*t.x,this.y=i*t.y,this}rotate(t){var i=this.heading()+t,s=this.mag();this.x=Math.cos(i)*s,this.y=Math.sin(i)*s}}var o=h;var r=class{constructor(t,i,s,e,n){this.pos=new Vector(t,i),this.oldpos=new Vector(t+(s||0),i+(e||0)),this.bounce=.99,this.friction=.97,this.groundFriction=.7,this.gravity=new Vector(0,1),this.pinned=!1,this.radius=n||5,this.color="#e62a4f",this.mass=1,this.sticks=[],this.forceAcc=1}setGravity(t){return this.gravity=t,this}setFriction(t){return this.friction=t,this}setGroundFriction(t){return this.groundFriction=t,this}setBounce(t){return this.bounce=t,this}setForceAcc(t){return this.forceAcc=t,this}setMass(t){return this.mass=t,this}setRadius(t){return this.radius=t,this}setColor(t){return this.color=t,this}setVelocity(t){return this.oldpos.setXY(t.x,t.y),this}pin(){return this.pinned=!0,this}unpin(){return this.pinned=!1,this}resetVelocity(){this.oldpos.setXY(this.pos.x,this.pos.y)}rotate(t,i){let s=i.x+(this.pos.x-i.x)*Math.cos(t)-(this.pos.y-i.y)*Math.sin(t),e=i.y+(this.pos.x-i.x)*Math.sin(t)+(this.pos.y-i.y)*Math.cos(t);this.pos.setXY(s,e)}resolveBehaviors(t,i=this.radius,s=this.forceAcc){var e=Vector.sub(this.pos,t.pos),n=e.magSq();let h=i*i;if(nt.WIDTH-this.radius&&(this.pos.x=t.WIDTH-this.radius),this.pos.xt.HEIGHT-this.radius&&(this.pos.y=t.HEIGHT-this.radius),this.pos.y=t.HEIGHT-this.radius&&i.magSq()>1e-6){var s=i.mag();i.x/=s,i.y/=s,i.mult(s*this.groundFriction)}this.oldpos.setXY(this.pos.x,this.pos.y),this.pos.add(i),this.pos.add(this.gravity)}render(t){t.beginPath(),t.fillStyle=this.color,t.arc(this.pos.x,this.pos.y,this.radius,0,2*Math.PI),t.fill(),t.closePath()}};var d=class{constructor(t,i,s,e,n){this.startPoint=t,this.endPoint=i,this.stiffness=e||2,this.color="#f5476a",this.hidden=n,this.length=s||this.startPoint.pos.dist(this.endPoint.pos),this.startPoint.sticks.push(this),this.endPoint.sticks.push(this)}update(t){let i=this.endPoint.pos.x-this.startPoint.pos.x,s=this.endPoint.pos.y-this.startPoint.pos.y,e=Math.sqrt(i*i+s*s),n=(this.length-e)/e*this.stiffness,h=i*n*.5,o=s*n*.5,r=this.startPoint.mass+this.endPoint.mass,d=this.startPoint.mass/r;r=this.endPoint.mass/r,this.startPoint.pinned||(this.startPoint.pos.x-=h*r,this.startPoint.pos.y-=o*r),this.endPoint.pinned||(this.endPoint.pos.x+=h*d,this.endPoint.pos.y+=o*d)}setColor(t){return this.color=t,this}setLength(t){return this.length=t,this}setStiffness(t){return this.stiffness=t,this}setHidden(t){return this.hidden=t,this}render(t){this.hidden||(t.beginPath(),t.strokeStyle=this.color,t.moveTo(this.startPoint.pos.x,this.startPoint.pos.y),t.lineTo(this.endPoint.pos.x,this.endPoint.pos.y),t.stroke(),t.closePath())}};var a=class{constructor(t,i){this.points=[],this.sticks=[],this.verlyInstance=i,this.iterations=t||16}setGravity(t){for(let i=0;i{s.oldpos.x+=t,s.oldpos.y+=i})}addPoint(t,i,s,e,n){let h;return h=t instanceof Point?t:new Point(t,i,s,e,n),this.points.push(h),h}addStick(t,i,s,e,n){let h;return h=t instanceof Stick?t:new Stick(this.points[t],this.points[i],s,e,n),this.sticks.push(h),h}updatePoints(){for(let t=0;t0&&s {\r\n this.down = true;\r\n if (this.draggedPoint) {\r\n this.offset.setXY(e.offsetX - this.draggedPoint.pos.x, e.offsetY - this.draggedPoint.pos.y);\r\n this.offsetCoord = Vector.sub(this.coord, this.offset);\r\n }\r\n })\r\n this.canvas.addEventListener('mouseup', (e) => {\r\n if (this.draggedPoint) {\r\n this.draggedPoint.resetVelocity();\r\n };\r\n this.down = false;\r\n this.draggedPoint = null;\r\n })\r\n\r\n this.canvas.addEventListener('mousemove', (e) => {\r\n this.coord.setXY(e.offsetX, e.offsetY);\r\n this.offsetCoord = Vector.sub(this.coord, this.offset);\r\n })\r\n\r\n // TOUCH\r\n this.canvas.addEventListener('touchstart', (e) => {\r\n let offset = e.touches[0];\r\n this.down = true;\r\n if (this.draggedPoint) {\r\n this.offset.setXY(offset.clientX - this.draggedPoint.pos.x, offset.clientY - this.draggedPoint.pos.y);\r\n this.offsetCoord = Vector.sub(this.coord, this.offset);\r\n }\r\n })\r\n this.canvas.addEventListener('touchend', (e) => {\r\n if (this.draggedPoint) {\r\n this.draggedPoint.resetVelocity();\r\n };\r\n this.down = false;\r\n this.draggedPoint = null;\r\n })\r\n this.canvas.addEventListener('touchmove', (e) => {\r\n let offset = e.touches[0];\r\n this.coord.setXY(offset.pageX, offset.pageY);\r\n this.offsetCoord = Vector.sub(this.coord, this.offset);\r\n })\r\n }\r\n\r\n dragPoint() {\r\n if (!this.down) return;\r\n this.draggedPoint.pos.setXY(this.offsetCoord.x, this.offsetCoord.y);\r\n }\r\n\r\n drag() {\r\n if (!this.down) {\r\n this.draggedPoint = this.getNearestPoint();\r\n }\r\n if (this.draggedPoint) {\r\n this.renderDraggedPoint(this.draggedPoint);\r\n this.dragPoint();\r\n }\r\n }\r\n \r\n renderDraggedPoint(point) {\r\n this.ctx.beginPath();\r\n this.ctx.strokeStyle = 'black';\r\n this.ctx.arc(point.pos.x, point.pos.y, point.radius * 1.5, 0, Math.PI * 2);\r\n this.ctx.stroke();\r\n this.ctx.closePath();\r\n }\r\n\r\n\r\n getNearestPoint() {\r\n // if (!this.down) return false;\r\n let d = 20;\r\n let p = null;\r\n for (let k = 0; k < this.entities.length; k++) {\r\n for (let i = 0; i < this.entities[k].points.length; i++) {\r\n let dist = this.entities[k].points[i].pos.dist(this.coord);\r\n if (dist < d) {\r\n p = this.entities[k].points[i];\r\n }\r\n }\r\n }\r\n return p;\r\n }\r\n}\r\n","import Mouse from './Mouse';\r\n\r\n/**\r\n * @class Verly\r\n * @version 1.2.0\r\n * @author \r\n */\r\nclass Verly {\r\n /**\r\n * \r\n * @param {Number} iterations \r\n * @param {HTMLCanvasElement} canvas \r\n * @param {CanvasRenderingContext2D} ctx \r\n */\r\n constructor(iterations, canvas, ctx) {\r\n this.entities = [];\r\n this.iterations = iterations;\r\n this.currentFrame = 0;\r\n this.canvas = canvas;\r\n this.WIDTH = canvas.width;\r\n this.HEIGHT = canvas.height;\r\n this.ctx = ctx;\r\n this.mouse = new Mouse(this.entities, this.canvas, this.ctx);\r\n }\r\n\r\n /**\r\n * @param {...Entity} args\r\n * @description Joins two Entity Class Together \r\n * \r\n * @example\r\n * let canvas = document.getElementById('c');\r\n * let ctx = canvas.getContext('2d');\r\n * let width = canvas.width = 600;\r\n * let height = canvas.height = 500;\r\n * \r\n * let verly = new Verly(16, canvas, ctx);\r\n * let box = verly.createBox(100, 100, 100, 100);\r\n * let rope = verly.createRope(100, 100, 15, 10, 0);\r\n * \r\n * // verly.joinEntities(...Entity)\r\n * let mix = verly.joinEntities(box, rope);\r\n * mix.addStick(0, 18, 20)\r\n * \r\n * function animate() {\r\n * ctx.clearRect(0, 0, width, height);\r\n * \r\n * verly.update();\r\n * verly.render();\r\n * verly.interact();\r\n * verly.renderPointIndex();\r\n * \r\n * requestAnimationFrame(animate);\r\n * }\r\n * animate();\r\n * \r\n */\r\n joinEntities(...args) {\r\n let mixEntity = new Entity(this.iterations, this);\r\n\r\n let points = [];\r\n let sticks = [];\r\n\r\n // loop through the args and push points and sticks to the array\r\n for (let i = 0; i < args.length; i++) {\r\n points.push(args[i].points);\r\n sticks.push(args[i].sticks);\r\n\r\n // get the index which item we should splice in [this.entities]\r\n let index = this.entities.indexOf(args[i]);\r\n this.entities.splice(index, 1);\r\n }\r\n\r\n // join multiple arrays\r\n points = [].concat.apply([], points);\r\n sticks = [].concat.apply([], sticks);\r\n\r\n // add the arrays to the mix::Entity\r\n mixEntity.points = points;\r\n mixEntity.sticks = sticks;\r\n\r\n // add the mix::Entity to [this.entities]\r\n this.addEntity(mixEntity);\r\n return mixEntity; // return for chaining\r\n }\r\n\r\n /**\r\n * @param {Entity} e \r\n */\r\n addEntity(e) {\r\n this.entities.push(e);\r\n }\r\n\r\n /**\r\n * drags points\r\n */\r\n interact() {\r\n this.mouse.drag();\r\n }\r\n\r\n /**\r\n * updates all the physics stuff\r\n */\r\n update() {\r\n for (let i = 0; i < this.entities.length; i++) {\r\n this.entities[i].update();\r\n }\r\n\r\n this.currentFrame++;\r\n }\r\n\r\n /**\r\n */\r\n renderPointIndex() {\r\n for (let i = 0; i < this.entities.length; i++) {\r\n this.entities[i].renderPointIndex(this.ctx);\r\n }\r\n }\r\n\r\n /**\r\n * renders all the entity\r\n */\r\n render() {\r\n for (let i = 0; i < this.entities.length; i++) {\r\n this.entities[i].render(this.ctx);\r\n }\r\n }\r\n\r\n\r\n\r\n\r\n /**\r\n * @param {number} x \r\n * @param {number} y \r\n * @param {number} w \r\n * @param {number} h \r\n */\r\n createBox(x, y, w, h) {\r\n const box = new Entity(this.iterations, this);\r\n box.addPoint(x, y, 0, 0);\r\n box.addPoint(x + w, y, 0, 0);\r\n box.addPoint(x + w, y + h, 0, 0);\r\n box.addPoint(x, y + h, 0, 0);\r\n box.addStick(0, 1);\r\n box.addStick(1, 2);\r\n box.addStick(2, 3);\r\n box.addStick(3, 0);\r\n box.addStick(3, 1);\r\n\r\n this.addEntity(box);\r\n return box;\r\n }\r\n\r\n\r\n /**\r\n * @param {number} x \r\n * @param {number} y \r\n * @param {number} segments \r\n * @param {number} radius=50\r\n * @param {number} stride1=1\r\n * @param {number} stride2=5\r\n */\r\n createHexagon(x, y, segments, radius = 50, stride1 = 1, stride2 = 5) {\r\n const hexagon = new Entity(this.iterations, this);\r\n\r\n let stride = (2 * Math.PI) / segments;\r\n\r\n // points\r\n for (let i = 0; i < segments; ++i) {\r\n let theta = i * stride;\r\n hexagon.addPoint(\r\n x + Math.cos(theta) * radius,\r\n y + Math.sin(theta) * radius,\r\n 0, 0\r\n );\r\n }\r\n\r\n let center = hexagon.addPoint(x, y, 0, 0);\r\n\r\n // sticks\r\n for (let i = 0; i < segments; ++i) {\r\n hexagon.addStick(i, (i + stride1) % segments);\r\n hexagon.addStick(new Stick(hexagon.points[i], center));\r\n hexagon.addStick(i, (i + stride2) % segments);\r\n }\r\n\r\n\r\n this.addEntity(hexagon);\r\n return hexagon;\r\n }\r\n\r\n /**\r\n * @param {number} posx \r\n * @param {number} posy \r\n * @param {number} w \r\n * @param {number} h \r\n * @param {number} segments \r\n * @param {number} pinOffset \r\n */\r\n createCloth(posx, posy, w, h, segments, pinOffset) {\r\n let cloth = new Entity(this.iterations, this);\r\n\r\n let xStride = w / segments;\r\n let yStride = h / segments;\r\n\r\n let x, y;\r\n for (y = 0; y < segments; ++y) {\r\n for (x = 0; x < segments; ++x) {\r\n let px = posx + x * xStride - w / 2 + xStride / 2;\r\n let py = posy + y * yStride - h / 2 + yStride / 2;\r\n cloth.addPoint(px, py);\r\n\r\n if (x > 0) {\r\n cloth.addStick(y * segments + x, y * segments + x - 1);\r\n }\r\n\r\n if (y > 0) {\r\n cloth.addStick(y * segments + x, (y - 1) * segments + x);\r\n }\r\n }\r\n }\r\n\r\n // as the name suggest\r\n function tear(threshold) {\r\n for (let i = 0; i < cloth.sticks.length; i++) {\r\n // find the distance between two points\r\n let dist = cloth.sticks[i].startPoint.pos.dist(cloth.sticks[i].endPoint.pos)\r\n if (dist > (threshold || 20)) { // remove if the dist is > than threshold \r\n cloth.removeSticks(cloth.sticks[i].startPoint);\r\n }\r\n }\r\n }\r\n\r\n cloth.tear = tear;\r\n\r\n for (x = 0; x < segments; ++x) {\r\n if (x % pinOffset == 0) { // magic\r\n cloth.pin(x);\r\n }\r\n }\r\n\r\n !this.dontPush && this.addEntity(cloth);\r\n return cloth;\r\n }\r\n\r\n\r\n /**\r\n * @param {number} x \r\n * @param {number} y \r\n * @param {number} segments=10\r\n * @param {number} gap=15\r\n * @param {number} pin=0\r\n */\r\n createRope(x, y, segments = 10, gap = 15, pin) {\r\n let rope = new Entity(this.iterations, this);\r\n\r\n for (let i = 0; i < segments; i++) {\r\n rope.addPoint(x + i * gap, y, 0, 0)\r\n }\r\n\r\n for (let i = 0; i < segments - 1; i++) {\r\n rope.addStick(i, (i + 1) % segments);\r\n }\r\n\r\n if (pin !== undefined) {\r\n rope.pin(pin);\r\n }\r\n this.addEntity(rope);\r\n return rope;\r\n }\r\n\r\n\r\n createRagdoll(x0, y0) {\r\n let ragdoll = new Entity(this.iterations, this);\r\n\r\n // Head\r\n ragdoll.addPoint(x0, y0).setRadius(15).setMass(5);\r\n\r\n // Groin\r\n ragdoll.addPoint(x0, y0 + 100);\r\n\r\n // Hips\r\n ragdoll.addPoint(x0 + 30, y0 + 90);\r\n ragdoll.addPoint(x0 - 30, y0 + 90);\r\n\r\n // Knees\r\n ragdoll.addPoint(x0 + 20, y0 + 150);\r\n ragdoll.addPoint(x0 - 20, y0 + 150);\r\n\r\n // Feet\r\n ragdoll.addPoint(x0 + 30, y0 + 190).setRadius(10).setMass(20);\r\n ragdoll.addPoint(x0 - 30, y0 + 190).setRadius(10).setMass(20);\r\n\r\n // Neck\r\n ragdoll.addPoint(x0, y0 + 25);\r\n\r\n // Shoulders\r\n ragdoll.addPoint(x0 + 25, y0 + 30);\r\n ragdoll.addPoint(x0 - 25, y0 + 30);\r\n\r\n // Hands\r\n ragdoll.addPoint(x0 + 15, y0 + 105).setRadius(10).setMass(5);\r\n ragdoll.addPoint(x0 - 15, y0 + 105).setRadius(10).setMass(5);\r\n\r\n\r\n\r\n // \"Muscles\"\r\n // Head - shoulders\r\n ragdoll.addStick(0, 9);\r\n ragdoll.addStick(0, 10);\r\n // Shoulder - shoulder\r\n ragdoll.addStick(9, 10);\r\n\r\n // Shoulders - hips\r\n ragdoll.addStick(9, 2);\r\n ragdoll.addStick(10, 3);\r\n // Shoulders - hips opposite side\r\n ragdoll.addStick(9, 3);\r\n ragdoll.addStick(10, 2);\r\n\r\n // Hips - feet\r\n ragdoll.addStick(2, 6);\r\n ragdoll.addStick(3, 7);\r\n\r\n // Hips - feet, opposite\r\n ragdoll.addStick(2, 7);\r\n ragdoll.addStick(3, 6);\r\n\r\n // Head - groin\r\n ragdoll.addStick(0, 1);\r\n\r\n // Hip - hip\r\n ragdoll.addStick(2, 3);\r\n // Shoulder - hip\r\n ragdoll.addStick(9, 2);\r\n ragdoll.addStick(10, 3);\r\n\r\n // Head - knee\r\n ragdoll.addStick(0, 4);\r\n // Head - knee\r\n ragdoll.addStick(0, 5);\r\n\r\n // Head feet\r\n ragdoll.addStick(0, 6);\r\n ragdoll.addStick(0, 7);\r\n\r\n // Body parts\r\n // Hips\r\n ragdoll.addStick(1, 2);\r\n ragdoll.addStick(1, 3);\r\n // Legs\r\n ragdoll.addStick(2, 4);\r\n ragdoll.addStick(3, 5);\r\n ragdoll.addStick(4, 6);\r\n ragdoll.addStick(5, 7);\r\n\r\n ragdoll.addStick(0, 8);\r\n ragdoll.addStick(8, 1);\r\n\r\n // Left arm\r\n ragdoll.addStick(8, 9);\r\n ragdoll.addStick(9, 11);\r\n\r\n // Right arm\r\n ragdoll.addStick(8, 10);\r\n ragdoll.addStick(10, 12);\r\n\r\n this.addEntity(ragdoll);\r\n return ragdoll;\r\n }\r\n}\r\n\r\nexport default Verly;","/**\r\n * @class Vector\r\n * @version v1.0.0\r\n * @author Anurag Hazra\r\n * @param {number} x\r\n * @param {number} y\r\n */\r\nclass Vector {\r\n\r\n constructor(x, y) {\r\n this.x = x || 0;\r\n this.y = y || 0;\r\n }\r\n\r\n /**\r\n * get distance from two vectors\r\n * @param {Vector} v1 \r\n * @param {Vector} v2 \r\n * @return {number}\r\n */\r\n static dist(v1, v2) {\r\n return v1.dist(v2);\r\n }\r\n \r\n /**\r\n * get distance squared from two vectors \r\n * @param {Vector} v1 \r\n * @param {Vector} v2 \r\n * @return {number}\r\n */\r\n static distSq(v1, v2) {\r\n return v1.distSq(v2);\r\n }\r\n\r\n /**\r\n * subtract two vectors\r\n * @param {Vector} v1 \r\n * @param {Vector} v2 \r\n * @return {Vector}\r\n */\r\n static sub(v1, v2) {\r\n return new Vector(v1.x - v2.x, v1.y - v2.y);\r\n }\r\n\r\n /**\r\n * add two vectors\r\n * @param {Vector} v1 \r\n * @param {Vector} v2 \r\n * @return {Vector}\r\n */\r\n static add(v1, v2) {\r\n return new Vector(v1.x + v2.x, v1.y + v2.y);\r\n }\r\n\r\n /**\r\n * create vector from angle\r\n * @param {number} angle \r\n */\r\n static fromAngle(angle) {\r\n let v = new Vector(0, 0);\r\n v.x = Math.cos(angle);\r\n v.y = Math.sin(angle);\r\n return v;\r\n }\r\n\r\n /**\r\n * create random2d vector\r\n * @return {Vector}\r\n */\r\n static random2D() {\r\n return Vector.fromAngle(Math.random() * Math.PI * 180);\r\n } \r\n \r\n /**\r\n * adds random jitter motion\r\n * @param {number} a \r\n * @param {number} b \r\n * @return {Vector}\r\n */\r\n jitter(a, b) {\r\n var v = new Vector(a, b);\r\n this.x += normalizedRandom() * v.x;\r\n this.y += normalizedRandom() * v.y;\r\n return this;\r\n }\r\n\r\n /**\r\n * add this vector to another vector\r\n * @param {Vector|number} x \r\n * @param {Number} y \r\n * @return {Vector}\r\n */\r\n add(x, y) {\r\n if (arguments.length === 1) {\r\n this.x += x.x;\r\n this.y += x.y;\r\n } else if (arguments.length === 2) {\r\n this.x += x;\r\n this.y += y;\r\n }\r\n return this;\r\n }\r\n\r\n /**\r\n * subtracts this vector to another vector\r\n * @param {Vector|number} x \r\n * @param {Number} y \r\n * @return {Vector}\r\n */\r\n sub(x, y) {\r\n if (arguments.length === 1) {\r\n this.x -= x.x;\r\n this.y -= x.y;\r\n } else if (arguments.length === 2) {\r\n this.x -= x;\r\n this.y -= y;\r\n }\r\n return this;\r\n }\r\n\r\n /**\r\n * multiply this vector to a scalar value or a vector\r\n * @param {Vector|number} v \r\n * @return {Vector}\r\n */\r\n mult(v) {\r\n if (typeof v === 'number') {\r\n this.x *= v;\r\n this.y *= v;\r\n } else {\r\n this.x *= v.x;\r\n this.y *= v.y;\r\n }\r\n return this;\r\n }\r\n\r\n /**\r\n * divide this vector to a scalar value or a vector\r\n * @param {Vector|number} v \r\n * @return {Vector}\r\n */\r\n div(v) {\r\n if (typeof v === 'number') {\r\n this.x /= v;\r\n this.y /= v;\r\n } else {\r\n this.x /= v.x;\r\n this.y /= v.y;\r\n }\r\n return this;\r\n }\r\n\r\n /**\r\n * set this vectors angle\r\n * @param {number} angle \r\n */\r\n setAngle(angle) {\r\n var len = this.mag();\r\n this.x = Math.cos(angle) * len;\r\n this.y = Math.sin(angle) * len;\r\n }\r\n\r\n\r\n /**\r\n * get the magnitude of this vector\r\n * @return {number}\r\n */\r\n mag() {\r\n return Math.sqrt(this.x * this.x + this.y * this.y);\r\n }\r\n\r\n /**\r\n * get the magnitude sqr of this vector\r\n * @return {number}\r\n */\r\n magSq() {\r\n return (this.x * this.x + this.y * this.y);\r\n }\r\n\r\n /**\r\n * set x, y of this vector\r\n * @param {number} x \r\n * @param {number} y \r\n * @return {Vector}\r\n */\r\n setXY(x, y) {\r\n this.x = x;\r\n this.y = y;\r\n return this;\r\n }\r\n\r\n /**\r\n * set the magnitude of this vector\r\n * @param {number} value \r\n * @return {Vector}\r\n */\r\n setMag(value) {\r\n this.normalize();\r\n this.mult(value);\r\n return this;\r\n }\r\n \r\n /**\r\n * normalize this vector \r\n * @return {Vector}\r\n */\r\n normalize() {\r\n let m = this.mag();\r\n if (m > 0) {\r\n this.div(m);\r\n }\r\n return this;\r\n }\r\n\r\n /**\r\n * normalize this vector to a specific length\r\n * @param {number} length \r\n * @return {Vector}\r\n */\r\n normalizeTo(length) {\r\n var mag = this.mag();\r\n if (mag > 0) {\r\n mag = length / mag;\r\n this.mult(mag);\r\n }\r\n return this;\r\n }\r\n\r\n /**\r\n * limit this vector\r\n * @param {number} max \r\n * @return {Vector}\r\n */\r\n limit(max) {\r\n if (this.mag() > max) {\r\n this.normalize();\r\n this.mult(max);\r\n }\r\n return this;\r\n }\r\n\r\n /**\r\n * get heading of this vector in radians\r\n * @return {number}\r\n */\r\n heading() {\r\n return (-Math.atan2(-this.y, this.x));\r\n }\r\n \r\n /**\r\n * get distance between this and specific vector\r\n * @param {Vector} v \r\n * @return {number}\r\n */\r\n dist(v) {\r\n let dx = this.x - v.x;\r\n let dy = this.y - v.y;\r\n return Math.sqrt(dx * dx + dy * dy);\r\n }\r\n\r\n /**\r\n * get distance sqr between this and specific vector\r\n * @param {Vector} v \r\n * @return {number}\r\n */\r\n distSq(v) {\r\n let dx = this.x - v.x;\r\n let dy = this.y - v.y;\r\n return (dx * dx + dy * dy);\r\n }\r\n\r\n /**\r\n * copy this vector\r\n * @return {Vector}\r\n */\r\n copy() {\r\n return new Vector(this.x, this.y);\r\n }\r\n \r\n /**\r\n * revert this vector\r\n * @return {Vector}\r\n */\r\n negative() {\r\n this.x = -this.x;\r\n this.y = -this.y;\r\n return this;\r\n }\r\n \r\n /**\r\n * return an array representation of this vector\r\n * @return {Array}\r\n */\r\n array() {\r\n return [this.x, this.y];\r\n }\r\n \r\n /**\r\n * return a string representation of this vector\r\n * @return {String}\r\n */\r\n toString() {\r\n return \"[\" + this.x + \", \" + this.y + \", \" + this.z + \"]\";\r\n }\r\n \r\n /**\r\n * \r\n * @param {Vector} v \r\n * @return {Vector}\r\n */\r\n project(v) {\r\n var coeff = ((this.x * v.x) + (this.y * v.y)) / ((v.x * v.x) + (v.y * v.y));\r\n this.x = coeff * v.x;\r\n this.y = coeff * v.y;\r\n return this;\r\n }\r\n \r\n /**\r\n * rotate this vector\r\n * @param {number} a \r\n */\r\n rotate(a) {\r\n var b = this.heading() + a;\r\n var c = this.mag();\r\n this.x = Math.cos(b) * c;\r\n this.y = Math.sin(b) * c;\r\n }\r\n}\r\n\r\nexport default Vector;","class Point {\r\n /**\r\n * \r\n * @param {number} x \r\n * @param {number} y \r\n * @param {number=} vx \r\n * @param {number=} vy \r\n * @param {number=} radius \r\n */\r\n constructor(x, y, vx, vy, radius) {\r\n this.pos = new Vector(x, y);\r\n this.oldpos = new Vector(x + (vx || 0), y + (vy || 0));\r\n this.bounce = 0.99;\r\n this.friction = 0.97;\r\n this.groundFriction = 0.7;\r\n this.gravity = new Vector(0, 1);\r\n this.pinned = false;\r\n this.radius = radius || 5;\r\n this.color = '#e62a4f';\r\n this.mass = 1;\r\n this.sticks = [];\r\n // this.behaviors = [];\r\n this.forceAcc = 1;\r\n }\r\n\r\n /**\r\n * \r\n * @param {Vector} g \r\n */\r\n setGravity(g) {\r\n this.gravity = g;\r\n return this;\r\n }\r\n /**\r\n * \r\n * @param {number} f \r\n */\r\n setFriction(f) {\r\n this.friction = f;\r\n return this;\r\n }\r\n /**\r\n * \r\n * @param {number} f \r\n */\r\n setGroundFriction(f) {\r\n this.groundFriction = f;\r\n return this;\r\n }\r\n /**\r\n * \r\n * @param {number} b\r\n */\r\n setBounce(b) {\r\n this.bounce = b;\r\n return this;\r\n }\r\n /**\r\n * \r\n * @param {number} f \r\n * @returns {Point}\r\n */\r\n setForceAcc(f) {\r\n this.forceAcc = f;\r\n return this;\r\n }\r\n /**\r\n * \r\n * @param {number} m \r\n * @returns {Point}\r\n */\r\n setMass(m) {\r\n this.mass = m;\r\n return this;\r\n }\r\n /**\r\n * \r\n * @param {number} radius \r\n * @returns {Point}\r\n */\r\n setRadius(radius) {\r\n this.radius = radius;\r\n return this;\r\n }\r\n\r\n /**\r\n * @param {string} color \r\n * @returns {Point}\r\n */\r\n setColor(color) {\r\n this.color = color;\r\n return this;\r\n }\r\n\r\n /**\r\n * @param {Vector} vel \r\n * @returns {Point}\r\n */\r\n setVelocity(vel) {\r\n this.oldpos.setXY(vel.x, vel.y);\r\n return this;\r\n }\r\n\r\n /**\r\n * @returns {Point}\r\n */\r\n pin() {\r\n this.pinned = true;\r\n return this;\r\n }\r\n /**\r\n * @returns {Point}\r\n */\r\n unpin() {\r\n this.pinned = false;\r\n return this;\r\n }\r\n\r\n resetVelocity() {\r\n this.oldpos.setXY(this.pos.x, this.pos.y);\r\n }\r\n\r\n /**\r\n * \r\n * @param {number} angle \r\n * @param {number} offset \r\n */\r\n rotate(angle, offset) {\r\n let x = offset.x + (this.pos.x - offset.x) * Math.cos(angle) - (this.pos.y - offset.y) * Math.sin(angle);\r\n let y = offset.y + (this.pos.x - offset.x) * Math.sin(angle) + (this.pos.y - offset.y) * Math.cos(angle);\r\n this.pos.setXY(x, y);\r\n }\r\n\r\n /**\r\n * \r\n * @param {Point} p \r\n * @param {number} radius \r\n * @param {number} strength \r\n */\r\n resolveBehaviors(p, radius = this.radius, strength = this.forceAcc) {\r\n var delta = Vector.sub(this.pos, p.pos);\r\n var dist = delta.magSq();\r\n\r\n let magR = radius * radius;\r\n if (dist < magR) {\r\n var f = delta.normalizeTo(1 - (dist / magR)).mult(strength);\r\n this.applyForce(f);\r\n }\r\n }\r\n\r\n /**\r\n * \r\n * @param {number|Vector} f \r\n */\r\n applyForce(f) {\r\n this.pos.add(f);\r\n }\r\n\r\n /**\r\n * \r\n * @param {number} x \r\n * @param {number} y \r\n * @param {number} time \r\n * @param {number} radius \r\n * @param {number} speed \r\n */\r\n addMotor(x, y, time, radius, speed) {\r\n this.pos.x = x + radius * Math.cos(time * speed);\r\n this.pos.y = y + radius * Math.sin(time * speed);\r\n }\r\n\r\n /**\r\n * @param {Verly} verlyInstance \r\n */\r\n constrain(verlyInstance) {\r\n // if (this.pos.y > HEIGHT - 1) {\r\n // this.pos.y = HEIGHT - 1;\r\n // }\r\n // if (this.pos.x < 0) {\r\n // this.pos.x = 0;\r\n // }\r\n // if (this.pos.x > WIDTH - 1) {\r\n // this.pos.x = WIDTH - 1;\r\n // }\r\n // let vel = Vector.sub(this.pos, this.oldpos);\r\n if (this.pos.x > verlyInstance.WIDTH - this.radius) {\r\n this.pos.x = verlyInstance.WIDTH - this.radius;\r\n // this.oldpos.x = (this.pos.x + vel.x) * this.bounce;\r\n }\r\n if (this.pos.x < this.radius) {\r\n this.pos.x = this.radius;\r\n // this.oldpos.x = (this.pos.x + vel.x) * this.bounce;\r\n }\r\n if (this.pos.y > verlyInstance.HEIGHT - this.radius) {\r\n this.pos.y = verlyInstance.HEIGHT - this.radius;\r\n // this.oldpos.y = (this.pos.y + vel.y) * this.bounce;\r\n }\r\n if (this.pos.y < this.radius) {\r\n this.pos.y = this.radius;\r\n // this.oldpos.y = (this.pos.y + vel.y) * this.bounce;\r\n }\r\n };\r\n\r\n\r\n /**\r\n * @param {Verly} verlyInstance \r\n */\r\n update(verlyInstance) {\r\n if (this.pinned) return;\r\n let vel = Vector.sub(this.pos, this.oldpos);\r\n vel.mult(this.friction);\r\n // if the point touches the ground set groundFriction\r\n if (this.pos.y >= verlyInstance.HEIGHT - this.radius && vel.magSq() > 0.000001) {\r\n var m = vel.mag();\r\n vel.x /= m;\r\n vel.y /= m;\r\n vel.mult(m * this.groundFriction);\r\n }\r\n this.oldpos.setXY(this.pos.x, this.pos.y);\r\n this.pos.add(vel);\r\n this.pos.add(this.gravity);\r\n }\r\n\r\n /**\r\n * @param {CanvasRenderingContext2D} ctx \r\n */\r\n render(ctx) {\r\n ctx.beginPath();\r\n ctx.fillStyle = this.color;\r\n ctx.arc(this.pos.x, this.pos.y, this.radius, 0, Math.PI * 2);\r\n ctx.fill();\r\n ctx.closePath();\r\n }\r\n}\r\n\r\n\r\nexport default Point;","class Stick {\r\n /**\r\n * creates a stick between two Point\r\n * takes optional length and stiffness \r\n * @param {Point} p1 \r\n * @param {Point} p2 \r\n * @param {number=} length \r\n * @param {number=} stiffness \r\n * @param {boolean=} hidden \r\n */\r\n constructor(p1, p2, length, stiffness, hidden) {\r\n this.startPoint = p1;\r\n this.endPoint = p2;\r\n this.stiffness = stiffness || 2;\r\n this.color = '#f5476a';\r\n this.hidden = hidden;\r\n if (!length) {\r\n this.length = this.startPoint.pos.dist(this.endPoint.pos);\r\n } else {\r\n this.length = length;\r\n }\r\n this.startPoint.sticks.push(this);\r\n this.endPoint.sticks.push(this);\r\n }\r\n\r\n /**\r\n * \r\n * @param {number=} stepCoef \r\n */\r\n update(stepCoef) {\r\n // not gonna use vectors for performance optimization\r\n // let dx = this.endPoint.pos.x - this.startPoint.pos.x;\r\n // let dy = this.endPoint.pos.y - this.startPoint.pos.y;\r\n // let dist = Math.sqrt(dx * dx + dy * dy);\r\n // let diff = this.length - dist;\r\n // let percent = diff / dist / 2;\r\n // let offsetx = (dx * percent);\r\n // let offsety = (dy * percent);\r\n // if (!this.startPoint.pinned) {\r\n // this.startPoint.pos.x -= offsetx;\r\n // this.startPoint.pos.y -= offsety;\r\n // }\r\n // if (!this.endPoint.pinned) {\r\n // this.endPoint.pos.x += offsetx;\r\n // this.endPoint.pos.y += offsety;\r\n // }\r\n // ----- algo two\r\n\r\n // algo three\r\n let dx = this.endPoint.pos.x - this.startPoint.pos.x;\r\n let dy = this.endPoint.pos.y - this.startPoint.pos.y;\r\n let dist = Math.sqrt(dx * dx + dy * dy);\r\n let diff = (this.length - dist) / dist * this.stiffness;\r\n\r\n let offsetx = dx * diff * 0.5;\r\n let offsety = dy * diff * 0.5;\r\n\r\n // calculate mass\r\n let m1 = this.startPoint.mass + this.endPoint.mass;\r\n let m2 = this.startPoint.mass / m1;\r\n m1 = this.endPoint.mass / m1;\r\n\r\n if (!this.startPoint.pinned) {\r\n this.startPoint.pos.x -= offsetx * m1;\r\n this.startPoint.pos.y -= offsety * m1;\r\n }\r\n if (!this.endPoint.pinned) {\r\n this.endPoint.pos.x += offsetx * m2;\r\n this.endPoint.pos.y += offsety * m2;\r\n }\r\n\r\n \r\n // calculate mass\r\n // var m1 = this.startPoint.mass + this.endPoint.mass;\r\n // var m2 = this.startPoint.mass / m1;\r\n // m1 = this.endPoint.mass / m1;\r\n \r\n // var normal = Vector.sub(this.startPoint.pos, this.endPoint.pos);\r\n // var m = normal.magSq();\r\n // let diff = ((this.length * this.length) - m);\r\n // normal.mult((diff / m) * this.stiffness * stepCoef);\r\n \r\n // if (!this.startPoint.pinned) {\r\n // this.startPoint.pos.add(normal);\r\n // }\r\n // if (!this.endPoint.pinned) {\r\n // this.endPoint.pos.sub(normal);\r\n // }\r\n }\r\n\r\n /**\r\n * @param {string} color\r\n * @returns {Stick}\r\n */\r\n setColor(color) {\r\n this.color = color;\r\n return this;\r\n }\r\n\r\n /**\r\n * @param {number} length\r\n * @returns {Stick}\r\n */\r\n setLength(length) {\r\n this.length = length;\r\n return this;\r\n }\r\n\r\n /**\r\n * @param {number} value\r\n * @returns {Stick}\r\n */\r\n setStiffness(value) {\r\n this.stiffness = value;\r\n return this;\r\n }\r\n\r\n /**\r\n * @param {boolean} value\r\n * @returns {Stick}\r\n */\r\n setHidden(value) {\r\n this.hidden = value;\r\n return this;\r\n }\r\n\r\n /**\r\n * \r\n * @param {CanvasRenderingContext2D} ctx \r\n */\r\n render(ctx) {\r\n if (this.hidden) return;\r\n ctx.beginPath();\r\n ctx.strokeStyle = this.color;\r\n ctx.moveTo(this.startPoint.pos.x, this.startPoint.pos.y);\r\n ctx.lineTo(this.endPoint.pos.x, this.endPoint.pos.y);\r\n ctx.stroke();\r\n ctx.closePath();\r\n }\r\n}\r\n\r\nexport default Stick;\r\n","class Entity {\r\n\r\n /**\r\n * @param {number} iterations \r\n * @param {Verly} verlyInstance \r\n */\r\n constructor(iterations, verlyInstance) {\r\n this.points = [];\r\n this.sticks = [];\r\n this.verlyInstance = verlyInstance;\r\n this.iterations = iterations || 16;\r\n }\r\n\r\n\r\n // join(...args) {\r\n // let points = [];\r\n // let sticks = [];\r\n\r\n // // loop through the args and push points and sticks to the array\r\n // for (let i = 0; i < args.length; i++) {\r\n // points.push(args[i].points);\r\n // sticks.push(args[i].sticks);\r\n // }\r\n\r\n // // join multiple arrays\r\n // points = [].concat.apply([], points);\r\n // sticks = [].concat.apply([], sticks);\r\n\r\n // // add the arrays to the mix::Entity\r\n // this.points = points;\r\n // this.sticks = sticks;\r\n\r\n // return this; // return for chaining\r\n // }\r\n\r\n /**\r\n * sets the gravity of this entity\r\n * @param {Vector} g \r\n */\r\n setGravity(g) {\r\n for (let i = 0; i < this.points.length; i++) {\r\n this.points[i].setGravity(g);\r\n }\r\n }\r\n\r\n /**\r\n * sets the friction of this entity\r\n * @param {number} f \r\n */\r\n setFriction(f) {\r\n for (let i = 0; i < this.points.length; i++) {\r\n this.points[i].setFriction(f);\r\n }\r\n }\r\n\r\n /**\r\n * pin a specific Point\r\n * @param {number} index \r\n */\r\n pin(index) {\r\n this.points[index].pin();\r\n }\r\n\r\n /**\r\n * remove a specific Point\r\n * @param {Point} p\r\n */\r\n removeSticks(p) {\r\n this.sticks.splice(this.sticks.indexOf(p.sticks[0]), 1);\r\n p.sticks.splice(0, 1);\r\n }\r\n\r\n /**\r\n * \r\n * @param {Number} x \r\n * @param {Number} y \r\n */\r\n setVelocity(x, y) {\r\n this.points.map(e => {\r\n e.oldpos.x += x;\r\n e.oldpos.y += y;\r\n })\r\n }\r\n\r\n /**\r\n * adds a Point in points array with {x,y,vx,vy,radius}\r\n * @param {Number|Point} x \r\n * @param {Number=} y \r\n * @param {Number=} vx \r\n * @param {Number=} vy \r\n * @param {Number=} radius \r\n * @returns {Point}\r\n */\r\n addPoint(x, y, vx, vy, radius) {\r\n let p\r\n if (x instanceof Point) {\r\n p = x;\r\n } else {\r\n p = new Point(x, y, vx, vy, radius);\r\n }\r\n this.points.push(p);\r\n return p;\r\n }\r\n\r\n /**\r\n * adds a stick inbetween two points\r\n * @param {number|Stick} p1 \r\n * @param {number=} p2 \r\n * @param {number=} length \r\n * @param {number=} stiffness \r\n * @param {boolean=} ishidden \r\n */\r\n addStick(p1, p2, length, stiffness, ishidden) {\r\n let stick;\r\n if (p1 instanceof Stick) {\r\n stick = p1;\r\n } else {\r\n stick = new Stick(this.points[p1], this.points[p2], length, stiffness, ishidden);\r\n }\r\n this.sticks.push(stick);\r\n return stick;\r\n }\r\n\r\n /**\r\n */\r\n updatePoints() {\r\n for (let i = 0; i < this.points.length; i++) {\r\n this.points[i].update(this.verlyInstance);\r\n }\r\n }\r\n\r\n /**\r\n * @methdo updateSticks\r\n * @param {Number=} stepCoef \r\n */\r\n updateSticks(stepCoef) {\r\n for (let i = 0; i < this.sticks.length; i++) {\r\n this.sticks[i].update(stepCoef);\r\n }\r\n }\r\n\r\n /**\r\n */\r\n updateConstraints() {\r\n for (let i = 0; i < this.points.length; i++) {\r\n this.points[i].constrain(this.verlyInstance);\r\n }\r\n }\r\n\r\n /**\r\n */\r\n update() {\r\n // var stepCoef = 1 / this.iterations;\r\n this.updatePoints();\r\n for (let j = 0; j < this.iterations; ++j) {\r\n this.updateSticks();\r\n this.updateConstraints();\r\n }\r\n }\r\n\r\n /**\r\n */\r\n renderPoints() {\r\n for (let i = 0; i < this.points.length; i++) {\r\n this.points[i].render(this.verlyInstance.ctx);\r\n }\r\n }\r\n\r\n /**\r\n */\r\n renderSticks() {\r\n for (let i = 0; i < this.sticks.length; i++) {\r\n this.sticks[i].render(this.verlyInstance.ctx);\r\n }\r\n }\r\n\r\n /**\r\n */\r\n renderPointIndex() {\r\n for (let i = 0; i < this.points.length; i++) {\r\n this.verlyInstance.ctx.beginPath();\r\n this.verlyInstance.ctx.fillStyle = 'black';\r\n this.verlyInstance.ctx.fillText(i, this.points[i].pos.x + 5, this.points[i].pos.y - 6);\r\n this.verlyInstance.ctx.closePath();\r\n }\r\n }\r\n\r\n\r\n /**\r\n */\r\n render() {\r\n this.renderPoints();\r\n this.renderSticks();\r\n }\r\n}\r\n\r\nexport default Entity;","class TypoGraphy {\r\n /**\r\n * \r\n * @param {number} x \r\n * @param {number} y \r\n * @param {number} size \r\n * @param {string} letter \r\n * @param {Verly} verlyInstance \r\n */\r\n constructor(x, y, size, letter, verlyInstance) {\r\n this.x = x;\r\n this.y = y;\r\n this.size = size;\r\n this.stickDistance = this.size;\r\n this.iterations = 50;\r\n // A\r\n this.A = [\r\n [0, 0, 1, 0, 0],\r\n [0, 1, 1, 1, 0],\r\n [0, 1, 0, 1, 0],\r\n [1, 1, 1, 1, 1],\r\n [1, 0, 0, 0, 1]\r\n ]\r\n // B\r\n this.B = [\r\n [1, 1, 1, 0, 0],\r\n [1, 1, 1, 1, 0],\r\n [1, 1, 1, 0, 0],\r\n [1, 1, 1, 1, 0],\r\n [1, 1, 1, 0, 0]\r\n ]\r\n\r\n // C\r\n this.C = [\r\n [1, 1, 1, 1, 0],\r\n [1, 1, 1, 1, 0],\r\n [1, 1, 0, 0, 0],\r\n [1, 1, 1, 1, 0],\r\n [1, 1, 1, 1, 0]\r\n ]\r\n\r\n // D\r\n this.D = [\r\n [1, 1, 1, 0, 0],\r\n [1, 1, 1, 1, 0],\r\n [1, 1, 1, 1, 0],\r\n [1, 1, 1, 1, 0],\r\n [1, 1, 1, 0, 0]\r\n ];\r\n\r\n // E\r\n this.E = [\r\n [0, 1, 1, 1, 0],\r\n [0, 1, 1, 0, 0],\r\n [0, 1, 1, 1, 0],\r\n [0, 1, 1, 0, 0],\r\n [0, 1, 1, 1, 0]\r\n ]\r\n\r\n // S\r\n this.S = [\r\n [0, 1, 1, 1, 0],\r\n [1, 1, 1, 0, 0],\r\n [1, 1, 1, 1, 0],\r\n [0, 1, 1, 1, 0],\r\n [1, 1, 1, 0, 0]\r\n ]\r\n\r\n // I \r\n this.I = [\r\n [0, 0, 1, 0, 0],\r\n [0, 1, 1, 1, 0],\r\n [0, 1, 1, 1, 0],\r\n [0, 1, 1, 1, 0],\r\n [0, 1, 1, 1, 0]\r\n ]\r\n\r\n\r\n // K\r\n this.K = [\r\n [1, 0, 1, 1, 0],\r\n [1, 1, 1, 0, 0],\r\n [1, 1, 0, 0, 0],\r\n [1, 1, 1, 0, 0],\r\n [1, 0, 1, 1, 0]\r\n ]\r\n\r\n // U\r\n this.U = [\r\n [1, 1, 0, 1, 1],\r\n [1, 1, 0, 1, 1],\r\n [1, 1, 0, 1, 1],\r\n [1, 1, 1, 1, 1],\r\n [0, 1, 1, 1, 0]\r\n ]\r\n\r\n // N\r\n this.N = [\r\n [0, 0, 0, 0, 0, 0],\r\n [1, 1, 0, 0, 1, 1],\r\n [1, 1, 1, 0, 1, 1],\r\n [1, 1, 1, 1, 1, 1],\r\n [1, 1, 0, 1, 1, 1],\r\n [1, 1, 0, 0, 1, 1]\r\n ]\r\n\r\n // R\r\n this.R = [\r\n [1, 1, 1, 0, 0],\r\n [1, 1, 1, 1, 0],\r\n [1, 1, 1, 1, 0],\r\n [1, 1, 1, 0, 0],\r\n [1, 1, 1, 1, 0]\r\n ]\r\n\r\n // G\r\n this.G = [\r\n [0, 1, 1, 1, 0],\r\n [1, 1, 1, 0, 0],\r\n [1, 1, 0, 1, 1],\r\n [1, 1, 1, 1, 1],\r\n [0, 1, 1, 1, 0]\r\n ]\r\n\r\n // L\r\n this.L = [\r\n [1, 1, 0, 0, 0],\r\n [1, 1, 0, 0, 0],\r\n [1, 1, 0, 0, 0],\r\n [1, 1, 1, 1, 1],\r\n [1, 1, 1, 1, 1]\r\n ]\r\n\r\n // Y\r\n this.Y = [\r\n [1, 1, 0, 1, 1],\r\n [1, 1, 0, 1, 1],\r\n [0, 1, 1, 1, 0],\r\n [0, 1, 1, 1, 0],\r\n [0, 1, 1, 1, 0]\r\n ]\r\n\r\n // V\r\n this.V = [\r\n [1, 0, 0, 0, 1],\r\n [1, 1, 0, 1, 1],\r\n [1, 1, 0, 1, 1],\r\n [1, 1, 1, 1, 1],\r\n [0, 1, 1, 1, 0]\r\n ]\r\n\r\n //X\r\n this.X = [\r\n [1, 1, 1, 1, 1],\r\n [1, 1, 1, 1, 1],\r\n [1, 1, 1, 1, 1],\r\n [1, 1, 1, 1, 1],\r\n [1, 1, 1, 1, 1]\r\n ]\r\n\r\n //P\r\n this.P = [\r\n [1, 1, 1, 0, 0],\r\n [1, 1, 1, 1, 0],\r\n [1, 1, 1, 1, 0],\r\n [1, 1, 1, 0, 0],\r\n [1, 1, 1, 0, 0]\r\n ]\r\n\r\n //H\r\n this.H = [\r\n [1, 1, 0, 1, 1],\r\n [1, 1, 0, 1, 1],\r\n [1, 1, 1, 1, 1],\r\n [1, 1, 0, 1, 1],\r\n [1, 1, 0, 1, 1]\r\n ]\r\n\r\n //O\r\n this.O = [\r\n [0, 1, 1, 1, 0],\r\n [1, 1, 0, 1, 1],\r\n [1, 1, 0, 1, 1],\r\n [1, 1, 0, 1, 1],\r\n [0, 1, 1, 1, 0]\r\n ]\r\n\r\n this.letters = {\r\n A: this.A,\r\n B: this.B,\r\n C: this.C,\r\n D: this.D,\r\n E: this.E,\r\n K: this.K,\r\n I: this.I,\r\n S: this.S,\r\n U: this.U,\r\n N: this.N,\r\n R: this.R,\r\n G: this.G,\r\n L: this.L,\r\n Y: this.Y,\r\n V: this.V,\r\n X: this.X,\r\n P: this.P,\r\n H: this.H,\r\n O: this.O,\r\n }\r\n\r\n\r\n let gridArray = this.letters[letter];\r\n\r\n this.text = new Entity(this.iterations, verlyInstance);\r\n // this.text.renderPoints = function() {};\r\n\r\n for (let x = 0; x < gridArray.length; x++) {\r\n for (let y = 0; y < gridArray[x].length; y++) {\r\n if (gridArray[y][x] == 1) {\r\n let p = new Point(this.x + x * this.size, this.y + y * this.size);\r\n p.setRadius(2);\r\n this.text.addPoint(p);\r\n }\r\n }\r\n }\r\n\r\n // join\r\n for (let i = 0; i < this.text.points.length; i++) {\r\n for (let j = 0; j < this.text.points.length; j++) {\r\n if (this.text.points[i] == this.text.points[j]) break;\r\n let d = this.text.points[i].pos.dist(this.text.points[j].pos);\r\n\r\n if (d > 0 && d < this.size + this.stickDistance) {\r\n this.text.addStick(i, j);\r\n }\r\n }\r\n }\r\n }\r\n}\r\n\r\nexport default TypoGraphy;","import Verly from './Verly';\r\nimport Utils from './Utils';\r\nimport Vector from './Vector';\r\nimport Point from './Point';\r\nimport Stick from './Stick';\r\nimport Entity from './Entity';\r\nimport TypoGraphy from './TypoGraphy';\r\n\r\nwindow.Verly = Verly;\r\nwindow.Vector = Vector;\r\nwindow.Point = Point;\r\nwindow.Stick = Stick;\r\nwindow.Entity = Entity;\r\nwindow.TypoGraphy = TypoGraphy;\r\n\r\nexport default Verly;"],"sourceRoot":""} \ No newline at end of file +{"version":3,"sources":["webpack:///webpack/bootstrap","webpack:///./src/Utils.js","webpack:///./src/Mouse.js","webpack:///./src/Verly.js","webpack:///./src/Vector.js","webpack:///./src/Point.js","webpack:///./src/Stick.js","webpack:///./src/Entity.js","webpack:///./src/TypoGraphy.js","webpack:///./src/app.js"],"names":["installedModules","__webpack_require__","moduleId","exports","module","i","l","modules","call","m","c","d","name","getter","o","Object","defineProperty","enumerable","get","r","Symbol","toStringTag","value","t","mode","__esModule","ns","create","key","bind","n","object","property","prototype","hasOwnProperty","p","s","window","normalizedRandom","Math","random","degreesToRad","degrees","PI","clamp","min","max","rand","arguments","length","lerp","a","b","Mouse","[object Object]","entities","canvas","ctx","this","draggedPoint","down","coord","Vector","offset","offsetCoord","addEventListener","e","setXY","offsetX","pos","x","offsetY","y","sub","resetVelocity","touches","clientX","clientY","pageX","pageY","getNearestPoint","renderDraggedPoint","dragPoint","point","beginPath","strokeStyle","arc","radius","stroke","closePath","k","points","dist","src_Verly","iterations","currentFrame","WIDTH","width","HEIGHT","height","mouse","args","mixEntity","Entity","sticks","push","index","indexOf","splice","concat","apply","addEntity","drag","update","renderPointIndex","render","w","h","box","addPoint","addStick","segments","stride1","stride2","hexagon","stride","theta","cos","sin","center","Stick","posx","posy","pinOffset","cloth","xStride","yStride","px","py","tear","threshold","startPoint","endPoint","removeSticks","pin","dontPush","gap","rope","undefined","x0","y0","ragdoll","setRadius","setMass","Vector_Vector","v1","v2","distSq","angle","v","fromAngle","len","mag","sqrt","normalize","mult","div","atan2","dx","dy","z","coeff","heading","src_Vector","src_Point","vx","vy","oldpos","bounce","friction","groundFriction","gravity","pinned","color","mass","forceAcc","g","f","vel","strength","delta","magSq","magR","normalizeTo","applyForce","add","time","speed","verlyInstance","fillStyle","fill","src_Stick","p1","p2","stiffness","hidden","stepCoef","diff","offsetx","offsety","m1","m2","moveTo","lineTo","src_Entity","setGravity","setFriction","map","Point","ishidden","stick","constrain","updatePoints","j","updateSticks","updateConstraints","fillText","renderPoints","renderSticks","src_TypoGraphy","size","letter","stickDistance","A","B","C","D","E","S","I","K","U","N","R","G","L","Y","V","X","P","H","O","letters","gridArray","text","Verly","TypoGraphy","__webpack_exports__"],"mappings":"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","file":"verly.bundle.js","sourcesContent":[" \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, { enumerable: true, get: getter });\n \t\t}\n \t};\n\n \t// define __esModule on exports\n \t__webpack_require__.r = function(exports) {\n \t\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n \t\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n \t\t}\n \t\tObject.defineProperty(exports, '__esModule', { value: true });\n \t};\n\n \t// create a fake namespace object\n \t// mode & 1: value is a module id, require it\n \t// mode & 2: merge all properties of value into the ns\n \t// mode & 4: return value when already ns object\n \t// mode & 8|1: behave like require\n \t__webpack_require__.t = function(value, mode) {\n \t\tif(mode & 1) value = __webpack_require__(value);\n \t\tif(mode & 8) return value;\n \t\tif((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;\n \t\tvar ns = Object.create(null);\n \t\t__webpack_require__.r(ns);\n \t\tObject.defineProperty(ns, 'default', { enumerable: true, value: value });\n \t\tif(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));\n \t\treturn ns;\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = 1);\n","/**\r\n * @method normalizedRandom\r\n */\r\nwindow.normalizedRandom = function () {\r\n return Math.random() * 2 - 1;\r\n};\r\n/**\r\n * @method degreesToRad\r\n * @param {number} degrees\r\n */\r\nwindow.degreesToRad = function (degrees) {\r\n var pi = Math.PI;\r\n return degrees * (pi / 180);\r\n}\r\n/**\r\n * @method clamp\r\n * @param {number} value\r\n * @param {number} min\r\n * @param {number} max\r\n */\r\nwindow.clamp = function (value, min, max) {\r\n return Math.max(min, Math.min(value, max));\r\n}\r\n/**\r\n * @method random\r\n */\r\nwindow.random = function (rand, min, max) {\r\n //one param\r\n if (arguments.length === 1) {\r\n return Math.random() * arguments[0];\r\n } else if (arguments.length == 2) {\r\n //min and max\r\n max = min;\r\n min = rand;\r\n rand = Math.random;\r\n }\r\n if (!min && !max) {\r\n return Math.random();\r\n } else if (!max) {\r\n //if only one is provided, then thats actually the max\r\n max = min;\r\n return rand() * max;\r\n }\r\n return rand() * (max - min) + min;\r\n};\r\n/**\r\n * @method lerp\r\n * @param {number} a\r\n * @param {number} b\r\n * @param {number} p\r\n */\r\nwindow.lerp = function (a, b, p) {\r\n return (b - a) * p + a;\r\n}\r\n","export default class Mouse {\r\n constructor(entities, canvas, ctx) {\r\n this.entities = entities;\r\n // Drag Interaction\r\n this.draggedPoint = null;\r\n this.down = false;\r\n this.coord = new Vector();\r\n this.offset = new Vector();\r\n this.offsetCoord = new Vector();\r\n this.canvas = canvas;\r\n this.ctx = ctx;\r\n\r\n this.canvas.addEventListener('mousedown', (e) => {\r\n this.down = true;\r\n if (this.draggedPoint) {\r\n this.offset.setXY(e.offsetX - this.draggedPoint.pos.x, e.offsetY - this.draggedPoint.pos.y);\r\n this.offsetCoord = Vector.sub(this.coord, this.offset);\r\n }\r\n })\r\n this.canvas.addEventListener('mouseup', (e) => {\r\n if (this.draggedPoint) {\r\n this.draggedPoint.resetVelocity();\r\n };\r\n this.down = false;\r\n this.draggedPoint = null;\r\n })\r\n\r\n this.canvas.addEventListener('mousemove', (e) => {\r\n this.coord.setXY(e.offsetX, e.offsetY);\r\n this.offsetCoord = Vector.sub(this.coord, this.offset);\r\n })\r\n\r\n // TOUCH\r\n this.canvas.addEventListener('touchstart', (e) => {\r\n let offset = e.touches[0];\r\n this.down = true;\r\n if (this.draggedPoint) {\r\n this.offset.setXY(offset.clientX - this.draggedPoint.pos.x, offset.clientY - this.draggedPoint.pos.y);\r\n this.offsetCoord = Vector.sub(this.coord, this.offset);\r\n }\r\n })\r\n this.canvas.addEventListener('touchend', (e) => {\r\n if (this.draggedPoint) {\r\n this.draggedPoint.resetVelocity();\r\n };\r\n this.down = false;\r\n this.draggedPoint = null;\r\n })\r\n this.canvas.addEventListener('touchmove', (e) => {\r\n let offset = e.touches[0];\r\n this.coord.setXY(offset.pageX, offset.pageY);\r\n this.offsetCoord = Vector.sub(this.coord, this.offset);\r\n })\r\n }\r\n\r\n dragPoint() {\r\n if (!this.down) return;\r\n this.draggedPoint.pos.setXY(this.offsetCoord.x, this.offsetCoord.y);\r\n }\r\n\r\n drag() {\r\n if (!this.down) {\r\n this.draggedPoint = this.getNearestPoint();\r\n }\r\n if (this.draggedPoint) {\r\n this.renderDraggedPoint(this.draggedPoint);\r\n this.dragPoint();\r\n }\r\n }\r\n \r\n renderDraggedPoint(point) {\r\n this.ctx.beginPath();\r\n this.ctx.strokeStyle = 'black';\r\n this.ctx.arc(point.pos.x, point.pos.y, point.radius * 1.5, 0, Math.PI * 2);\r\n this.ctx.stroke();\r\n this.ctx.closePath();\r\n }\r\n\r\n\r\n getNearestPoint() {\r\n // if (!this.down) return false;\r\n let d = 20;\r\n let p = null;\r\n for (let k = 0; k < this.entities.length; k++) {\r\n for (let i = 0; i < this.entities[k].points.length; i++) {\r\n let dist = this.entities[k].points[i].pos.dist(this.coord);\r\n if (dist < d) {\r\n p = this.entities[k].points[i];\r\n }\r\n }\r\n }\r\n return p;\r\n }\r\n}\r\n","import Mouse from './Mouse';\r\n\r\n/**\r\n * @class Verly\r\n * @version 1.2.1\r\n * @author \r\n */\r\nclass Verly {\r\n /**\r\n * \r\n * @param {Number} iterations \r\n * @param {HTMLCanvasElement} canvas \r\n * @param {CanvasRenderingContext2D} ctx \r\n */\r\n constructor(iterations, canvas, ctx) {\r\n this.entities = [];\r\n this.iterations = iterations;\r\n this.currentFrame = 0;\r\n this.canvas = canvas;\r\n this.WIDTH = canvas.width;\r\n this.HEIGHT = canvas.height;\r\n this.ctx = ctx;\r\n this.mouse = new Mouse(this.entities, this.canvas, this.ctx);\r\n }\r\n\r\n /**\r\n * @param {...Entity} args\r\n * @description Joins two Entity Class Together \r\n * \r\n * @example\r\n * let canvas = document.getElementById('c');\r\n * let ctx = canvas.getContext('2d');\r\n * let width = canvas.width = 600;\r\n * let height = canvas.height = 500;\r\n * \r\n * let verly = new Verly(16, canvas, ctx);\r\n * let box = verly.createBox(100, 100, 100, 100);\r\n * let rope = verly.createRope(100, 100, 15, 10, 0);\r\n * \r\n * // verly.joinEntities(...Entity)\r\n * let mix = verly.joinEntities(box, rope);\r\n * mix.addStick(0, 18, 20)\r\n * \r\n * function animate() {\r\n * ctx.clearRect(0, 0, width, height);\r\n * \r\n * verly.update();\r\n * verly.render();\r\n * verly.interact();\r\n * verly.renderPointIndex();\r\n * \r\n * requestAnimationFrame(animate);\r\n * }\r\n * animate();\r\n * \r\n */\r\n joinEntities(...args) {\r\n let mixEntity = new Entity(this.iterations, this);\r\n\r\n let points = [];\r\n let sticks = [];\r\n\r\n // loop through the args and push points and sticks to the array\r\n for (let i = 0; i < args.length; i++) {\r\n points.push(args[i].points);\r\n sticks.push(args[i].sticks);\r\n\r\n // get the index which item we should splice in [this.entities]\r\n let index = this.entities.indexOf(args[i]);\r\n this.entities.splice(index, 1);\r\n }\r\n\r\n // join multiple arrays\r\n points = [].concat.apply([], points);\r\n sticks = [].concat.apply([], sticks);\r\n\r\n // add the arrays to the mix::Entity\r\n mixEntity.points = points;\r\n mixEntity.sticks = sticks;\r\n\r\n // add the mix::Entity to [this.entities]\r\n this.addEntity(mixEntity);\r\n return mixEntity; // return for chaining\r\n }\r\n\r\n /**\r\n * @param {Entity} e \r\n */\r\n addEntity(e) {\r\n this.entities.push(e);\r\n }\r\n\r\n /**\r\n * drags points\r\n */\r\n interact() {\r\n this.mouse.drag();\r\n }\r\n\r\n /**\r\n * updates all the physics stuff\r\n */\r\n update() {\r\n for (let i = 0; i < this.entities.length; i++) {\r\n this.entities[i].update();\r\n }\r\n\r\n this.currentFrame++;\r\n }\r\n\r\n /**\r\n */\r\n renderPointIndex() {\r\n for (let i = 0; i < this.entities.length; i++) {\r\n this.entities[i].renderPointIndex(this.ctx);\r\n }\r\n }\r\n\r\n /**\r\n * renders all the entity\r\n */\r\n render() {\r\n for (let i = 0; i < this.entities.length; i++) {\r\n this.entities[i].render(this.ctx);\r\n }\r\n }\r\n\r\n\r\n\r\n\r\n /**\r\n * @param {number} x \r\n * @param {number} y \r\n * @param {number} w \r\n * @param {number} h \r\n */\r\n createBox(x, y, w, h) {\r\n const box = new Entity(this.iterations, this);\r\n box.addPoint(x, y, 0, 0);\r\n box.addPoint(x + w, y, 0, 0);\r\n box.addPoint(x + w, y + h, 0, 0);\r\n box.addPoint(x, y + h, 0, 0);\r\n box.addStick(0, 1);\r\n box.addStick(1, 2);\r\n box.addStick(2, 3);\r\n box.addStick(3, 0);\r\n box.addStick(3, 1);\r\n\r\n this.addEntity(box);\r\n return box;\r\n }\r\n\r\n\r\n /**\r\n * @param {number} x \r\n * @param {number} y \r\n * @param {number} segments \r\n * @param {number} radius=50\r\n * @param {number} stride1=1\r\n * @param {number} stride2=5\r\n */\r\n createHexagon(x, y, segments, radius = 50, stride1 = 1, stride2 = 5) {\r\n const hexagon = new Entity(this.iterations, this);\r\n\r\n let stride = (2 * Math.PI) / segments;\r\n\r\n // points\r\n for (let i = 0; i < segments; ++i) {\r\n let theta = i * stride;\r\n hexagon.addPoint(\r\n x + Math.cos(theta) * radius,\r\n y + Math.sin(theta) * radius,\r\n 0, 0\r\n );\r\n }\r\n\r\n let center = hexagon.addPoint(x, y, 0, 0);\r\n\r\n // sticks\r\n for (let i = 0; i < segments; ++i) {\r\n hexagon.addStick(i, (i + stride1) % segments);\r\n hexagon.addStick(new Stick(hexagon.points[i], center));\r\n hexagon.addStick(i, (i + stride2) % segments);\r\n }\r\n\r\n\r\n this.addEntity(hexagon);\r\n return hexagon;\r\n }\r\n\r\n /**\r\n * @param {number} posx \r\n * @param {number} posy \r\n * @param {number} w \r\n * @param {number} h \r\n * @param {number} segments \r\n * @param {number} pinOffset \r\n */\r\n createCloth(posx, posy, w, h, segments, pinOffset) {\r\n let cloth = new Entity(this.iterations, this);\r\n\r\n let xStride = w / segments;\r\n let yStride = h / segments;\r\n\r\n let x, y;\r\n for (y = 0; y < segments; ++y) {\r\n for (x = 0; x < segments; ++x) {\r\n let px = posx + x * xStride - w / 2 + xStride / 2;\r\n let py = posy + y * yStride - h / 2 + yStride / 2;\r\n cloth.addPoint(px, py);\r\n\r\n if (x > 0) {\r\n cloth.addStick(y * segments + x, y * segments + x - 1);\r\n }\r\n\r\n if (y > 0) {\r\n cloth.addStick(y * segments + x, (y - 1) * segments + x);\r\n }\r\n }\r\n }\r\n\r\n // as the name suggest\r\n function tear(threshold) {\r\n for (let i = 0; i < cloth.sticks.length; i++) {\r\n // find the distance between two points\r\n let dist = cloth.sticks[i].startPoint.pos.dist(cloth.sticks[i].endPoint.pos)\r\n if (dist > (threshold || 20)) { // remove if the dist is > than threshold \r\n cloth.removeSticks(cloth.sticks[i].startPoint);\r\n }\r\n }\r\n }\r\n\r\n cloth.tear = tear;\r\n\r\n for (x = 0; x < segments; ++x) {\r\n if (x % pinOffset == 0) { // magic\r\n cloth.pin(x);\r\n }\r\n }\r\n\r\n !this.dontPush && this.addEntity(cloth);\r\n return cloth;\r\n }\r\n\r\n\r\n /**\r\n * @param {number} x \r\n * @param {number} y \r\n * @param {number} segments=10\r\n * @param {number} gap=15\r\n * @param {number} pin=0\r\n */\r\n createRope(x, y, segments = 10, gap = 15, pin) {\r\n let rope = new Entity(this.iterations, this);\r\n\r\n for (let i = 0; i < segments; i++) {\r\n rope.addPoint(x + i * gap, y, 0, 0)\r\n }\r\n\r\n for (let i = 0; i < segments - 1; i++) {\r\n rope.addStick(i, (i + 1) % segments);\r\n }\r\n\r\n if (pin !== undefined) {\r\n rope.pin(pin);\r\n }\r\n this.addEntity(rope);\r\n return rope;\r\n }\r\n\r\n\r\n createRagdoll(x0, y0) {\r\n let ragdoll = new Entity(this.iterations, this);\r\n\r\n // Head\r\n ragdoll.addPoint(x0, y0).setRadius(15).setMass(5);\r\n\r\n // Groin\r\n ragdoll.addPoint(x0, y0 + 100);\r\n\r\n // Hips\r\n ragdoll.addPoint(x0 + 30, y0 + 90);\r\n ragdoll.addPoint(x0 - 30, y0 + 90);\r\n\r\n // Knees\r\n ragdoll.addPoint(x0 + 20, y0 + 150);\r\n ragdoll.addPoint(x0 - 20, y0 + 150);\r\n\r\n // Feet\r\n ragdoll.addPoint(x0 + 30, y0 + 190).setRadius(10).setMass(20);\r\n ragdoll.addPoint(x0 - 30, y0 + 190).setRadius(10).setMass(20);\r\n\r\n // Neck\r\n ragdoll.addPoint(x0, y0 + 25);\r\n\r\n // Shoulders\r\n ragdoll.addPoint(x0 + 25, y0 + 30);\r\n ragdoll.addPoint(x0 - 25, y0 + 30);\r\n\r\n // Hands\r\n ragdoll.addPoint(x0 + 15, y0 + 105).setRadius(10).setMass(5);\r\n ragdoll.addPoint(x0 - 15, y0 + 105).setRadius(10).setMass(5);\r\n\r\n\r\n\r\n // \"Muscles\"\r\n // Head - shoulders\r\n ragdoll.addStick(0, 9);\r\n ragdoll.addStick(0, 10);\r\n // Shoulder - shoulder\r\n ragdoll.addStick(9, 10);\r\n\r\n // Shoulders - hips\r\n ragdoll.addStick(9, 2);\r\n ragdoll.addStick(10, 3);\r\n // Shoulders - hips opposite side\r\n ragdoll.addStick(9, 3);\r\n ragdoll.addStick(10, 2);\r\n\r\n // Hips - feet\r\n ragdoll.addStick(2, 6);\r\n ragdoll.addStick(3, 7);\r\n\r\n // Hips - feet, opposite\r\n ragdoll.addStick(2, 7);\r\n ragdoll.addStick(3, 6);\r\n\r\n // Head - groin\r\n ragdoll.addStick(0, 1);\r\n\r\n // Hip - hip\r\n ragdoll.addStick(2, 3);\r\n // Shoulder - hip\r\n ragdoll.addStick(9, 2);\r\n ragdoll.addStick(10, 3);\r\n\r\n // Head - knee\r\n ragdoll.addStick(0, 4);\r\n // Head - knee\r\n ragdoll.addStick(0, 5);\r\n\r\n // Head feet\r\n ragdoll.addStick(0, 6);\r\n ragdoll.addStick(0, 7);\r\n\r\n // Body parts\r\n // Hips\r\n ragdoll.addStick(1, 2);\r\n ragdoll.addStick(1, 3);\r\n // Legs\r\n ragdoll.addStick(2, 4);\r\n ragdoll.addStick(3, 5);\r\n ragdoll.addStick(4, 6);\r\n ragdoll.addStick(5, 7);\r\n\r\n ragdoll.addStick(0, 8);\r\n ragdoll.addStick(8, 1);\r\n\r\n // Left arm\r\n ragdoll.addStick(8, 9);\r\n ragdoll.addStick(9, 11);\r\n\r\n // Right arm\r\n ragdoll.addStick(8, 10);\r\n ragdoll.addStick(10, 12);\r\n\r\n this.addEntity(ragdoll);\r\n return ragdoll;\r\n }\r\n}\r\n\r\nexport default Verly;","/**\r\n * @class Vector\r\n * @version v1.0.0\r\n * @author Anurag Hazra\r\n * @param {number} x\r\n * @param {number} y\r\n */\r\nclass Vector {\r\n\r\n constructor(x, y) {\r\n this.x = x || 0;\r\n this.y = y || 0;\r\n }\r\n\r\n /**\r\n * get distance from two vectors\r\n * @param {Vector} v1 \r\n * @param {Vector} v2 \r\n * @return {number}\r\n */\r\n static dist(v1, v2) {\r\n return v1.dist(v2);\r\n }\r\n \r\n /**\r\n * get distance squared from two vectors \r\n * @param {Vector} v1 \r\n * @param {Vector} v2 \r\n * @return {number}\r\n */\r\n static distSq(v1, v2) {\r\n return v1.distSq(v2);\r\n }\r\n\r\n /**\r\n * subtract two vectors\r\n * @param {Vector} v1 \r\n * @param {Vector} v2 \r\n * @return {Vector}\r\n */\r\n static sub(v1, v2) {\r\n return new Vector(v1.x - v2.x, v1.y - v2.y);\r\n }\r\n\r\n /**\r\n * add two vectors\r\n * @param {Vector} v1 \r\n * @param {Vector} v2 \r\n * @return {Vector}\r\n */\r\n static add(v1, v2) {\r\n return new Vector(v1.x + v2.x, v1.y + v2.y);\r\n }\r\n\r\n /**\r\n * create vector from angle\r\n * @param {number} angle \r\n */\r\n static fromAngle(angle) {\r\n let v = new Vector(0, 0);\r\n v.x = Math.cos(angle);\r\n v.y = Math.sin(angle);\r\n return v;\r\n }\r\n\r\n /**\r\n * create random2d vector\r\n * @return {Vector}\r\n */\r\n static random2D() {\r\n return Vector.fromAngle(Math.random() * Math.PI * 180);\r\n } \r\n \r\n /**\r\n * adds random jitter motion\r\n * @param {number} a \r\n * @param {number} b \r\n * @return {Vector}\r\n */\r\n jitter(a, b) {\r\n var v = new Vector(a, b);\r\n this.x += normalizedRandom() * v.x;\r\n this.y += normalizedRandom() * v.y;\r\n return this;\r\n }\r\n\r\n /**\r\n * add this vector to another vector\r\n * @param {Vector|number} x \r\n * @param {Number} y \r\n * @return {Vector}\r\n */\r\n add(x, y) {\r\n if (arguments.length === 1) {\r\n this.x += x.x;\r\n this.y += x.y;\r\n } else if (arguments.length === 2) {\r\n this.x += x;\r\n this.y += y;\r\n }\r\n return this;\r\n }\r\n\r\n /**\r\n * subtracts this vector to another vector\r\n * @param {Vector|number} x \r\n * @param {Number} y \r\n * @return {Vector}\r\n */\r\n sub(x, y) {\r\n if (arguments.length === 1) {\r\n this.x -= x.x;\r\n this.y -= x.y;\r\n } else if (arguments.length === 2) {\r\n this.x -= x;\r\n this.y -= y;\r\n }\r\n return this;\r\n }\r\n\r\n /**\r\n * multiply this vector to a scalar value or a vector\r\n * @param {Vector|number} v \r\n * @return {Vector}\r\n */\r\n mult(v) {\r\n if (typeof v === 'number') {\r\n this.x *= v;\r\n this.y *= v;\r\n } else {\r\n this.x *= v.x;\r\n this.y *= v.y;\r\n }\r\n return this;\r\n }\r\n\r\n /**\r\n * divide this vector to a scalar value or a vector\r\n * @param {Vector|number} v \r\n * @return {Vector}\r\n */\r\n div(v) {\r\n if (typeof v === 'number') {\r\n this.x /= v;\r\n this.y /= v;\r\n } else {\r\n this.x /= v.x;\r\n this.y /= v.y;\r\n }\r\n return this;\r\n }\r\n\r\n /**\r\n * set this vectors angle\r\n * @param {number} angle \r\n */\r\n setAngle(angle) {\r\n var len = this.mag();\r\n this.x = Math.cos(angle) * len;\r\n this.y = Math.sin(angle) * len;\r\n }\r\n\r\n\r\n /**\r\n * get the magnitude of this vector\r\n * @return {number}\r\n */\r\n mag() {\r\n return Math.sqrt(this.x * this.x + this.y * this.y);\r\n }\r\n\r\n /**\r\n * get the magnitude sqr of this vector\r\n * @return {number}\r\n */\r\n magSq() {\r\n return (this.x * this.x + this.y * this.y);\r\n }\r\n\r\n /**\r\n * set x, y of this vector\r\n * @param {number} x \r\n * @param {number} y \r\n * @return {Vector}\r\n */\r\n setXY(x, y) {\r\n this.x = x;\r\n this.y = y;\r\n return this;\r\n }\r\n\r\n /**\r\n * set the magnitude of this vector\r\n * @param {number} value \r\n * @return {Vector}\r\n */\r\n setMag(value) {\r\n this.normalize();\r\n this.mult(value);\r\n return this;\r\n }\r\n \r\n /**\r\n * normalize this vector \r\n * @return {Vector}\r\n */\r\n normalize() {\r\n let m = this.mag();\r\n if (m > 0) {\r\n this.div(m);\r\n }\r\n return this;\r\n }\r\n\r\n /**\r\n * normalize this vector to a specific length\r\n * @param {number} length \r\n * @return {Vector}\r\n */\r\n normalizeTo(length) {\r\n var mag = this.mag();\r\n if (mag > 0) {\r\n mag = length / mag;\r\n this.mult(mag);\r\n }\r\n return this;\r\n }\r\n\r\n /**\r\n * limit this vector\r\n * @param {number} max \r\n * @return {Vector}\r\n */\r\n limit(max) {\r\n if (this.mag() > max) {\r\n this.normalize();\r\n this.mult(max);\r\n }\r\n return this;\r\n }\r\n\r\n /**\r\n * get heading of this vector in radians\r\n * @return {number}\r\n */\r\n heading() {\r\n return (-Math.atan2(-this.y, this.x));\r\n }\r\n \r\n /**\r\n * get distance between this and specific vector\r\n * @param {Vector} v \r\n * @return {number}\r\n */\r\n dist(v) {\r\n let dx = this.x - v.x;\r\n let dy = this.y - v.y;\r\n return Math.sqrt(dx * dx + dy * dy);\r\n }\r\n\r\n /**\r\n * get distance sqr between this and specific vector\r\n * @param {Vector} v \r\n * @return {number}\r\n */\r\n distSq(v) {\r\n let dx = this.x - v.x;\r\n let dy = this.y - v.y;\r\n return (dx * dx + dy * dy);\r\n }\r\n\r\n /**\r\n * copy this vector\r\n * @return {Vector}\r\n */\r\n copy() {\r\n return new Vector(this.x, this.y);\r\n }\r\n \r\n /**\r\n * revert this vector\r\n * @return {Vector}\r\n */\r\n negative() {\r\n this.x = -this.x;\r\n this.y = -this.y;\r\n return this;\r\n }\r\n \r\n /**\r\n * return an array representation of this vector\r\n * @return {Array}\r\n */\r\n array() {\r\n return [this.x, this.y];\r\n }\r\n \r\n /**\r\n * return a string representation of this vector\r\n * @return {String}\r\n */\r\n toString() {\r\n return \"[\" + this.x + \", \" + this.y + \", \" + this.z + \"]\";\r\n }\r\n \r\n /**\r\n * \r\n * @param {Vector} v \r\n * @return {Vector}\r\n */\r\n project(v) {\r\n var coeff = ((this.x * v.x) + (this.y * v.y)) / ((v.x * v.x) + (v.y * v.y));\r\n this.x = coeff * v.x;\r\n this.y = coeff * v.y;\r\n return this;\r\n }\r\n \r\n /**\r\n * rotate this vector\r\n * @param {number} a \r\n */\r\n rotate(a) {\r\n var b = this.heading() + a;\r\n var c = this.mag();\r\n this.x = Math.cos(b) * c;\r\n this.y = Math.sin(b) * c;\r\n }\r\n}\r\n\r\nexport default Vector;","class Point {\r\n /**\r\n * \r\n * @param {number} x \r\n * @param {number} y \r\n * @param {number=} vx \r\n * @param {number=} vy \r\n * @param {number=} radius \r\n */\r\n constructor(x, y, vx, vy, radius) {\r\n this.pos = new Vector(x, y);\r\n this.oldpos = new Vector(x + (vx || 0), y + (vy || 0));\r\n this.bounce = 0.99;\r\n this.friction = 0.97;\r\n this.groundFriction = 0.7;\r\n this.gravity = new Vector(0, 1);\r\n this.pinned = false;\r\n this.radius = radius || 5;\r\n this.color = '#e62a4f';\r\n this.mass = 1;\r\n this.sticks = [];\r\n // this.behaviors = [];\r\n this.forceAcc = 1;\r\n }\r\n\r\n /**\r\n * \r\n * @param {Vector} g \r\n */\r\n setGravity(g) {\r\n this.gravity = g;\r\n return this;\r\n }\r\n /**\r\n * \r\n * @param {number} f \r\n */\r\n setFriction(f) {\r\n this.friction = f;\r\n return this;\r\n }\r\n /**\r\n * \r\n * @param {number} f \r\n */\r\n setGroundFriction(f) {\r\n this.groundFriction = f;\r\n return this;\r\n }\r\n /**\r\n * \r\n * @param {number} b\r\n */\r\n setBounce(b) {\r\n this.bounce = b;\r\n return this;\r\n }\r\n /**\r\n * \r\n * @param {number} f \r\n * @returns {Point}\r\n */\r\n setForceAcc(f) {\r\n this.forceAcc = f;\r\n return this;\r\n }\r\n /**\r\n * \r\n * @param {number} m \r\n * @returns {Point}\r\n */\r\n setMass(m) {\r\n this.mass = m;\r\n return this;\r\n }\r\n /**\r\n * \r\n * @param {number} radius \r\n * @returns {Point}\r\n */\r\n setRadius(radius) {\r\n this.radius = radius;\r\n return this;\r\n }\r\n\r\n /**\r\n * @param {string} color \r\n * @returns {Point}\r\n */\r\n setColor(color) {\r\n this.color = color;\r\n return this;\r\n }\r\n\r\n /**\r\n * @param {Vector} vel \r\n * @returns {Point}\r\n */\r\n setVelocity(vel) {\r\n this.oldpos.setXY(vel.x, vel.y);\r\n return this;\r\n }\r\n\r\n /**\r\n * @returns {Point}\r\n */\r\n pin() {\r\n this.pinned = true;\r\n return this;\r\n }\r\n /**\r\n * @returns {Point}\r\n */\r\n unpin() {\r\n this.pinned = false;\r\n return this;\r\n }\r\n\r\n resetVelocity() {\r\n this.oldpos.setXY(this.pos.x, this.pos.y);\r\n }\r\n\r\n /**\r\n * \r\n * @param {number} angle \r\n * @param {number} offset \r\n */\r\n rotate(angle, offset) {\r\n let x = offset.x + (this.pos.x - offset.x) * Math.cos(angle) - (this.pos.y - offset.y) * Math.sin(angle);\r\n let y = offset.y + (this.pos.x - offset.x) * Math.sin(angle) + (this.pos.y - offset.y) * Math.cos(angle);\r\n this.pos.setXY(x, y);\r\n }\r\n\r\n /**\r\n * \r\n * @param {Point} p \r\n * @param {number} radius \r\n * @param {number} strength \r\n */\r\n resolveBehaviors(p, radius = this.radius, strength = this.forceAcc) {\r\n var delta = Vector.sub(this.pos, p.pos);\r\n var dist = delta.magSq();\r\n\r\n let magR = radius * radius;\r\n if (dist < magR) {\r\n var f = delta.normalizeTo(1 - (dist / magR)).mult(strength);\r\n this.applyForce(f);\r\n }\r\n }\r\n\r\n /**\r\n * \r\n * @param {number|Vector} f \r\n */\r\n applyForce(f) {\r\n this.pos.add(f);\r\n }\r\n\r\n /**\r\n * \r\n * @param {number} x \r\n * @param {number} y \r\n * @param {number} time \r\n * @param {number} radius \r\n * @param {number} speed \r\n */\r\n addMotor(x, y, time, radius, speed) {\r\n this.pos.x = x + radius * Math.cos(time * speed);\r\n this.pos.y = y + radius * Math.sin(time * speed);\r\n }\r\n\r\n /**\r\n * @param {Verly} verlyInstance \r\n */\r\n constrain(verlyInstance) {\r\n // if (this.pos.y > HEIGHT - 1) {\r\n // this.pos.y = HEIGHT - 1;\r\n // }\r\n // if (this.pos.x < 0) {\r\n // this.pos.x = 0;\r\n // }\r\n // if (this.pos.x > WIDTH - 1) {\r\n // this.pos.x = WIDTH - 1;\r\n // }\r\n // let vel = Vector.sub(this.pos, this.oldpos);\r\n if (this.pos.x > verlyInstance.WIDTH - this.radius) {\r\n this.pos.x = verlyInstance.WIDTH - this.radius;\r\n // this.oldpos.x = (this.pos.x + vel.x) * this.bounce;\r\n }\r\n if (this.pos.x < this.radius) {\r\n this.pos.x = this.radius;\r\n // this.oldpos.x = (this.pos.x + vel.x) * this.bounce;\r\n }\r\n if (this.pos.y > verlyInstance.HEIGHT - this.radius) {\r\n this.pos.y = verlyInstance.HEIGHT - this.radius;\r\n // this.oldpos.y = (this.pos.y + vel.y) * this.bounce;\r\n }\r\n if (this.pos.y < this.radius) {\r\n this.pos.y = this.radius;\r\n // this.oldpos.y = (this.pos.y + vel.y) * this.bounce;\r\n }\r\n };\r\n\r\n\r\n /**\r\n * @param {Verly} verlyInstance \r\n */\r\n update(verlyInstance) {\r\n if (this.pinned) return;\r\n let vel = Vector.sub(this.pos, this.oldpos);\r\n vel.mult(this.friction);\r\n // if the point touches the ground set groundFriction\r\n if (this.pos.y >= verlyInstance.HEIGHT - this.radius && vel.magSq() > 0.000001) {\r\n var m = vel.mag();\r\n vel.x /= m;\r\n vel.y /= m;\r\n vel.mult(m * this.groundFriction);\r\n }\r\n this.oldpos.setXY(this.pos.x, this.pos.y);\r\n this.pos.add(vel);\r\n this.pos.add(this.gravity);\r\n }\r\n\r\n /**\r\n * @param {CanvasRenderingContext2D} ctx \r\n */\r\n render(ctx) {\r\n ctx.beginPath();\r\n ctx.fillStyle = this.color;\r\n ctx.arc(this.pos.x, this.pos.y, this.radius, 0, Math.PI * 2);\r\n ctx.fill();\r\n ctx.closePath();\r\n }\r\n}\r\n\r\n\r\nexport default Point;","class Stick {\r\n /**\r\n * creates a stick between two Point\r\n * takes optional length and stiffness \r\n * @param {Point} p1 \r\n * @param {Point} p2 \r\n * @param {number=} length \r\n * @param {number=} stiffness \r\n * @param {boolean=} hidden \r\n */\r\n constructor(p1, p2, length, stiffness, hidden) {\r\n this.startPoint = p1;\r\n this.endPoint = p2;\r\n this.stiffness = stiffness || 2;\r\n this.color = '#f5476a';\r\n this.hidden = hidden;\r\n if (!length) {\r\n this.length = this.startPoint.pos.dist(this.endPoint.pos);\r\n } else {\r\n this.length = length;\r\n }\r\n this.startPoint.sticks.push(this);\r\n this.endPoint.sticks.push(this);\r\n }\r\n\r\n /**\r\n * \r\n * @param {number=} stepCoef \r\n */\r\n update(stepCoef) {\r\n // not gonna use vectors for performance optimization\r\n // let dx = this.endPoint.pos.x - this.startPoint.pos.x;\r\n // let dy = this.endPoint.pos.y - this.startPoint.pos.y;\r\n // let dist = Math.sqrt(dx * dx + dy * dy);\r\n // let diff = this.length - dist;\r\n // let percent = diff / dist / 2;\r\n // let offsetx = (dx * percent);\r\n // let offsety = (dy * percent);\r\n // if (!this.startPoint.pinned) {\r\n // this.startPoint.pos.x -= offsetx;\r\n // this.startPoint.pos.y -= offsety;\r\n // }\r\n // if (!this.endPoint.pinned) {\r\n // this.endPoint.pos.x += offsetx;\r\n // this.endPoint.pos.y += offsety;\r\n // }\r\n // ----- algo two\r\n\r\n // algo three\r\n let dx = this.endPoint.pos.x - this.startPoint.pos.x;\r\n let dy = this.endPoint.pos.y - this.startPoint.pos.y;\r\n let dist = Math.sqrt(dx * dx + dy * dy);\r\n let diff = (this.length - dist) / dist * this.stiffness;\r\n\r\n let offsetx = dx * diff * 0.5;\r\n let offsety = dy * diff * 0.5;\r\n\r\n // calculate mass\r\n let m1 = this.startPoint.mass + this.endPoint.mass;\r\n let m2 = this.startPoint.mass / m1;\r\n m1 = this.endPoint.mass / m1;\r\n\r\n if (!this.startPoint.pinned) {\r\n this.startPoint.pos.x -= offsetx * m1;\r\n this.startPoint.pos.y -= offsety * m1;\r\n }\r\n if (!this.endPoint.pinned) {\r\n this.endPoint.pos.x += offsetx * m2;\r\n this.endPoint.pos.y += offsety * m2;\r\n }\r\n\r\n \r\n // calculate mass\r\n // var m1 = this.startPoint.mass + this.endPoint.mass;\r\n // var m2 = this.startPoint.mass / m1;\r\n // m1 = this.endPoint.mass / m1;\r\n \r\n // var normal = Vector.sub(this.startPoint.pos, this.endPoint.pos);\r\n // var m = normal.magSq();\r\n // let diff = ((this.length * this.length) - m);\r\n // normal.mult((diff / m) * this.stiffness * stepCoef);\r\n \r\n // if (!this.startPoint.pinned) {\r\n // this.startPoint.pos.add(normal);\r\n // }\r\n // if (!this.endPoint.pinned) {\r\n // this.endPoint.pos.sub(normal);\r\n // }\r\n }\r\n\r\n /**\r\n * @param {string} color\r\n * @returns {Stick}\r\n */\r\n setColor(color) {\r\n this.color = color;\r\n return this;\r\n }\r\n\r\n /**\r\n * @param {number} length\r\n * @returns {Stick}\r\n */\r\n setLength(length) {\r\n this.length = length;\r\n return this;\r\n }\r\n\r\n /**\r\n * @param {number} value\r\n * @returns {Stick}\r\n */\r\n setStiffness(value) {\r\n this.stiffness = value;\r\n return this;\r\n }\r\n\r\n /**\r\n * @param {boolean} value\r\n * @returns {Stick}\r\n */\r\n setHidden(value) {\r\n this.hidden = value;\r\n return this;\r\n }\r\n\r\n /**\r\n * \r\n * @param {CanvasRenderingContext2D} ctx \r\n */\r\n render(ctx) {\r\n if (this.hidden) return;\r\n ctx.beginPath();\r\n ctx.strokeStyle = this.color;\r\n ctx.moveTo(this.startPoint.pos.x, this.startPoint.pos.y);\r\n ctx.lineTo(this.endPoint.pos.x, this.endPoint.pos.y);\r\n ctx.stroke();\r\n ctx.closePath();\r\n }\r\n}\r\n\r\nexport default Stick;\r\n","class Entity {\r\n\r\n /**\r\n * @param {number} iterations \r\n * @param {Verly} verlyInstance \r\n */\r\n constructor(iterations, verlyInstance) {\r\n this.points = [];\r\n this.sticks = [];\r\n this.verlyInstance = verlyInstance;\r\n this.iterations = iterations || 16;\r\n }\r\n\r\n\r\n // join(...args) {\r\n // let points = [];\r\n // let sticks = [];\r\n\r\n // // loop through the args and push points and sticks to the array\r\n // for (let i = 0; i < args.length; i++) {\r\n // points.push(args[i].points);\r\n // sticks.push(args[i].sticks);\r\n // }\r\n\r\n // // join multiple arrays\r\n // points = [].concat.apply([], points);\r\n // sticks = [].concat.apply([], sticks);\r\n\r\n // // add the arrays to the mix::Entity\r\n // this.points = points;\r\n // this.sticks = sticks;\r\n\r\n // return this; // return for chaining\r\n // }\r\n\r\n /**\r\n * sets the gravity of this entity\r\n * @param {Vector} g \r\n */\r\n setGravity(g) {\r\n for (let i = 0; i < this.points.length; i++) {\r\n this.points[i].setGravity(g);\r\n }\r\n }\r\n\r\n /**\r\n * sets the friction of this entity\r\n * @param {number} f \r\n */\r\n setFriction(f) {\r\n for (let i = 0; i < this.points.length; i++) {\r\n this.points[i].setFriction(f);\r\n }\r\n }\r\n\r\n /**\r\n * pin a specific Point\r\n * @param {number} index \r\n */\r\n pin(index) {\r\n this.points[index].pin();\r\n }\r\n\r\n /**\r\n * remove a specific Point\r\n * @param {Point} p\r\n */\r\n removeSticks(p) {\r\n this.sticks.splice(this.sticks.indexOf(p.sticks[0]), 1);\r\n p.sticks.splice(0, 1);\r\n }\r\n\r\n /**\r\n * \r\n * @param {Number} x \r\n * @param {Number} y \r\n */\r\n setVelocity(x, y) {\r\n this.points.map(e => {\r\n e.oldpos.x += x;\r\n e.oldpos.y += y;\r\n })\r\n }\r\n\r\n /**\r\n * adds a Point in points array with {x,y,vx,vy,radius}\r\n * @param {Number|Point} x \r\n * @param {Number=} y \r\n * @param {Number=} vx \r\n * @param {Number=} vy \r\n * @param {Number=} radius \r\n * @returns {Point}\r\n */\r\n addPoint(x, y, vx, vy, radius) {\r\n let p\r\n if (x instanceof Point) {\r\n p = x;\r\n } else {\r\n p = new Point(x, y, vx, vy, radius);\r\n }\r\n this.points.push(p);\r\n return p;\r\n }\r\n\r\n /**\r\n * adds a stick inbetween two points\r\n * @param {number|Stick} p1 \r\n * @param {number=} p2 \r\n * @param {number=} length \r\n * @param {number=} stiffness \r\n * @param {boolean=} ishidden \r\n */\r\n addStick(p1, p2, length, stiffness, ishidden) {\r\n let stick;\r\n if (p1 instanceof Stick) {\r\n stick = p1;\r\n } else {\r\n stick = new Stick(this.points[p1], this.points[p2], length, stiffness, ishidden);\r\n }\r\n this.sticks.push(stick);\r\n return stick;\r\n }\r\n\r\n /**\r\n */\r\n updatePoints() {\r\n for (let i = 0; i < this.points.length; i++) {\r\n this.points[i].update(this.verlyInstance);\r\n }\r\n }\r\n\r\n /**\r\n * @methdo updateSticks\r\n * @param {Number=} stepCoef \r\n */\r\n updateSticks(stepCoef) {\r\n for (let i = 0; i < this.sticks.length; i++) {\r\n this.sticks[i].update(stepCoef);\r\n }\r\n }\r\n\r\n /**\r\n */\r\n updateConstraints() {\r\n for (let i = 0; i < this.points.length; i++) {\r\n this.points[i].constrain(this.verlyInstance);\r\n }\r\n }\r\n\r\n /**\r\n */\r\n update() {\r\n // var stepCoef = 1 / this.iterations;\r\n this.updatePoints();\r\n for (let j = 0; j < this.iterations; ++j) {\r\n this.updateSticks();\r\n this.updateConstraints();\r\n }\r\n }\r\n\r\n /**\r\n */\r\n renderPoints() {\r\n for (let i = 0; i < this.points.length; i++) {\r\n this.points[i].render(this.verlyInstance.ctx);\r\n }\r\n }\r\n\r\n /**\r\n */\r\n renderSticks() {\r\n for (let i = 0; i < this.sticks.length; i++) {\r\n this.sticks[i].render(this.verlyInstance.ctx);\r\n }\r\n }\r\n\r\n /**\r\n */\r\n renderPointIndex() {\r\n for (let i = 0; i < this.points.length; i++) {\r\n this.verlyInstance.ctx.beginPath();\r\n this.verlyInstance.ctx.fillStyle = 'black';\r\n this.verlyInstance.ctx.fillText(i, this.points[i].pos.x + 5, this.points[i].pos.y - 6);\r\n this.verlyInstance.ctx.closePath();\r\n }\r\n }\r\n\r\n\r\n /**\r\n */\r\n render() {\r\n this.renderPoints();\r\n this.renderSticks();\r\n }\r\n}\r\n\r\nexport default Entity;","class TypoGraphy {\r\n /**\r\n * \r\n * @param {number} x \r\n * @param {number} y \r\n * @param {number} size \r\n * @param {string} letter \r\n * @param {Verly} verlyInstance \r\n */\r\n constructor(x, y, size, letter, verlyInstance) {\r\n this.x = x;\r\n this.y = y;\r\n this.size = size;\r\n this.stickDistance = this.size;\r\n this.iterations = 50;\r\n // A\r\n this.A = [\r\n [0, 0, 1, 0, 0],\r\n [0, 1, 1, 1, 0],\r\n [0, 1, 0, 1, 0],\r\n [1, 1, 1, 1, 1],\r\n [1, 0, 0, 0, 1]\r\n ]\r\n // B\r\n this.B = [\r\n [1, 1, 1, 0, 0],\r\n [1, 1, 1, 1, 0],\r\n [1, 1, 1, 0, 0],\r\n [1, 1, 1, 1, 0],\r\n [1, 1, 1, 0, 0]\r\n ]\r\n\r\n // C\r\n this.C = [\r\n [1, 1, 1, 1, 0],\r\n [1, 1, 1, 1, 0],\r\n [1, 1, 0, 0, 0],\r\n [1, 1, 1, 1, 0],\r\n [1, 1, 1, 1, 0]\r\n ]\r\n\r\n // D\r\n this.D = [\r\n [1, 1, 1, 0, 0],\r\n [1, 1, 1, 1, 0],\r\n [1, 1, 1, 1, 0],\r\n [1, 1, 1, 1, 0],\r\n [1, 1, 1, 0, 0]\r\n ];\r\n\r\n // E\r\n this.E = [\r\n [0, 1, 1, 1, 0],\r\n [0, 1, 1, 0, 0],\r\n [0, 1, 1, 1, 0],\r\n [0, 1, 1, 0, 0],\r\n [0, 1, 1, 1, 0]\r\n ]\r\n\r\n // S\r\n this.S = [\r\n [0, 1, 1, 1, 0],\r\n [1, 1, 1, 0, 0],\r\n [1, 1, 1, 1, 0],\r\n [0, 1, 1, 1, 0],\r\n [1, 1, 1, 0, 0]\r\n ]\r\n\r\n // I \r\n this.I = [\r\n [0, 0, 1, 0, 0],\r\n [0, 1, 1, 1, 0],\r\n [0, 1, 1, 1, 0],\r\n [0, 1, 1, 1, 0],\r\n [0, 1, 1, 1, 0]\r\n ]\r\n\r\n\r\n // K\r\n this.K = [\r\n [1, 0, 1, 1, 0],\r\n [1, 1, 1, 0, 0],\r\n [1, 1, 0, 0, 0],\r\n [1, 1, 1, 0, 0],\r\n [1, 0, 1, 1, 0]\r\n ]\r\n\r\n // U\r\n this.U = [\r\n [1, 1, 0, 1, 1],\r\n [1, 1, 0, 1, 1],\r\n [1, 1, 0, 1, 1],\r\n [1, 1, 1, 1, 1],\r\n [0, 1, 1, 1, 0]\r\n ]\r\n\r\n // N\r\n this.N = [\r\n [0, 0, 0, 0, 0, 0],\r\n [1, 1, 0, 0, 1, 1],\r\n [1, 1, 1, 0, 1, 1],\r\n [1, 1, 1, 1, 1, 1],\r\n [1, 1, 0, 1, 1, 1],\r\n [1, 1, 0, 0, 1, 1]\r\n ]\r\n\r\n // R\r\n this.R = [\r\n [1, 1, 1, 0, 0],\r\n [1, 1, 1, 1, 0],\r\n [1, 1, 1, 1, 0],\r\n [1, 1, 1, 0, 0],\r\n [1, 1, 1, 1, 0]\r\n ]\r\n\r\n // G\r\n this.G = [\r\n [0, 1, 1, 1, 0],\r\n [1, 1, 1, 0, 0],\r\n [1, 1, 0, 1, 1],\r\n [1, 1, 1, 1, 1],\r\n [0, 1, 1, 1, 0]\r\n ]\r\n\r\n // L\r\n this.L = [\r\n [1, 1, 0, 0, 0],\r\n [1, 1, 0, 0, 0],\r\n [1, 1, 0, 0, 0],\r\n [1, 1, 1, 1, 1],\r\n [1, 1, 1, 1, 1]\r\n ]\r\n\r\n // Y\r\n this.Y = [\r\n [1, 1, 0, 1, 1],\r\n [1, 1, 0, 1, 1],\r\n [0, 1, 1, 1, 0],\r\n [0, 1, 1, 1, 0],\r\n [0, 1, 1, 1, 0]\r\n ]\r\n\r\n // V\r\n this.V = [\r\n [1, 0, 0, 0, 1],\r\n [1, 1, 0, 1, 1],\r\n [1, 1, 0, 1, 1],\r\n [1, 1, 1, 1, 1],\r\n [0, 1, 1, 1, 0]\r\n ]\r\n\r\n //X\r\n this.X = [\r\n [1, 1, 1, 1, 1],\r\n [1, 1, 1, 1, 1],\r\n [1, 1, 1, 1, 1],\r\n [1, 1, 1, 1, 1],\r\n [1, 1, 1, 1, 1]\r\n ]\r\n\r\n //P\r\n this.P = [\r\n [1, 1, 1, 0, 0],\r\n [1, 1, 1, 1, 0],\r\n [1, 1, 1, 1, 0],\r\n [1, 1, 1, 0, 0],\r\n [1, 1, 1, 0, 0]\r\n ]\r\n\r\n //H\r\n this.H = [\r\n [1, 1, 0, 1, 1],\r\n [1, 1, 0, 1, 1],\r\n [1, 1, 1, 1, 1],\r\n [1, 1, 0, 1, 1],\r\n [1, 1, 0, 1, 1]\r\n ]\r\n\r\n //O\r\n this.O = [\r\n [0, 1, 1, 1, 0],\r\n [1, 1, 0, 1, 1],\r\n [1, 1, 0, 1, 1],\r\n [1, 1, 0, 1, 1],\r\n [0, 1, 1, 1, 0]\r\n ]\r\n\r\n this.letters = {\r\n A: this.A,\r\n B: this.B,\r\n C: this.C,\r\n D: this.D,\r\n E: this.E,\r\n K: this.K,\r\n I: this.I,\r\n S: this.S,\r\n U: this.U,\r\n N: this.N,\r\n R: this.R,\r\n G: this.G,\r\n L: this.L,\r\n Y: this.Y,\r\n V: this.V,\r\n X: this.X,\r\n P: this.P,\r\n H: this.H,\r\n O: this.O,\r\n }\r\n\r\n\r\n let gridArray = this.letters[letter];\r\n\r\n this.text = new Entity(this.iterations, verlyInstance);\r\n // this.text.renderPoints = function() {};\r\n\r\n for (let x = 0; x < gridArray.length; x++) {\r\n for (let y = 0; y < gridArray[x].length; y++) {\r\n if (gridArray[y][x] == 1) {\r\n let p = new Point(this.x + x * this.size, this.y + y * this.size);\r\n p.setRadius(2);\r\n this.text.addPoint(p);\r\n }\r\n }\r\n }\r\n\r\n // join\r\n for (let i = 0; i < this.text.points.length; i++) {\r\n for (let j = 0; j < this.text.points.length; j++) {\r\n if (this.text.points[i] == this.text.points[j]) break;\r\n let d = this.text.points[i].pos.dist(this.text.points[j].pos);\r\n\r\n if (d > 0 && d < this.size + this.stickDistance) {\r\n this.text.addStick(i, j);\r\n }\r\n }\r\n }\r\n }\r\n}\r\n\r\nexport default TypoGraphy;","import Verly from './Verly';\r\nimport Utils from './Utils';\r\nimport Vector from './Vector';\r\nimport Point from './Point';\r\nimport Stick from './Stick';\r\nimport Entity from './Entity';\r\nimport TypoGraphy from './TypoGraphy';\r\n\r\nwindow.Verly = Verly;\r\nwindow.Vector = Vector;\r\nwindow.Point = Point;\r\nwindow.Stick = Stick;\r\nwindow.Entity = Entity;\r\nwindow.TypoGraphy = TypoGraphy;\r\n\r\nexport default Verly;"],"sourceRoot":""} \ No newline at end of file diff --git a/examples/behavior.html b/examples/behavior.html index d348c0b..4be437d 100644 --- a/examples/behavior.html +++ b/examples/behavior.html @@ -16,12 +16,10 @@ html, body { margin: 0; - padding: 10px; + padding: 0; + overflow: hidden; } - canvas { - outline: 1px solid black; - } @@ -34,10 +32,13 @@ window.onload = function () { let canvas = document.getElementById('c'); let ctx = canvas.getContext('2d'); - let width = 600; - let height = 500; + let width = window.innerWidth; + let height = window.innerHeight; canvas.width = width; canvas.height = height; + + let PARTICLE_COUNT = 700; + if (width < 400) PARTICLE_COUNT = 400; let verly = new Verly(16, canvas, ctx); @@ -58,7 +59,7 @@ particles.addPoint(x, y).setRadius(3).setGravity(new Vector(0, 0)); } - for (let i = 0; i < 700; i++) { + for (let i = 0; i < PARTICLE_COUNT; i++) { addParticles(random(width), random(height)); } diff --git a/examples/behavior2.html b/examples/behavior2.html index 8863e01..157fb31 100644 --- a/examples/behavior2.html +++ b/examples/behavior2.html @@ -16,12 +16,10 @@ html, body { margin: 0; - padding: 10px; + padding: 0; + overflow: hidden; } - canvas { - outline: 1px solid black; - } @@ -37,19 +35,20 @@ window.onload = function () { let canvas = document.getElementById('c'); let ctx = canvas.getContext('2d'); - let width = 600; - let height = 600; + let width = window.innerWidth; + let height = window.innerHeight; canvas.width = width; canvas.height = height; + let PARTICLE_COUNT = 400; let verly = new Verly(16, canvas, ctx); let particle = new Entity(16, verly); let p1 = particle.addPoint(0, 0).setRadius(20); let p2 = particle.addPoint(0, 0).setRadius(20); - for (let i = 0; i < 400; i++) { - particle.addPoint(random(width), random(height)); + for (let i = 0; i < PARTICLE_COUNT; i++) { + particle.addPoint(random(width), random(height)).setRadius(4); } particle.setGravity(new Vector(0, 0)); verly.addEntity(particle); diff --git a/examples/dynamicCustomMesh.html b/examples/dynamicCustomMesh.html index c670fdd..6e7a392 100644 --- a/examples/dynamicCustomMesh.html +++ b/examples/dynamicCustomMesh.html @@ -16,12 +16,10 @@ html, body { margin: 0; - padding: 10px; + padding: 0; + overflow: hidden; } - canvas { - outline: 1px solid black; - } @@ -31,12 +29,12 @@ diff --git a/index.js b/index.js index e2c90c2..dc37982 100644 --- a/index.js +++ b/index.js @@ -1,27 +1,105 @@ window.onload = function () { - let canvas = document.getElementById('c'); - let ctx = canvas.getContext('2d'); - let width = 600; - let height = 600; - canvas.width = width; - canvas.height = height; + let examples = [ + { title: 'Behavior', src: './examples/behavior.html' }, + { title: 'Multiple Behavior', src: './examples/behavior2.html' }, + { title: 'Fluid Gyroscope', src: './examples/fluidGyroscope.html' }, + { title: 'Dynamic Mesh (right click)', src: './examples/dynamicCustomMesh.html' }, + { title: 'Ragdoll', src: './examples/ragdoll.html' }, + { title: 'Shaded Cloth', src: './examples/shadedCloth.html' }, + { title: 'Typography', src: './examples/typography/index.html' }, + { title: 'Custom Entity', src: './examples/joinEntities.html' }, + { title: 'Ship', src: './examples/ship/index.html' }, + ]; - let verly = new Verly(16, canvas, ctx); - let cloth = verly.createCloth(200, 200, 300, 300, 20, 2); - // let ragdoll = verly.createRagdoll(100, 100); - let box = verly.createBox(100, 100, 100, 100); - - function animate() { - ctx.clearRect(0, 0, width, height); + const dom_ui = document.querySelector('.examples-container'); + const frame = document.getElementById('frame'); - verly.update(); - verly.render(); - verly.interact(); - - // verly.renderPointIndex(); + frame.src = examples[0].src; + if (window.location.hash) { + frame.src = window.location.hash.replace('#', ''); + } + var content = frame.contentWindow.document.body; - requestAnimationFrame(animate); + content.style.padding = 0; + content.style.margin = 0; + for (let i = 0; i < examples.length; i++) { + let button = document.createElement('button'); + button.innerHTML = examples[i].title; + button.dataset.src = examples[i].src; + button.onclick = function (e) { + frame.src = button.dataset.src; + window.location.hash = button.dataset.src; + } + dom_ui.appendChild(button); } - animate(); } + + + + + + + + +// CAN BE USED FOR DOCS +// let width = 400; +// let height = 300; +// window.onload = function () { +// const DOMWrapper = document.querySelector('.cards-container'); + +// let cards = { +// Box: [width / 2 - 50, 150, 100, 100], +// Cloth: [width / 2, 150, 200, 200, 15, 7], +// Rope: [width / 2, 20, 20, 10, 0], +// Hexagon: [width / 2, 150, 18, 60, 2, 13], +// Ragdoll: [width / 2, 0] +// } + +// let domStr = ''; +// for (const card in cards) { +// domStr += ` +//
+//

verly.create${card}()

+//
+// +//
+// ` +// } +// DOMWrapper.innerHTML = domStr; +// for (const card in cards) { +// initCardVerly(card.toLowerCase(), cards[card]) +// } + +// } +// function initCardVerly(type, params) { +// let canvas = document.getElementById(`canvas-${type}`); +// let ctx = canvas.getContext('2d'); +// canvas.width = 400; +// canvas.height = 300; + +// let verly = new Verly(16, canvas, ctx); + +// if (type === 'box') { +// verly.createBox(...params); +// } else if (type === 'cloth') { +// verly.createCloth(...params); +// } else if (type === 'hexagon') { +// verly.createHexagon(...params); +// } else if (type === 'rope') { +// verly.createRope(...params); +// } else if (type === 'ragdoll') { +// verly.createRagdoll(...params); +// } + +// function animate() { +// ctx.clearRect(0, 0, width, height); + +// verly.update(); +// verly.render(); +// verly.interact(); + +// requestAnimationFrame(animate); +// } +// animate(); +// } diff --git a/src/Utils.js b/src/Utils.js index 792c416..68e950b 100644 --- a/src/Utils.js +++ b/src/Utils.js @@ -19,7 +19,7 @@ window.degreesToRad = function (degrees) { * @param {number} max */ window.clamp = function (value, min, max) { - return Math.min(Math.max(value, Math.min(min, max), Math.max(min, max))) + return Math.max(min, Math.min(value, max)); } /** * @method random diff --git a/src/Verly.js b/src/Verly.js index fda5acd..b66e2de 100644 --- a/src/Verly.js +++ b/src/Verly.js @@ -2,7 +2,7 @@ import Mouse from './Mouse'; /** * @class Verly - * @version 1.2.0 + * @version 1.2.1 * @author */ class Verly { diff --git a/style.css b/style.css new file mode 100644 index 0000000..011da78 --- /dev/null +++ b/style.css @@ -0,0 +1,76 @@ +* { + box-sizing: border-box; +} + +html, +body { + margin: 0; + padding: 10px; + font-family: "Francois One", sans-serif; +} + +#frame { + margin-top: 30px; + width: 100%; + height: 80vh; + overflow: hidden; + border: none; +} +canvas { + border-radius: 8px; +} + +h3 { + margin: 10px 0; + color: #ee3f62; +} + +a { + color: #ee3f62; +} +a:hover { + color: #24c5a5; +} + +ul { + padding: 0; + list-style: none; + line-height: 30px; +} + +.site-title { + color: #ee3f62; +} + +.wrapper { + max-width: 1000px; + margin: auto; +} + +.examples-container { + display: flex; + justify-content: center; + width: 100%; + flex-wrap: wrap; +} + +button { + padding: 10px; + border: none; + background-color: #ee3f62; + color: white; + margin: 10px; + cursor: pointer; + border-radius: 3px; +} +button:hover { + background-color: #24c5a5; +} + +hr { + border: 1px solid #ee3f62; +} + +footer { + padding: 30px 0; +}