Skip to content

Commit

Permalink
Give properties to node on initialization.
Browse files Browse the repository at this point in the history
  • Loading branch information
freiksenet committed Nov 20, 2014
1 parent 665b825 commit 43deb54
Show file tree
Hide file tree
Showing 9 changed files with 110 additions and 75 deletions.
7 changes: 5 additions & 2 deletions .jshintrc
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,8 @@
"newcap": true,
"maxlen": 80,
"globalstrict": true,
"predef": ["module", "require", "window", "document"]
}
"predef": [
"module", "require", "window", "document",
"describe", "it", "expect"
]
}
21 changes: 7 additions & 14 deletions demo/smoke-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -99,26 +99,19 @@ React.renderComponent(
<Wedge x="30" y="225" radius="40"
fill="red" stroke="black" strokeWidth="5"
angle="60" rotation="-120" />
<Text x="10" y="15" text="Text" fontSize="30" fontFamily="Calibri"
fill="green" />
<TextPath x="100" y="50" fill="#333"
fontSize="24" fontFamily="Arial"
text="All the world's a stage, and all the men and women merely players."
data="M10,10 C0,0 10,150 100,100 S300,150 400,50" />
</Layer>
</Stage>,
document.getElementById("canvas")
);

/*
<Label x="100" y="100" draggable="true">
<Tag fill="#bbb" stroke="#333"
shadowColor="black" shadowBlur="10"
shadowOffsetX="10" shadowOffsetY="10" shadowOpacity="0.2"
lineJoin="round"
pointerDirection="up" pointerWidth="20" pointerHeight="20"
cornerRadius="5" />
<Text text="Label Text" fontSize="50" lineHeight="1.2" padding="10" fill="blue" />
</Label>
<Text x="10" y="15" text="Text" fontSize="30" fontFamily="Calibri" fill="green" />
<TextPath x="100" y="50" fill="#333"
fontSize="24" fontFamily="Arial"
text="All the world's a stage, and all the men and women merely players."
data="M10,10 C0,0 10,150 100,100 S300,150 400,50" />-->
-->
This smoke-test is not complete.
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
"demo": "npm run umd && cp -r demo build/ && cp index.html build/",
"umd-min": "webpack --config webpack.config.min.js",
"start": "webpack-dev-server -d --colors --progress",
"test": "jshint ./react-kinetic.js ./src/*.js && karma start --single-run --browsers Firefox",
"test": "jshint ./react-kinetic.js ./src/*.js ./test/*.js && karma start --single-run --browsers Firefox",
"test-watch": "karma start",
"gh-pages": "./scripts/gh-pages.sh"
}
Expand Down
95 changes: 56 additions & 39 deletions src/KineticBaseMixin.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@ var KineticProperty = require('./KineticProperty').KineticProperty;

var KineticBaseMixin = {
componentWillMount: function () {
this._node = this.createKineticNode();
this.nodeName = this._node.className || this._node.nodeType;
this._propValidCache = {};
var initialProps = this._getRequiredUpdates({}, this.props);
this._node = this.createKineticNode(initialProps.properties);
},

componentDidMount: function () {
Expand All @@ -25,60 +26,76 @@ var KineticBaseMixin = {
},

_isPropValid: function (prop) {
var nodeName = this.nodeName;
return KineticProperty.getValidProps[nodeName][prop];
return KineticProperty.getValidProps[this.constructor.displayName][prop];
},

updateNodeProperties: function (prevProps) {
if (!this._propValidCache) {
this._propValidCache = {};
_getValidProp: function (propKey) {
if (!this._propValidCache.hasOwnProperty(propKey)) {
this._propValidCache[propKey] = this._isPropValid(propKey);
}
var propCache = this._propValidCache;
return this._propValidCache[propKey];
},

_getRequiredUpdates: function (oldProps, newProps) {
var updates = {
eventsOn: {},
eventsOff: {},
properties: {}
};

var propKey;
var validEvent;
var validProp;
var eventName;
var nextProps = this.props;
var node = this.getKineticNode();

for (propKey in prevProps) {
eventName = KineticProperty.getEventName[propKey];
if (!propCache.hasOwnProperty(propKey)) {
propCache[propKey] = this._isPropValid(propKey);
for (propKey in oldProps) {
validEvent = KineticProperty.getEventName[propKey];
validProp = this._getValidProp(propKey);
if (!newProps.hasOwnProperty(propKey)) {
if (validEvent) {
updates.eventsOff[validEvent] = true;
} else if (validProp) {
updates.properties[propKey] = validProp[1];
}
}
validProp = propCache[propKey];
}

if (!nextProps.hasOwnProperty(propKey) &&
prevProps.hasOwnProperty(propKey)) {
if (eventName) {
node.off(eventName);
for (propKey in newProps) {
validEvent = KineticProperty.getEventName[propKey];
validProp = this._getValidProp(propKey);
if (validEvent) {
if (oldProps.hasOwnProperty(propKey)) {
if (oldProps[propKey] !== newProps[propKey]) {
updates.eventsOff[validEvent] = true;
updates.eventsOn[validEvent] = newProps[propKey];
}
} else {
updates.eventsOn[validEvent] = newProps[propKey];
}
else if (validProp) {
node[propKey](validProp[1]);
} else if (validProp) {
if (!oldProps.hasOwnProperty(propKey) ||
oldProps[propKey] !== newProps[propKey]) {
updates.properties[propKey] = newProps[propKey];
}
}
}

for (propKey in nextProps) {
eventName = KineticProperty.getEventName[propKey];
if (!propCache.hasOwnProperty(propKey)) {
propCache[propKey] = this._isPropValid(propKey);
}
validProp = propCache[propKey];
return updates;
},

var nextProp = nextProps[propKey];
var prevProp = prevProps[propKey];
updateNodeProperties: function (prevProps) {
var node = this.getKineticNode();
var updates = this._getRequiredUpdates(prevProps, this.props);

if (eventName) {
node.off(eventName);
node.on(eventName, nextProp);
}
else if (validProp) {
if (nextProps.hasOwnProperty(propKey) && nextProp !== prevProp) {
node[propKey](nextProp);
}
}
var eventName;
for (eventName in updates.eventsOff) {
node.off(eventName);
}

for (eventName in updates.eventsOn) {
node.on(eventName, updates.eventsOn[eventName]);
}

node.setAttrs(updates.properties);
}
};

Expand Down
4 changes: 2 additions & 2 deletions src/KineticFactory.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ var KineticFactory = {

mixins: mixins,

createKineticNode: function () {
return new Kinetic[kineticClass]();
createKineticNode: function (properties) {
return new Kinetic[kineticClass](properties);
},

render: util.nodeRenderer
Expand Down
5 changes: 4 additions & 1 deletion src/KineticProperty.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,10 @@ function injectKineticProperties (kineticConfig,
for (var ci in children) {
var child = children[ci];
var existingProps = KineticProperty.getValidProps[child] || {};
existingProps[propName] = [propType, defaultValue];
existingProps[propName] = {
type: propType,
defaultValue: defaultValue
};
KineticProperty.getValidProps[child] = existingProps;
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/KineticPropertyConfig.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ var KineticHierarchy = {
Line: ['Shape', 'Node'],
Sprite: ['Shape', 'Node'],
Path: ['Shape', 'Node'],
TextPath: ['Shape', 'Node'],
TextPath: ['Shape', 'Node', 'Path', 'Text'],
RegularPolygon: ['Shape', 'Node'],
Star: ['Shape', 'Node'],
Tag: ['Shape', 'Node']
Expand Down
7 changes: 2 additions & 5 deletions src/KineticStage.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,20 +27,17 @@ var Stage = React.createClass({
// Kinetic modifies children array in place
var children = oldNode.getChildren().slice();

this._node = this.createKineticNode(this.refs.canvas.getDOMNode());
this._node = this.createKineticNode({}, this.refs.canvas.getDOMNode());
this.updateNodeProperties({});

children.forEach(function (child) {
child.moveTo(this.getKineticNode());
}.bind(this));

oldNode.destroy();
},componentWillMount: function () {
this._node = this.createKineticNode();
this.nodeName = this._node.className || this._node.nodeType;
},

createKineticNode: function (container) {
createKineticNode: function (props, container) {
if (!container) {
container = document.createElement("div");
}
Expand Down
42 changes: 32 additions & 10 deletions test/react-kinetic.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
"use strict";

var React = require('react/addons');
var TestUtils = React.addons.TestUtils;
var RK = require('../react-kinetic');
Expand All @@ -20,8 +22,14 @@ describe('Circle', function () {
it('can render Circle', function () {
var stageInstance = TestUtils.renderIntoDocument(
RK.Stage(null,
RK.Layer(null, RK.Circle({id: 1, x: 10, y: 20, radius: 5, stroke: 'red'}))));
var circleInstance = TestUtils.findRenderedComponentWithType(stageInstance, RK.Circle);
RK.Layer(null, RK.Circle({
id: 1, x: 10, y: 20,
radius: 5, stroke: 'red'
}))));
var circleInstance = TestUtils.findRenderedComponentWithType(
stageInstance,
RK.Circle
);
var kineticCircle = circleInstance.getKineticNode();
expect(kineticCircle.x()).toBe(10);
expect(kineticCircle.y()).toBe(20);
Expand All @@ -35,31 +43,42 @@ describe('Text', function () {

it('can render Text with no size', function () {
var stageInstance = renderIntoStage(RK.Text({text: 'Hello, world'}));
var renderedText = TestUtils.findRenderedComponentWithType(stageInstance, RK.Text);
var renderedText = TestUtils.findRenderedComponentWithType(
stageInstance,
RK.Text
);
var kineticInstance = renderedText.getKineticNode();
expect(kineticInstance.text()).toEqual('Hello, world');
expect(kineticInstance.getText()).toEqual('Hello, world');
});

it('can render Text with size', function () {
var stageInstance = renderIntoStage(RK.Text, RK.Text({
id: "text1",
var stageInstance = renderIntoStage(RK.Text({
x: 10,
y: 15,
text: 'Simple Text',
text: 'Hello, world',
fontSize: 30,
fontFamily: 'Calibri',
fill: 'green'
}, 'Hello, world'));
var renderedText = TestUtils.findRenderedComponentWithType(stageInstance, RK.Text);
}));
var renderedText = TestUtils.findRenderedComponentWithType(
stageInstance,
RK.Text
);
var kineticInstance = renderedText.getKineticNode();
expect(kineticInstance.text()).toEqual('Hello, world');
});
});

describe('Text2', function () {

});

describe('TextPath', function () {
it('can render TextPath', function () {
var txt = 'All the world\'s a stage, and all the men and women merely players.';
var txt = (
'All the world\'s a stage, and all the men and women merely players.'
);
var stageInstance = renderIntoStage(RK.TextPath({
x: 100,
y: 50,
Expand All @@ -69,7 +88,10 @@ describe('TextPath', function () {
text: txt,
data: 'M10,10 C0,0 10,150 100,100 S300,150 400,50'
}));
var renderedTextPath = TestUtils.findRenderedComponentWithType(stageInstance, RK.TextPath);
var renderedTextPath = TestUtils.findRenderedComponentWithType(
stageInstance,
RK.TextPath
);
expect(renderedTextPath).not.toBeNull();
var kineticInstance = renderedTextPath.getKineticNode();
expect(kineticInstance.getText()).toEqual(txt);
Expand Down

0 comments on commit 43deb54

Please sign in to comment.