TiddlyWiki / TiddlyWiki5

A self-contained JavaScript wiki for the browser, Node.js, AWS Lambda etc.
https://tiddlywiki.com/
Other
8.04k stars 1.19k forks source link

Proposal: Canvas - transparent background #4035

Open twMat opened 5 years ago

twMat commented 5 years ago

Proposal: Allow the canvas background and the image editor background to be transparent so that one can lay it on top of something and still see what is behind it.

It is currently possible to set transparency for the "paint" but not for the canvas. It is also possible, using css, to make the whole image transparent but this makes the actual image(-lines) less visible which is not the desired effect.

Use cases

For the first, image-on-image, I made a prototype. It uses the css opacity attribute to make the overlaying canvas transparent but, as noted, this makes the image hazy.

twMat commented 5 years ago

I've made many attempts to do this with CSS but no avail. To name a specific issue: For an image tiddler (irrespective of format) the editwidget class parameter has no effect at all! Seems only text tiddlers are stylable.

But maybe this post explains a js based solution to get transparent background, see 3-4 posts down that deals with canvases that are redrawn continuously. (This relevant for us?) Basically, they advise context.clearRect(0,0,width,height);

Here is a more detailed description.

twMat commented 2 years ago

Transparent background is still missing, as is transparency as a colour in general to paint with, which should be possible for png and is actually a main feature for the png file format which makes it so useful on the web.

It is worth noting that you can import an image with transparent areas. And you can draw on transparent areas and the transparency stays as a background.

This makes me think that it should be possible to use a transparent background as default, instead of the current white.

However, possibly a bug related to the OP here: Gradients with transparency are killed(!) You can test it with the attached png. If you, in TW, edit the image carefully by slowly drawing a line at it, you can see how the gradient becomes solidified like in a chemical reaction.

gradient_transp .

pmario commented 2 years ago

The TW image editor doesn't know, how to deal with the alpha channel and gradients: https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/Applying_styles_and_colors#a_createlineargradient_example ... It would make the editor much more complex.

twMat commented 2 years ago

@pmario thanks. OK, if gradients would make the editor a lot more complex then it is probably not worth including it.

But transparent as a paintable color or at least as default background would definitely increase usability. To name one thing, it would enable people to draw icons that at least could appear semi decent on other backgrounds. Few people have the chops to create svg icons.

pmario commented 2 years ago

..But transparent as a paintable color or at least as default background would definitely increase usability.

hmm, That's the same thing. I did have a close look at: http://fabricjs.com/ ... It's a nice library, that contains a lot of cool stuff. ... But it is 300kByte compressed. ... There may be a possibility to "compile" as striped down version, which only contains the stuff we really need. ...

The best feature from my point of view is, that it allows to save the configuration as JSON or as SVG. So the image can be drawn "on demand" and it shouldn't use several 100kByte per image. eg: Your example is a 100kByte PNG. If saved as a tiddler it needs about 130kByte.

For more complex drawings, the "rule of thumb" is that TW uses double the space for .tid as the .PNG actually is. ...

If we could convert a drawing into JSON or SVG it may use much less space ...

BUT ... This would be a complete project and can't be done as a "hack" ... :/

twMat commented 2 years ago

http://fabricjs.com/

Cool. Much more than a painting tool. I'm guessing the code seen in their free drawing demo is the specific code for that functionality but that requires a substantially bigger "processing code".

If it is in JSON or SVG then maybe it would be possible to create something I've attempted for a long time, namely to scribble on tiddlers, e.g to underline stuff or jot sketches etc directly onto text notes. Then TW would really be a note book. This is one reason why I want transparent background. (But a major problem is text flows with the tiddler width so scribbles would have to be attached to moving points in the text. Not sure that's possible.. but if it is, then I image JSON or SVG would be more easily worked with...)

BUT ... This would be a complete project and can't be done as a "hack" ... :/

Right. The team behind Fabric is clearly open source people though so maybe they have some ideas if we ask them. Just maybe they've modularized the code in some way so splitting things is not a huge project.

pmario commented 2 years ago

Cool. Much more than a painting tool. I'm guessing the code seen in their free drawing demo is the specific code for that functionality but that requires a substantially bigger "processing code".

It seems the whole code for the demo is right below the demo. .. I didn't see this example.

If that's really all the code needed to create that editor, it's really impressive, what the library can handle.

pmario commented 2 years ago

... Just maybe they've modularized the code in some way so splitting things is not a huge project.

There is a build instruction, how to build a smaller library. That shouldn't be the problem. ... The problem is, to implement the library functionality into TW using the "TW way". ...

twMat commented 2 years ago

A thing to note regarding footprint; If a better drawing tool is introduced then the current one can be removed. How big is the current one? (How do I even look up that question?)

twMat commented 2 years ago

The problem is, to implement the library functionality into TW using the "TW way". ...

A cool thing IF this is solved in a generic way, is that people could maybe create plugins for the other Fabric functionalities they demo. Then if "objects" are tiddlers, the TW could turn into a very "visual studio" to draw and animate things.

twMat commented 2 months ago

Here is a very small, no-library, js to make the canvas transparent. It is described here (first post).

Could this work for the OP? The hope is still to be able to make scribbles that can be laid on top of text.

code:

var el = document.getElementById('code');

var canvas = document.createElement('canvas');
canvas.setAttribute('width', 250);
canvas.setAttribute('height', 250);
var context = canvas.getContext("2d");
context.drawImage(el, 0, 0, canvas.width, canvas.height);

var imageData = context.getImageData(0, 0, canvas.width, canvas.height);

var preserveColor = function(imageData, color) {
    var data = imageData.data;
    for (var i = 0; i < data.length; i += 4) {
    var preserve = data[i] === color.r
        && data[i + 1] === color.g
      && data[i + 2] === color.b
      && data[i + 3] === color.a;

    data[i + 3] = preserve ? data[i + 3] : 0;
  }
  return imageData;
};

var newData = preserveColor(imageData, {r: 255, g: 255, b: 255, a: 255});
context.putImageData(newData, 0, 0);

document.body.appendChild(canvas);
Jermolene commented 2 months ago

Hi @twMat apologies I don't think I had seen this. It would be very straightforward to add support for clearing the canvas to a transparent colour. It's possible it could be done in wikitext – have a look at $:/core/ui/EditorToolbar/clear-dropdown