Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# Shadertoy frame exporter

Save PNG frames from Shadertoy
Save frames from Shadertoy to PNG or JPG

<img src="/screenshot.png?raw=true" alt="Screenshot" width="640" height="400" />
<img src="/screenshot.png?raw=true" alt="Screenshot" width="832" height="618" />

## Installation

Expand Down
4 changes: 2 additions & 2 deletions inject.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,5 @@ function injectScript(file, node) {
s.setAttribute('src', file);
th.appendChild(s);
}
injectScript( chrome.extension.getURL('/main.js'), 'body');
injectScript( chrome.extension.getURL('/lib/FileSaver-2.0.4.min.js'), 'body');
injectScript( chrome.runtime.getURL('/main.js'), 'body');
injectScript( chrome.runtime.getURL('/lib/FileSaver-2.0.4.min.js'), 'body');
48 changes: 41 additions & 7 deletions main.js
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ FrameExporter.prototype.render = function(original_render) {
this.frameUpdated = false;
original_render();

this.saveFrame(gShaderToy.mCanvas, function() {
this.saveFunction(gShaderToy.mCanvas, function() {
this.frameCounter.incrementFrame();
if (this.frameCounter.looped) {
this.stopRecording();
Expand Down Expand Up @@ -232,11 +232,34 @@ FrameExporter.prototype.createUi = function() {
}
}.bind(this));

var button = document.createElement('button');
button.textContent = 'Save frames';
this.addClass(button, 'sfe-save');
this.controls.appendChild(button);
button.addEventListener('click', this.startRecording.bind(this));
this.controls.appendChild(document.createElement('div')); // To force line return for save controls

// PNG Save part
var buttonPNG = document.createElement('button');
buttonPNG.textContent = 'Save as png';
this.addClass(buttonPNG, 'sfe-save');
this.controls.appendChild(buttonPNG);
buttonPNG.addEventListener('click', function() {
this.saveFunction = FrameExporter.prototype.saveFramePNG;
this.startRecording.bind(this)();
}.bind(this));

// JPG Save part
var jpgQualityInput = this.createInput('JPG Quality', 'number', 0.8);
jpgQualityInput.step = 0.05;
this.jpgQualityInput = jpgQualityInput;
this.jpgQualityInput.addEventListener('change', function(event) {
if (jpgQualityInput.value < 0) jpgQualityInput.value = 0;
if (jpgQualityInput.value > 1) jpgQualityInput.value = 1;
});
var buttonJPG = document.createElement('button');
buttonJPG.textContent = 'Save as jpg';
this.addClass(buttonJPG, 'sfe-save');
this.controls.appendChild(buttonJPG);
buttonJPG.addEventListener('click', function() {
this.saveFunction = FrameExporter.prototype.saveFrameJPG;
this.startRecording.bind(this)();
}.bind(this));

this.settingsChanged();
};
Expand Down Expand Up @@ -289,7 +312,7 @@ FrameExporter.prototype.createInput = function(name, type, value) {
/* Utilities
========================================================================== */

FrameExporter.prototype.saveFrame = function(canvas, done) {
FrameExporter.prototype.saveFramePNG = function (canvas, done) {
var totalFrames = this.frameCounter.totalFrames;
var digits = totalFrames.toString().length;
var frameString = this.pad(this.frameCounter.frameNumber, digits);
Expand All @@ -300,6 +323,17 @@ FrameExporter.prototype.saveFrame = function(canvas, done) {
});
};

FrameExporter.prototype.saveFrameJPG = function (canvas, done) {
var totalFrames = this.frameCounter.totalFrames;
var digits = totalFrames.toString().length;
var frameString = this.pad(this.frameCounter.frameNumber, digits);
var filename = this.prefix + frameString + '.jpg';
canvas.toBlob(function(blob) {
saveAs(blob, filename);
setTimeout(done, 100);
}, 'image/jpeg', this.jpgQualityInput.value);
};

FrameExporter.prototype.insertAfter = function(newNode, referenceNode) {
referenceNode.parentNode.insertBefore(newNode, referenceNode.nextSibling);
};
Expand Down
16 changes: 11 additions & 5 deletions manifest.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"manifest_version": 2,
"manifest_version": 3,
"name": "Shadertoy frame exporter",
"version": "0.2.6",
"description": "High quality timed frame export from Shadertoy",
Expand All @@ -15,8 +15,14 @@
"css": ["styles.css"]
}
],
"web_accessible_resources": [
"main.js",
"lib/FileSaver-2.0.4.min.js"
]
"host_permissions": ["https://www.shadertoy.com/view/*"],
"web_accessible_resources": [{
"resources": [
"main.js",
"lib/FileSaver-2.0.4.min.js"
],
"matches":[
"https://*/*"
]
}]
}
Binary file modified screenshot.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.