Skip to content

Commit

Permalink
Merge branch 'master' into bool-cleanup
Browse files Browse the repository at this point in the history
* master: (36 commits)
  Avoid dividing with zero while splitting curves
  Implement propper support for pointer events and MSPointer events.
  Clean up white-space.
  WinGums: Some more code clean-up.
  WineGum example: Untangle the offset calculation code a bit.
  WineGum example: Some more style changes.
  Some more simplifications and style changes.
  Convert to cleaner OOP style.
  Precalculate side points again for better performance.
  Optimise WineGums example.
  Change title of WineGums example.
  Optimise WineGums example.
  Add WineGums example by kynd.info.
  Fix newly introduced issue in CompoundPath#moveTo() / #lineTo()
  Optimize and fix code that draws selections and handles.
  Minor clean-up in the way Base.exports are handled.
  Better handle Path#moveTo() / #closePath() edge cases in SVG data.
  Fix SVG issues with reflected control points in the commands 'SsTt'
  Prevent accidental transformation of selection bounds in TextItem.
  Fix importPoly() on Node.js
  ...
  • Loading branch information
hkrish committed Mar 13, 2014
2 parents 7911d8b + 066d47d commit b1fca8d
Show file tree
Hide file tree
Showing 30 changed files with 604 additions and 272 deletions.
150 changes: 150 additions & 0 deletions examples/Animated/WineGums.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Wine Gums</title>
<link rel="stylesheet" href="../css/style.css">
<script type="text/javascript" src="../../dist/paper.js"></script>
<script type="text/paperscript" canvas="canvas">
// kynd.info 2014

function Ball(r, p, v) {
this.radius = r;
this.point = p;
this.vector = v;
this.maxVec = 15;
this.numSegment = Math.floor(r / 3 + 2);
this.boundOffset = [];
this.boundOffsetBuff = [];
this.sidePoints = [];
this.path = new Path({
fillColor: {
hue: Math.random() * 360,
saturation: 1,
brightness: 1
},
blendMode: 'screen'
});

for (var i = 0; i < this.numSegment; i ++) {
this.boundOffset.push(this.radius);
this.boundOffsetBuff.push(this.radius);
this.path.add(new Point());
this.sidePoints.push(new Point({
angle: 360 / this.numSegment * i,
length: 1
}));
}
}

Ball.prototype = {
iterate: function() {
this.checkWallCollision();
if (this.vector.length > this.maxVec)
this.vector.length = this.maxVec;
this.point += this.vector;
this.updateShape();
},

checkWallCollision: function() {
var size = view.size;
if (this.point.x < -this.radius)
this.point.x = size.width + this.radius;
if (this.point.x > size.width + this.radius)
this.point.x = -this.radius;
if (this.point.y < -this.radius)
this.point.y = size.height + this.radius;
if (this.point.y > size.height + this.radius)
this.point.y = -this.radius;
},

updateShape: function() {
var segments = this.path.segments;
for (var i = 0; i < this.numSegment; i ++)
segments[i].point = this.getSidePoint(i);

this.path.smooth();
for (var i = 0; i < this.numSegment; i ++) {
if (this.boundOffset[i] < this.radius / 4)
this.boundOffset[i] = this.radius / 4;
var next = (i + 1) % this.numSegment;
var prev = (i > 0) ? i - 1 : this.numSegment - 1;
var offset = this.boundOffset[i];
offset += (this.radius - offset) / 15;
offset += ((this.boundOffset[next] + this.boundOffset[prev]) / 2 - offset) / 3;
this.boundOffsetBuff[i] = this.boundOffset[i] = offset;
}
},

react: function(b) {
var dist = this.point.getDistance(b.point);
if (dist < this.radius + b.radius && dist != 0) {
var overlap = this.radius + b.radius - dist;
var direc = (this.point - b.point).normalize(overlap * 0.015);
this.vector += direc;
b.vector -= direc;

this.calcBounds(b);
b.calcBounds(this);
this.updateBounds();
b.updateBounds();
}
},

getBoundOffset: function(b) {
var diff = this.point - b;
var angle = (diff.angle + 180) % 360;
return this.boundOffset[Math.floor(angle / 360 * this.boundOffset.length)];
},

calcBounds: function(b) {
for (var i = 0; i < this.numSegment; i ++) {
var tp = this.getSidePoint(i);
var bLen = b.getBoundOffset(tp);
var td = tp.getDistance(b.point);
if (td < bLen) {
this.boundOffsetBuff[i] -= (bLen - td) / 2;
}
}
},

getSidePoint: function(index) {
return this.point + this.sidePoints[index] * this.boundOffset[index];
},

updateBounds: function() {
for (var i = 0; i < this.numSegment; i ++)
this.boundOffset[i] = this.boundOffsetBuff[i];
}
};

