mirror of
https://github.com/Jermolene/TiddlyWiki5
synced 2024-12-28 19:10:28 +00:00
Innerwiki: Add support for SVG overlays
This commit is contained in:
parent
049244e8a8
commit
b6d901f888
@ -45,10 +45,28 @@ var TW_Element = function(tag,namespace) {
|
||||
this.attributes = {};
|
||||
this.isRaw = false;
|
||||
this.children = [];
|
||||
this.style = {};
|
||||
this._style = {};
|
||||
this.namespaceURI = namespace || "http://www.w3.org/1999/xhtml";
|
||||
};
|
||||
|
||||
Object.defineProperty(TW_Element.prototype, "style", {
|
||||
get: function() {
|
||||
return this._style;
|
||||
},
|
||||
set: function(str) {
|
||||
var self = this;
|
||||
str = str || "";
|
||||
$tw.utils.each(str.split(";"),function(declaration) {
|
||||
var parts = declaration.split(":"),
|
||||
name = $tw.utils.trim(parts[0]),
|
||||
value = $tw.utils.trim(parts[1]);
|
||||
if(name && value) {
|
||||
self._style[$tw.utils.convertStyleNameToPropertyName(name)] = value;
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
Object.defineProperty(TW_Element.prototype, "nodeType", {
|
||||
get: function() {
|
||||
return 1;
|
||||
@ -169,13 +187,13 @@ Object.defineProperty(TW_Element.prototype, "outerHTML", {
|
||||
}
|
||||
}
|
||||
}
|
||||
if(this.style) {
|
||||
if(this._style) {
|
||||
var style = [];
|
||||
for(var s in this.style) {
|
||||
style.push(s + ":" + this.style[s] + ";");
|
||||
for(var s in this._style) {
|
||||
style.push($tw.utils.convertPropertyNameToStyleName(s) + ":" + this._style[s] + ";");
|
||||
}
|
||||
if(style.length > 0) {
|
||||
output.push(" style=\"",style.join(""),"\"")
|
||||
output.push(" style=\"",style.join(""),"\"");
|
||||
}
|
||||
}
|
||||
output.push(">");
|
||||
|
@ -8,5 +8,7 @@ To try these examples under Node.js:
|
||||
# Execute the following command in the root of the TiddlyWiki 5 repo:
|
||||
|
||||
```
|
||||
./tiddlywiki.js editions/innerwikidemo --screenshot '[[$:/plugins/tiddlywiki/innerwiki/examples]]' 4
|
||||
./tiddlywiki.js editions/innerwikidemo --screenshot '[[$:/plugins/tiddlywiki/innerwiki/examples]]' 4 --render '[[$:/plugins/tiddlywiki/innerwiki/examples]]' "examples.html"
|
||||
```
|
||||
|
||||
Open `examples.html` to see the generated static HTML rendering.
|
||||
|
@ -1,5 +1,11 @@
|
||||
title: $:/plugins/tiddlywiki/innerwiki/examples
|
||||
|
||||
\define big-arrow(x,y,colour:"#ff0000",border:"#000000")
|
||||
<g transform="translate($x$,$y$)">
|
||||
<path d="m-81.43106,34.99315l40.25737,-49.78116l40.25737,49.78116l-20.12869,0l0,50.02069l-40.25737,0l0,-50.02069l-20.12869,0l0,0z" fill="$colour$" stroke="$border$" stroke-dasharray="null" stroke-linecap="null" stroke-linejoin="null" stroke-width="5" transform="rotate(49.3775 -41.1737 35.1129)"/>
|
||||
</g>
|
||||
\end
|
||||
|
||||
\define example(text)
|
||||
<$codeblock code=<<__text__>>/>
|
||||
|
||||
@ -12,10 +18,10 @@ $text$
|
||||
|
||||
The innerwiki widget specifies the dimensions of the virtual screen used to render the wiki (in pixels) and CSS styles to apply to it. Nested `<$data>` widgets are used to specify individual payload tiddlers to be loaded into the wiki. In this example, we initialise the innerwiki with two tiddlers "HelloThere" and "$:/DefaultTiddlers":
|
||||
|
||||
<<example """<$innerwiki width="1200" height="400" style="width:100%;" filename="screenshot-1">
|
||||
<$macrocall $name="example" text="""<$innerwiki width="1200" height="400" style="width:100%;" filename="screenshot-1.png">
|
||||
<$data title="HelloThere" text="This tiddler is inside a wiki"/>
|
||||
<$data title="$:/DefaultTiddlers" text="HelloThere"/>
|
||||
</$innerwiki>""">>
|
||||
</$innerwiki>"""/>
|
||||
|
||||
Note that the "screenshot" is a shrunken but fully interactive TiddlyWiki.
|
||||
|
||||
@ -24,50 +30,70 @@ Note that the "screenshot" is a shrunken but fully interactive TiddlyWiki.
|
||||
To render these examples as a PNG bitmap under Node.js, execute the following at the command prompt:
|
||||
|
||||
```
|
||||
tiddlywiki mywiki --screenshot $:/plugins/tiddlywiki/innerwiki/examples
|
||||
tiddlywiki editions/innerwikidemo --screenshot $:/plugins/tiddlywiki/innerwiki/examples
|
||||
```
|
||||
|
||||
The screenshots will be saved as `screenshot-1.png` etc in the `./output` folder of the wiki.
|
||||
|
||||
To render this example tiddler as a static HTML file that embeds the screenshot images and includes the SVG overlays:
|
||||
|
||||
```
|
||||
tiddlywiki editions/innerwikidemo --render '[[$:/plugins/tiddlywiki/innerwiki/examples]]' "examples.html" --build index
|
||||
```
|
||||
|
||||
!! SVG overlays
|
||||
|
||||
Any displayable content within innerwiki widget is displayed within an automatically created SVG element. This allows overlays to be added:
|
||||
|
||||
<$macrocall $name="example" text="""<$innerwiki width="1200" height="400" style="width:100%;" filename="screenshot-2.png">
|
||||
<$data title="HelloThere" text="This tiddler is inside a wiki"/>
|
||||
<$data title="$:/DefaultTiddlers" text="HelloThere"/>
|
||||
<circle cx="600" cy="50" r="40" stroke="black" stroke-width="2" fill="green" />
|
||||
<<big-arrow 600 50>>
|
||||
</$innerwiki>"""/>
|
||||
|
||||
Notice how macros can be used to encapsulate SVG fragments ([[see the source of this tiddler|$:/plugins/tiddlywiki/innerwiki/examples]]).
|
||||
|
||||
!! Clipping
|
||||
|
||||
A clipping rectangle can be applied to limit the area of the wiki that is displayed. For example:
|
||||
|
||||
<<example """<$innerwiki width="1200" height="400" style="width:100%;" clipLeft="500" clipTop="100" clipWidth="600" clipHeight="300" filename="screenshot-2">
|
||||
<$macrocall $name="example" text="""<$innerwiki width="1200" height="400" style="width:100%;" clipLeft="500" clipTop="100" clipWidth="600" clipHeight="300" filename="screenshot-3.png">
|
||||
<$data title="HelloThere" text="! This tiddler is inside a wiki that is inside a wiki"/>
|
||||
<$data title="$:/DefaultTiddlers" text="HelloThere"/>
|
||||
</$innerwiki>""">>
|
||||
</$innerwiki>"""/>
|
||||
|
||||
!! Transcluding payload tiddlers
|
||||
|
||||
This example shows how the `<$data>` widget can be transcluded from other tiddlers (see $:/plugins/tiddlywiki/innerwiki/example-data):
|
||||
|
||||
<<example """<$innerwiki width="600" height="400" style="width:100%;" filename="screenshot-3">
|
||||
<$macrocall $name="example" text="""<$innerwiki width="600" height="400" style="width:100%;" filename="screenshot-4.png">
|
||||
{{$:/plugins/tiddlywiki/innerwiki/example-data}}
|
||||
<$data title="HelloThere" text="! This tiddler is inside a wiki that is inside a wiki"/>
|
||||
<$data title="$:/DefaultTiddlers" text="HelloThere"/>
|
||||
</$innerwiki>""">>
|
||||
</$innerwiki>"""/>
|
||||
|
||||
!! Customising the wiki state
|
||||
|
||||
By injecting the right payload tiddlers, the innerwiki can be initialised to any desired state. In this example we inject a configuration tiddler to make the "more" page control button visible, and a state tiddler to cause the dropdown to appear:
|
||||
|
||||
<<example """<$innerwiki template="$:/plugins/tiddlywiki/innerwiki/template" filename="screenshot-4" width="1200" height="400" clipLeft="500" clipTop="100" clipWidth="600" clipHeight="300" style="width:100%;">
|
||||
<$macrocall $name="example" text="""<$innerwiki template="$:/plugins/tiddlywiki/innerwiki/template" filename="screenshot-5.png" width="1200" height="400" clipLeft="500" clipTop="100" clipWidth="600" clipHeight="300" style="width:100%;">
|
||||
<$data title="HelloThere" text="! This tiddler is inside a wiki that is inside a wiki"/>
|
||||
<$data title="$:/DefaultTiddlers" text="HelloThere"/>
|
||||
<$data title="$:/config/PageControlButtons/Visibility/$:/core/ui/Buttons/more-page-actions" text="show"/>
|
||||
<$data title="$:/state/popup/more--1600698846" text="(151,144,21,25)"/>
|
||||
</$innerwiki>""">>
|
||||
</$innerwiki>"""/>
|
||||
|
||||
!! Inception
|
||||
|
||||
An innerwiki can itself contain an inner-innerwiki:
|
||||
|
||||
<<example """<$innerwiki width="1200" height="600" style="width:100%;" filename="screenshot-5">
|
||||
<$macrocall $name="example" text="""<$innerwiki width="1200" height="600" style="width:100%;" filename="screenshot-6.png">
|
||||
<$data title="HelloThere" text="! This tiddler is inside a wiki that is inside a wiki"/>
|
||||
<$data title="$:/DefaultTiddlers" text="HelloThere $:/plugins/tiddlywiki/innerwiki/inner-example"/>
|
||||
<$data $tiddler="$:/plugins/tiddlywiki/innerwiki"/>
|
||||
</$innerwiki>""">>
|
||||
<<big-arrow 100 50 colour:#00ff00>>
|
||||
</$innerwiki>"""/>
|
||||
|
||||
(You can see the innerwiki here: $:/plugins/tiddlywiki/innerwiki/inner-example)
|
||||
|
||||
|
@ -40,11 +40,19 @@ InnerWikiWidget.prototype.render = function(parent,nextSibling) {
|
||||
classes.push("tc-innerwiki-wrapper");
|
||||
domWrapper.className = classes.join(" ");
|
||||
domWrapper.style = this.innerWikiStyle;
|
||||
domWrapper.style.overflow = "hidden";
|
||||
domWrapper.style.position = "relative";
|
||||
domWrapper.style.boxSizing = "content-box";
|
||||
// Set up the SVG container
|
||||
var domSVG = this.document.createElementNS("http://www.w3.org/2000/svg","svg");
|
||||
domSVG.style = this.innerWikiStyle;
|
||||
domSVG.style.position = "absolute";
|
||||
domSVG.style.zIndex = "1";
|
||||
domSVG.setAttribute("viewBox","0 0 " + this.innerWikiClipWidth + " " + this.innerWikiClipHeight);
|
||||
domWrapper.appendChild(domSVG);
|
||||
this.setVariable("namespace","http://www.w3.org/2000/svg");
|
||||
// If we're on the real DOM, adjust the wrapper and iframe
|
||||
if(!this.document.isTiddlyWikiFakeDom) {
|
||||
domWrapper.style.overflow = "hidden";
|
||||
domWrapper.style.position = "relative";
|
||||
domWrapper.style.boxSizing = "content-box";
|
||||
// Create iframe
|
||||
var domIFrame = this.document.createElement("iframe");
|
||||
domIFrame.className = "tc-innerwiki-iframe";
|
||||
@ -54,10 +62,16 @@ InnerWikiWidget.prototype.render = function(parent,nextSibling) {
|
||||
domIFrame.width = this.innerWikiWidth;
|
||||
domIFrame.height = this.innerWikiHeight;
|
||||
domWrapper.appendChild(domIFrame);
|
||||
} else {
|
||||
// Create image placeholder
|
||||
var domImage = this.document.createElement("img");
|
||||
domImage.style = this.innerWikiStyle;
|
||||
domImage.setAttribute("src",this.innerWikiFilename);
|
||||
domWrapper.appendChild(domImage);
|
||||
}
|
||||
// Insert wrapper into the DOM
|
||||
parent.insertBefore(domWrapper,nextSibling);
|
||||
this.renderChildren(domWrapper,null);
|
||||
this.renderChildren(domSVG,null);
|
||||
this.domNodes.push(domWrapper);
|
||||
// If we're on the real DOM, finish the initialisation that needs us to be in the DOM
|
||||
if(!this.document.isTiddlyWikiFakeDom) {
|
||||
@ -65,14 +79,16 @@ InnerWikiWidget.prototype.render = function(parent,nextSibling) {
|
||||
domIFrame.contentWindow.document.open();
|
||||
domIFrame.contentWindow.document.write(this.createInnerHTML());
|
||||
domIFrame.contentWindow.document.close();
|
||||
// Scale the iframe and adjust the height of the wrapper
|
||||
var clipLeft = self.innerWikiClipLeft,
|
||||
clipTop = self.innerWikiClipTop,
|
||||
clipWidth = self.innerWikiClipWidth,
|
||||
clipHeight = self.innerWikiClipHeight,
|
||||
translateX = -clipLeft,
|
||||
translateY = -clipTop,
|
||||
scale = domWrapper.clientWidth / clipWidth;
|
||||
}
|
||||
// Scale the iframe and adjust the height of the wrapper
|
||||
var clipLeft = this.innerWikiClipLeft,
|
||||
clipTop = this.innerWikiClipTop,
|
||||
clipWidth = this.innerWikiClipWidth,
|
||||
clipHeight = this.innerWikiClipHeight,
|
||||
translateX = -clipLeft,
|
||||
translateY = -clipTop,
|
||||
scale = domWrapper.clientWidth / clipWidth;
|
||||
if(!this.document.isTiddlyWikiFakeDom) {
|
||||
domIFrame.style.transformOrigin = (-translateX) + "px " + (-translateY) + "px";
|
||||
domIFrame.style.transform = "translate(" + translateX + "px," + translateY + "px) scale(" + scale + ")";
|
||||
domWrapper.style.height = (clipHeight * scale) + "px";
|
||||
@ -205,7 +221,7 @@ InnerWikiWidget.prototype.saveScreenshot = function(options,callback) {
|
||||
return callback(null);
|
||||
}
|
||||
var path = require("path"),
|
||||
filepath = path.resolve(basepath,this.innerWikiFilename) + ".png";
|
||||
filepath = path.resolve(basepath,this.innerWikiFilename);
|
||||
$tw.utils.createFileDirectories(filepath);
|
||||
console.log("Taking screenshot",filepath);
|
||||
// Fire up Puppeteer
|
||||
|
Loading…
Reference in New Issue
Block a user