Skip to content

Commit 585dd11

Browse files
committed
Merge branch 'master' of github.com:Flipboard/react-canvas into unicode-linebreaking
2 parents 297650a + 049f3c8 commit 585dd11

File tree

14 files changed

+107
-29
lines changed

14 files changed

+107
-29
lines changed

examples/css-layout/app.js

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,9 @@ var App = React.createClass({
2323
<Text style={this.getTitleStyle()}>
2424
Professor PuddinPop
2525
</Text>
26-
<Image src='http://lorempixel.com/360/420/cats/1/' style={this.getImageStyle()} fadeIn={true} />
26+
<Group style={this.getImageGroupStyle()}>
27+
<Image src='http://lorempixel.com/360/420/cats/1/' style={this.getImageStyle()} fadeIn={true} />
28+
</Group>
2729
<Text style={this.getExcerptStyle()}>
2830
With these words the Witch fell down in a brown, melted, shapeless mass and began to spread over the clean boards of the kitchen floor. Seeing that she had really melted away to nothing, Dorothy drew another bucket of water and threw it over the mess. She then swept it all out the door. After picking out the silver shoe, which was all that was left of the old woman, she cleaned and dried it with a cloth, and put it on her foot again. Then, being at last free to do as she chose, she ran out to the courtyard to tell the Lion that the Wicked Witch of the West had come to an end, and that they were no longer prisoners in a strange land.
2931
</Text>
@@ -51,17 +53,28 @@ var App = React.createClass({
5153
};
5254
},
5355

54-
getImageStyle: function () {
56+
getImageGroupStyle: function () {
5557
return {
58+
position: 'relative',
5659
flex: 1,
5760
backgroundColor: '#eee'
5861
};
5962
},
6063

64+
getImageStyle: function () {
65+
return {
66+
position: 'absolute',
67+
left: 0,
68+
top: 0,
69+
right: 0,
70+
bottom: 0
71+
};
72+
},
73+
6174
getTitleStyle: function () {
6275
return {
6376
fontFace: FontFace('Georgia'),
64-
fontSize: 18,
77+
fontSize: 22,
6578
lineHeight: 28,
6679
height: 28,
6780
marginBottom: 10,
@@ -73,7 +86,7 @@ var App = React.createClass({
7386
getExcerptStyle: function () {
7487
return {
7588
fontFace: FontFace('Georgia'),
76-
fontSize: 12,
89+
fontSize: 17,
7790
lineHeight: 25,
7891
marginTop: 15,
7992
flex: 1,

examples/timeline/components/Page.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ var Page = React.createClass({
9191
top: this.getImageHeight() + CONTENT_INSET,
9292
left: CONTENT_INSET,
9393
width: this.props.width - 2 * CONTENT_INSET,
94-
fontSize: 20,
94+
fontSize: 22,
9595
lineHeight: 30,
9696
fontFace: FontFace('Avenir Next Condensed, Helvetica, sans-serif', null, {weight: 500})
9797
};
@@ -102,7 +102,7 @@ var Page = React.createClass({
102102
left: CONTENT_INSET,
103103
width: this.props.width - 2 * CONTENT_INSET,
104104
fontFace: FontFace('Georgia, serif'),
105-
fontSize: 12,
105+
fontSize: 15,
106106
lineHeight: 23
107107
};
108108
},

lib/CanvasUtils.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,7 @@ function drawText (ctx, text, x, y, width, height, fontFace, options) {
136136
}
137137

138138
ctx.fillStyle = options.color;
139-
ctx.font = fontFace.attributes.style + ' normal ' + fontFace.attributes.weight + ' ' + options.fontSize + 'pt ' + fontFace.family;
139+
ctx.font = fontFace.attributes.style + ' ' + fontFace.attributes.weight + ' ' + options.fontSize + 'px ' + fontFace.family;
140140

141141
textMetrics.lines.forEach(function (line, index) {
142142
currText = line.text;

lib/Image.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ var RawImage = createComponent('Image', LayerMixin, {
3434
var props = nextComponent.props;
3535
this.applyLayerProps(prevProps, props);
3636
this._currentElement = nextComponent;
37+
this.node.invalidateLayout();
3738
},
3839

3940
});

lib/ImageCache.js

Lines changed: 60 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -77,16 +77,65 @@ assign(Img.prototype, EventEmitter.prototype, {
7777
});
7878

7979
var kInstancePoolLength = 300;
80-
var _instancePool = [];
8180

82-
function getPooledImage (src) {
83-
for (var i=0, len=_instancePool.length; i < len; i++) {
84-
if (_instancePool[i].getOriginalSrc() === src) {
85-
return _instancePool[i];
81+
var _instancePool = {
82+
length: 0,
83+
// Keep all the nodes in memory.
84+
elements: {
85+
86+
},
87+
88+
// Push with 0 frequency
89+
push: function (hash, data) {
90+
this.length++;
91+
this.elements[hash] = {
92+
hash: hash, // Helps identifying
93+
freq: 0,
94+
data: data
95+
};
96+
},
97+
98+
get: function (path) {
99+
var element = this.elements[path];
100+
101+
if( element ){
102+
element.freq++;
103+
return element.data;
104+
}
105+
106+
return null;
107+
},
108+
109+
// used to explicitely remove the path
110+
removeElement: function (path) {
111+
// Now almighty GC can claim this soul
112+
var element = this.elements[path];
113+
delete this.elements[path];
114+
this.length--;
115+
return element;
116+
},
117+
118+
_reduceLeastUsed: function (least, currentHash) {
119+
var current = _instancePool.elements[currentHash];
120+
121+
if( least.freq > current.freq ){
122+
return current;
86123
}
124+
125+
return least;
126+
},
127+
128+
popLeastUsed: function () {
129+
var reducer = _instancePool._reduceLeastUsed;
130+
var minUsed = Object.keys(this.elements).reduce(reducer, { freq: Infinity });
131+
132+
if( minUsed.hash ){
133+
return this.removeElement(minUsed.hash);
134+
}
135+
136+
return null;
87137
}
88-
return null;
89-
}
138+
};
90139

91140
var ImageCache = {
92141

@@ -96,14 +145,14 @@ var ImageCache = {
96145
* @return {Img}
97146
*/
98147
get: function (src) {
99-
var image = getPooledImage(src);
148+
var image = _instancePool.get(src);
100149
if (!image) {
101-
// Simple FIFO queue
150+
// Awesome LRU
102151
image = new Img(src);
103152
if (_instancePool.length >= kInstancePoolLength) {
104-
_instancePool.shift().destructor();
153+
_instancePool.popLeastUsed().destructor();
105154
}
106-
_instancePool.push(image);
155+
_instancePool.push(image.getOriginalSrc(), image);
107156
}
108157
return image;
109158
}

lib/Layer.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ var Layer = createComponent('Layer', LayerMixin, {
1717
var props = nextComponent.props;
1818
this.applyLayerProps(prevProps, props);
1919
this._currentElement = nextComponent;
20+
this.node.invalidateLayout();
2021
}
2122

2223
});

lib/LayerMixin.js

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -81,11 +81,6 @@ var LayerMixin = {
8181
},
8282

8383
unmountComponent: function() {
84-
// Purge backing stores on unmount.
85-
var layer = this.node;
86-
if (layer.backingStoreId) {
87-
DrawingUtils.invalidateBackingStore(layer.backingStoreId);
88-
}
8984
this.destroyEventListeners();
9085
}
9186

lib/Surface.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -145,8 +145,8 @@ var Surface = React.createClass({
145145
// Execute pending draw that may have been scheduled during previous frame
146146
this._frameReady = true;
147147
if (this._pendingTick) {
148-
this.tick();
149148
this._pendingTick = false;
149+
this.batchedTick();
150150
}
151151
},
152152

lib/Text.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ var Text = createComponent('Text', LayerMixin, {
3333
this.applyLayerProps(prevProps, props);
3434
this.applyTextProps(prevProps, props);
3535
this._currentElement = nextComponent;
36+
this.node.invalidateLayout();
3637
}
3738

3839
});

lib/__tests__/clamp-test.js

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
jest.dontMock('../clamp.js');
2+
3+
var clamp = require('../clamp');
4+
5+
describe('clamp', function() {
6+
it('returns the min if n is less than min', function() {
7+
expect(clamp(-1, 0, 1)).toBe(0);
8+
});
9+
10+
it('returns the max if n is greater than max', function() {
11+
expect(clamp(2, 0, 1)).toBe(1);
12+
});
13+
14+
it('returns n if n is between min and max', function() {
15+
expect(clamp(0.5, 0, 1)).toBe(0.5);
16+
});
17+
});

0 commit comments

Comments
 (0)