//--------------------- main ---------------------

var balls = [];
var numBalls = 18;
for (var i = 0; i < numBalls; i++) {
var position = Point.random() * view.size;
var vector = new Point({
angle: 360 * Math.random(),
length: Math.random() * 10
});
balls.push(new Ball(Math.random() * 60 + 60, position, vector));
}

function onFrame() {
for (var i = 0; i < balls.length - 1; i++) {
for (var j = i + 1; j < balls.length; j++) {
balls[i].react(balls[j]);
}
}
for (var i = 0, l = balls.length; i < l; i++) {
balls[i].iterate();
}
}

</script>
</head>
<body>
<canvas id="canvas" resize hidpi="off" style="background:black"></canvas>
</body>
</html>
8 changes: 4 additions & 4 deletions src/basic/Point.js
Original file line number Diff line number Diff line change
Expand Up @@ -709,7 +709,7 @@ var Point = Base.extend(/** @lends Point# */{
* @returns {Boolean} {@true it is colinear}
*/
isColinear: function(point) {
return this.cross(point) < /*#=*/ Numerical.TOLERANCE;
return Math.abs(this.cross(point)) < /*#=*/ Numerical.TOLERANCE;
},

/**
Expand All @@ -720,13 +720,13 @@ var Point = Base.extend(/** @lends Point# */{
* @returns {Boolean} {@true it is orthogonal}
*/
isOrthogonal: function(point) {
return this.dot(point) < /*#=*/ Numerical.TOLERANCE;
return Math.abs(this.dot(point)) < /*#=*/ Numerical.TOLERANCE;
},

/**
* Checks if this point has both the x and y coordinate set to 0.
*
* @returns {Boolean} {@true both x and y are 0}
* @returns {Boolean} {@true if both x and y are 0}
*/
isZero: function() {
return Numerical.isZero(this.x) && Numerical.isZero(this.y);
Expand Down Expand Up @@ -792,7 +792,7 @@ var Point = Base.extend(/** @lends Point# */{
*
* @name Point#selected
* @property
* @return {Boolean} {@true the point is selected}
* @return {Boolean} {@true if the point is selected}
*/

/**
Expand Down
2 changes: 1 addition & 1 deletion src/basic/Rectangle.js
Original file line number Diff line number Diff line change
Expand Up @@ -482,7 +482,7 @@ var Rectangle = Base.extend(/** @lends Rectangle# */{
},

/**
* @return {Boolean} {@true the rectangle is empty}
* @return {Boolean} {@true if the rectangle is empty}
*/
isEmpty: function() {
return this.width === 0 || this.height === 0;
Expand Down
2 changes: 1 addition & 1 deletion src/basic/Size.js
Original file line number Diff line number Diff line change
Expand Up @@ -375,7 +375,7 @@ var Size = Base.extend(/** @lends Size# */{
* {@grouptitle Tests}
* Checks if this size has both the width and height set to 0.
*
* @return {Boolean} {@true both width and height are 0}
* @return {Boolean} {@true if both width and height are 0}
*/
isZero: function() {
return Numerical.isZero(this.width) && Numerical.isZero(this.height);
Expand Down
18 changes: 9 additions & 9 deletions src/canvas/CanvasProvider.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,19 +15,19 @@
var CanvasProvider = {
canvases: [],

getCanvas: function(width, height, ratio) {
getCanvas: function(width, height, pixelRatio) {
var canvas,
init = true;
if (typeof width === 'object') {
ratio = height;
pixelRatio = height;
height = width.height;
width = width.width;
}
if (!ratio) {
ratio = 1;
} else if (ratio !== 1) {
width *= ratio;
height *= ratio;
if (!pixelRatio) {
pixelRatio = 1;
} else if (pixelRatio !== 1) {
width *= pixelRatio;
height *= pixelRatio;
}
if (this.canvases.length) {
canvas = this.canvases.pop();
Expand All @@ -52,8 +52,8 @@ var CanvasProvider = {
}
// We save on retrieval and restore on release.
ctx.save();
if (ratio !== 1)
ctx.scale(ratio, ratio);
if (pixelRatio !== 1)
ctx.scale(pixelRatio, pixelRatio);
return canvas;
},

Expand Down
4 changes: 3 additions & 1 deletion src/core/Base.js
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,9 @@ Base.inject(/** @lends Base# */{
statics: /** @lends Base */{

// Keep track of all named classes for serialization and exporting.
exports: {},
exports: {
enumerable: true // For PaperScope.inject() in export.js
},

extend: function extend() {
// Override Base.extend() to register named classes in Base.exports,
Expand Down
2 changes: 1 addition & 1 deletion src/core/Callback.js
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ var Callback = {
return false;
var args = [].slice.call(arguments, 1),
that = this;
for (var i in handlers) {
for (var i = 0, l = handlers.length; i < l; i++) {
// When the handler function returns false, prevent the default
// behaviour and stop propagation of the event by calling stop()
if (handlers[i].apply(that, args) === false
Expand Down
36 changes: 29 additions & 7 deletions src/dom/DomElement.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,24 @@ var DomElement = new function() {
return res;
}

// Handles both getting and setting of vendor prefix values
function handlePrefix(el, name, set, value) {
var prefixes = ['webkit', 'moz', 'Moz', 'ms', 'o', ''],
suffix = name[0].toUpperCase() + name.substring(1);
for (var i = 0; i < 6; i++) {
var prefix = prefixes[i],
key = prefix ? prefix + suffix : name;
if (key in el) {
if (set) {
el[key] = value;
} else {
return el[key];
}
break;
}
}
}

return /** @lends DomElement */{
create: function(nodes, parent) {
var isArray = Array.isArray(nodes),
Expand Down Expand Up @@ -203,13 +221,17 @@ var DomElement = new function() {
* Gets the given property from the element, trying out all browser
* prefix variants.
*/
getPrefixValue: function(el, name) {
var value = el[name],
prefixes = ['webkit', 'moz', 'ms', 'o'],
suffix = name[0].toUpperCase() + name.substring(1);
for (var i = 0; i < 4 && value == null; i++)
value = el[prefixes[i] + suffix];
return value;
getPrefixed: function(el, name) {
return handlePrefix(el, name);
},

setPrefixed: function(el, name, value) {
if (typeof name === 'object') {
for (var key in name)
handlePrefix(el, key, true, name[key]);
} else {
handlePrefix(el, name, true, value);
}
}
};
};
19 changes: 13 additions & 6 deletions src/dom/DomEvent.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,21 @@
*/
var DomEvent = /** @lends DomEvent */{
add: function(el, events) {
for (var type in events)
el.addEventListener(type, events[type], false);
for (var type in events) {
var func = events[type],
parts = type.split(/[\s,]+/g);
for (var i = 0, l = parts.length; i < l; i++)
el.addEventListener(parts[i], func, false);
}
},

remove: function(el, events) {
for (var type in events)
el.removeEventListener(type, events[type], false);
for (var type in events) {
var func = events[type],
parts = type.split(/[\s,]+/g);
for (var i = 0, l = parts.length; i < l; i++)
el.removeEventListener(parts[i], func, false);
}
},

getPoint: function(event) {
Expand Down Expand Up @@ -59,8 +67,7 @@ var DomEvent = /** @lends DomEvent */{
};

DomEvent.requestAnimationFrame = new function() {
var nativeRequest = DomElement.getPrefixValue(window,
'requestAnimationFrame'),
var nativeRequest = DomElement.getPrefixed(window, 'requestAnimationFrame'),
requested = false,
callbacks = [],
focused = true,
Expand Down
8 changes: 4 additions & 4 deletions src/export.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
// PaperScope, and create the initial paper object, all in one statement:
/*#*/ if (__options.environment == 'browser') {

paper = new (PaperScope.inject(new Base(Base.exports, {
paper = new (PaperScope.inject(Base.exports, {
// Mark fields as enumeralbe so PaperScope.inject can pick them up
enumerable: true,
Base: Base,
Expand All @@ -24,7 +24,7 @@ paper = new (PaperScope.inject(new Base(Base.exports, {
DomEvent: DomEvent,
Http: Http,
Key: Key
})))();
}))();

// Support AMD (e.g. require.js)
// Use named module AMD syntax since there are other unnamed calls to define()
Expand All @@ -35,7 +35,7 @@ if (typeof define === 'function' && define.amd)

/*#*/ } else if (__options.environment == 'node') {

paper = new (PaperScope.inject(new Base(Base.exports, {
paper = new (PaperScope.inject(Base.exports, {
// Mark fields as enumeralbe so PaperScope.inject can pick them up
enumerable: true,
Base: Base,
Expand All @@ -45,7 +45,7 @@ paper = new (PaperScope.inject(new Base(Base.exports, {
XMLSerializer: XMLSerializer,
DOMParser: DOMParser,
Canvas: Canvas
})))();
}))();

// Export the paper scope.
module.exports = paper;
Expand Down
Loading

0 comments on commit b1fca8d

Please sign in to comment.