Hi guys,
Is there any way to draw rounded corner rectangles using DrawNode in cocos2d-js?
I use the 9slice and a rounded rectangle then I change the the size
#include “ui/UIScale9Sprite.h”
cocos2d::ui::Scale9Sprite *sprite = cocos2d::ui::Scale9Sprite::createWithSpriteFrameName(“Square.png”);
sprite->setContentSize(Size( width , height ));
addChild(sprite,-1);
Hi Razer,
Actually I wanted to draw rounded corner rectangle using cc.DrawNode.
I have added a function in CCDrawNode.js and CCDrawNodeCanvasRenderCmd.js to achieve this Rounded Rect ( I have tested this for canvas only not tested this for webgl. ie for “renderMode”: 1 in project.json )
Ex -
var x = 500, y = 350;
var width = 50, height = 60;
var r = x + width;
var b = y + height;
var radius = 15;
var vertices = [
{x: x + radius, y: y},
{x: r - radius, y: y},
{cpx: r, cpy: y, x: r, y: y + radius},
{x: r, y: b - radius},
{cpx: r, cpy: b, x: r - radius, y: b},
{x: x + radius, y: b},
{cpx: x, cpy: b, x: x, y: b - radius},
{x: x, y: y + radius},
{cpx: x, cpy: y, x: x + radius, y: y}
];
var roundRect = new cc.DrawNode();
roundRect.drawArc(vertices, 2, 5, cc.color(255, 255, 0), cc.color(250, 0, 0), true);
this.addChild(roundRect, 20);
Inside CCDrawNode.js add this line
cc.DrawNode.TYPE_ARC = 3; // add this line below cc.DrawNode.TYPE_POLY = 2;
Add this function in CCDrawNode.js below drawRect
/**
* draws a rectangle given the origin and destination point measured in points.
* @param {Array} vertices Array of objects{x,y}
* @param {Number} lineWidth
* @param {Number} radius
* @param {cc.Color} fillColor
* @param {cc.Color} lineColor
* @param {Boolean} isClosedPolygon
*/
drawArc:function (vertices, lineWidth, radius, fillColor, lineColor, isClosedPolygon) {
lineWidth = (lineWidth == null) ? this._lineWidth : lineWidth;
lineColor = lineColor || this.getDrawColor();
if(lineColor.a == null)
lineColor.a = 255;
var element = new cc._DrawNodeElement(cc.DrawNode.TYPE_ARC);
element.verts = vertices;
element.lineWidth = lineWidth;
element.lineColor = lineColor;
element.isClosePolygon = isClosedPolygon || true;
element.isStroke = true;
element.lineCap = "round";
element.fillColor = fillColor;
element.radius = radius || 5;
if (fillColor) {
if(fillColor.a == null)
fillColor.a = 255;
element.isFill = true;
}
this._buffer.push(element);
},
Inside CCDrawNodeCanvasRenderCmd.js
(function () {
cc.DrawNode.CanvasRenderCmd = function (renderableObject) {
cc.Node.CanvasRenderCmd.call(this, renderableObject);
this._needDraw = true;
this._buffer = null;
this._drawColor = null;
this._blendFunc = null;
};
cc.DrawNode.CanvasRenderCmd.prototype = Object.create(cc.Node.CanvasRenderCmd.prototype);
cc.DrawNode.CanvasRenderCmd.prototype.constructor = cc.DrawNode.CanvasRenderCmd;
cc.extend(cc.DrawNode.CanvasRenderCmd.prototype, {
rendering: function (ctx, scaleX, scaleY) {
var wrapper = ctx || cc._renderContext, context = wrapper.getContext(), node = this._node;
var alpha = node._displayedOpacity / 255;
if (alpha === 0)
return;
wrapper.setTransform(this._worldTransform, scaleX, scaleY);
//context.save();
wrapper.setGlobalAlpha(alpha);
if ((this._blendFunc && (this._blendFunc.src === cc.SRC_ALPHA) && (this._blendFunc.dst === cc.ONE)))
wrapper.setCompositeOperation('lighter'); //todo: need refactor
var locBuffer = this._buffer;
for (var i = 0, len = locBuffer.length; i < len; i++) {
var element = locBuffer[i];
switch (element.type) {
case cc.DrawNode.TYPE_DOT:
this._drawDot(wrapper, element, scaleX, scaleY);
break;
case cc.DrawNode.TYPE_SEGMENT:
this._drawSegment(wrapper, element, scaleX, scaleY);
break;
case cc.DrawNode.TYPE_POLY:
this._drawPoly(wrapper, element, scaleX, scaleY);
break;
case cc.DrawNode.TYPE_ARC:
this._drawArc(wrapper, element, scaleX, scaleY);
break;
}
}
//context.restore(); //todo It can be reserve
},
_drawDot: function (wrapper, element, scaleX, scaleY) {
var locColor = element.fillColor, locPos = element.verts[0], locRadius = element.lineWidth;
var ctx = wrapper.getContext();
wrapper.setFillStyle("rgba(" + (0 | locColor.r) + "," + (0 | locColor.g) + "," + (0 | locColor.b) + "," + locColor.a / 255 + ")");
ctx.beginPath();
ctx.arc(locPos.x * scaleX, -locPos.y * scaleY, locRadius * scaleX, 0, Math.PI * 2, false);
ctx.closePath();
ctx.fill();
},
_drawSegment: function (wrapper, element, scaleX, scaleY) {
var locColor = element.lineColor;
var locFrom = element.verts[0], locTo = element.verts[1];
var locLineWidth = element.lineWidth, locLineCap = element.lineCap;
var ctx = wrapper.getContext();
wrapper.setStrokeStyle("rgba(" + (0 | locColor.r) + "," + (0 | locColor.g) + "," + (0 | locColor.b) + "," + locColor.a / 255 + ")");
ctx.lineWidth = locLineWidth * scaleX;
ctx.beginPath();
ctx.lineCap = locLineCap;
ctx.moveTo(locFrom.x * scaleX, -locFrom.y * scaleY);
ctx.lineTo(locTo.x * scaleX, -locTo.y * scaleY);
ctx.stroke();
},
_drawPoly: function (wrapper, element, scaleX, scaleY) {
var locVertices = element.verts, locLineCap = element.lineCap;
if (locVertices == null)
return;
var locFillColor = element.fillColor, locLineWidth = element.lineWidth;
var locLineColor = element.lineColor, locIsClosePolygon = element.isClosePolygon;
var locIsFill = element.isFill, locIsStroke = element.isStroke;
var ctx = wrapper.getContext();
var firstPoint = locVertices[0];
ctx.lineCap = locLineCap;
if (locFillColor)
wrapper.setFillStyle("rgba(" + (0 | locFillColor.r) + "," + (0 | locFillColor.g) + ","
+ (0 | locFillColor.b) + "," + locFillColor.a / 255 + ")");
if (locLineWidth)
ctx.lineWidth = locLineWidth * scaleX;
if (locLineColor)
wrapper.setStrokeStyle("rgba(" + (0 | locLineColor.r) + "," + (0 | locLineColor.g) + ","
+ (0 | locLineColor.b) + "," + locLineColor.a / 255 + ")");
ctx.beginPath();
ctx.moveTo(firstPoint.x * scaleX, -firstPoint.y * scaleY);
for (var i = 1, len = locVertices.length; i < len; i++)
ctx.lineTo(locVertices[i].x * scaleX, -locVertices[i].y * scaleY);
if (locIsClosePolygon)
ctx.closePath();
if (locIsFill)
ctx.fill();
if (locIsStroke)
ctx.stroke();
},
_drawArc: function (wrapper, element, scaleX, scaleY) {
var locVertices = element.verts, locLineCap = element.lineCap;
if (locVertices == null)
return;
var locFillColor = element.fillColor, locLineWidth = element.lineWidth;
var locLineColor = element.lineColor, locIsClosePolygon = element.isClosePolygon;
var locIsFill = element.isFill, locIsStroke = element.isStroke;
var radius = element.radius;
var ctx = wrapper.getContext();
var firstPoint = locVertices[0];
ctx.lineCap = locLineCap;
if (locFillColor)
wrapper.setFillStyle("rgba(" + (0 | locFillColor.r) + "," + (0 | locFillColor.g) + ","
+ (0 | locFillColor.b) + "," + locFillColor.a / 255 + ")");
if (locLineWidth)
ctx.lineWidth = locLineWidth * scaleX;
if (locLineColor)
wrapper.setStrokeStyle("rgba(" + (0 | locLineColor.r) + "," + (0 | locLineColor.g) + ","
+ (0 | locLineColor.b) + "," + locLineColor.a / 255 + ")");
ctx.beginPath();
ctx.moveTo(firstPoint.x * scaleX, -firstPoint.y * scaleY);
for (var i = 1, len = locVertices.length - 1; i < len; i++) {
ctx.lineTo(
locVertices[i].x * scaleX,
-locVertices[i].y * scaleY
);
ctx.quadraticCurveTo(
locVertices[i + 1].cpx * scaleX,
-locVertices[i + 1].cpy * scaleY,
locVertices[i + 1].x * scaleX,
-locVertices[i + 1].y * scaleY
);
++i;
}
if (locIsClosePolygon)
ctx.closePath();
if (locIsFill)
ctx.fill();
if (locIsStroke)
ctx.stroke();
}
});
})();