mirror of
https://github.com/Jermolene/TiddlyWiki5
synced 2025-06-05 16:14:07 +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.attributes = {};
|
||||||
this.isRaw = false;
|
this.isRaw = false;
|
||||||
this.children = [];
|
this.children = [];
|
||||||
this.style = {};
|
this._style = {};
|
||||||
this.namespaceURI = namespace || "http://www.w3.org/1999/xhtml";
|
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", {
|
Object.defineProperty(TW_Element.prototype, "nodeType", {
|
||||||
get: function() {
|
get: function() {
|
||||||
return 1;
|
return 1;
|
||||||
@ -169,13 +187,13 @@ Object.defineProperty(TW_Element.prototype, "outerHTML", {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(this.style) {
|
if(this._style) {
|
||||||
var style = [];
|
var style = [];
|
||||||
for(var s in this.style) {
|
for(var s in this._style) {
|
||||||
style.push(s + ":" + this.style[s] + ";");
|
style.push($tw.utils.convertPropertyNameToStyleName(s) + ":" + this._style[s] + ";");
|
||||||
}
|
}
|
||||||
if(style.length > 0) {
|
if(style.length > 0) {
|
||||||
output.push(" style=\"",style.join(""),"\"")
|
output.push(" style=\"",style.join(""),"\"");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
output.push(">");
|
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:
|
# 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
|
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)
|
\define example(text)
|
||||||
<$codeblock code=<<__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":
|
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="HelloThere" text="This tiddler is inside a wiki"/>
|
||||||
<$data title="$:/DefaultTiddlers" text="HelloThere"/>
|
<$data title="$:/DefaultTiddlers" text="HelloThere"/>
|
||||||
</$innerwiki>""">>
|
</$innerwiki>"""/>
|
||||||
|
|
||||||
Note that the "screenshot" is a shrunken but fully interactive TiddlyWiki.
|
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:
|
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.
|
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
|
!! Clipping
|
||||||
|
|
||||||
A clipping rectangle can be applied to limit the area of the wiki that is displayed. For example:
|
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="HelloThere" text="! This tiddler is inside a wiki that is inside a wiki"/>
|
||||||
<$data title="$:/DefaultTiddlers" text="HelloThere"/>
|
<$data title="$:/DefaultTiddlers" text="HelloThere"/>
|
||||||
</$innerwiki>""">>
|
</$innerwiki>"""/>
|
||||||
|
|
||||||
!! Transcluding payload tiddlers
|
!! Transcluding payload tiddlers
|
||||||
|
|
||||||
This example shows how the `<$data>` widget can be transcluded from other tiddlers (see $:/plugins/tiddlywiki/innerwiki/example-data):
|
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}}
|
{{$:/plugins/tiddlywiki/innerwiki/example-data}}
|
||||||
<$data title="HelloThere" text="! This tiddler is inside a wiki that is inside a wiki"/>
|
<$data title="HelloThere" text="! This tiddler is inside a wiki that is inside a wiki"/>
|
||||||
<$data title="$:/DefaultTiddlers" text="HelloThere"/>
|
<$data title="$:/DefaultTiddlers" text="HelloThere"/>
|
||||||
</$innerwiki>""">>
|
</$innerwiki>"""/>
|
||||||
|
|
||||||
!! Customising the wiki state
|
!! 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:
|
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="HelloThere" text="! This tiddler is inside a wiki that is inside a wiki"/>
|
||||||
<$data title="$:/DefaultTiddlers" text="HelloThere"/>
|
<$data title="$:/DefaultTiddlers" text="HelloThere"/>
|
||||||
<$data title="$:/config/PageControlButtons/Visibility/$:/core/ui/Buttons/more-page-actions" text="show"/>
|
<$data title="$:/config/PageControlButtons/Visibility/$:/core/ui/Buttons/more-page-actions" text="show"/>
|
||||||
<$data title="$:/state/popup/more--1600698846" text="(151,144,21,25)"/>
|
<$data title="$:/state/popup/more--1600698846" text="(151,144,21,25)"/>
|
||||||
</$innerwiki>""">>
|
</$innerwiki>"""/>
|
||||||
|
|
||||||
!! Inception
|
!! Inception
|
||||||
|
|
||||||
An innerwiki can itself contain an inner-innerwiki:
|
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="HelloThere" text="! This tiddler is inside a wiki that is inside a wiki"/>
|
||||||
<$data title="$:/DefaultTiddlers" text="HelloThere $:/plugins/tiddlywiki/innerwiki/inner-example"/>
|
<$data title="$:/DefaultTiddlers" text="HelloThere $:/plugins/tiddlywiki/innerwiki/inner-example"/>
|
||||||
<$data $tiddler="$:/plugins/tiddlywiki/innerwiki"/>
|
<$data $tiddler="$:/plugins/tiddlywiki/innerwiki"/>
|
||||||
</$innerwiki>""">>
|
<<big-arrow 100 50 colour:#00ff00>>
|
||||||
|
</$innerwiki>"""/>
|
||||||
|
|
||||||
(You can see the innerwiki here: $:/plugins/tiddlywiki/innerwiki/inner-example)
|
(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");
|
classes.push("tc-innerwiki-wrapper");
|
||||||
domWrapper.className = classes.join(" ");
|
domWrapper.className = classes.join(" ");
|
||||||
domWrapper.style = this.innerWikiStyle;
|
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 we're on the real DOM, adjust the wrapper and iframe
|
||||||
if(!this.document.isTiddlyWikiFakeDom) {
|
if(!this.document.isTiddlyWikiFakeDom) {
|
||||||
domWrapper.style.overflow = "hidden";
|
|
||||||
domWrapper.style.position = "relative";
|
|
||||||
domWrapper.style.boxSizing = "content-box";
|
|
||||||
// Create iframe
|
// Create iframe
|
||||||
var domIFrame = this.document.createElement("iframe");
|
var domIFrame = this.document.createElement("iframe");
|
||||||
domIFrame.className = "tc-innerwiki-iframe";
|
domIFrame.className = "tc-innerwiki-iframe";
|
||||||
@ -54,10 +62,16 @@ InnerWikiWidget.prototype.render = function(parent,nextSibling) {
|
|||||||
domIFrame.width = this.innerWikiWidth;
|
domIFrame.width = this.innerWikiWidth;
|
||||||
domIFrame.height = this.innerWikiHeight;
|
domIFrame.height = this.innerWikiHeight;
|
||||||
domWrapper.appendChild(domIFrame);
|
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
|
// Insert wrapper into the DOM
|
||||||
parent.insertBefore(domWrapper,nextSibling);
|
parent.insertBefore(domWrapper,nextSibling);
|
||||||
this.renderChildren(domWrapper,null);
|
this.renderChildren(domSVG,null);
|
||||||
this.domNodes.push(domWrapper);
|
this.domNodes.push(domWrapper);
|
||||||
// If we're on the real DOM, finish the initialisation that needs us to be in the DOM
|
// If we're on the real DOM, finish the initialisation that needs us to be in the DOM
|
||||||
if(!this.document.isTiddlyWikiFakeDom) {
|
if(!this.document.isTiddlyWikiFakeDom) {
|
||||||
@ -65,14 +79,16 @@ InnerWikiWidget.prototype.render = function(parent,nextSibling) {
|
|||||||
domIFrame.contentWindow.document.open();
|
domIFrame.contentWindow.document.open();
|
||||||
domIFrame.contentWindow.document.write(this.createInnerHTML());
|
domIFrame.contentWindow.document.write(this.createInnerHTML());
|
||||||
domIFrame.contentWindow.document.close();
|
domIFrame.contentWindow.document.close();
|
||||||
// Scale the iframe and adjust the height of the wrapper
|
}
|
||||||
var clipLeft = self.innerWikiClipLeft,
|
// Scale the iframe and adjust the height of the wrapper
|
||||||
clipTop = self.innerWikiClipTop,
|
var clipLeft = this.innerWikiClipLeft,
|
||||||
clipWidth = self.innerWikiClipWidth,
|
clipTop = this.innerWikiClipTop,
|
||||||
clipHeight = self.innerWikiClipHeight,
|
clipWidth = this.innerWikiClipWidth,
|
||||||
translateX = -clipLeft,
|
clipHeight = this.innerWikiClipHeight,
|
||||||
translateY = -clipTop,
|
translateX = -clipLeft,
|
||||||
scale = domWrapper.clientWidth / clipWidth;
|
translateY = -clipTop,
|
||||||
|
scale = domWrapper.clientWidth / clipWidth;
|
||||||
|
if(!this.document.isTiddlyWikiFakeDom) {
|
||||||
domIFrame.style.transformOrigin = (-translateX) + "px " + (-translateY) + "px";
|
domIFrame.style.transformOrigin = (-translateX) + "px " + (-translateY) + "px";
|
||||||
domIFrame.style.transform = "translate(" + translateX + "px," + translateY + "px) scale(" + scale + ")";
|
domIFrame.style.transform = "translate(" + translateX + "px," + translateY + "px) scale(" + scale + ")";
|
||||||
domWrapper.style.height = (clipHeight * scale) + "px";
|
domWrapper.style.height = (clipHeight * scale) + "px";
|
||||||
@ -205,7 +221,7 @@ InnerWikiWidget.prototype.saveScreenshot = function(options,callback) {
|
|||||||
return callback(null);
|
return callback(null);
|
||||||
}
|
}
|
||||||
var path = require("path"),
|
var path = require("path"),
|
||||||
filepath = path.resolve(basepath,this.innerWikiFilename) + ".png";
|
filepath = path.resolve(basepath,this.innerWikiFilename);
|
||||||
$tw.utils.createFileDirectories(filepath);
|
$tw.utils.createFileDirectories(filepath);
|
||||||
console.log("Taking screenshot",filepath);
|
console.log("Taking screenshot",filepath);
|
||||||
// Fire up Puppeteer
|
// Fire up Puppeteer
|
||||||
|
Loading…
x
Reference in New Issue
Block a user