Drawing rounded corner rectangle in cocos2d-js


#1

Hi guys,
Is there any way to draw rounded corner rectangles using DrawNode in cocos2d-js?


#2

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);


#3

Hi Razer,
Actually I wanted to draw rounded corner rectangle using cc.DrawNode.


#4

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();

                }
            });

        })();

How to draw rounded square?
Rounded polygon