mirror of
https://github.com/tiennm99/fbird.git
synced 2026-06-18 03:30:47 +00:00
432 lines
15 KiB
JavaScript
Vendored
432 lines
15 KiB
JavaScript
Vendored
/****************************************************************************
|
|
Copyright (c) 2008-2010 Ricardo Quesada
|
|
Copyright (c) 2011-2012 cocos2d-x.org
|
|
Copyright (c) 2013-2014 Chukong Technologies Inc.
|
|
|
|
http://www.cocos2d-x.org
|
|
|
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
of this software and associated documentation files (the "Software"), to deal
|
|
in the Software without restriction, including without limitation the rights
|
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
copies of the Software, and to permit persons to whom the Software is
|
|
furnished to do so, subject to the following conditions:
|
|
|
|
The above copyright notice and this permission notice shall be included in
|
|
all copies or substantial portions of the Software.
|
|
|
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
THE SOFTWARE.
|
|
****************************************************************************/
|
|
/**
|
|
* @const
|
|
* @type {number}
|
|
*/
|
|
cc.PI2 = Math.PI * 2;
|
|
|
|
/**
|
|
* Canvas of DrawingPrimitive implement version use for canvasMode
|
|
* @class
|
|
* @extends cc.Class
|
|
* @param {CanvasRenderingContext2D} renderContext
|
|
*/
|
|
cc.DrawingPrimitiveCanvas = cc.Class.extend(/** @lends cc.DrawingPrimitiveCanvas# */{
|
|
_cacheArray:[],
|
|
_renderContext:null,
|
|
/**
|
|
* Constructor of cc.DrawingPrimitiveCanvas
|
|
* @param {cc.CanvasContextWrapper} renderContext
|
|
*/
|
|
ctor:function (renderContext) {
|
|
this._renderContext = renderContext;
|
|
},
|
|
|
|
/**
|
|
* draws a point given x and y coordinate measured in points
|
|
* @override
|
|
* @param {cc.Point} point
|
|
* @param {Number} size
|
|
*/
|
|
drawPoint:function (point, size) {
|
|
if (!size) {
|
|
size = 1;
|
|
}
|
|
var ctx = this._renderContext.getContext();
|
|
ctx.beginPath();
|
|
ctx.arc(point.x, -point.y, size, 0, Math.PI * 2, false);
|
|
ctx.closePath();
|
|
ctx.fill();
|
|
},
|
|
|
|
/**
|
|
* draws an array of points.
|
|
* @override
|
|
* @param {Array} points point of array
|
|
* @param {Number} numberOfPoints
|
|
* @param {Number} size
|
|
*/
|
|
drawPoints:function (points, numberOfPoints, size) {
|
|
if (points == null)
|
|
return;
|
|
|
|
if (!size) {
|
|
size = 1;
|
|
}
|
|
var locContext = this._renderContext.getContext();
|
|
|
|
locContext.beginPath();
|
|
for (var i = 0, len = points.length; i < len; i++)
|
|
locContext.arc(points[i].x, -points[i].y, size, 0, Math.PI * 2, false);
|
|
locContext.closePath();
|
|
locContext.fill();
|
|
},
|
|
|
|
/**
|
|
* draws a line given the origin and destination point measured in points
|
|
* @override
|
|
* @param {cc.Point} origin
|
|
* @param {cc.Point} destination
|
|
*/
|
|
drawLine:function (origin, destination) {
|
|
var locContext = this._renderContext.getContext();
|
|
locContext.beginPath();
|
|
locContext.moveTo(origin.x , -origin.y );
|
|
locContext.lineTo(destination.x, -destination.y );
|
|
locContext.closePath();
|
|
locContext.stroke();
|
|
},
|
|
|
|
/**
|
|
* draws a rectangle given the origin and destination point measured in points.
|
|
* @param {cc.Point} origin
|
|
* @param {cc.Point} destination
|
|
*/
|
|
drawRect:function (origin, destination) {
|
|
//todo need optimize for performance
|
|
this.drawLine(cc.p(origin.x, origin.y), cc.p(destination.x, origin.y));
|
|
this.drawLine(cc.p(destination.x, origin.y), cc.p(destination.x, destination.y));
|
|
this.drawLine(cc.p(destination.x, destination.y), cc.p(origin.x, destination.y));
|
|
this.drawLine(cc.p(origin.x, destination.y), cc.p(origin.x, origin.y));
|
|
},
|
|
|
|
/**
|
|
* draws a solid rectangle given the origin and destination point measured in points.
|
|
* @param {cc.Point} origin
|
|
* @param {cc.Point} destination
|
|
* @param {cc.Color} color
|
|
*/
|
|
drawSolidRect:function (origin, destination, color) {
|
|
var vertices = [
|
|
origin,
|
|
cc.p(destination.x, origin.y),
|
|
destination,
|
|
cc.p(origin.x, destination.y)
|
|
];
|
|
|
|
this.drawSolidPoly(vertices, 4, color);
|
|
},
|
|
|
|
/**
|
|
* draws a polygon given a pointer to cc.Point coordinates and the number of vertices measured in points.
|
|
* @override
|
|
* @param {Array} vertices a pointer to cc.Point coordinates
|
|
* @param {Number} numOfVertices the number of vertices measured in points
|
|
* @param {Boolean} closePolygon The polygon can be closed or open
|
|
* @param {Boolean} [fill=] The polygon can be closed or open and optionally filled with current color
|
|
*/
|
|
drawPoly:function (vertices, numOfVertices, closePolygon, fill) {
|
|
fill = fill || false;
|
|
|
|
if (vertices == null)
|
|
return;
|
|
|
|
if (vertices.length < 3)
|
|
throw new Error("Polygon's point must greater than 2");
|
|
|
|
var firstPoint = vertices[0], locContext = this._renderContext.getContext();
|
|
locContext.beginPath();
|
|
locContext.moveTo(firstPoint.x , -firstPoint.y );
|
|
for (var i = 1, len = vertices.length; i < len; i++)
|
|
locContext.lineTo(vertices[i].x , -vertices[i].y );
|
|
|
|
if (closePolygon)
|
|
locContext.closePath();
|
|
|
|
if (fill)
|
|
locContext.fill();
|
|
else
|
|
locContext.stroke();
|
|
},
|
|
|
|
/**
|
|
* draws a solid polygon given a pointer to CGPoint coordinates, the number of vertices measured in points, and a color.
|
|
* @param {Array} polygons
|
|
* @param {Number} numberOfPoints
|
|
* @param {cc.Color} color
|
|
*/
|
|
drawSolidPoly:function (polygons, numberOfPoints, color) {
|
|
this.setDrawColor(color.r, color.g, color.b, color.a);
|
|
this.drawPoly(polygons, numberOfPoints, true, true);
|
|
},
|
|
|
|
/**
|
|
* draws a circle given the center, radius and number of segments.
|
|
* @override
|
|
* @param {cc.Point} center center of circle
|
|
* @param {Number} radius
|
|
* @param {Number} angle angle in radians
|
|
* @param {Number} segments
|
|
* @param {Boolean} [drawLineToCenter=]
|
|
*/
|
|
drawCircle: function (center, radius, angle, segments, drawLineToCenter) {
|
|
drawLineToCenter = drawLineToCenter || false;
|
|
var locContext = this._renderContext.getContext();
|
|
locContext.beginPath();
|
|
var endAngle = angle - Math.PI * 2;
|
|
locContext.arc(0 | (center.x ), 0 | -(center.y ), radius , -angle, -endAngle, false);
|
|
if (drawLineToCenter) {
|
|
locContext.lineTo(0 | (center.x ), 0 | -(center.y ));
|
|
}
|
|
locContext.stroke();
|
|
},
|
|
|
|
/**
|
|
* draws a quad bezier path
|
|
* @override
|
|
* @param {cc.Point} origin
|
|
* @param {cc.Point} control
|
|
* @param {cc.Point} destination
|
|
* @param {Number} segments
|
|
*/
|
|
drawQuadBezier:function (origin, control, destination, segments) {
|
|
//this is OpenGL Algorithm
|
|
var vertices = this._cacheArray;
|
|
vertices.length =0;
|
|
|
|
var t = 0.0;
|
|
for (var i = 0; i < segments; i++) {
|
|
var x = Math.pow(1 - t, 2) * origin.x + 2.0 * (1 - t) * t * control.x + t * t * destination.x;
|
|
var y = Math.pow(1 - t, 2) * origin.y + 2.0 * (1 - t) * t * control.y + t * t * destination.y;
|
|
vertices.push(cc.p(x, y));
|
|
t += 1.0 / segments;
|
|
}
|
|
vertices.push(cc.p(destination.x, destination.y));
|
|
|
|
this.drawPoly(vertices, segments + 1, false, false);
|
|
},
|
|
|
|
/**
|
|
* draws a cubic bezier path
|
|
* @override
|
|
* @param {cc.Point} origin
|
|
* @param {cc.Point} control1
|
|
* @param {cc.Point} control2
|
|
* @param {cc.Point} destination
|
|
* @param {Number} segments
|
|
*/
|
|
drawCubicBezier:function (origin, control1, control2, destination, segments) {
|
|
//this is OpenGL Algorithm
|
|
var vertices = this._cacheArray;
|
|
vertices.length =0;
|
|
|
|
var t = 0;
|
|
for (var i = 0; i < segments; i++) {
|
|
var x = Math.pow(1 - t, 3) * origin.x + 3.0 * Math.pow(1 - t, 2) * t * control1.x + 3.0 * (1 - t) * t * t * control2.x + t * t * t * destination.x;
|
|
var y = Math.pow(1 - t, 3) * origin.y + 3.0 * Math.pow(1 - t, 2) * t * control1.y + 3.0 * (1 - t) * t * t * control2.y + t * t * t * destination.y;
|
|
vertices.push(cc.p(x , y ));
|
|
t += 1.0 / segments;
|
|
}
|
|
vertices.push(cc.p(destination.x , destination.y));
|
|
|
|
this.drawPoly(vertices, segments + 1, false, false);
|
|
},
|
|
|
|
/**
|
|
* draw a CatmullRom curve
|
|
* @override
|
|
* @param {Array} points
|
|
* @param {Number} segments
|
|
*/
|
|
drawCatmullRom:function (points, segments) {
|
|
this.drawCardinalSpline(points, 0.5, segments);
|
|
},
|
|
|
|
/**
|
|
* draw a cardinal spline path
|
|
* @override
|
|
* @param {Array} config
|
|
* @param {Number} tension
|
|
* @param {Number} segments
|
|
*/
|
|
drawCardinalSpline:function (config, tension, segments) {
|
|
//lazy_init();
|
|
cc._renderContext.setStrokeStyle("rgba(255,255,255,1)");
|
|
var points = this._cacheArray;
|
|
points.length = 0;
|
|
var p, lt;
|
|
var deltaT = 1.0 / config.length;
|
|
|
|
for (var i = 0; i < segments + 1; i++) {
|
|
var dt = i / segments;
|
|
|
|
// border
|
|
if (dt === 1) {
|
|
p = config.length - 1;
|
|
lt = 1;
|
|
} else {
|
|
p = 0 | (dt / deltaT);
|
|
lt = (dt - deltaT * p) / deltaT;
|
|
}
|
|
|
|
// Interpolate
|
|
var newPos = cc.CardinalSplineAt(
|
|
cc.getControlPointAt(config, p - 1),
|
|
cc.getControlPointAt(config, p - 0),
|
|
cc.getControlPointAt(config, p + 1),
|
|
cc.getControlPointAt(config, p + 2),
|
|
tension, lt);
|
|
points.push(newPos);
|
|
}
|
|
this.drawPoly(points, segments + 1, false, false);
|
|
},
|
|
|
|
/**
|
|
* draw an image
|
|
* @override
|
|
* @param {HTMLImageElement|HTMLCanvasElement} image
|
|
* @param {cc.Point} sourcePoint
|
|
* @param {cc.Size} sourceSize
|
|
* @param {cc.Point} destPoint
|
|
* @param {cc.Size} destSize
|
|
*/
|
|
drawImage:function (image, sourcePoint, sourceSize, destPoint, destSize) {
|
|
var len = arguments.length;
|
|
var ctx = this._renderContext.getContext();
|
|
switch (len) {
|
|
case 2:
|
|
var height = image.height;
|
|
ctx.drawImage(image, sourcePoint.x, -(sourcePoint.y + height));
|
|
break;
|
|
case 3:
|
|
ctx.drawImage(image, sourcePoint.x, -(sourcePoint.y + sourceSize.height), sourceSize.width, sourceSize.height);
|
|
break;
|
|
case 5:
|
|
ctx.drawImage(image, sourcePoint.x, sourcePoint.y, sourceSize.width, sourceSize.height, destPoint.x, -(destPoint.y + destSize.height),
|
|
destSize.width, destSize.height);
|
|
break;
|
|
default:
|
|
throw new Error("Argument must be non-nil");
|
|
break;
|
|
}
|
|
},
|
|
|
|
/**
|
|
* draw a star
|
|
* @param {cc.CanvasContextWrapper} ctx canvas context
|
|
* @param {Number} radius
|
|
* @param {cc.Color} color
|
|
*/
|
|
drawStar:function (ctx, radius, color) {
|
|
var wrapper = ctx || this._renderContext;
|
|
var context = wrapper.getContext();
|
|
var colorStr = "rgba(" + (0 | color.r) + "," + (0 | color.g) + "," + (0 | color.b);
|
|
wrapper.setFillStyle(colorStr + ",1)");
|
|
//context.fillStyle = colorStr + ",1)";
|
|
var subRadius = radius / 10;
|
|
|
|
context.beginPath();
|
|
context.moveTo(-radius, radius);
|
|
context.lineTo(0, subRadius);
|
|
context.lineTo(radius, radius);
|
|
context.lineTo(subRadius, 0);
|
|
context.lineTo(radius, -radius);
|
|
context.lineTo(0, -subRadius);
|
|
context.lineTo(-radius, -radius);
|
|
context.lineTo(-subRadius, 0);
|
|
context.lineTo(-radius, radius);
|
|
context.closePath();
|
|
context.fill();
|
|
|
|
var rg = context.createRadialGradient(0, 0, subRadius, 0, 0, radius);
|
|
rg.addColorStop(0, colorStr + ", 1)");
|
|
rg.addColorStop(0.3, colorStr + ", 0.8)");
|
|
rg.addColorStop(1.0, colorStr + ", 0.0)");
|
|
wrapper.setFillStyle(rg);
|
|
//context.fillStyle = g1;
|
|
context.beginPath();
|
|
var startAngle_1 = 0;
|
|
var endAngle_1 = cc.PI2;
|
|
context.arc(0, 0, radius - subRadius, startAngle_1, endAngle_1, false);
|
|
context.closePath();
|
|
context.fill();
|
|
},
|
|
|
|
/**
|
|
* draw a color ball
|
|
* @param {cc.CanvasContextWrapper} ctx canvas context
|
|
* @param {Number} radius
|
|
* @param {cc.Color} color
|
|
*/
|
|
drawColorBall:function (ctx, radius, color) {
|
|
var wrapper = ctx || this._renderContext;
|
|
var context = wrapper.getContext();
|
|
var colorStr = "rgba(" +(0|color.r) + "," + (0|color.g) + "," + (0|color.b);
|
|
var subRadius = radius / 10;
|
|
|
|
var g1 = context.createRadialGradient(0, 0, subRadius, 0, 0, radius);
|
|
g1.addColorStop(0, colorStr + ", 1)");
|
|
g1.addColorStop(0.3, colorStr + ", 0.8)");
|
|
g1.addColorStop(0.6, colorStr + ", 0.4)");
|
|
g1.addColorStop(1.0, colorStr + ", 0.0)");
|
|
wrapper.setFillStyle(g1);
|
|
//context.fillStyle = g1;
|
|
context.beginPath();
|
|
var startAngle_1 = 0;
|
|
var endAngle_1 = cc.PI2;
|
|
context.arc(0, 0, radius, startAngle_1, endAngle_1, false);
|
|
context.closePath();
|
|
context.fill();
|
|
},
|
|
|
|
/**
|
|
* fill text
|
|
* @param {String} strText
|
|
* @param {Number} x
|
|
* @param {Number} y
|
|
*/
|
|
fillText:function (strText, x, y) {
|
|
this._renderContext.getContext().fillText(strText, x, -y);
|
|
},
|
|
|
|
/**
|
|
* set the drawing color with 4 unsigned bytes
|
|
* @param {Number} r red value (0 to 255)
|
|
* @param {Number} g green value (0 to 255)
|
|
* @param {Number} b blue value (0 to 255)
|
|
* @param {Number} a Alpha value (0 to 255)
|
|
*/
|
|
setDrawColor:function (r, g, b, a) {
|
|
this._renderContext.setFillStyle("rgba(" + r + "," + g + "," + b + "," + a / 255 + ")");
|
|
this._renderContext.setStrokeStyle("rgba(" + r + "," + g + "," + b + "," + a / 255 + ")");
|
|
},
|
|
|
|
/**
|
|
* set the point size in points. Default 1.
|
|
* @param {Number} pointSize
|
|
*/
|
|
setPointSize:function (pointSize) {
|
|
},
|
|
|
|
/**
|
|
* set the line width. Default 1.
|
|
* @param {Number} width
|
|
*/
|
|
setLineWidth:function (width) {
|
|
this._renderContext.getContext().lineWidth = width;
|
|
}
|
|
}); |