From a7566c42d6aaaf552bd955bd18e71c5805a59ad7 Mon Sep 17 00:00:00 2001 From: yofreke Date: Fri, 16 Sep 2016 15:38:23 -0700 Subject: [PATCH] implement examples componentWillUnmount --- examples/components/ClmImageExample.js | 22 ++++++++++++++++++---- examples/components/FaceMaskExample.js | 20 ++++++++++++++++---- examples/components/SimpleExample.js | 20 ++++++++++++++++++-- examples/components/VideoExample.js | 20 +++++++++++++++++--- ui/container/TrackerContainer.js | 19 +++++++++++++------ 5 files changed, 82 insertions(+), 19 deletions(-) diff --git a/examples/components/ClmImageExample.js b/examples/components/ClmImageExample.js index 569ec498..801484df 100644 --- a/examples/components/ClmImageExample.js +++ b/examples/components/ClmImageExample.js @@ -6,7 +6,10 @@ import RaisedButton from 'material-ui/RaisedButton'; import Tracker from 'clmtrackr/js/Tracker'; import { resizeImage } from 'clmtrackr/js/utils/image'; -import { requestAnimFrame, cancelRequestAnimFrame } from 'clmtrackr/js/utils/anim'; +import { + requestAnimFrame, + cancelRequestAnimFrame +} from 'clmtrackr/js/utils/anim'; import TrackerContainer from 'clmtrackr/ui/container/TrackerContainer'; @@ -36,7 +39,7 @@ export default class ClmImageExample extends React.Component { cropActive: false }; - this._boundOnFrame = this._onFrame.bind(this); + this._animateRequestId = null; } _loadMediaSrc (src) { @@ -75,13 +78,24 @@ export default class ClmImageExample extends React.Component { tracker.on('converged', (event) => { this.setState({ convergenceText: 'CONVERGED', convergenceStatus: 'good' }); // stop drawloop - cancelRequestAnimFrame(this._boundOnFrame); + cancelRequestAnimFrame(this._animateRequestId); + this._animateRequestId = null; }); tracker.on('started', () => this.setState({ isTrackerRunning: true })); tracker.on('stopped', () => this.setState({ isTrackerRunning: false })); } + componentWillUnmount () { + const tracker = this.state.tracker; + tracker.stop(); + + if (this._animateRequestId) { + cancelRequestAnimFrame(this._animateRequestId); + this._animateRequestId = null; + } + } + _onFrame () { // Update overlay const trackerContainer = this.refs.trackerContainer; @@ -91,7 +105,7 @@ export default class ClmImageExample extends React.Component { cc.clearRect(0, 0, MEDIA_SIZE.width, MEDIA_SIZE.height); tracker.draw(cc.canvas); } - requestAnimFrame(this._boundOnFrame); + this._animateRequestId = requestAnimFrame(this._onFrame.bind(this)); } _start (box) { diff --git a/examples/components/FaceMaskExample.js b/examples/components/FaceMaskExample.js index 95f5eac7..a7163a70 100644 --- a/examples/components/FaceMaskExample.js +++ b/examples/components/FaceMaskExample.js @@ -7,7 +7,10 @@ import MenuItem from 'material-ui/MenuItem'; import VideoExample from './VideoExample'; import Tracker from 'clmtrackr/js/Tracker'; -import { requestAnimFrame } from 'clmtrackr/js/utils/anim'; +import { + requestAnimFrame, + cancelRequestAnimFrame +} from 'clmtrackr/js/utils/anim'; import { MASKS, getMask } from 'clmtrackr/examples/masks'; import Deformer from 'clmtrackr/js/deformers/twgl'; @@ -23,6 +26,7 @@ export default class FaceMaskExample extends VideoExample { }); this.mediaSize = { width: 370, height: 288 }; + this._animateRequestId = null; } newTracker () { @@ -44,6 +48,14 @@ export default class FaceMaskExample extends VideoExample { }); } + componentWillUnmount () { + super.componentWillUnmount(); + if (this._animateRequestId) { + cancelRequestAnimFrame(this._animateRequestId); + this._animateRequestId = null; + } + } + _setupFaceDeformation () { const trackerContainer = this.refs.trackerContainer; const video = trackerContainer.refs.media; @@ -79,9 +91,9 @@ export default class FaceMaskExample extends VideoExample { var pn = tracker.getConvergence(); if (pn < 0.4) { this._switchMasks(); - requestAnimFrame(this._drawMaskLoop.bind(this)); + this._animateRequestId = requestAnimFrame(this._drawMaskLoop.bind(this)); } else { - requestAnimFrame(this._drawGridLoop.bind(this)); + this._animateRequestId = requestAnimFrame(this._drawGridLoop.bind(this)); } } @@ -95,7 +107,7 @@ export default class FaceMaskExample extends VideoExample { const deformer = this.state.deformer; deformer.draw(positions); } - requestAnimFrame(this._drawMaskLoop.bind(this)); + this._animateRequestId = requestAnimFrame(this._drawMaskLoop.bind(this)); } startVideo () { diff --git a/examples/components/SimpleExample.js b/examples/components/SimpleExample.js index 0c8d9fe3..f2594100 100644 --- a/examples/components/SimpleExample.js +++ b/examples/components/SimpleExample.js @@ -1,6 +1,10 @@ import React from 'react'; import Tracker from 'clmtrackr/js/Tracker'; +import { + requestAnimFrame, + cancelRequestAnimFrame +} from 'clmtrackr/js/utils/anim'; import TrackerContainer from 'clmtrackr/ui/container/TrackerContainer'; @@ -18,6 +22,8 @@ export default class SimpleExample extends React.Component { tracker: null, points: null }; + + this._animateRequestId = null; } componentDidMount () { @@ -28,7 +34,17 @@ export default class SimpleExample extends React.Component { const trackerContainer = this.refs.trackerContainer; tracker.start(trackerContainer.refs.media); - requestAnimationFrame(this._onFrame.bind(this)); + setTimeout(() => this._onFrame()); + } + + componentWillUnmount () { + const tracker = this.state.tracker; + tracker.stop(); + + if (this._animateRequestId) { + cancelRequestAnimFrame(this._animateRequestId); + this._animateRequestId = null; + } } _onFrame () { @@ -43,7 +59,7 @@ export default class SimpleExample extends React.Component { // Update the rendered points this.setState({ points: tracker.getCurrentPosition() }); } - requestAnimationFrame(this._onFrame.bind(this)); + this._animateRequestId = requestAnimFrame(this._onFrame.bind(this)); } render () { diff --git a/examples/components/VideoExample.js b/examples/components/VideoExample.js index 11202371..b31ce547 100644 --- a/examples/components/VideoExample.js +++ b/examples/components/VideoExample.js @@ -11,7 +11,10 @@ import { supportsUserMedia, loadVideo } from 'clmtrackr/js/utils/video'; -import { requestAnimFrame } from 'clmtrackr/js/utils/anim'; +import { + requestAnimFrame, + cancelRequestAnimFrame +} from 'clmtrackr/js/utils/anim'; import TrackerContainer from 'clmtrackr/ui/container/TrackerContainer'; @@ -39,7 +42,7 @@ export default class VideoExample extends React.Component { this.oggVideoSrc = 'media/cap13_edit2.ogv'; this.mp4VideoSrc = 'media/cap13_edit2.mp4'; - this._boundOnFrame = this._onFrame.bind(this); + this._onFrameAnimId = null; } newTracker () { @@ -63,6 +66,17 @@ export default class VideoExample extends React.Component { }); } + componentWillUnmount () { + // Stop tracker + const tracker = this.state.tracker; + tracker.stop(); + + if (this._onFrameAnimId) { + cancelRequestAnimFrame(this._onFrameAnimId); + this._onFrameAnimId = null; + } + } + _setupVideoStream () { if (this.state.useStockVideo) { this._insertAltVideo(); @@ -99,7 +113,7 @@ export default class VideoExample extends React.Component { const tracker = this.state.tracker; tracker.draw(trackerContainer.refs.canvas); } - requestAnimFrame(this._boundOnFrame); + this._onFrameAnimId = requestAnimFrame(this._onFrame.bind(this)); } _resetTracker () { diff --git a/ui/container/TrackerContainer.js b/ui/container/TrackerContainer.js index 0922cb13..4fd93e08 100644 --- a/ui/container/TrackerContainer.js +++ b/ui/container/TrackerContainer.js @@ -27,6 +27,10 @@ export default class TrackerContainer extends React.Component { this.componentDidUpdate({ tracker: null }); } + componentWillUnmount () { + this._shutdownMediaStream(); + } + _addTrackerListeners (tracker) { tracker.on('iteration', this._boundUpdateStats); } @@ -67,6 +71,14 @@ export default class TrackerContainer extends React.Component { this._updateVideoSrc(); } + _shutdownMediaStream () { + if (!this._mediaSrcStream) { return; } + // Shut down video stream (if it has been set) + const tracks = this._mediaSrcStream.getVideoTracks(); + tracks.forEach(track => track.stop()); + this._mediaSrcStream = null; + } + _updateVideoSrc () { const mediaType = this.props.mediaType; if (mediaType !== 'video') { return; } @@ -77,12 +89,7 @@ export default class TrackerContainer extends React.Component { this._mediaSrcStream = mediaSrc; setVideoSrc(videoEl, mediaSrc); } else { - // Shut down video stream (if it has been set) - if (this._mediaSrcStream) { - const tracks = this._mediaSrcStream.getVideoTracks(); - tracks.forEach(track => track.stop()); - this._mediaSrcStream = null; - } + this._shutdownMediaStream(); if (videoEl.src) { videoEl.removeAttribute('src'); }