mirror of
https://github.com/scratchfoundation/paper.js.git
synced 2024-12-28 17:02:24 -05:00
Remove all direct calls to view.update() and favor of the new view.requestUpdate()
Pure window.requestAnimationFrame() smoothness, automatic updates even when working directly from JavaScript, and no more slow-downs from onLoad events! Closes #830, #925
This commit is contained in:
parent
9ad63a7231
commit
b71ffdbe71
9 changed files with 76 additions and 96 deletions
|
@ -122,7 +122,6 @@
|
|||
var image = document.createElement('img');
|
||||
image.onload = function () {
|
||||
handleImage(image);
|
||||
view.update();
|
||||
};
|
||||
image.src = event.target.result;
|
||||
};
|
||||
|
|
|
@ -273,8 +273,6 @@
|
|||
// var nup = unite(pathA, pathB);
|
||||
// console.timeEnd('unite');
|
||||
// // nup.style = booleanStyle;
|
||||
|
||||
// view.update();
|
||||
}
|
||||
|
||||
var booleanStyle = {
|
||||
|
@ -307,7 +305,6 @@
|
|||
var boolPathU = _p1U.unite(_p2U);
|
||||
console.timeEnd('Union');
|
||||
boolPathU.style = booleanStyle;
|
||||
view.update();
|
||||
}
|
||||
|
||||
if (operations.intersection) {
|
||||
|
@ -318,7 +315,6 @@
|
|||
var boolPathI = _p1I.intersect(_p2I);
|
||||
console.timeEnd('Intersection');
|
||||
boolPathI.style = booleanStyle;
|
||||
view.update();
|
||||
}
|
||||
|
||||
if (operations.subtraction) {
|
||||
|
@ -329,7 +325,6 @@
|
|||
var boolPathS = _p1S.subtract(_p2S);
|
||||
console.timeEnd('Subtraction');
|
||||
boolPathS.style = booleanStyle;
|
||||
view.update();
|
||||
}
|
||||
|
||||
if (operations.exclusion) {
|
||||
|
@ -340,7 +335,6 @@
|
|||
var boolPathE = _p1E.exclude(_p2E);
|
||||
console.timeEnd('Exclusion');
|
||||
boolPathE.style = booleanStyle;
|
||||
view.update();
|
||||
}
|
||||
|
||||
if (operations.division) {
|
||||
|
@ -352,7 +346,6 @@
|
|||
console.timeEnd('Division');
|
||||
disperse(boolPathD);
|
||||
boolPathD.style = booleanStyle;
|
||||
view.update();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -482,8 +482,6 @@ Base.exports.PaperScript = (function() {
|
|||
});
|
||||
if (res.onFrame)
|
||||
view.setOnFrame(res.onFrame);
|
||||
// Automatically update view at the end.
|
||||
view.update();
|
||||
}
|
||||
return compiled;
|
||||
}
|
||||
|
|
|
@ -134,8 +134,6 @@ var Key = new function() {
|
|||
paper = scope;
|
||||
// Call the onKeyDown or onKeyUp handler if present
|
||||
tool.emit(type, new KeyEvent(down, key, character, event));
|
||||
if (view)
|
||||
view.update();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -230,9 +230,6 @@ var Raster = Item.extend(/** @lends Raster# */{
|
|||
if (view && that.responds(type)) {
|
||||
paper = view._scope;
|
||||
that.emit(type, new Event(event));
|
||||
// TODO: Request a redraw in the next animation frame from
|
||||
// update() instead!
|
||||
view.update();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -88,7 +88,13 @@ var Project = PaperScopeItem.extend(/** @lends Project# */{
|
|||
*/
|
||||
_changed: function(flags, item) {
|
||||
if (flags & /*#=*/ChangeFlag.APPEARANCE) {
|
||||
// Never draw changes right away. Simply mark the project as "dirty"
|
||||
// and request a view update through window.requestAnimationFrame()
|
||||
// (via view.requestUpdate()), which handles the smooth updates.
|
||||
this._needsUpdate = true;
|
||||
var view = this._view;
|
||||
if (view && !view._requested)
|
||||
view.requestUpdate();
|
||||
}
|
||||
// Have project keep track of changed items so they can be iterated.
|
||||
// This can be used for example to update the SVG tree. Needs to be
|
||||
|
|
|
@ -558,7 +558,6 @@ new function() {
|
|||
view = scope.project && scope.getView();
|
||||
if (onLoad)
|
||||
onLoad.call(this, item);
|
||||
view.update();
|
||||
}
|
||||
|
||||
if (isRoot) {
|
||||
|
|
|
@ -119,13 +119,11 @@ var CanvasView = View.extend(/** @lends CanvasView# */{
|
|||
* event hanlders for interaction, animation and load events, this method is
|
||||
* invoked for you automatically at the end.
|
||||
*
|
||||
* @param {Boolean} [force=false] {@true if the view should be updated even
|
||||
* if no change has happened}
|
||||
* @return {Boolean} {@true if the view was updated}
|
||||
*/
|
||||
update: function(force) {
|
||||
update: function() {
|
||||
var project = this._project;
|
||||
if (!project || !force && !project._needsUpdate)
|
||||
if (!project || !project._needsUpdate)
|
||||
return false;
|
||||
var ctx = this._context,
|
||||
size = this._viewSize;
|
||||
|
|
144
src/view/View.js
144
src/view/View.js
|
@ -160,18 +160,73 @@ var View = Base.extend(Emitter, /** @lends View# */{
|
|||
_time: 0,
|
||||
_count: 0,
|
||||
|
||||
_requestFrame: function() {
|
||||
var that = this;
|
||||
DomEvent.requestAnimationFrame(function() {
|
||||
that._requested = false;
|
||||
// Do we need to stop due to a call to the frame event's uninstall()
|
||||
if (!that._animate)
|
||||
return;
|
||||
// Request next frame already before handling the current frame
|
||||
that._requestFrame();
|
||||
that._handleFrame();
|
||||
}, this._element);
|
||||
this._requested = true;
|
||||
/**
|
||||
* Updates the view if there are changes. Note that when using built-in
|
||||
* event hanlders for interaction, animation and load events, this method is
|
||||
* invoked for you automatically at the end.
|
||||
*
|
||||
* @name View#update
|
||||
* @function
|
||||
* @param {Boolean} [force=false] {@true if the view should be updated even
|
||||
* if no change has happened}
|
||||
* @return {Boolean} {@true if the view was updated}
|
||||
*/
|
||||
// update: function(force) {
|
||||
// },
|
||||
|
||||
/**
|
||||
* Updates the view if there are changes.
|
||||
*
|
||||
* @deprecated use {@link #update()} instead.
|
||||
*/
|
||||
draw: '#update',
|
||||
|
||||
/**
|
||||
* Requests an update of the view if there are changes through the browser's
|
||||
* requestAnimationFrame() mechanism for smooth animation. Note that when
|
||||
* using built-in event handlers for interaction, animation and load events,
|
||||
* updates are automatically invoked for you automatically at the end.
|
||||
*
|
||||
* @function
|
||||
*/
|
||||
requestUpdate: function() {
|
||||
if (!this._requested) {
|
||||
var that = this;
|
||||
DomEvent.requestAnimationFrame(function() {
|
||||
that._requested = false;
|
||||
// Only handle frame and request next one if we don't need to
|
||||
// stop, e.g. due to a call to pause(), or a request for a
|
||||
// single redraw.
|
||||
if (that._animate) {
|
||||
// Request next frame before handling the current frame
|
||||
that.requestUpdate();
|
||||
that._handleFrame();
|
||||
}
|
||||
// Even if we're not animating, update the view now since this
|
||||
// might have been a request for a single redraw after a change
|
||||
that.update();
|
||||
}, this._element);
|
||||
this._requested = true;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Makes all animation play by adding the view to the request animation
|
||||
* loop.
|
||||
*/
|
||||
play: function() {
|
||||
this._animate = true;
|
||||
// Request a frame handler straight away to initialize the
|
||||
// sequence of onFrame calls.
|
||||
this.requestUpdate();
|
||||
},
|
||||
|
||||
/**
|
||||
* Makes all animation pause by removing the view to the request animation
|
||||
* loop.
|
||||
*/
|
||||
pause: function() {
|
||||
this._animate = false;
|
||||
},
|
||||
|
||||
_handleFrame: function() {
|
||||
|
@ -193,8 +248,6 @@ var View = Base.extend(Emitter, /** @lends View# */{
|
|||
if (this._stats)
|
||||
this._stats.update();
|
||||
this._handlingFrame = false;
|
||||
// Automatically update view on each frame.
|
||||
this.update();
|
||||
},
|
||||
|
||||
_animateItem: function(item, animate) {
|
||||
|
@ -229,20 +282,6 @@ var View = Base.extend(Emitter, /** @lends View# */{
|
|||
}
|
||||
},
|
||||
|
||||
_update: function() {
|
||||
this._project._needsUpdate = true;
|
||||
if (this._handlingFrame)
|
||||
return;
|
||||
if (this._animate) {
|
||||
// If we're animating, call _handleFrame staight away, but without
|
||||
// requesting another animation frame.
|
||||
this._handleFrame();
|
||||
} else {
|
||||
// Otherwise simply update the view now
|
||||
this.update();
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Private notifier that is called whenever a change occurs in this view.
|
||||
* Used only by Matrix for now.
|
||||
|
@ -317,7 +356,7 @@ var View = Base.extend(Emitter, /** @lends View# */{
|
|||
delta: delta
|
||||
});
|
||||
this._changed();
|
||||
this.update();
|
||||
this.requestUpdate();
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -539,49 +578,6 @@ var View = Base.extend(Emitter, /** @lends View# */{
|
|||
this.translate(Point.read(arguments).negate());
|
||||
}
|
||||
}), /** @lends View# */{
|
||||
/**
|
||||
* Makes all animation play by adding the view to the request animation
|
||||
* loop.
|
||||
*/
|
||||
play: function() {
|
||||
this._animate = true;
|
||||
// Request a frame handler straight away to initialize the
|
||||
// sequence of onFrame calls.
|
||||
if (!this._requested)
|
||||
this._requestFrame();
|
||||
},
|
||||
|
||||
/**
|
||||
* Makes all animation pause by removing the view to the request animation
|
||||
* loop.
|
||||
*/
|
||||
pause: function() {
|
||||
this._animate = false;
|
||||
},
|
||||
|
||||
/**
|
||||
* Updates the view if there are changes. Note that when using built-in
|
||||
* event hanlders for interaction, animation and load events, this method is
|
||||
* invoked for you automatically at the end.
|
||||
*
|
||||
* @name View#update
|
||||
* @function
|
||||
* @param {Boolean} [force=false] {@true if the view should be updated even
|
||||
* if no change has happened}
|
||||
* @return {Boolean} {@true if the view was updated}
|
||||
*/
|
||||
// update: function(force) {
|
||||
// },
|
||||
|
||||
/**
|
||||
* Updates the view if there are changes.
|
||||
*
|
||||
* @deprecated use {@link #update()} instead.
|
||||
*/
|
||||
draw: function() {
|
||||
this.update();
|
||||
},
|
||||
|
||||
// TODO: getInvalidBounds
|
||||
// TODO: invalidate(rect)
|
||||
// TODO: style: artwork / preview / raster / opaque / ink
|
||||
|
@ -1186,10 +1182,6 @@ new function() { // Injection scope for mouse events on the browser
|
|||
if (called && (!nativeMove || responds('mousedrag'))
|
||||
|| mouse.down && responds('mouseup'))
|
||||
event.preventDefault();
|
||||
|
||||
// In the end we always call update(), which only updates the view
|
||||
// if anything has changed in the above calls.
|
||||
this.update();
|
||||
},
|
||||
|
||||
_countItemEvent: function(type, sign) {
|
||||
|
|
Loading…
Reference in a new issue