everyting but gif is missing 1 frame

This commit is contained in:
JuliusHerrmann 2022-01-07 02:00:50 +01:00
parent bf6f99e87c
commit 4042f232ff
2 changed files with 64 additions and 61 deletions

View File

@ -21,57 +21,61 @@ class GIFGenerator extends React.Component {
return; return;
} }
this.setState({rendering: true}); this.setState({rendering: true});
this.setState({duration: Math.abs(this.state.duration)}); this.setState({duration: Number(Math.abs(this.state.duration))},
var gif = new GIF( { () => {
workers: 2, var gif = new GIF( {
quality: 10, workers: 2,
repeat: this.state.loop? 0 : -1, quality: 10,
background: this.state.background repeat: this.state.loop? 0 : -1,
}); background: this.state.background
});
//set download trigger //set download trigger
gif.on('finished', function(blob) { gif.on('finished', function(blob) {
this.setState({rendering: false}); this.setState({rendering: false});
const link = document.createElement('a'); const link = document.createElement('a');
// create a blobURI pointing to our Blob // create a blobURI pointing to our Blob
link.href = URL.createObjectURL(blob); link.href = URL.createObjectURL(blob);
link.download = "simulationGIF"; link.download = "simulationGIF";
// some browser needs the anchor to be in the doc // some browser needs the anchor to be in the doc
document.body.append(link); document.body.append(link);
link.click(); link.click();
link.remove(); link.remove();
// in case the Blob uses a lot of memory // in case the Blob uses a lot of memory
setTimeout(() => URL.revokeObjectURL(link.href), 7000); setTimeout(() => URL.revokeObjectURL(link.href), 7000);
}.bind(this)); }.bind(this));
let stepBefore = this.state.step; let stepBefore = this.state.step;
//clear playing animation //clear playing animation
clearInterval(this.animationId); clearInterval(this.animationId);
this.props.setState({step: 0}, () => { this.props.setState({step: 0}, () => {
this.stepTime = 1; this.animationId = setInterval(this.grabImageAndNextStep.bind(null, gif, stepBefore,this.state.duration * 1000 / this.props.animationLength), 1);
//this.animationId = setInterval(this.visualizeOneStep, this.stepTime); this.props.setState({playing: true});
this.animationId = setInterval(this.grabImageAndNextStep.bind(null, gif, stepBefore), this.stepTime); });
this.props.setState({playing: true}); });
});
} }
grabImageAndNextStep = (gif, stepBefore) => { grabImageAndNextStep = (gif, stepBefore, delay) => {
//check if we are at the end //check if we are at the end
if (this.props.state.step > this.props.animationLength) { if (this.props.state.step >= this.props.animationLength) {
//add last frame and finish
this.props.visualizeOneStep();
clearInterval(this.animationId);
gif.addFrame(document.querySelectorAll("canvas")[2],
{copy: true, delay: delay});
//reset animation
this.props.setState({playing: false});
this.props.setState({step: stepBefore}); this.props.setState({step: stepBefore});
this.props.visualizeOneStep(false); this.props.visualizeOneStep(false);
clearInterval(this.animationId);
gif.render(); gif.render();
this.props.setState({playing: false});
return; return;
} }
this.props.visualizeOneStep(); this.props.visualizeOneStep();
//select the canvas (this is a bit hacky but ey it works) //select the canvas (this is a bit hacky but ey it works)
gif.addFrame(document.querySelectorAll("canvas")[2], gif.addFrame(document.querySelectorAll("canvas")[2],
// there is probably a minimum cap.... I'm not sure {copy: true, delay: delay});
{copy: true, delay: this.state.duration / this.props.animationLength});
} }
getButtonText = () => { getButtonText = () => {
@ -81,34 +85,34 @@ class GIFGenerator extends React.Component {
return "Generate GIF 📸"; return "Generate GIF 📸";
} }
//onChange={(e) => this.setState({loop: e.state.value})}> //onChange={(e) => this.setState({loop: e.state.value})}>
render() { render() {
return ( return (
<div id="generateGIFPopup"> <div id="generateGIFPopup">
<div className="popupHeader"> <div className="popupHeader">
GIF Generator GIF Generator
</div> </div>
<div className="popupSection"> <div className="popupSection">
<label htmlFor="gifDuration" id="gifLengthLabel">Duration In Seconds: </label> <label htmlFor="gifDuration" id="gifLengthLabel">Duration In Seconds: </label>
<input htmlFor="gifDuration" type="number" id="gifLengthInput" <input htmlFor="gifDuration" type="number" id="gifLengthInput"
value={this.state.duration} onChange={(e) => this.setState({duration: e.target.value})}/> value={this.state.duration} onChange={(e) => this.setState({duration: e.target.value})}/>
</div> </div>
<div className="popupSection"> <div className="popupSection">
<label htmlFor="gifBackground" id="gifBackgroundLabel">Background Color: </label> <label htmlFor="gifBackground" id="gifBackgroundLabel">Background Color: </label>
<input htmlFor="gifBackground" id="gifBackgroundInput" type='color' <input htmlFor="gifBackground" id="gifBackgroundInput" type='color'
value={this.state.background} value={this.state.background}
onChange={(e) => this.setState({background: e.target.value})}/> onChange={(e) => this.setState({background: e.target.value})}/>
</div>
<div className="popupSection">
<label htmlFor="gifLoop" id="gifLoopLabel">Loop: </label>
<input htmlFor="gifLoop" id="gifLoopInput" type="checkbox" checked={this.state.loop}
onChange={(e) =>
this.setState({loop: e.target.checked})}/>
</div>
<button className="popupButton" onClick={this.generateGIF} >{this.getButtonText()}</button>
</div> </div>
<div className="popupSection"> );
<label htmlFor="gifLoop" id="gifLoopLabel">Loop: </label>
<input htmlFor="gifLoop" id="gifLoopInput" type="checkbox" checked={this.state.loop}
onChange={(e) =>
this.setState({loop: e.target.checked})}/>
</div>
<button className="popupButton" onClick={this.generateGIF} >{this.getButtonText()}</button>
</div>
);
} }
} }

View File

@ -124,7 +124,6 @@ class Graph extends React.Component {
this.setState({playing: true}); this.setState({playing: true});
return; return;
} }
console.log("here")
this.neverPlayed = false; this.neverPlayed = false;
//check if we pause the animation //check if we pause the animation
clearInterval(this.animationId); clearInterval(this.animationId);