Cocos Creator 2.0 _ccsg

Hey what happened to the _ccsg class from previous versions?

I’m using the raphael ccc extension and it uses new _ccsg.GraphicsNode()

Is there a new equivalent?

3 Likes

:point_up_2::point_up_2::point_up_2::point_up_2::+1::+1:

I’m also curious to know ho to get Raphael working with CC 2.0, current examples doesn’t work.

Documentation says it is possible, but need new examples:
http://docs.cocos.com/creator/manual/en/render/graphics/

i’ve been using ccc raphael with 1.10.1 to get my prototype going

from what i have investigated, this isn’t a straight forward swap because the underlying structure of sgNode is now gone in 2.0 and ccc raphael depends heavily on it

it might be a simple swap over to just using the child/parent and ctx behavior differently and just using cc.Graphics rather than _ccsg.GraphicsNode, but I don’t know enough about how and why sgNode was done away with

i really hope 2youyou2 refactors it to support 2.0

1 Like

What was _ccsg replaced with? (in general)

I hope it too, would be very useful for many of us for sure!

too many things are different between 1.x and 2.x, the entire /core/ folder is completely different, and sgNode architecture has been completely gutted, there is no ‘general’ replacement that i can find

for what it’s worth, I actually don’t think we need anything here.

CC 2.0+ has cc.Graphics and the demos show how to use it. Raphael was a nice helper but at this point it seems unnecessary.

Could you share a link to these demos that can replace Raphael? Can you include .svg files through cc.Graphics?

demos are included in the creator download - go to New Project -> Example Collection

this will make a project that has all the CC dev team demos and examples

find the Graphics one in the list, it’s actually not under 01_graphics, it’s under another folder just called ‘graphics’, and the ‘doodle’ example is a pretty good starting point.

In terms of SVG files, i’ve actually setup a workflow for myself where I convert my SVG into a json like this

{
//...
paths: {
 layer1: "M 1 1", //etc
}

then i use the R.curve utility file (which is stand alone JS) to turn the string into path curve commands, and then use those commands in a switch statement that correlates the resulting command do the cc.Graphics method call (e.i a command looks like ['M',1,1]or ['C', 1, 1,1 1, 1, 1, 1] which are .moveTo and .bezierCurveTo methods

i made it into an extension file of the default cc.Graphics component, i’ll post the code later if you want

1 Like

Wow @skara that’s amazing and thank you for taking the time to explain these things to me!

Do you have some automated conversion of the SVG files into JSON? What if you have a crazy long SVG file exported from Photoshop?

I’m very interested in seeing your extension and helping you develop it further if you are willing to share it :slightly_smiling_face:

1 Like

currently i’m just manually converting my SVGs because they are not very long

however it should be possible to load up an SVG as a ‘text’ asset and then use js to parse the text string and get your resulting JSON that way, i haven’t used it yet but a quick search found https://github.com/elrumordelaluz/svgson

i’ll post it later tonight when i’m back at my dev station

1 Like

“graphics extension”

import { path2curve } from 'R.curve'
import { interpolate } from 'polymorph-js'

let graphicsExtension = cc.Class({
extends: cc.Graphics,

path: function (pstring) {
	this._commands = path2curve(pstring);
	for (let cdx = 0; cdx < this._commands.length; cdx++) {
		let cmd = this._commands[cdx];
		switch (cmd[0]) {
			case 'M' || 'm':

				this.moveTo(cmd[1], cmd[2])
				break;
			case 'C' || 'c':

				this.bezierCurveTo(cmd[1], cmd[2], cmd[3], cmd[4], cmd[5], cmd[6])
				break;
		}
	}
},

animate: function (pathString, pathString2, duration, animating) {
	this._fromPath = pathString;
	this._toPath = pathString2;
	this.morph = interpolate([pathString, pathString2]);
	this._time = 0;
	this._duration = duration;
	this._animating = typeof animating === 'undefined' ? true : animating;
	return this.morph;
},

_stepAnimate: function (time) {
	if (!this.morph) {
		throw 'missing morph'
		return;
	}
	var pos = time / this._duration;
	if (pos > 1) pos = 1;
	var mid = this.morph(pos)
	this._dirty = true;
	this.clear()
	this.path(mid)
	this.fill()
	if (pos >= 1) {
		this._animating = false;
		dispatch.circulate('svgFin')
	}
},

_getAnimating: function () {
	return this._animating
},

_updateAnimate: function (dt) {
	if (this._animating) {
		this._time += dt;
		this._stepAnimate(this._time);
	}
}
})

module.exports = graphicsExtension

“svg script”

onLoad: function () {
	this.SVG = null
	this.svgData = {}
	let ilen = this.svgPaths.length // property that has url paths to svg files
	for (let idx = 1; idx <= ilen; idx++) {
		let name = this.svgPaths[idx - 1]
		cc.loader.loadRes(`svg/${name}`, (err, asset) => { // svg loaded as json
			if (err) {
				cc.error(err.toString())
				return
			}
			this.preload(asset, idx, ilen, name)
		})
	}
},

preload: function (asset, idx, ilen, name) { 
	let data = asset.json .  // svg is json that has names, strings, colors, zindex as keys with values
	let names = Object.keys(data.paths)
	let strings = data.paths
	let colors = data.colors
	let zIndex = data.zIndex
	let viewBox = data.viewBox

	this.svgData[name] = {
		names,
		strings,
		colors,
		zIndex,
		viewBox
	}
	if (idx !== ilen) {
		return
	}
	this.loadingComplete()
},

loadingComplete: function () {
	this.placeSVG()
},

placeSVG: function (id = CONSTS.FIRST) {
	let svgData = this.svgData[id]
	this.SVG = new cc.Node(id)
	this.SVG.paths = {}
	for (let ndx = 0; ndx < svgData.names.length; ndx++) {
		let name = svgData.names[ndx]
		this.SVG.paths[name] = cc.instantiate(this.svgPrefab)
		this.SVG.paths[name].name = name
		let realpath = this.SVG.paths[name].getComponent(graphicsExtension)
		realpath.fillColor.fromHEX(svgData.colors[name])
		realpath.strokeColor = CONSTS.DISABLED_STROKE_COLOR
		realpath.path(svgData.strings[name])
		realpath.fill()
		this.SVG.addChild(this.SVG.paths[name], svgData.zIndex[name])
	}
	this.SVG.setPosition({
		x: svgData.viewBox.width,
		y: svgData.viewBox.height
	})
	//this.SVG.setScale(1, -1)
	this.stageMain.addChild(this.SVG)
	this.SVG.active = true
},

hope this helps :beers:

2 Likes

Thank you so much for this @skara, cheers! :beers:

I will go through this and try it out and see how it supports everything. Amazing work! :clap:

@skara or @Ronsku thanks this thread! Would you have a working example project? Since I can’t find R.curve to include it in my project

Sure you can find it here:

1 Like