twinejs
twinejs copied to clipboard
Importing image resources
Originally reported by: Leon Arnott (Bitbucket: L, GitHub: Unknown)
There's some author demand (with myself being the first) for the return of Twine 1's image resource importing, whereby you just drag and drop an image file from your desktop into the Story Map, and Twine converts it to base64 and adds it to the story as a "passage" that other passages can include. The advantages, of course, are that the image is always available to the story, offline or on, and when the story is archived and unarchived (much like the assets in graphical games).
This would, I think, be rendered into the story format's HTML as a special element, separate from a <tw-passagedata>
- maybe a <tw-imagedata>
? - that the story format can figure out for itself.
Considering images and base64 are native to the web, this should actually be a mite easier than it was for me to implement in Twine 1.
P.S. Once this is implemented, I'd like to expand it to an area Twine 1 never reached: importing MP3 files as audio resources.
- Bitbucket: https://bitbucket.org/klembot/twinejs/issue/114
Original comment by Chris Klimas (Bitbucket: klembot, GitHub: klembot):
Issue #179 was marked as a duplicate of this issue.
Original comment by Leon Arnott (Bitbucket: L, GitHub: Unknown):
A related feature I've been reminded of: external <img>
images could be imported into base64 <tw-imagedata>
passages when the story is published - similar to Twine 1's prompt for importing when it detects an <img>
in the passage.
I would be very interested in working on this.
For reference here is what @klembot wrote over in #1490 on this:
I feel embedding images directly into exported HTML with Base64, which many people have suggested in the past, is not a good idea. I can go into more detail on why I feel this way if you'd like. And whatever solution would be proposed would also need to consider browser Twine users--see design goals for more explanation.
@klembot: I would be very interested in hearing your thoughts on why base64 embedding might be a bad Idea.
Also I can here add a bit more on what I could imagine this feature to look like after reading the design goals:
UI-wise:
Have a button in the "Story" tab that might be named "Assets" or "Images" that opens a drawer where users can drag & drop files to choose files to add to the story. In that pane users should also be able to (re-)name files and delete them from the story. The files should then be able to be used in a way as if they were in the same folder as the exported story. E.g. if the image is named "example.jpg" users should be able to write <img src="example.jpg" />
.
Technology-wise: I see two main concerns here:
- Storage in the editor (this again may be different for browser-twine and electron-twine). For browser-twine I would suggest using something like the origin private file system api while for the electron version I would suggest to put the assets in the Story folder. Just embedding them into the twine string might become a problem as there is a 10mb limit on localstorage in most browsers.
- Bundeling in exported files: For this I would prefer to embed the assets in some way into the HTML file. this would allow us to keep the simplicity of having just one html file. Base64 seems to be the obvious choice here but there might be alternatives.
@anuejn if the goal is to be able to enter HTML with relative URLs in a story, then we have that workflow more or less already in app Twine, I think:
- Create folder in the Twine directory named something like "Assets" or "Resources"
- Reference files in there with syntax like
<img src="../Assets/picture.jpeg" alt="" />
. This should work in test mode. - For the published version, either reproduce this directory structure, or do a find/replace to change references like
"../Assets/
to"Assets/
.
It's not currently documented because the feature is new, and if there are bugs with this, it'd mean files would get inadvertantly deleted, but Twine shouldn't delete folders in the scratch folder, so you could potentially put the Assets folder in your scratch folder and skip step 3.
The reason I don't think base64 is a good idea for assets is because base64'd content blocks HTML parsing in the browser. Story formats can't start to execute code while the browser is parsing, I believe, so the player gets a blank page or perhaps some static HTML until the page is fully loaded and parsed--a format couldn't even show a progress bar, because it hasn't been loaded or parsed yet. With an additional ~33% filesize overhead introduced by base64, things can get really dire with even a small amount of media, I feel. Assets referenced by source URLs don't have this problem because the browser can keep parsing the HTML and execute JS while the assets load.
That said... if you have a POC showing how base64 encoded content can avoid blocking story format JS from running, I'd be interested in exploring that.
For browser-twine I would suggest using something like the origin private file system api
note: Files stored in the origin private file system are not visible/accessible to the end-user, except via the related API. eg. the end-user can't easily access those files using their Operating System's File Manager/Explorer application.
This means any modification or deletion of the files stored in the origin private file system must be done view the web-app. This makes something like post-storage image editing a more complex action, unless the end-user is storing a 2nd copy of the specific image file else where, which kind of defeats the purpose of allowing the end-user to store assets relative to their project.
@klembot that is indeed a very good hint, thanks. This works for me for the time being (especially putting assets into the Storys folder which I share with my collaborators via git) is very handy. I think that might do it for me for now but ultimately a “proper” solution would be nice.
@greyelf I think that it would be very confusing to have a webapp work on local files. I know of none that does that, and it would change the mechanics of current browser-twine a lot (it currently behaves like a "normal webapp" where the files are stored "in the app").
@anuejn
I think that it would be very confusing to have a webapp work on local files.
You suggested changing the browser based release of the Twine 2.x application to use the origin private file system api.
For browser-twine I would suggest using something like the origin private file system api
That API stores the files it manages on the end-user's local hard-drive, in a hidden folder controlled by the web-browser. So you were the one who suggested having "a webapp work on local files", not I.
I was just explaining that the end-user won't have easy access to those files, except via the functionality of the Twine 2.x application.
IIRC a script tag that's not a module or deferred blocks the loading, so if you'd include the base64 data after the story script and include the data in e.g. a script tag with a non-executable type, the browser should be able to go over it pretty fast since it will treat the contents as arbitrary data. I don't know if the browser is able to render anything changed with JS while the document is still loading though, or if the DOM is even accessible while loading.
Another option would be that the "publish as file" would be converted to "publish as zip" when resources are used, and the zip contains the appropriate directory structure alongside an index.html. The zip can then be extracted or uploaded to a service like itch.io. Base64 inclusion could be a fallback if you really need the story to be in one file for some reason.