mirror of
https://github.com/Jermolene/TiddlyWiki5
synced 2026-09-19 00:00:43 +00:00
Introduce Tour Plugin and Confetti Plugin, improve Dynannotate Plugin (#7734)
* First commit * Typo * Add support for delay parameter * Add confetti widget * Add tour plugin * Add element spotlight to dynannotate plugin Useful for highlighting on screen elements for the user * More and bigger confetti by default * Use new element spotlight to provide hints * Adjust hint selectors for create tiddler tour step * Include confetti plugin in prerelease * Clarify wording of confetti demo * Don't link TiddlyWiki in the tour panel * Tweaks to tour buttons * Mark dependents of the tour plugin * Add full screen section of tour and tour edition * Remove Anna Freud references from welcome tiddler * Build the tour edition in the preview * Fix typo in build script * Populate tour edition with solar system data From Simple English Wikipedia * Missing tag * Add page control button to start tour Also make the tour controls visible in full screen mode * Refactor to use global procedures to control the tour * Change "startup-actions" field to "enter-actions" to avoid confusion * Add a tour logo * Refactor to allow multiple tours to be loaded at once * Remove wikification from welcome tour step * Update docs * Simplify styles for top bar * Tours should have a $:/tags/Tour tag * Tour should autostart in the tour edition, but not in the main wiki * Better labelling for the main preview * Fix build process We build a separate tour.html wiki, but can include the tour in other wikis too * Remove obsolete text * Add "using tags" as a separate tour * Remove old debugging code * Add tour chooser * Ensure that the current tour isn't listed as an option in the final step * Use whitespace trim Note that the setting is inherited by procedure and widget definitions * Simplify tour step format * Remove obsolete state tiddler Not needed because now we initialise it in startup actions * Fix gap between navigation buttons * Clean up tiddler titles within the introduction tour * Finish allowing the name "TiddlyWiki" to be customised Some of the code was in the previous commit. Next we'll wire up the user interface * Clarify docs * Add a settings pane giving a birds eye view of a tour * Avoid having to embed confetti in the final step * Update docs * Tweak styling of tour chooser dropdown * Add a button to launch tour steps directly, and give them captions * Expose custom tour settings * Use the tour step caption as the heading * Fix initialisation when jumping to a tour step * Introduce step about tags * Improve wording * Improve styling of task call-to-action and nav buttons * Adopt new conditional shortcut syntax * Wording and ordering tweaks * Fix typos Thanks @pmario * Simplify styling of tour overlay * Use custom palette colours Makes it easier for people to use their own colour scheme for the tour * More custom colours * Tour wording tweaks * Extends the tour plugin with a condition field (#7861) * feat: support condition field to determine whether a step should be shown * feat: add support for overriding the hint text using the field 'hint' from the step tiddler * fix: roll back tour display procedure for now until an override mechanism has been discussed * fix: renamed advance-criterion field and associated variables to step-success-filter * fix: renamed hint field to hint-text and selector to hint-selector * refactor: to create function to get all tour tiddlers filtered by their condition field * refactor: rename globals tiddlers to variables and avoid making any of the tour procedures global * fix: also rename globals.tid file to variables.tid * docs: cover all tour steps tiddler fields * fix: improve spacing in Tour HUD * WIP --------- Co-authored-by: Jeremy Ruston <174761+Jermolene@users.noreply.github.com> Co-authored-by: Saq Imtiaz <saq.imtiaz@gmail.com>
This commit is contained in:
co-authored by
Jeremy Ruston
Saq Imtiaz
parent
c3de9df84f
commit
a9f9ffd409
@@ -0,0 +1,56 @@
|
||||
/*\
|
||||
title: $:/plugins/tiddlywiki/confetti/confetti-manager.js
|
||||
type: application/javascript
|
||||
module-type: global
|
||||
|
||||
Confetti manager
|
||||
|
||||
\*/
|
||||
(function(){
|
||||
|
||||
/*jslint node: true, browser: true */
|
||||
/*global $tw: false */
|
||||
"use strict";
|
||||
|
||||
var confetti = require("$:/plugins/tiddlywiki/confetti/confetti.js");
|
||||
|
||||
function ConfettiManager() {
|
||||
this.outstandingTimers = [];
|
||||
}
|
||||
|
||||
ConfettiManager.prototype.launch = function (delay,options) {
|
||||
var self = this,
|
||||
defaultOptions = {
|
||||
scalar: 1.2,
|
||||
particleCount: 400,
|
||||
zIndex: 2000
|
||||
};
|
||||
options = $tw.utils.extend(defaultOptions,options);
|
||||
if(delay > 0) {
|
||||
var id = setTimeout(function() {
|
||||
var p = self.outstandingTimers.indexOf(id);
|
||||
if(p !== -1) {
|
||||
self.outstandingTimers.splice(p,1);
|
||||
} else {
|
||||
console.log("Confetti Manager Error: Cannot find previously stored timer ID");
|
||||
debugger;
|
||||
}
|
||||
confetti(options);
|
||||
},delay);
|
||||
this.outstandingTimers.push(id);
|
||||
} else {
|
||||
confetti(options);
|
||||
}
|
||||
};
|
||||
|
||||
ConfettiManager.prototype.reset = function () {
|
||||
$tw.utils.each(this.outstandingTimers,function(id) {
|
||||
clearTimeout(id);
|
||||
});
|
||||
this.outstandingTimers = [];
|
||||
confetti.reset();
|
||||
};
|
||||
|
||||
exports.ConfettiManager = ConfettiManager;
|
||||
|
||||
})();
|
||||
@@ -0,0 +1,67 @@
|
||||
/*\
|
||||
title: $:/plugins/tiddlywiki/confetti/confetti-widget.js
|
||||
type: application/javascript
|
||||
module-type: widget
|
||||
|
||||
Confetti widget
|
||||
|
||||
\*/
|
||||
(function(){
|
||||
|
||||
/*jslint node: true, browser: true */
|
||||
/*global $tw: false */
|
||||
"use strict";
|
||||
|
||||
var Widget = require("$:/core/modules/widgets/widget.js").widget;
|
||||
|
||||
var confetti = require("$:/plugins/tiddlywiki/confetti/confetti.js");
|
||||
|
||||
var ConfettiWidget = function(parseTreeNode,options) {
|
||||
this.initialise(parseTreeNode,options);
|
||||
};
|
||||
|
||||
/*
|
||||
Inherit from the base widget class
|
||||
*/
|
||||
ConfettiWidget.prototype = new Widget();
|
||||
|
||||
/*
|
||||
Render this widget into the DOM
|
||||
*/
|
||||
ConfettiWidget.prototype.render = function(parent,nextSibling) {
|
||||
var self = this;
|
||||
// Remember parent
|
||||
this.parentDomNode = parent;
|
||||
// Compute attributes and execute state
|
||||
this.computeAttributes();
|
||||
this.execute();
|
||||
// Launch confetti
|
||||
if($tw.browser) {
|
||||
var options = {};
|
||||
$tw.utils.each(this.attributes,function(attribute,name) {
|
||||
options[name] = self.getAttribute(name);
|
||||
});
|
||||
$tw.confettiManager.launch(options.delay,options);
|
||||
}
|
||||
// Render children
|
||||
this.renderChildren(parent,nextSibling);
|
||||
};
|
||||
|
||||
/*
|
||||
Compute the internal state of the widget
|
||||
*/
|
||||
ConfettiWidget.prototype.execute = function() {
|
||||
// Make child widgets
|
||||
this.makeChildWidgets();
|
||||
};
|
||||
|
||||
/*
|
||||
Selectively refreshes the widget if needed. Returns true if the widget or any of its children needed re-rendering
|
||||
*/
|
||||
ConfettiWidget.prototype.refresh = function(changedTiddlers) {
|
||||
return this.refreshChildren(changedTiddlers);
|
||||
};
|
||||
|
||||
exports.confetti = ConfettiWidget;
|
||||
|
||||
})();
|
||||
@@ -0,0 +1,9 @@
|
||||
title: $:/plugins/tiddlywiki/confetti/examples/staggered
|
||||
tags: $:/tags/ConfettiExample
|
||||
|
||||
<$button>
|
||||
<$action-sendmessage $message="tm-confetti-launch"/>
|
||||
<$action-sendmessage $message="tm-confetti-launch" originY=0.6 spread=70 delay=300/>
|
||||
<$action-sendmessage $message="tm-confetti-launch" originY=0.55 spread=30 delay=600/>
|
||||
Launch three staggered rounds of confetti
|
||||
</$button>
|
||||
@@ -0,0 +1,10 @@
|
||||
title: $:/plugins/tiddlywiki/confetti/examples/typing-trigger
|
||||
tags: $:/tags/ConfettiExample
|
||||
|
||||
Type the word "launch": <$edit-text tiddler="$:/temp/confetti/launchstatus" tag="input" placeholder="Type here"/>
|
||||
|
||||
<$list filter="[{$:/temp/confetti/launchstatus}match:caseinsensitive[launch]]" variable="ignore">
|
||||
Launched!
|
||||
<$confetti particleCount=100/>
|
||||
<$confetti particleCount=100 delay=300/>
|
||||
</$list>
|
||||
@@ -0,0 +1,15 @@
|
||||
ISC License
|
||||
|
||||
Copyright (c) 2020, Kiril Vatev
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
@@ -0,0 +1,626 @@
|
||||
(function main(global, module, isWorker, workerSize) {
|
||||
var canUseWorker = !!(
|
||||
global.Worker &&
|
||||
global.Blob &&
|
||||
global.Promise &&
|
||||
global.OffscreenCanvas &&
|
||||
global.OffscreenCanvasRenderingContext2D &&
|
||||
global.HTMLCanvasElement &&
|
||||
global.HTMLCanvasElement.prototype.transferControlToOffscreen &&
|
||||
global.URL &&
|
||||
global.URL.createObjectURL);
|
||||
|
||||
function noop() {}
|
||||
|
||||
// create a promise if it exists, otherwise, just
|
||||
// call the function directly
|
||||
function promise(func) {
|
||||
var ModulePromise = module.exports.Promise;
|
||||
var Prom = ModulePromise !== void 0 ? ModulePromise : global.Promise;
|
||||
|
||||
if (typeof Prom === 'function') {
|
||||
return new Prom(func);
|
||||
}
|
||||
|
||||
func(noop, noop);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
var raf = (function () {
|
||||
var TIME = Math.floor(1000 / 60);
|
||||
var frame, cancel;
|
||||
var frames = {};
|
||||
var lastFrameTime = 0;
|
||||
|
||||
if (typeof requestAnimationFrame === 'function' && typeof cancelAnimationFrame === 'function') {
|
||||
frame = function (cb) {
|
||||
var id = Math.random();
|
||||
|
||||
frames[id] = requestAnimationFrame(function onFrame(time) {
|
||||
if (lastFrameTime === time || lastFrameTime + TIME - 1 < time) {
|
||||
lastFrameTime = time;
|
||||
delete frames[id];
|
||||
|
||||
cb();
|
||||
} else {
|
||||
frames[id] = requestAnimationFrame(onFrame);
|
||||
}
|
||||
});
|
||||
|
||||
return id;
|
||||
};
|
||||
cancel = function (id) {
|
||||
if (frames[id]) {
|
||||
cancelAnimationFrame(frames[id]);
|
||||
}
|
||||
};
|
||||
} else {
|
||||
frame = function (cb) {
|
||||
return setTimeout(cb, TIME);
|
||||
};
|
||||
cancel = function (timer) {
|
||||
return clearTimeout(timer);
|
||||
};
|
||||
}
|
||||
|
||||
return { frame: frame, cancel: cancel };
|
||||
}());
|
||||
|
||||
var getWorker = (function () {
|
||||
var worker;
|
||||
var prom;
|
||||
var resolves = {};
|
||||
|
||||
function decorate(worker) {
|
||||
function execute(options, callback) {
|
||||
worker.postMessage({ options: options || {}, callback: callback });
|
||||
}
|
||||
worker.init = function initWorker(canvas) {
|
||||
var offscreen = canvas.transferControlToOffscreen();
|
||||
worker.postMessage({ canvas: offscreen }, [offscreen]);
|
||||
};
|
||||
|
||||
worker.fire = function fireWorker(options, size, done) {
|
||||
if (prom) {
|
||||
execute(options, null);
|
||||
return prom;
|
||||
}
|
||||
|
||||
var id = Math.random().toString(36).slice(2);
|
||||
|
||||
prom = promise(function (resolve) {
|
||||
function workerDone(msg) {
|
||||
if (msg.data.callback !== id) {
|
||||
return;
|
||||
}
|
||||
|
||||
delete resolves[id];
|
||||
worker.removeEventListener('message', workerDone);
|
||||
|
||||
prom = null;
|
||||
done();
|
||||
resolve();
|
||||
}
|
||||
|
||||
worker.addEventListener('message', workerDone);
|
||||
execute(options, id);
|
||||
|
||||
resolves[id] = workerDone.bind(null, { data: { callback: id }});
|
||||
});
|
||||
|
||||
return prom;
|
||||
};
|
||||
|
||||
worker.reset = function resetWorker() {
|
||||
worker.postMessage({ reset: true });
|
||||
|
||||
for (var id in resolves) {
|
||||
resolves[id]();
|
||||
delete resolves[id];
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
return function () {
|
||||
if (worker) {
|
||||
return worker;
|
||||
}
|
||||
|
||||
if (!isWorker && canUseWorker) {
|
||||
var code = [
|
||||
'var CONFETTI, SIZE = {}, module = {};',
|
||||
'(' + main.toString() + ')(this, module, true, SIZE);',
|
||||
'onmessage = function(msg) {',
|
||||
' if (msg.data.options) {',
|
||||
' CONFETTI(msg.data.options).then(function () {',
|
||||
' if (msg.data.callback) {',
|
||||
' postMessage({ callback: msg.data.callback });',
|
||||
' }',
|
||||
' });',
|
||||
' } else if (msg.data.reset) {',
|
||||
' CONFETTI && CONFETTI.reset();',
|
||||
' } else if (msg.data.resize) {',
|
||||
' SIZE.width = msg.data.resize.width;',
|
||||
' SIZE.height = msg.data.resize.height;',
|
||||
' } else if (msg.data.canvas) {',
|
||||
' SIZE.width = msg.data.canvas.width;',
|
||||
' SIZE.height = msg.data.canvas.height;',
|
||||
' CONFETTI = module.exports.create(msg.data.canvas);',
|
||||
' }',
|
||||
'}',
|
||||
].join('\n');
|
||||
try {
|
||||
worker = new Worker(URL.createObjectURL(new Blob([code])));
|
||||
} catch (e) {
|
||||
// eslint-disable-next-line no-console
|
||||
typeof console !== undefined && typeof console.warn === 'function' ? console.warn('🎊 Could not load worker', e) : null;
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
decorate(worker);
|
||||
}
|
||||
|
||||
return worker;
|
||||
};
|
||||
})();
|
||||
|
||||
var defaults = {
|
||||
particleCount: 50,
|
||||
angle: 90,
|
||||
spread: 45,
|
||||
startVelocity: 45,
|
||||
decay: 0.9,
|
||||
gravity: 1,
|
||||
drift: 0,
|
||||
ticks: 200,
|
||||
x: 0.5,
|
||||
y: 0.5,
|
||||
shapes: ['square', 'circle'],
|
||||
zIndex: 100,
|
||||
colors: [
|
||||
'#26ccff',
|
||||
'#a25afd',
|
||||
'#ff5e7e',
|
||||
'#88ff5a',
|
||||
'#fcff42',
|
||||
'#ffa62d',
|
||||
'#ff36ff'
|
||||
],
|
||||
// probably should be true, but back-compat
|
||||
disableForReducedMotion: false,
|
||||
scalar: 1
|
||||
};
|
||||
|
||||
function convert(val, transform) {
|
||||
return transform ? transform(val) : val;
|
||||
}
|
||||
|
||||
function isOk(val) {
|
||||
return !(val === null || val === undefined);
|
||||
}
|
||||
|
||||
function prop(options, name, transform) {
|
||||
return convert(
|
||||
options && isOk(options[name]) ? options[name] : defaults[name],
|
||||
transform
|
||||
);
|
||||
}
|
||||
|
||||
function onlyPositiveInt(number){
|
||||
return number < 0 ? 0 : Math.floor(number);
|
||||
}
|
||||
|
||||
function randomInt(min, max) {
|
||||
// [min, max)
|
||||
return Math.floor(Math.random() * (max - min)) + min;
|
||||
}
|
||||
|
||||
function toDecimal(str) {
|
||||
return parseInt(str, 16);
|
||||
}
|
||||
|
||||
function colorsToRgb(colors) {
|
||||
return colors.map(hexToRgb);
|
||||
}
|
||||
|
||||
function hexToRgb(str) {
|
||||
var val = String(str).replace(/[^0-9a-f]/gi, '');
|
||||
|
||||
if (val.length < 6) {
|
||||
val = val[0]+val[0]+val[1]+val[1]+val[2]+val[2];
|
||||
}
|
||||
|
||||
return {
|
||||
r: toDecimal(val.substring(0,2)),
|
||||
g: toDecimal(val.substring(2,4)),
|
||||
b: toDecimal(val.substring(4,6))
|
||||
};
|
||||
}
|
||||
|
||||
function getOrigin(options) {
|
||||
var origin = prop(options, 'origin', Object);
|
||||
origin.x = prop(origin, 'x', Number);
|
||||
origin.y = prop(origin, 'y', Number);
|
||||
|
||||
return origin;
|
||||
}
|
||||
|
||||
function setCanvasWindowSize(canvas) {
|
||||
canvas.width = document.documentElement.clientWidth;
|
||||
canvas.height = document.documentElement.clientHeight;
|
||||
}
|
||||
|
||||
function setCanvasRectSize(canvas) {
|
||||
var rect = canvas.getBoundingClientRect();
|
||||
canvas.width = rect.width;
|
||||
canvas.height = rect.height;
|
||||
}
|
||||
|
||||
function getCanvas(zIndex) {
|
||||
var canvas = document.createElement('canvas');
|
||||
|
||||
canvas.style.position = 'fixed';
|
||||
canvas.style.top = '0px';
|
||||
canvas.style.left = '0px';
|
||||
canvas.style.pointerEvents = 'none';
|
||||
canvas.style.zIndex = zIndex;
|
||||
|
||||
return canvas;
|
||||
}
|
||||
|
||||
function ellipse(context, x, y, radiusX, radiusY, rotation, startAngle, endAngle, antiClockwise) {
|
||||
context.save();
|
||||
context.translate(x, y);
|
||||
context.rotate(rotation);
|
||||
context.scale(radiusX, radiusY);
|
||||
context.arc(0, 0, 1, startAngle, endAngle, antiClockwise);
|
||||
context.restore();
|
||||
}
|
||||
|
||||
function randomPhysics(opts) {
|
||||
var radAngle = opts.angle * (Math.PI / 180);
|
||||
var radSpread = opts.spread * (Math.PI / 180);
|
||||
|
||||
return {
|
||||
x: opts.x,
|
||||
y: opts.y,
|
||||
wobble: Math.random() * 10,
|
||||
wobbleSpeed: Math.min(0.11, Math.random() * 0.1 + 0.05),
|
||||
velocity: (opts.startVelocity * 0.5) + (Math.random() * opts.startVelocity),
|
||||
angle2D: -radAngle + ((0.5 * radSpread) - (Math.random() * radSpread)),
|
||||
tiltAngle: (Math.random() * (0.75 - 0.25) + 0.25) * Math.PI,
|
||||
color: opts.color,
|
||||
shape: opts.shape,
|
||||
tick: 0,
|
||||
totalTicks: opts.ticks,
|
||||
decay: opts.decay,
|
||||
drift: opts.drift,
|
||||
random: Math.random() + 2,
|
||||
tiltSin: 0,
|
||||
tiltCos: 0,
|
||||
wobbleX: 0,
|
||||
wobbleY: 0,
|
||||
gravity: opts.gravity * 3,
|
||||
ovalScalar: 0.6,
|
||||
scalar: opts.scalar
|
||||
};
|
||||
}
|
||||
|
||||
function updateFetti(context, fetti) {
|
||||
fetti.x += Math.cos(fetti.angle2D) * fetti.velocity + fetti.drift;
|
||||
fetti.y += Math.sin(fetti.angle2D) * fetti.velocity + fetti.gravity;
|
||||
fetti.wobble += fetti.wobbleSpeed;
|
||||
fetti.velocity *= fetti.decay;
|
||||
fetti.tiltAngle += 0.1;
|
||||
fetti.tiltSin = Math.sin(fetti.tiltAngle);
|
||||
fetti.tiltCos = Math.cos(fetti.tiltAngle);
|
||||
fetti.random = Math.random() + 2;
|
||||
fetti.wobbleX = fetti.x + ((10 * fetti.scalar) * Math.cos(fetti.wobble));
|
||||
fetti.wobbleY = fetti.y + ((10 * fetti.scalar) * Math.sin(fetti.wobble));
|
||||
|
||||
var progress = (fetti.tick++) / fetti.totalTicks;
|
||||
|
||||
var x1 = fetti.x + (fetti.random * fetti.tiltCos);
|
||||
var y1 = fetti.y + (fetti.random * fetti.tiltSin);
|
||||
var x2 = fetti.wobbleX + (fetti.random * fetti.tiltCos);
|
||||
var y2 = fetti.wobbleY + (fetti.random * fetti.tiltSin);
|
||||
|
||||
context.fillStyle = 'rgba(' + fetti.color.r + ', ' + fetti.color.g + ', ' + fetti.color.b + ', ' + (1 - progress) + ')';
|
||||
context.beginPath();
|
||||
|
||||
if (fetti.shape === 'circle') {
|
||||
context.ellipse ?
|
||||
context.ellipse(fetti.x, fetti.y, Math.abs(x2 - x1) * fetti.ovalScalar, Math.abs(y2 - y1) * fetti.ovalScalar, Math.PI / 10 * fetti.wobble, 0, 2 * Math.PI) :
|
||||
ellipse(context, fetti.x, fetti.y, Math.abs(x2 - x1) * fetti.ovalScalar, Math.abs(y2 - y1) * fetti.ovalScalar, Math.PI / 10 * fetti.wobble, 0, 2 * Math.PI);
|
||||
} else if (fetti.shape === 'star') {
|
||||
var rot = Math.PI / 2 * 3;
|
||||
var innerRadius = 4 * fetti.scalar;
|
||||
var outerRadius = 8 * fetti.scalar;
|
||||
var x = fetti.x;
|
||||
var y = fetti.y;
|
||||
var spikes = 5;
|
||||
var step = Math.PI / spikes;
|
||||
|
||||
while (spikes--) {
|
||||
x = fetti.x + Math.cos(rot) * outerRadius;
|
||||
y = fetti.y + Math.sin(rot) * outerRadius;
|
||||
context.lineTo(x, y);
|
||||
rot += step;
|
||||
|
||||
x = fetti.x + Math.cos(rot) * innerRadius;
|
||||
y = fetti.y + Math.sin(rot) * innerRadius;
|
||||
context.lineTo(x, y);
|
||||
rot += step;
|
||||
}
|
||||
} else {
|
||||
context.moveTo(Math.floor(fetti.x), Math.floor(fetti.y));
|
||||
context.lineTo(Math.floor(fetti.wobbleX), Math.floor(y1));
|
||||
context.lineTo(Math.floor(x2), Math.floor(y2));
|
||||
context.lineTo(Math.floor(x1), Math.floor(fetti.wobbleY));
|
||||
}
|
||||
|
||||
context.closePath();
|
||||
context.fill();
|
||||
|
||||
return fetti.tick < fetti.totalTicks;
|
||||
}
|
||||
|
||||
function animate(canvas, fettis, resizer, size, done) {
|
||||
var animatingFettis = fettis.slice();
|
||||
var context = canvas.getContext('2d');
|
||||
var animationFrame;
|
||||
var destroy;
|
||||
|
||||
var prom = promise(function (resolve) {
|
||||
function onDone() {
|
||||
animationFrame = destroy = null;
|
||||
|
||||
context.clearRect(0, 0, size.width, size.height);
|
||||
|
||||
done();
|
||||
resolve();
|
||||
}
|
||||
|
||||
function update() {
|
||||
if (isWorker && !(size.width === workerSize.width && size.height === workerSize.height)) {
|
||||
size.width = canvas.width = workerSize.width;
|
||||
size.height = canvas.height = workerSize.height;
|
||||
}
|
||||
|
||||
if (!size.width && !size.height) {
|
||||
resizer(canvas);
|
||||
size.width = canvas.width;
|
||||
size.height = canvas.height;
|
||||
}
|
||||
|
||||
context.clearRect(0, 0, size.width, size.height);
|
||||
|
||||
animatingFettis = animatingFettis.filter(function (fetti) {
|
||||
return updateFetti(context, fetti);
|
||||
});
|
||||
|
||||
if (animatingFettis.length) {
|
||||
animationFrame = raf.frame(update);
|
||||
} else {
|
||||
onDone();
|
||||
}
|
||||
}
|
||||
|
||||
animationFrame = raf.frame(update);
|
||||
destroy = onDone;
|
||||
});
|
||||
|
||||
return {
|
||||
addFettis: function (fettis) {
|
||||
animatingFettis = animatingFettis.concat(fettis);
|
||||
|
||||
return prom;
|
||||
},
|
||||
canvas: canvas,
|
||||
promise: prom,
|
||||
reset: function () {
|
||||
if (animationFrame) {
|
||||
raf.cancel(animationFrame);
|
||||
}
|
||||
|
||||
if (destroy) {
|
||||
destroy();
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function confettiCannon(canvas, globalOpts) {
|
||||
var isLibCanvas = !canvas;
|
||||
var allowResize = !!prop(globalOpts || {}, 'resize');
|
||||
var globalDisableForReducedMotion = prop(globalOpts, 'disableForReducedMotion', Boolean);
|
||||
var shouldUseWorker = canUseWorker && !!prop(globalOpts || {}, 'useWorker');
|
||||
var worker = shouldUseWorker ? getWorker() : null;
|
||||
var resizer = isLibCanvas ? setCanvasWindowSize : setCanvasRectSize;
|
||||
var initialized = (canvas && worker) ? !!canvas.__confetti_initialized : false;
|
||||
var preferLessMotion = typeof matchMedia === 'function' && matchMedia('(prefers-reduced-motion)').matches;
|
||||
var animationObj;
|
||||
|
||||
function fireLocal(options, size, done) {
|
||||
var particleCount = prop(options, 'particleCount', onlyPositiveInt);
|
||||
var angle = prop(options, 'angle', Number);
|
||||
var spread = prop(options, 'spread', Number);
|
||||
var startVelocity = prop(options, 'startVelocity', Number);
|
||||
var decay = prop(options, 'decay', Number);
|
||||
var gravity = prop(options, 'gravity', Number);
|
||||
var drift = prop(options, 'drift', Number);
|
||||
var colors = prop(options, 'colors', colorsToRgb);
|
||||
var ticks = prop(options, 'ticks', Number);
|
||||
var shapes = prop(options, 'shapes');
|
||||
var scalar = prop(options, 'scalar');
|
||||
var origin = getOrigin(options);
|
||||
|
||||
var temp = particleCount;
|
||||
var fettis = [];
|
||||
|
||||
var startX = canvas.width * origin.x;
|
||||
var startY = canvas.height * origin.y;
|
||||
|
||||
while (temp--) {
|
||||
fettis.push(
|
||||
randomPhysics({
|
||||
x: startX,
|
||||
y: startY,
|
||||
angle: angle,
|
||||
spread: spread,
|
||||
startVelocity: startVelocity,
|
||||
color: colors[temp % colors.length],
|
||||
shape: shapes[randomInt(0, shapes.length)],
|
||||
ticks: ticks,
|
||||
decay: decay,
|
||||
gravity: gravity,
|
||||
drift: drift,
|
||||
scalar: scalar
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
// if we have a previous canvas already animating,
|
||||
// add to it
|
||||
if (animationObj) {
|
||||
return animationObj.addFettis(fettis);
|
||||
}
|
||||
|
||||
animationObj = animate(canvas, fettis, resizer, size , done);
|
||||
|
||||
return animationObj.promise;
|
||||
}
|
||||
|
||||
function fire(options) {
|
||||
var disableForReducedMotion = globalDisableForReducedMotion || prop(options, 'disableForReducedMotion', Boolean);
|
||||
var zIndex = prop(options, 'zIndex', Number);
|
||||
|
||||
if (disableForReducedMotion && preferLessMotion) {
|
||||
return promise(function (resolve) {
|
||||
resolve();
|
||||
});
|
||||
}
|
||||
|
||||
if (isLibCanvas && animationObj) {
|
||||
// use existing canvas from in-progress animation
|
||||
canvas = animationObj.canvas;
|
||||
} else if (isLibCanvas && !canvas) {
|
||||
// create and initialize a new canvas
|
||||
canvas = getCanvas(zIndex);
|
||||
document.body.appendChild(canvas);
|
||||
}
|
||||
|
||||
if (allowResize && !initialized) {
|
||||
// initialize the size of a user-supplied canvas
|
||||
resizer(canvas);
|
||||
}
|
||||
|
||||
var size = {
|
||||
width: canvas.width,
|
||||
height: canvas.height
|
||||
};
|
||||
|
||||
if (worker && !initialized) {
|
||||
worker.init(canvas);
|
||||
}
|
||||
|
||||
initialized = true;
|
||||
|
||||
if (worker) {
|
||||
canvas.__confetti_initialized = true;
|
||||
}
|
||||
|
||||
function onResize() {
|
||||
if (worker) {
|
||||
// TODO this really shouldn't be immediate, because it is expensive
|
||||
var obj = {
|
||||
getBoundingClientRect: function () {
|
||||
if (!isLibCanvas) {
|
||||
return canvas.getBoundingClientRect();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
resizer(obj);
|
||||
|
||||
worker.postMessage({
|
||||
resize: {
|
||||
width: obj.width,
|
||||
height: obj.height
|
||||
}
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
// don't actually query the size here, since this
|
||||
// can execute frequently and rapidly
|
||||
size.width = size.height = null;
|
||||
}
|
||||
|
||||
function done() {
|
||||
animationObj = null;
|
||||
|
||||
if (allowResize) {
|
||||
global.removeEventListener('resize', onResize);
|
||||
}
|
||||
|
||||
if (isLibCanvas && canvas) {
|
||||
document.body.removeChild(canvas);
|
||||
canvas = null;
|
||||
initialized = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (allowResize) {
|
||||
global.addEventListener('resize', onResize, false);
|
||||
}
|
||||
|
||||
if (worker) {
|
||||
return worker.fire(options, size, done);
|
||||
}
|
||||
|
||||
return fireLocal(options, size, done);
|
||||
}
|
||||
|
||||
fire.reset = function () {
|
||||
if (worker) {
|
||||
worker.reset();
|
||||
}
|
||||
|
||||
if (animationObj) {
|
||||
animationObj.reset();
|
||||
}
|
||||
};
|
||||
|
||||
return fire;
|
||||
}
|
||||
|
||||
// Make default export lazy to defer worker creation until called.
|
||||
var defaultFire;
|
||||
function getDefaultFire() {
|
||||
if (!defaultFire) {
|
||||
defaultFire = confettiCannon(null, { useWorker: true, resize: true });
|
||||
}
|
||||
return defaultFire;
|
||||
}
|
||||
|
||||
module.exports = function() {
|
||||
return getDefaultFire().apply(this, arguments);
|
||||
};
|
||||
module.exports.reset = function() {
|
||||
getDefaultFire().reset();
|
||||
};
|
||||
module.exports.create = confettiCannon;
|
||||
}((function () {
|
||||
if (typeof window !== 'undefined') {
|
||||
return window;
|
||||
}
|
||||
|
||||
if (typeof self !== 'undefined') {
|
||||
return self;
|
||||
}
|
||||
|
||||
return this || {};
|
||||
})(), module, false));
|
||||
@@ -0,0 +1,20 @@
|
||||
{
|
||||
"tiddlers": [
|
||||
{
|
||||
"file": "confetti.js",
|
||||
"fields": {
|
||||
"type": "application/javascript",
|
||||
"title": "$:/plugins/tiddlywiki/confetti/confetti.js",
|
||||
"module-type": "library"
|
||||
},
|
||||
"prefix": "",
|
||||
"suffix": ""
|
||||
},{
|
||||
"file": "LICENSE",
|
||||
"fields": {
|
||||
"type": "text/plain",
|
||||
"title": "$:/plugins/tiddlywiki/confetti/license"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"title": "$:/plugins/tiddlywiki/confetti",
|
||||
"name": "Confetti",
|
||||
"description": "Animated confetti effect",
|
||||
"list": "readme"
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
title: $:/plugins/tiddlywiki/confetti/readme
|
||||
|
||||
\define show-example(name)
|
||||
<$let title={{{ [[$:/plugins/tiddlywiki/confetti/examples/]addsuffix<__name__>] }}}>
|
||||
|
||||
For example:
|
||||
|
||||
<$macrocall $name="copy-to-clipboard-above-right" src=<<__src__>>/>
|
||||
|
||||
<$codeblock code={{{ [<title>get[text]] }}}/>
|
||||
|
||||
Renders as:
|
||||
|
||||
<$transclude tiddler=<<title>> mode="block"/>
|
||||
|
||||
</$let>
|
||||
\end
|
||||
|
||||
! Introduction
|
||||
|
||||
This plugin adds a programmable confetti cannon to your TiddlyWiki. It is based on https://www.kirilv.com/canvas-confetti/ by Kiril Vatev.
|
||||
|
||||
! Usage
|
||||
|
||||
The confetti cannon can be controlled using messages or via the `<$confetti>` widget. Use the message approach when triggering confetti in response to an action (such as clicking a button). Use the widget approach when confetti is to be triggered by a condition (such as a target number of words being reached).
|
||||
|
||||
!! Messages: tm-confetti-launch and tm-confetti-reset
|
||||
|
||||
The `tm-confetti-launch` message launches the confetti cannon. See below for the available parameters.
|
||||
|
||||
The `tm-confetti-reset` message cancels any confetti that is in progress.
|
||||
|
||||
<<show-example staggered>>
|
||||
|
||||
!! Widget: `<$confetti>`
|
||||
|
||||
The `<$confetti>` widget launches the confetti cannon when it is first rendered. See below for the available attributes.
|
||||
|
||||
Typically it is used in conjunction with a `<$list>` or `<$reveal>` widget that shows the widget when the conditions required to trigger the confetti are satisfied.
|
||||
|
||||
In this example, the confetti will be launched when the word "launch" in typed into the box.
|
||||
|
||||
<<show-example typing-trigger>>
|
||||
|
||||
!! Confetti Launch parameters
|
||||
|
||||
The following options are supported:
|
||||
|
||||
|!Name |!Description |!Default |
|
||||
|''delay'' |Number of milliseconds to delay the launch |0 |
|
||||
|''particleCount'' |The number of confetti to launch |50 |
|
||||
|''angle'' |The angle in which to launch the confetti, in degrees (90 is straight up) |90 |
|
||||
|''spread'' |How far off center the confetti can go, in degrees. 45 means the confetti will launch at the defined `angle` plus or minus 22.5 degrees |45 |
|
||||
|''startVelocity'' |How fast the confetti will start going, in pixels |45 |
|
||||
|''decay'' |How quickly the confetti will lose speed. Keep this number between 0 and 1, otherwise the confetti will gain speed |0.9 |
|
||||
|''gravity'' |How quickly the particles are pulled down. 1 is full gravity, 0.5 is half gravity, etc. |1 |
|
||||
|''drift'' |How much to the side the confetti will drift. The default is 0, meaning that they will fall straight down. Use a negative number for left and positive number for right |0 |
|
||||
|''ticks'' |How many times the confetti will move (this is an abstract quantity; the designed recommends playing with it if the confetti disappears too quickly for you) |200 |
|
||||
|''originX'' |The `x` position on the page, with `0` being the left edge and `1` being the right edge |0.5 |
|
||||
|''originY'' |The `y` position on the page, with `0` being the top edge and `1` being the bottom edge |0.5 |
|
||||
|''colors'' |A space separated list of color strings in hex format (eg `#bada55` or `#ce5`) | |
|
||||
|''shapes'' |A space separated list of shapes for the confetti. The possible values are `square`, `circle`, and `star`. The default is to use both squares and circles in an even mix. To use a single shape, you can provide just one shape in the list, such as `star`. You can also change the mix by providing a value such as `circle circle square` to use two third circles and one third squares | |
|
||||
|''scalar'' |Scale factor for each confetti particle. Use decimals to make the confetti smaller |1 |
|
||||
|''zIndex'' |Z-index of confetti. Increase the value if the confetti is appearing behind other on-screen elements|100 |
|
||||
|''disableForReducedMotion'' |Set to `yes` to entirely disable confetti for users that [[prefer reduced motion|https://developer.mozilla.org/en-US/docs/Web/CSS/@media/prefers-reduced-motion]] |`no` |
|
||||
@@ -0,0 +1,55 @@
|
||||
/*\
|
||||
title: $:/plugins/tiddlywiki/confetti/startup.js
|
||||
type: application/javascript
|
||||
module-type: startup
|
||||
|
||||
Setup the root widget event handlers
|
||||
|
||||
\*/
|
||||
(function(){
|
||||
|
||||
/*jslint node: true, browser: true */
|
||||
/*global $tw: false */
|
||||
"use strict";
|
||||
|
||||
// Export name and synchronous status
|
||||
exports.name = "confetti";
|
||||
exports.platforms = ["browser"];
|
||||
exports.after = ["startup"];
|
||||
exports.synchronous = true;
|
||||
|
||||
// Install the root widget event handlers
|
||||
exports.startup = function() {
|
||||
$tw.confettiManager = new $tw.ConfettiManager();
|
||||
$tw.rootWidget.addEventListener("tm-confetti-launch",function(event) {
|
||||
var paramObject = event.paramObject || {},
|
||||
options = {},
|
||||
extractNumericParameter = function(name) {
|
||||
options[name] = paramObject[name] && $tw.utils.parseNumber(paramObject[name]);
|
||||
},
|
||||
extractListParameter = function(name) {
|
||||
options[name] = paramObject[name] && $tw.utils.parseStringArray(paramObject[name]);
|
||||
},
|
||||
extractBooleanParameter = function(name) {
|
||||
options[name] = paramObject[name] && paramObject[name] === "yes";
|
||||
};
|
||||
$tw.utils.each("particleCount angle spread startVelocity decay gravity drift ticks scalar zIndex".split(" "),function(name) {
|
||||
extractNumericParameter(name);
|
||||
});
|
||||
$tw.utils.each("colors shapes".split(" "),function(name) {
|
||||
extractListParameter(name);
|
||||
});
|
||||
options.origin = {
|
||||
x: paramObject.originX && $tw.utils.parseNumber(paramObject.originX),
|
||||
y: paramObject.originY && $tw.utils.parseNumber(paramObject.originY)
|
||||
};
|
||||
extractBooleanParameter("disableForReducedMotion");
|
||||
var delay = paramObject.delay ? $tw.utils.parseNumber(paramObject.delay) : 0;
|
||||
$tw.confettiManager.launch(delay,options);
|
||||
});
|
||||
$tw.rootWidget.addEventListener("tm-confetti-reset",function(event) {
|
||||
$tw.confettiManager.reset();
|
||||
});
|
||||
};
|
||||
|
||||
})();
|
||||
@@ -5,6 +5,7 @@ The ''Dynannotate'' plugin allows annotations on textual content to be created a
|
||||
* The dynannotate widget draws clickable textual annotations, search highlights and search snippets as overlays over the top of the content that it contains
|
||||
* The selection tracker keeps track of changes to the selected text in the main browser window. It triggers an action string when the selection changes, passing it the details of the selection. It can be used to display a popup menu
|
||||
** The original legacy selection tracker is also provided for backwards compatibility. It is much more limited, and not recommended for new projects
|
||||
* The element spotlight highlights on screen elements using a spotlight animation
|
||||
|
||||
!! Dynannotate Widget
|
||||
|
||||
@@ -172,3 +173,12 @@ Notes:
|
||||
|
||||
* The selection popup will disappear if the selection is cancelled; this will happen if the user clicks on any other element apart than a button. Thus it is not possible to have any interactive controls within the popup apart from buttons
|
||||
|
||||
!! Element Spotlight
|
||||
|
||||
The `tm-spotlight-element` message causes a spotlight effect to briefly appear to highlight a specified element. The message accepts the following parameters:
|
||||
|
||||
|!Parameter |!Description |
|
||||
|`selector` |CSS selector of the element to highlight |
|
||||
|{//Any parameter names starting with `selector-`}// |Fallback CSS selectors to be used if the primary selector does not resolve to an element |
|
||||
|
||||
The fallback CSS selectors are case-insensitively sorted by title before use, with uppercase letters sorting before lower case letters. The usual convention is to use numeric suffixes: `selector-00`, `selector-01` etc.
|
||||
|
||||
@@ -0,0 +1,71 @@
|
||||
title: $:/plugins/tiddlywiki/dynannotate/examples/spotlight
|
||||
tags: $:/tags/dynannotateExamples
|
||||
caption: Spotlight
|
||||
|
||||
\define show-example(example)
|
||||
<$codeblock code=<<__example__>>/>
|
||||
|
||||
//''Displays as:''//
|
||||
|
||||
$example$
|
||||
\end
|
||||
|
||||
<div class="tc-dynannotation-example-info">
|
||||
|
||||
!! Spotlighting an Image
|
||||
|
||||
</div>
|
||||
|
||||
<<show-example """
|
||||
<$button>
|
||||
<$action-sendmessage $message="tm-spotlight-element" selector=".tc-dynannotate-spotlight-image-example"/>
|
||||
Spotlight this image
|
||||
</$button>
|
||||
<div class="tc-dynannotate-spotlight-image-example" style="display:inline-block;">
|
||||
{{$:/core/images/globe}}
|
||||
</div>
|
||||
""">>
|
||||
|
||||
<div class="tc-dynannotation-example-info">
|
||||
|
||||
!! Spotlighting a Button
|
||||
|
||||
</div>
|
||||
|
||||
<<show-example """
|
||||
<$button class="tc-dynannotate-spotlight-button-example">
|
||||
<$action-sendmessage $message="tm-spotlight-element" selector=".tc-dynannotate-spotlight-button-example"/>
|
||||
Spotlight this button
|
||||
</$button>
|
||||
""">>
|
||||
|
||||
<div class="tc-dynannotation-example-info">
|
||||
|
||||
!! Spotlighting a Text Area
|
||||
|
||||
</div>
|
||||
|
||||
<<show-example """
|
||||
<$button>
|
||||
<$action-sendmessage $message="tm-spotlight-element" selector=".tc-dynannotate-spotlight-textarea-example"/>
|
||||
Spotlight this text area
|
||||
</$button>
|
||||
|
||||
<$edit-text class="tc-dynannotate-spotlight-textarea-example" tag="textarea" tiddler="$:/temp/dynannotate/spotlight/demo/text"/>
|
||||
|
||||
""">>
|
||||
|
||||
<div class="tc-dynannotation-example-info">
|
||||
|
||||
!! Spotlighting the Sidebar Search Input
|
||||
|
||||
This button will spotlight the sidebar search, but if the sidebar is hidden then it will spotlight the button for showing the sidebar.
|
||||
|
||||
</div>
|
||||
|
||||
<<show-example """
|
||||
<$button>
|
||||
<$action-sendmessage $message="tm-spotlight-element" selector=".tc-sidebar-search .tc-popup-handle" selector-fallback=".tc-menubar .tc-show-sidebar-btn"/>
|
||||
Spotlight the sidebar search input
|
||||
</$button>
|
||||
""">>
|
||||
@@ -0,0 +1,136 @@
|
||||
/*\
|
||||
title: $:/plugins/tiddlywiki/dynannotate/element-spotlight.js
|
||||
type: application/javascript
|
||||
module-type: library
|
||||
|
||||
Manages the element spotlight effect
|
||||
|
||||
\*/
|
||||
(function(){
|
||||
|
||||
/*jslint node: true, browser: true */
|
||||
/*global $tw: false */
|
||||
"use strict";
|
||||
|
||||
function ElementSpotlight() {
|
||||
this.animationStartTime; // Undefined if no animation is in progress
|
||||
// Create DOM nodes
|
||||
this.spotlightElement = $tw.utils.domMaker("div",{
|
||||
"class": "tc-dynannotate-spotlight"
|
||||
});
|
||||
this.spotlightWrapper = $tw.utils.domMaker("div",{
|
||||
"class": "tc-dynannotate-spotlight-wrapper",
|
||||
children: [
|
||||
this.spotlightElement
|
||||
]
|
||||
});
|
||||
document.body.appendChild(this.spotlightWrapper);
|
||||
}
|
||||
|
||||
/*
|
||||
Return the first visible element that matches a selector
|
||||
*/
|
||||
ElementSpotlight.prototype.querySelectorSafe = function(selector) {
|
||||
var targetNodes;
|
||||
// Get the matching elements
|
||||
try {
|
||||
targetNodes = document.querySelectorAll(selector);
|
||||
} catch(e) {
|
||||
console.log("Error with selector: " + selector);
|
||||
}
|
||||
if(!targetNodes) {
|
||||
return undefined;
|
||||
}
|
||||
// Remove any elements from the start of the list that are hidden, or have hidden ancestors
|
||||
var didRemoveFirstEntry;
|
||||
do {
|
||||
didRemoveFirstEntry = false;
|
||||
var hasHiddenAncestor = false,
|
||||
n = targetNodes[0];
|
||||
while(n) {
|
||||
if(n.hidden || (n instanceof Element && window.getComputedStyle(n).display === "none")) {
|
||||
hasHiddenAncestor = true;
|
||||
break;
|
||||
}
|
||||
n = n.parentNode;
|
||||
}
|
||||
if(hasHiddenAncestor) {
|
||||
// Remove first entry from targetNodes array
|
||||
targetNodes = [].slice.call(targetNodes, 1);
|
||||
didRemoveFirstEntry = true;
|
||||
}
|
||||
} while(didRemoveFirstEntry)
|
||||
// Return the first result
|
||||
return targetNodes[0];
|
||||
};
|
||||
|
||||
ElementSpotlight.prototype.positionSpotlight = function(x,y,innerRadius,outerRadius,opacity) {
|
||||
this.spotlightElement.style.display = "block";
|
||||
this.spotlightElement.style.backgroundImage = "radial-gradient(circle at " + (x / window.innerWidth * 100) + "% " + (y / window.innerHeight * 100) + "%, transparent " + innerRadius + "px, rgba(0, 0, 0, " + opacity + ") " + outerRadius + "px)";
|
||||
};
|
||||
|
||||
ElementSpotlight.prototype.easeInOut = function(v) {
|
||||
return (Math.sin((v - 0.5) * Math.PI) + 1) / 2;
|
||||
};
|
||||
|
||||
/*
|
||||
Shine a spotlight on the first element that matches an array of selectors
|
||||
*/
|
||||
ElementSpotlight.prototype.shineSpotlight = function(selectors) {
|
||||
var self = this;
|
||||
function animationLoop(selectors) {
|
||||
// Calculate how far through the animation we are
|
||||
// 0...1 = zoom in
|
||||
// 1...2 = hold
|
||||
// 2...3 = fade out
|
||||
var now = new Date(),
|
||||
t = (now - self.animationStartTime) / ($tw.utils.getAnimationDuration() * 2);
|
||||
t = t >= 3 ? 3 : t;
|
||||
// Query the selector for the target element
|
||||
var targetNode, selectorIndex = 0;
|
||||
while(!targetNode && selectorIndex < selectors.length) {
|
||||
targetNode = self.querySelectorSafe(selectors[selectorIndex]);
|
||||
selectorIndex += 1;
|
||||
}
|
||||
// Position the spotlight if we've got the target
|
||||
if(targetNode) {
|
||||
var rect = targetNode.getBoundingClientRect();
|
||||
var innerRadius, outerRadius, opacity;
|
||||
if(t <= 1) {
|
||||
t = self.easeInOut(t);
|
||||
innerRadius = rect.width / 2 + (window.innerWidth * 2 * (1 - t));
|
||||
outerRadius = rect.width + (window.innerWidth * 3 * (1 - t));
|
||||
opacity = 0.2 + t / 4;
|
||||
} else if(t <= 2) {
|
||||
innerRadius = rect.width / 2;
|
||||
outerRadius = rect.width;
|
||||
opacity = 0.45;
|
||||
} else {
|
||||
t = self.easeInOut(3 - t);
|
||||
innerRadius = rect.width / 2 + (window.innerWidth * 2 * (1 - t));
|
||||
outerRadius = rect.width + (window.innerWidth * 3 * (1 - t));
|
||||
opacity = t / 3;
|
||||
}
|
||||
self.positionSpotlight((rect.left + rect.right) / 2,(rect.top + rect.bottom) / 2,innerRadius,outerRadius,opacity);
|
||||
} else {
|
||||
self.spotlightElement.style.display = "none";
|
||||
}
|
||||
// Call the next frame unless we're at the end
|
||||
if(t <= 3) {
|
||||
window.requestAnimationFrame(function () {
|
||||
animationLoop(selectors);
|
||||
});
|
||||
} else {
|
||||
// End the animation if we've exceeded the time limit
|
||||
self.animationStartTime = undefined;
|
||||
}
|
||||
}
|
||||
this.animationStartTime = new Date();
|
||||
window.requestAnimationFrame(function () {
|
||||
animationLoop(selectors);
|
||||
});
|
||||
};
|
||||
|
||||
exports.ElementSpotlight = ElementSpotlight;
|
||||
|
||||
})();
|
||||
@@ -1,3 +1,5 @@
|
||||
const { ElementSpotlight } = require("./element-spotlight");
|
||||
|
||||
/*\
|
||||
title: $:/plugins/tiddlywiki/dynannotate/startup.js
|
||||
type: application/javascript
|
||||
@@ -22,18 +24,39 @@ var CONFIG_SELECTION_TRACKER_TITLE = "$:/config/Dynannotate/SelectionTracker/Ena
|
||||
CONFIG_LEGACY_SELECTION_TRACKER_TITLE = "$:/config/Dynannotate/LegacySelectionTracker/Enable";
|
||||
|
||||
var SelectionTracker = require("$:/plugins/tiddlywiki/dynannotate/selection-tracker.js").SelectionTracker,
|
||||
LegacySelectionTracker = require("$:/plugins/tiddlywiki/dynannotate/legacy-selection-tracker.js").LegacySelectionTracker;
|
||||
LegacySelectionTracker = require("$:/plugins/tiddlywiki/dynannotate/legacy-selection-tracker.js").LegacySelectionTracker,
|
||||
ElementSpotlight = require("$:/plugins/tiddlywiki/dynannotate/element-spotlight.js").ElementSpotlight;
|
||||
|
||||
exports.startup = function() {
|
||||
$tw.dynannotate = {};
|
||||
// Setup selection tracker
|
||||
if($tw.wiki.getTiddlerText(CONFIG_SELECTION_TRACKER_TITLE,"yes") === "yes") {
|
||||
$tw.dynannotate.selectionTracker = new SelectionTracker($tw.wiki);
|
||||
}
|
||||
// Setup legacy selection tracker
|
||||
if($tw.wiki.getTiddlerText(CONFIG_LEGACY_SELECTION_TRACKER_TITLE,"yes") === "yes") {
|
||||
$tw.dynannotate.legacySelectionTracker = new LegacySelectionTracker($tw.wiki,{
|
||||
allowBlankSelectionPopup: true
|
||||
});
|
||||
}
|
||||
// Set up the element spotlight
|
||||
$tw.dynannotate.elementSpotlight = new ElementSpotlight();
|
||||
$tw.rootWidget.addEventListener("tm-spotlight-element",function(event) {
|
||||
var selectors = [];
|
||||
if(event.paramObject.selector) {
|
||||
selectors.push(event.paramObject.selector);
|
||||
}
|
||||
$tw.utils.each(Object.keys(event.paramObject).sort(),function(name) {
|
||||
var SELECTOR_PROPERTY_PREFIX = "selector-";
|
||||
if($tw.utils.startsWith(name,SELECTOR_PROPERTY_PREFIX)) {
|
||||
selectors.push(event.paramObject[name]);
|
||||
}
|
||||
});
|
||||
if(event.paramObject["selector-fallback"]) {
|
||||
selectors.push(event.paramObject["selector-fallback"]);
|
||||
}
|
||||
$tw.dynannotate.elementSpotlight.shineSpotlight(selectors);
|
||||
});
|
||||
};
|
||||
|
||||
})();
|
||||
|
||||
@@ -52,3 +52,20 @@ tags: [[$:/tags/Stylesheet]]
|
||||
background: #ffa;
|
||||
padding: 1em;
|
||||
}
|
||||
|
||||
.tc-dynannotate-spotlight-wrapper {
|
||||
position: fixed;
|
||||
left: 0;
|
||||
right: 0;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
z-index: 1000;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.tc-dynannotate-spotlight {
|
||||
position: absolute;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
display: none;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
title: $:/config/AutoStartTour
|
||||
text: no
|
||||
@@ -0,0 +1,2 @@
|
||||
title: $:/config/CurrentTour
|
||||
text: $:/plugins/tiddlywiki/tour/introduction-to-tiddlywiki
|
||||
@@ -0,0 +1,31 @@
|
||||
title: $:/config/DefaultColourMappings/
|
||||
|
||||
tour-chooser-button-foreground: <<colour very-muted-foreground>>
|
||||
tour-chooser-button-hover-background: <<colour muted-foreground>>
|
||||
tour-chooser-button-hover-foreground:: <<colour background>>
|
||||
tour-chooser-button-selected-background: <<colour primary>>
|
||||
tour-chooser-button-selected-foreground: <<colour background>>
|
||||
tour-chooser-dropdown-foreground: <<colour very-muted-foreground>>
|
||||
tour-chooser-item-background: <<colour background>>
|
||||
tour-chooser-item-border: <<colour muted-foreground>>
|
||||
tour-chooser-item-foreground: <<colour foreground>>
|
||||
tour-chooser-item-shadow: <<colour muted-foreground>>
|
||||
tour-chooser-item-start-background: <<colour download-background>>
|
||||
tour-chooser-item-start-foreground: <<colour background>>
|
||||
tour-chooser-item-start-hover-background: <<colour primary>>
|
||||
tour-chooser-item-start-hover-foreground: <<colour background>>
|
||||
tour-fullscreen-background: <<colour page-background>>
|
||||
tour-fullscreen-controls-foreground: <<colour muted-foreground>>
|
||||
tour-navigation-buttons-back-background: red
|
||||
tour-navigation-buttons-back-foreground: white
|
||||
tour-navigation-buttons-hint-background: purple
|
||||
tour-navigation-buttons-hint-foreground: white
|
||||
tour-navigation-buttons-hover-background: <<colour foreground>>
|
||||
tour-navigation-buttons-hover-foreground: <<colour background>>
|
||||
tour-navigation-buttons-next-background: purple
|
||||
tour-navigation-buttons-next-foreground: white
|
||||
tour-overlay-background: #cbfff8
|
||||
tour-overlay-border: #228877
|
||||
tour-step-heading-background: none
|
||||
tour-step-task-background: <<colour download-background>>
|
||||
tour-step-task-foreground: <<colour download-foreground>>
|
||||
@@ -0,0 +1,2 @@
|
||||
title: $:/config/ShowTour
|
||||
text: hide
|
||||
@@ -0,0 +1,25 @@
|
||||
title: $:/plugins/tiddlywiki/tour/docs
|
||||
|
||||
Tour definition tiddlers have the following fields:
|
||||
|
||||
|!Name |!Description |
|
||||
|tags |Must include $:/tags/Tour |
|
||||
|tour-tag |Name of tag used to define tour step sequence |
|
||||
|logo |Title of tiddler containing logo of tour |
|
||||
|description |Brief description of the tour |
|
||||
|text |Longer description of the tour |
|
||||
|class |(optional) additional class to apply to the tour wrapper |
|
||||
|
||||
|
||||
Tour step tiddlers have the following fields:
|
||||
|
||||
|!Name |!Description |
|
||||
|tags|Must include the tag used to define the tour step sequence |
|
||||
|caption|Caption for the tour step |
|
||||
|display-mode|(optional) can be set to `fullscreen` |
|
||||
|enter-actions|(optional) action string invoked when the step is displayed |
|
||||
|hint-selector|(optional) selector to be highlighted by the hint button in steps with a step-success-filter |
|
||||
|hint-text|(optional) text to be displayed for the hint button |
|
||||
|condition|(optional) filter expression that must return a result for the step to be displayed |
|
||||
|step-success-filter|(optional) filter expression that must return a result for the step to be considered completed |
|
||||
|step-success-filtervar|(optional) filter expression evaluated to set the first result as the variable `step-success-filter-var` which can be used in the `step-success-filter` |
|
||||
@@ -0,0 +1,9 @@
|
||||
title: $:/plugins/tiddlywiki/tour/tour-button-icon
|
||||
tags: $:/tags/Image
|
||||
|
||||
\parameters (size:"22pt")
|
||||
<svg width=<<size>> height=<<size>> class="tc-image-tour-button tc-image-button" viewBox="0 0 24 24">
|
||||
<path d="M0 0h24v24H0z" style="fill:none"/>
|
||||
<path d="M1.832 10.356a1.024 1.024 0 0 1 0-1.832l9.71-4.856c.288-.144.628-.144.916 0l9.71 4.856a1.024 1.024 0 0 1 0 1.832l-9.71 4.855a1.025 1.025 0 0 1-.916 0l-9.71-4.855Z"/>
|
||||
<path d="M18.5 13.19v3.25h-.066c.044.163.066.33.066.5 0 1.932-2.913 3.5-6.5 3.5s-6.5-1.568-6.5-3.5c0-.17.022-.337.066-.5H5.5v-3.25l6.042 3.02c.288.145.628.145.916 0l6.042-3.02ZM2.73 8.44l.208 5-.681 3s-.002.709.974.717c.92.007 1-.717 1-.717l-.793-3 .293-5h-1Z"/>
|
||||
</svg>
|
||||
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"title": "$:/plugins/tiddlywiki/tour",
|
||||
"name": "Tour",
|
||||
"description": "A tour of TiddlyWiki",
|
||||
"list": "readme docs settings",
|
||||
"dependents": ["$:/plugins/tiddlywiki/confetti","$:/plugins/tiddlywiki/dynannotate"]
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
title: $:/plugins/tiddlywiki/tour/readme
|
||||
|
||||
The Tour Plugin for TiddlyWiki provides a framework for making interactive guided tours. An "Introduction to ~TiddlyWiki" tour is included in the plugin but it is also possible to load additional tours and switch between them.
|
||||
@@ -0,0 +1,154 @@
|
||||
title: $:/plugins/tiddlywiki/tour/settings
|
||||
|
||||
\import [[$:/plugins/tiddlywiki/tour/variables]]
|
||||
\procedure button-expand-collapse-all(caption,text)
|
||||
<$button>
|
||||
<$list filter="[all[shadows+tiddlers]tag<currentTourTag>]" variable="currentStep">
|
||||
<$let
|
||||
collapseState={{{ [[$:/state/Tour/Settings/Tour/Visibility/]addsuffix<currentTour>addsuffix<currentStep>] }}}
|
||||
>
|
||||
<$action-setfield $tiddler=<<collapseState>> text=<<text>>/>
|
||||
</$let>
|
||||
</$list>
|
||||
<$text text=<<caption>>/>
|
||||
</$button>
|
||||
\end
|
||||
|
||||
\procedure display-tour-step-field-text(fieldName,fieldCaption)
|
||||
<$list filter="[<currentStep>has<fieldName>]" variable="ignore">
|
||||
<tr>
|
||||
<th>
|
||||
<$text text=<<fieldCaption>>/>
|
||||
</th>
|
||||
<td>
|
||||
<$text text={{{ [<currentStep>get<fieldName>] }}}/>
|
||||
</td>
|
||||
</tr>
|
||||
</$list>
|
||||
\end
|
||||
|
||||
<$let
|
||||
stateCurrentTour=<<qualify "$:/state/Tour/Settings/Current">>
|
||||
defaultTour={{{ [{$:/config/CurrentTour}] :else[all[shadows+tiddlers]tag[$:/tags/Tour]] }}}
|
||||
>
|
||||
|
||||
! Tour Overview
|
||||
|
||||
Select a tour:
|
||||
<$select tiddler=<<stateCurrentTour>> default=<<defaultTour>>>
|
||||
<$list filter="[all[shadows+tiddlers]tag[$:/tags/Tour]]">
|
||||
<option value=<<currentTiddler>>>
|
||||
<$transclude $field="description">
|
||||
<$text text=<<currentTiddler>>/>
|
||||
</$transclude>
|
||||
</option>
|
||||
</$list>
|
||||
</$select>
|
||||
|
||||
<$let
|
||||
currentTour={{{ [<stateCurrentTour>get[text]] :else[<defaultTour>] }}}
|
||||
currentTourTag={{{ [<currentTour>get[tour-tag]] }}}
|
||||
>
|
||||
<table class="tc-tour-settings-tour-details">
|
||||
<tbody>
|
||||
<tr>
|
||||
<th>
|
||||
Tour title
|
||||
</th>
|
||||
<td>
|
||||
<$link to=<<currentTour>>><$text text=<<currentTour>>/></$link>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>
|
||||
Tour description
|
||||
</th>
|
||||
<td>
|
||||
<div class="tc-tour-settings-tour-details-description">
|
||||
<$transclude $tiddler=<<currentTour>>>
|
||||
(No description available)
|
||||
</$transclude>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>
|
||||
Tour logo
|
||||
</th>
|
||||
<td>
|
||||
<div class="tc-tour-settings-tour-details-logo">
|
||||
<$image source={{{ [<currentTour>get[logo]] }}}/>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>
|
||||
Tour step tag
|
||||
</th>
|
||||
<td>
|
||||
<$transclude $variable="tag" tag=<<currentTourTag>>/>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<$list filter="[<currentTour>has[settings]]" variable="ignore">
|
||||
<p>
|
||||
Custom tour settings:
|
||||
</p>
|
||||
<div class="tc-tour-settings-tour-settings">
|
||||
<$transclude $tiddler={{{ [<currentTour>get[settings]] }}}/>
|
||||
</div>
|
||||
</$list>
|
||||
<p>
|
||||
<<button-expand-collapse-all "Expand All" "show">>
|
||||
<<button-expand-collapse-all "Collapse All" "hide">>
|
||||
</p>
|
||||
<$list filter="[all[shadows+tiddlers]tag<currentTourTag>]" variable="currentStep" counter="stepNumber">
|
||||
<$let
|
||||
collapseState={{{ [[$:/state/Tour/Settings/Tour/Visibility/]addsuffix<currentTour>addsuffix<currentStep>] }}}
|
||||
>
|
||||
<div class="tc-tour-settings-tour-step">
|
||||
<div class="tc-tour-settings-tour-step-heading">
|
||||
<$button class="tc-btn-invisible tc-tour-settings-tour-step-open-button">
|
||||
<$action-setfield $tiddler=<<collapseState>> text={{{ [<collapseState>get[text]else[hide]match[show]then[hide]else[show]] }}}/>
|
||||
<$list filter="[<collapseState>get[text]else[hide]match[show]]" variable="ignore" emptyMessage="{{$:/core/images/right-arrow}}">
|
||||
{{$:/core/images/down-arrow}}
|
||||
</$list>
|
||||
<span class="tc-tour-settings-tour-step-heading-step-number">
|
||||
<$text text=<<stepNumber>>/>
|
||||
</span>
|
||||
<$transclude $tiddler=<<currentStep>> $field="caption">
|
||||
<$text text=<<currentStep>>/>
|
||||
</$transclude>
|
||||
</$button>
|
||||
<$button class="tc-btn-invisible tc-tour-settings-tour-step-launch-button" tooltip="Launch this step of the tour">
|
||||
<$transclude $variable="tour-start" title=<<currentTour>> step=<<currentStep>>/>
|
||||
{{$:/core/images/open-window}}
|
||||
</$button>
|
||||
</div>
|
||||
<$reveal state=<<collapseState>> text="show" type="match" default="hide" animate="yes">
|
||||
<table class="tc-tour-settings-tour-step-details">
|
||||
<tbody>
|
||||
<<display-tour-step-field-text "title" "Title">>
|
||||
<<display-tour-step-field-text "caption" "Caption">>
|
||||
<<display-tour-step-field-text "step-success-filter" "step-success-filter">>
|
||||
<<display-tour-step-field-text "step-success-filter-var" "step-success-filter Variable">>
|
||||
<<display-tour-step-field-text "display-mode" "Display Mode">>
|
||||
<<display-tour-step-field-text "enter-actions" "Enter Actions">>
|
||||
<<display-tour-step-field-text "hint-text" "Hint text">>
|
||||
<<display-tour-step-field-text "hint-selector" "Hint selector">>
|
||||
<<display-tour-step-field-text "hint-selector-fallback-1" "Hint selector Fallback 1">>
|
||||
<<display-tour-step-field-text "hint-selector-fallback-2" "Hint selector Fallback 2">>
|
||||
<<display-tour-step-field-text "condition" "Condition">>
|
||||
</tbody>
|
||||
</table>
|
||||
<div class="tc-tour-settings-tour-step-body">
|
||||
<$transclude $tiddler=<<currentStep>> $mode="block"/>
|
||||
</div>
|
||||
</$reveal>
|
||||
</div>
|
||||
</$let>
|
||||
</$list>
|
||||
</$let>
|
||||
|
||||
</$let>
|
||||
@@ -0,0 +1,106 @@
|
||||
title: $:/plugins/tiddlywiki/tour/simplified-tiddler-with-tags
|
||||
|
||||
\whitespace trim
|
||||
\define tag-pill-styles()
|
||||
background-color:$(backgroundColor)$;
|
||||
fill:$(foregroundColor)$;
|
||||
color:$(foregroundColor)$;
|
||||
\end
|
||||
|
||||
\procedure tag-pill-label(prefix)
|
||||
<$text text={{{ [<currentTiddler>removeprefix<prefix>] }}}/>
|
||||
\end
|
||||
|
||||
\procedure tag-pill-label-link(prefix)
|
||||
<div>
|
||||
<$link>
|
||||
<$transclude $variable="tag-pill-label" prefix=<<prefix>>/>
|
||||
</$link>
|
||||
</div>
|
||||
\end
|
||||
|
||||
<!-- This has no whitespace trim to avoid modifying $actions$. Closing tags omitted for brevity. -->
|
||||
\define tag-pill-inner(tag,icon,colour,fallbackTarget,colourA,colourB,element-tag,element-attributes,actions,prefix)
|
||||
\whitespace trim
|
||||
<$let
|
||||
foregroundColor=<<contrastcolour target:"""$colour$""" fallbackTarget:"""$fallbackTarget$""" colourA:"""$colourA$""" colourB:"""$colourB$""">>
|
||||
backgroundColor=<<__colour__>>
|
||||
>
|
||||
<$element-tag$
|
||||
$element-attributes$
|
||||
class="tc-tag-label tc-btn-invisible"
|
||||
style=<<tag-pill-styles>>
|
||||
>
|
||||
<<__actions__>>
|
||||
<$transclude tiddler=<<__icon__>>/>
|
||||
<$let currentTiddler=<<__tag__>>>
|
||||
<$transclude $variable="tag-pill-label" prefix=<<__prefix__>>/>
|
||||
</$let>
|
||||
</$element-tag$>
|
||||
</$let>
|
||||
\end
|
||||
|
||||
\define tag-pill-body(tag,icon,colour,palette,element-tag,element-attributes,actions,prefix)
|
||||
<$transclude $variable="tag-pill-inner"
|
||||
tag=<<__tag__>>
|
||||
icon=<<__icon__>>
|
||||
colour=<<__colour__>>
|
||||
fallbackTarget={{$palette$##tag-background}}
|
||||
colourA={{$palette$##foreground}}
|
||||
colourB={{$palette$##background}}
|
||||
element-tag=<<__element-tag__>>
|
||||
element-attributes=<<__element-attributes__>>
|
||||
actions=<<__actions__>>
|
||||
prefix=<<__prefix__>>
|
||||
/>
|
||||
\end
|
||||
|
||||
\procedure simplified-tag(prefix)
|
||||
<span class="tc-tag-list-item" data-tag-title=<<currentTiddler>>>
|
||||
<$set name="transclusion" value=<<currentTiddler>>>
|
||||
<$transclude $variable="tag-pill-body"
|
||||
tag=<<currentTiddler>>
|
||||
icon={{{ [<currentTiddler>] :cascade[all[shadows+tiddlers]tag[$:/tags/TiddlerIconFilter]!is[draft]get[text]] }}}
|
||||
colour={{{ [<currentTiddler>] :cascade[all[shadows+tiddlers]tag[$:/tags/TiddlerColourFilter]!is[draft]get[text]] }}}
|
||||
palette={{$:/palette}}
|
||||
element-tag="$button"
|
||||
element-attributes="""popup=<<qualify "$:/state/popup/tag">> dragFilter="[all[current]tagging[]]" tag='span'"""
|
||||
prefix=<<prefix>>
|
||||
/>
|
||||
<$reveal state=<<qualify "$:/state/popup/tag">> type="popup" position="below" animate="yes" class="tc-drop-down">
|
||||
<$set name="tv-show-missing-links" value="yes">
|
||||
<$transclude $variable="tag-pill-label-link" prefix=<<prefix>>/>
|
||||
</$set>
|
||||
<hr>
|
||||
<$list filter="[all[shadows+tiddlers]tag<currentTiddler>]">
|
||||
<$transclude $variable="tag-pill-label-link" prefix=<<prefix>>/>
|
||||
</$list>
|
||||
</$reveal>
|
||||
</$set>
|
||||
</span>
|
||||
\end
|
||||
|
||||
<$let storyTiddler=<<currentTiddler>>>
|
||||
<div class="tc-tiddler-frame tc-tiddler-view-frame tc-tiddler-exists tc-tiddler-shadow " role="article">
|
||||
<div class="tc-tiddler-title">
|
||||
<div class="tc-titlebar">
|
||||
<span class="tc-tiddler-controls">
|
||||
<$list filter="[<tour-simplified-tiddler-close-button>match[yes]]" variable="ignore">
|
||||
{{||$:/core/ui/Buttons/close}}
|
||||
</$list>
|
||||
</span>
|
||||
<span>
|
||||
<h2 class="tc-title"><$view field="caption"/></h2>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="tc-tags-wrapper">
|
||||
<$list filter="[all[current]tags[]sort[title]]" storyview="pop">
|
||||
<<simplified-tag "$:/plugins/tiddlywiki/tour/introduction-to-tiddlywiki/tiddlers/">>
|
||||
</$list>
|
||||
</div>
|
||||
<div class="tc-tiddler-body">
|
||||
<$transclude field="text" mode="block"/>
|
||||
</div>
|
||||
</div>
|
||||
</$let>
|
||||
@@ -0,0 +1,22 @@
|
||||
title: $:/plugins/tiddlywiki/tour/simplified-tiddler
|
||||
|
||||
\whitespace trim
|
||||
<$let storyTiddler=<<currentTiddler>>>
|
||||
<div class="tc-tiddler-frame tc-tiddler-view-frame tc-tiddler-exists tc-tiddler-shadow " role="article">
|
||||
<div class="tc-tiddler-title">
|
||||
<div class="tc-titlebar">
|
||||
<span class="tc-tiddler-controls">
|
||||
<$list filter="[<tour-simplified-tiddler-close-button>match[yes]]" variable="ignore">
|
||||
{{||$:/core/ui/Buttons/close}}
|
||||
</$list>
|
||||
</span>
|
||||
<span>
|
||||
<h2 class="tc-title"><$view field="caption"/></h2>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="tc-tiddler-body">
|
||||
<$transclude field="text" mode="block"/>
|
||||
</div>
|
||||
</div>
|
||||
</$let>
|
||||
@@ -0,0 +1,18 @@
|
||||
title: $:/plugins/tiddlywiki/tour/start-tour-button
|
||||
tags: $:/tags/PageControls
|
||||
caption: {{$:/plugins/tiddlywiki/tour/tour-button-icon}} Start Tour
|
||||
description: Start interactive training tour
|
||||
|
||||
\whitespace trim
|
||||
\import [[$:/plugins/tiddlywiki/tour/variables]]
|
||||
<$button tooltip="Start interactive training tour" aria-label="Start Tour" class=<<tv-config-toolbar-class>>>
|
||||
<<tour-restart>>
|
||||
<$list filter="[<tv-config-toolbar-icons>match[yes]]" variable="listItem">
|
||||
{{$:/plugins/tiddlywiki/tour/tour-button-icon}}
|
||||
</$list>
|
||||
<$list filter="[<tv-config-toolbar-text>match[yes]]">
|
||||
<span class="tc-btn-text">
|
||||
<$text text="Start Tour"/>
|
||||
</span>
|
||||
</$list>
|
||||
</$button>
|
||||
@@ -0,0 +1,7 @@
|
||||
title: $:/plugins/tiddlywiki/tour/startup-actions
|
||||
tags: $:/tags/StartupAction
|
||||
|
||||
\import [[$:/plugins/tiddlywiki/tour/variables]]
|
||||
<$list filter="[[$:/config/AutoStartTour]get[text]else[no]match[yes]]" variable="ignore">
|
||||
<<tour-restart>>
|
||||
</$list>
|
||||
@@ -0,0 +1,261 @@
|
||||
title: $:/plugins/tiddlywiki/tour/styles
|
||||
tags: $:/tags/Stylesheet
|
||||
|
||||
\rules only filteredtranscludeinline transcludeinline macrodef macrocallinline macrocallblock
|
||||
|
||||
.tc-tour-panel {
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
width: 310px;
|
||||
height: 400px;
|
||||
overflow: auto;
|
||||
-webkit-overflow-scrolling: touch;
|
||||
<<box-shadow "0px 0px 5px rgba(0, 0, 0, 0.3)">>
|
||||
border: 1px solid <<colour tour-overlay-border>>;
|
||||
background: <<colour tour-overlay-background>>;
|
||||
border-radius: 8px;
|
||||
padding: 1em;
|
||||
margin: 0.5em;
|
||||
z-index: 2000;
|
||||
}
|
||||
|
||||
.tc-tour-panel-navigation .tc-btn-big-green {
|
||||
border-radius: 0.25em;
|
||||
margin: 0 1em 0 0;
|
||||
}
|
||||
|
||||
.tc-tour-panel-navigation .tc-btn-big-green.tc-tour-panel-navigation-back {
|
||||
background: <<colour tour-navigation-buttons-back-background>>;
|
||||
color: <<colour tour-navigation-buttons-back-foreground>>;
|
||||
}
|
||||
|
||||
.tc-tour-panel-navigation .tc-btn-big-green.tc-tour-panel-navigation-next {
|
||||
background: <<colour tour-navigation-buttons-next-background>>;
|
||||
color: <<colour tour-navigation-buttons-next-foreground>>;
|
||||
}
|
||||
|
||||
.tc-tour-panel-navigation .tc-btn-big-green.tc-tour-panel-navigation-hint {
|
||||
background: <<colour tour-navigation-buttons-hint-background>>;
|
||||
color: <<colour tour-navigation-buttons-hint-foreground>>;
|
||||
}
|
||||
|
||||
.tc-tour-panel-navigation .tc-btn-big-green:hover {
|
||||
color: <<colour tour-navigation-buttons-hover-foreground>>;
|
||||
background: <<colour tour-navigation-buttons-hover-background>>;
|
||||
}
|
||||
|
||||
.tc-tour-panel-fullscreen {
|
||||
top: 0;
|
||||
right: 0;
|
||||
width: auto;
|
||||
height: auto;
|
||||
box-shadow: none;
|
||||
border: none;
|
||||
background: <<colour tour-fullscreen-background>>;
|
||||
margin: 0;
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
.tc-tour-panel-controls .tc-tour-panel-list-button {
|
||||
padding: 2px 8px;
|
||||
border-radius: 1em;
|
||||
color: <<color tour-chooser-button-foreground>>;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.tc-tour-panel-controls .tc-tour-panel-list-button.tc-selected {
|
||||
color: <<colour tour-chooser-button-selected-foreground>>;
|
||||
fill: <<colour tour-chooser-button-selected-foreground>>;
|
||||
background: <<color tour-chooser-button-selected-background>>;
|
||||
}
|
||||
|
||||
.tc-tour-panel-controls .tc-tour-panel-list-button:hover {
|
||||
background: <<colour tour-chooser-button-hover-background>>;
|
||||
color: <<colour tour-chooser-button-hover-foreground>>;
|
||||
}
|
||||
|
||||
.tc-tour-panel-controls .tc-popup .tc-drop-down {
|
||||
font-size: 1em;
|
||||
color: <<colour tour-chooser-dropdown-foreground>>;
|
||||
min-width: auto;
|
||||
}
|
||||
|
||||
.tc-tour-panel-chooser-item {
|
||||
border: 1px solid <<colour tour-chooser-item-border>>;
|
||||
background: <<colour tour-chooser-item-background>>;
|
||||
color: <<colour tour-chooser-item-foreground>>;
|
||||
padding: 4px 4px 4px 8px;
|
||||
margin: 12px 0;
|
||||
border-radius: 12px;
|
||||
box-shadow: 3px 3px 5px <<colour tour-chooser-item-shadow>>;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: space-between;
|
||||
gap: 1em;
|
||||
}
|
||||
|
||||
.tc-tour-panel-chooser-item .tc-tour-panel-chooser-start-button {
|
||||
display: inline-block;
|
||||
width: auto;
|
||||
padding: 4px;
|
||||
font-size: 0.7em;
|
||||
vertical-align: baseline;
|
||||
border-radius: 1em;
|
||||
background: <<colour tour-chooser-item-start-background>>;
|
||||
color: <<colour tour-chooser-item-start-foreground>>;
|
||||
fill: <<colour tour-chooser-item-start-foreground>>;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.tc-tour-panel-chooser-wrapper button:hover {
|
||||
background: <<colour tour-chooser-item-start-hover-background>>;
|
||||
color: <<colour tour-chooser-item-start-hover-foreground>>;
|
||||
}
|
||||
|
||||
.tc-tour-panel-fullscreen h1 {
|
||||
background: <<colour tour-step-heading-background>>;
|
||||
padding: 0.25em;
|
||||
margin: -0.25em;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.tc-tour-panel-fullscreen .tc-tour-panel-controls {
|
||||
/* display: none; */
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
padding: 4px;
|
||||
color: <<colour tour-fullscreen-controls-foreground>>;
|
||||
}
|
||||
|
||||
.tc-tour-panel .tc-tour-panel-banner-image {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.tc-tour-panel-fullscreen .tc-tour-panel-banner-image {
|
||||
display: block;
|
||||
width: 200px;
|
||||
float: right;
|
||||
margin: 4em 2em 2em 2em;
|
||||
}
|
||||
|
||||
.tc-tour-panel-fullscreen .tc-tour-panel-inner {
|
||||
width: 30%;
|
||||
min-width: 400px;
|
||||
height: 30%;
|
||||
margin: 20% auto;
|
||||
}
|
||||
|
||||
.tc-tour-panel .tc-tour-panel-inner .tc-tiddler-frame {
|
||||
width: auto;
|
||||
padding: 1.5em 2.5em;
|
||||
}
|
||||
|
||||
.tc-tour-panel .tc-tour-panel-inner .tc-tiddler-frame .tc-titlebar {
|
||||
font-size: 1.5em;
|
||||
line-height: 1.1;
|
||||
}
|
||||
|
||||
.tc-tour-task {
|
||||
background: <<colour tour-step-task-background>>;
|
||||
color: <<colour tour-step-task-foreground>>;
|
||||
padding: 0.5em;
|
||||
border-radius: 1em;
|
||||
}
|
||||
|
||||
.tc-tour-task svg {
|
||||
fill: <<colour tour-step-task-foreground>>;
|
||||
vertical-align: middle;
|
||||
width: 1.2em;
|
||||
height: 1.2em;
|
||||
margin-right: 0.5em;
|
||||
}
|
||||
|
||||
.tc-tour-settings-tour-details,
|
||||
.tc-tour-settings-tour-step-details {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.tc-tour-settings-tour-details th,
|
||||
.tc-tour-settings-tour-step-details th {
|
||||
text-align: right;
|
||||
vertical-align: top;
|
||||
font-weight: normal;
|
||||
width:10em;
|
||||
}
|
||||
|
||||
.tc-tour-settings-tour-details td,
|
||||
.tc-tour-settings-tour-step-details td {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.tc-tour-settings-tour-details-description {
|
||||
|
||||
}
|
||||
|
||||
.tc-tour-settings-tour-details-logo img {
|
||||
max-width: 200px;
|
||||
max-height: 100px;
|
||||
}
|
||||
|
||||
.tc-tour-settings-tour-settings {
|
||||
border: 1px solid <<colour muted-foreground>>;
|
||||
margin: 0.5em 0;
|
||||
padding: 0.5em;
|
||||
}
|
||||
|
||||
.tc-tour-settings-tour-step {
|
||||
border: 1px solid <<colour foreground>>;
|
||||
}
|
||||
|
||||
.tc-tour-settings-tour-step-heading {
|
||||
background: <<colour muted-foreground>>;
|
||||
border: 0;
|
||||
display: flex;
|
||||
flex-wrap: nowrap;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
gap: 5px;
|
||||
}
|
||||
|
||||
.tc-tour-settings-tour-step-open-button,
|
||||
.tc-tour-settings-tour-step-launch-button {
|
||||
display: inline-block;
|
||||
padding: 0.25em;
|
||||
}
|
||||
|
||||
.tc-tour-settings-tour-step-open-button {
|
||||
flex-grow: 1;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.tc-tour-settings-tour-step-launch-button {
|
||||
flex-grow: 0;
|
||||
}
|
||||
|
||||
.tc-tour-settings-tour-step-open-button:hover,
|
||||
.tc-tour-settings-tour-step-launch-button:hover {
|
||||
background: <<colour foreground>>;
|
||||
color: <<colour background>>;
|
||||
fill: <<colour background>>;
|
||||
}
|
||||
|
||||
.tc-tour-settings-tour-step-heading-step-number {
|
||||
font-weight: bold;
|
||||
background: <<colour foreground>>;
|
||||
color: <<colour background>>;
|
||||
border-radius: 1em;
|
||||
font-size: 0.9em;
|
||||
display: inline-block;
|
||||
padding: 0 4px;
|
||||
}
|
||||
|
||||
.tc-tour-settings-tour-step-details {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.tc-tour-settings-tour-step-body {
|
||||
padding: 0.5em;
|
||||
}
|
||||
@@ -0,0 +1,106 @@
|
||||
title: $:/plugins/tiddlywiki/tour/panel
|
||||
tags: $:/tags/PageTemplate
|
||||
|
||||
\whitespace trim
|
||||
|
||||
\procedure tour-buttons()
|
||||
\procedure tv-action-refresh-policy() always
|
||||
<div class="tc-tour-panel-navigation">
|
||||
<%if [function[tour-is-not-first-step]] %>
|
||||
<$button class="tc-btn-big-green tc-tour-panel-navigation-back">
|
||||
<<tour-previous-step>>
|
||||
back
|
||||
</$button>
|
||||
<%endif%>
|
||||
<%if [function[tour-is-not-last-step]] %>
|
||||
<$button class="tc-btn-big-green tc-tour-panel-navigation-next">
|
||||
<<tour-next-step>>
|
||||
next
|
||||
</$button>
|
||||
<%endif%>
|
||||
<%if [function[tour-is-last-step]] %>
|
||||
<$confetti/>
|
||||
<$confetti delay=100/>
|
||||
<$confetti delay=200/>
|
||||
<$confetti delay=300/>
|
||||
<$confetti delay=400/>
|
||||
<$confetti delay=500/>
|
||||
<%endif%>
|
||||
</div>
|
||||
\end
|
||||
|
||||
\procedure tour-step-no-success-filter()
|
||||
<$transclude tiddler=<<currentTourStep>> mode="block"/>
|
||||
<<tour-buttons>>
|
||||
\end tour-step-no-success-filter
|
||||
|
||||
\procedure tour-step-success-filter-not-satisfied()
|
||||
<$transclude tiddler=<<currentTourStep>> mode="block"/>
|
||||
<%if [{$:/state/tour/step}has[hint-selector]] %>
|
||||
<div class="tc-tour-panel-navigation">
|
||||
<$button class="tc-btn-big-green tc-tour-panel-navigation-hint">
|
||||
<$action-sendmessage $message="tm-spotlight-element" selector={{{ [{$:/state/tour/step}get[hint-selector]] }}} selector-fallback-1={{{ [{$:/state/tour/step}get[hint-selector-fallback-1]] }}} selector-fallback-2={{{ [{$:/state/tour/step}get[hint-selector-fallback-2]] }}}/>
|
||||
<$transclude tiddler={{$:/state/tour/step}} field="hint-text" mode="inline"> show me a hint </$transclude>
|
||||
</$button>
|
||||
</div>
|
||||
<%endif%>
|
||||
\end tour-step-success-filter-not-satisfied
|
||||
|
||||
\procedure tour-step-success-filter-satisfied()
|
||||
<$let tour-task="">
|
||||
<$transclude tiddler=<<currentTourStep>> mode="block"/>
|
||||
</$let>
|
||||
<$confetti/>
|
||||
<p>
|
||||
Congratulations, you may proceed
|
||||
</p>
|
||||
<<tour-buttons>>
|
||||
\end tour-step-success-filter-satisfied
|
||||
\import [[$:/plugins/tiddlywiki/tour/variables]]
|
||||
|
||||
<%if [{$:/config/ShowTour}!is[blank]else[show]match[show]] %>
|
||||
<div class=`tc-tour-panel tc-tour-panel-${ [{$:/state/tour/step}get[display-mode]else[normal]] }$ ${ [{$:/config/CurrentTour}get[class]] }$`>
|
||||
<$image class="tc-tour-panel-banner-image" source={{{ [{$:/config/CurrentTour}get[logo]] }}}/>
|
||||
<div class="tc-tour-panel-inner">
|
||||
<div class="tc-tiddler-controls tc-tour-panel-controls">
|
||||
<$button set="$:/config/ShowTour" setTo="no" class="tc-btn-invisible">{{$:/core/images/close-button}}</$button>
|
||||
<$button popup=<<qualify "$:/state/popup/tour-dropdown">> class="tc-btn-invisible tc-tour-panel-list-button" selectedClass="tc-selected">
|
||||
<span class="tc-small-gap-right">''Tour'':</span> <<tour-display-current-tour>>
|
||||
</$button>
|
||||
<$reveal state=<<qualify "$:/state/popup/tour-dropdown">> type="popup" position="belowleft" animate="yes" tag="div">
|
||||
<div class="tc-drop-down">
|
||||
<p>
|
||||
Choose a tour:
|
||||
</p>
|
||||
<p>
|
||||
<<tour-chooser>>
|
||||
</p>
|
||||
</div>
|
||||
</$reveal>
|
||||
</div>
|
||||
<$let
|
||||
currentTour={{$:/config/CurrentTour}}
|
||||
currentTourStep={{$:/state/tour/step}}
|
||||
step-success-filter-var={{{ [<currentTourStep>get[step-success-filter-var]] :map[subfilter<currentTiddler>] }}}
|
||||
>
|
||||
<%if [<currentTourStep>has[caption]] %>
|
||||
<h1><$transclude $tiddler=<<currentTourStep>> $field="caption" mode="inline"/></h1>
|
||||
<%endif%>
|
||||
<!-- Handle steps without a step-success-filter -->
|
||||
<%if [<currentTourStep>!has[step-success-filter]] %>
|
||||
<<tour-step-no-success-filter>>
|
||||
<%endif%>
|
||||
<!-- Handle steps that have a step-success-filter -->
|
||||
<%if [<currentTourStep>has[step-success-filter]] %>
|
||||
<$let step-success-filter={{{ [<currentTourStep>get[step-success-filter]] }}}>
|
||||
<%if [subfilter<step-success-filter>] %>
|
||||
<<tour-step-success-filter-satisfied>>
|
||||
<%else%>
|
||||
<<tour-step-success-filter-not-satisfied>>
|
||||
<%endif%>
|
||||
</$let>
|
||||
<%endif%>
|
||||
</$let>
|
||||
</div>
|
||||
</div>
|
||||
<%endif%>
|
||||
@@ -0,0 +1,2 @@
|
||||
title: $:/config/Tours/IntroductionToTiddlyWiki/ProductName
|
||||
text: ~TiddlyWiki
|
||||
@@ -0,0 +1,4 @@
|
||||
title: $:/plugins/tiddlywiki/tour/introduction-to-tiddlywiki/tiddlers/Gas Giant
|
||||
caption: Gas Giant
|
||||
|
||||
A gas giant is a large planet that has a solid core, but a very thick atmosphere. This means that most of the planet is made up of gas. These planets are very large.
|
||||
@@ -0,0 +1,5 @@
|
||||
title: $:/plugins/tiddlywiki/tour/introduction-to-tiddlywiki/tiddlers/Jupiter
|
||||
caption: Jupiter
|
||||
tags: $:/plugins/tiddlywiki/tour/introduction-to-tiddlywiki/tiddlers/Planet [[$:/plugins/tiddlywiki/tour/introduction-to-tiddlywiki/tiddlers/Gas Giant]]
|
||||
|
||||
Jupiter is the largest planet in the Solar System. It is the fifth planet from the Sun. Jupiter is a gas giant because it is so large and made of gas. The other gas giants in the Solar System are [[Saturn|$:/plugins/tiddlywiki/tour/introduction-to-tiddlywiki/tiddlers/Saturn]], Uranus, and Neptune.
|
||||
@@ -0,0 +1,5 @@
|
||||
title: $:/plugins/tiddlywiki/tour/introduction-to-tiddlywiki/tiddlers/Mars
|
||||
caption: Mars
|
||||
tags: $:/plugins/tiddlywiki/tour/introduction-to-tiddlywiki/tiddlers/Planet [[$:/plugins/tiddlywiki/tour/introduction-to-tiddlywiki/tiddlers/Rocky]]
|
||||
|
||||
Mars is the fourth planet from the Sun in the Solar System and the second-smallest planet. Mars is a terrestrial planet with polar ice caps of frozen water and carbon dioxide. It has the largest volcano in the Solar System, and some very large impact craters. Mars is named after the mythological Roman god of war because it appears of red color.
|
||||
@@ -0,0 +1,4 @@
|
||||
title: $:/plugins/tiddlywiki/tour/introduction-to-tiddlywiki/tiddlers/Planet
|
||||
caption: Planet
|
||||
|
||||
A planet is a large object such as Venus or Earth that orbits a star. Planets are smaller than stars, and they do not make light. Jupiter is the biggest planet in the Solar System, while the smallest planet in the Solar System is Mercury.
|
||||
@@ -0,0 +1,4 @@
|
||||
title: $:/plugins/tiddlywiki/tour/introduction-to-tiddlywiki/tiddlers/Rocky
|
||||
caption: Rocky
|
||||
|
||||
Rocky planets have a core, a mantle, and a crust. They are a bit like a boiled egg: the central yolk is the core; the white albumin is the mantle; and the shell is the crust. The crust of a terrestrial planet is thin, with the core and the mantle taking up the vast bulk, sometimes with a very large core, sometimes much smaller. Terrestrial planets have metallic cores of mostly iron, with rocky mantles and crusts.
|
||||
@@ -0,0 +1,5 @@
|
||||
title: $:/plugins/tiddlywiki/tour/introduction-to-tiddlywiki/tiddlers/Saturn
|
||||
caption: Saturn
|
||||
tags: $:/plugins/tiddlywiki/tour/introduction-to-tiddlywiki/tiddlers/Planet [[$:/plugins/tiddlywiki/tour/introduction-to-tiddlywiki/tiddlers/Gas Giant]]
|
||||
|
||||
Saturn is the sixth planet from the Sun located in the Solar System. It is the second largest planet in the Solar System, after Jupiter. Saturn is one of the four gas giant planets in the Solar System, along with [[Jupiter|$:/plugins/tiddlywiki/tour/introduction-to-tiddlywiki/tiddlers/Jupiter]], Uranus, and Neptune.
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg width="100%" height="100%" viewBox="0 0 500 335" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;">
|
||||
<g transform="matrix(0.488281,0,0,0.436198,0,0)">
|
||||
<rect id="Artboard1" x="0" y="0" width="1024" height="768" style="fill:none;"/>
|
||||
<clipPath id="_clip1">
|
||||
<rect id="Artboard11" serif:id="Artboard1" x="0" y="0" width="1024" height="768"/>
|
||||
</clipPath>
|
||||
<g clip-path="url(#_clip1)">
|
||||
<g transform="matrix(3.66495,0,0,4.10256,0,0.218772)">
|
||||
<g transform="matrix(1,0,0,1,-59.5095,-391.468)">
|
||||
<path d="M320.725,420.421C326.96,417.788 332.843,414.256 338.913,411.253C338.882,411.406 338.722,411.458 338.626,411.561C328.964,419.375 327.614,432.589 328.751,444.808C329.174,451.149 327.382,458.033 325.167,464.525C321.022,475.102 313.017,486.251 303.726,485.68C300.214,485.568 298.174,483.58 295.563,481.456C295.057,485.757 293.067,489.595 291.148,493.398C286.718,501.831 275.14,505.548 264.419,514.553C253.699,523.558 267.849,555.718 271.28,561.578C274.711,567.439 284.287,569.583 280.571,574.872C279.434,576.618 277.696,577.243 275.838,577.921L273.318,578.249C262.308,577.938 257.466,577.965 251.859,568.744L247.489,568.87C242.402,568.644 244.522,568.746 241.129,568.577C235.455,568.356 236.364,562.965 235.366,560.117C233.769,550.449 237.478,540.73 237.361,531.06C237.32,527.627 232.462,515.476 230.727,511.132C225.287,512.156 219.817,512.351 214.298,512.626C201.576,512.595 188.94,511.037 176.396,509.059C173.952,519.157 166.686,533.291 172.692,543.554C179.982,554.17 185.098,557.111 193.028,557.751C200.957,558.39 202.748,567.343 200.829,570.541C199.131,572.751 196.147,573.152 193.611,573.687L188.539,573.925C184.548,573.791 180.98,572.714 177.424,571.052C171.485,567.736 165.351,560.844 160.793,555.895C161.854,557.871 162.487,561.729 161.525,563.524C158.83,567.341 147.176,567.318 141.839,564.946C135.776,562.252 121.125,543.335 118.86,529.168C124.886,517.772 133.665,507.845 138.106,495.437C128.425,489.26 123.24,479.204 123.913,467.813L124.156,466.494C114.631,468.277 119.57,467.614 109.323,468.389C76.689,468.289 47.99,446.162 64.15,411.773C65.201,409.737 66.201,407.885 67.982,408.77C69.412,409.479 69.207,412.325 68.487,415.481C59.25,456.572 104.396,456.886 132.149,449.282C134.903,448.528 140.381,443.444 144.176,441.759C150.379,439.004 157.111,437.887 163.793,437.082C180.411,435.188 200.384,443.943 210.533,444.228C220.681,444.514 235.118,441.798 243.98,442.37C250.41,442.664 256.724,443.825 262.928,445.478C266.944,425.911 267.228,411.489 276.748,408.151C281.18,408.851 284.806,413.787 287.706,417.829L287.706,423.746C287.706,428.653 295.104,432.636 304.216,432.636C313.328,432.636 320.725,428.653 320.725,423.746L320.725,420.421ZM151.046,554.19L152.645,554.662C154.654,553.763 158.693,555.152 160.836,555.832C156.89,551.458 150.947,545.035 146.664,540.986C145.259,536.084 145.859,531.152 146.161,526.148L146.222,525.734C144.534,529.74 142.391,533.634 141.24,537.85C139.893,543.539 147.228,549.677 150.073,553.194L151.046,554.19Z"/>
|
||||
</g>
|
||||
<g transform="matrix(2.12347,0,0,2.12347,219.225,-7.42467)">
|
||||
<g transform="matrix(1,0,0,0.666667,-0.185118,3.43957)">
|
||||
<path d="M0.667,9.362C0.576,9.293 0.518,9.153 0.518,9C0.518,8.847 0.576,8.707 0.667,8.638C2.756,7.072 10.971,0.911 12.065,0.09C12.14,0.033 12.23,0.033 12.306,0.09C13.399,0.911 21.614,7.072 23.703,8.638C23.794,8.707 23.852,8.847 23.852,9C23.852,9.153 23.794,9.293 23.703,9.362C21.614,10.928 13.399,17.089 12.306,17.91C12.23,17.967 12.14,17.967 12.065,17.91C10.971,17.089 2.756,10.928 0.667,9.362Z"/>
|
||||
</g>
|
||||
<g transform="matrix(1,0,0,1,1.77636e-15,4.43957)">
|
||||
<path d="M18.5,8.75L18.5,13.744C18.5,15.675 15.587,17.244 12,17.244C8.413,17.244 5.5,15.675 5.5,13.744L5.5,8.75L11.951,11.975C11.982,11.991 12.018,11.991 12.049,11.975L18.5,8.75Z"/>
|
||||
</g>
|
||||
<g transform="matrix(1,0,0,0.648293,19.2746,5.5086)">
|
||||
<path d="M2,6L2.207,11L1.526,14C1.526,14 1.524,14.709 2.5,14.717C3.421,14.724 3.5,14 3.5,14L2.707,11L3,6L2,6Z"/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 4.5 KiB |
+2
@@ -0,0 +1,2 @@
|
||||
title: $:/plugins/tiddlywiki/tour/tiddlywiki-tour-logo
|
||||
type: image/svg+xml
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
title: $:/plugins/tiddlywiki/tour/introduction-to-tiddlywiki
|
||||
tags: $:/tags/Tour
|
||||
tour-tag: $:/tags/Tour/IntroductionToTiddlyWiki
|
||||
logo: $:/plugins/tiddlywiki/tour/tiddlywiki-tour-logo
|
||||
description: Introduction to {{$:/config/Tours/IntroductionToTiddlyWiki/ProductName}}
|
||||
settings: $:/plugins/tiddlywiki/tour/introduction-to-tiddlywiki/settings
|
||||
|
||||
An introductory tour to {{$:/config/Tours/IntroductionToTiddlyWiki/ProductName}}
|
||||
@@ -0,0 +1,4 @@
|
||||
title: $:/plugins/tiddlywiki/tour/introduction-to-tiddlywiki/settings
|
||||
|
||||
Customise name used for ~TiddlyWiki: <$edit tiddler="$:/config/Tours/IntroductionToTiddlyWiki/ProductName" tag="input"/>
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
title: $:/plugins/tiddlywiki/tour/introduction-to-tiddlywiki/steps/close-control-panel
|
||||
caption: Close the control panel
|
||||
tags: $:/tags/Tour/IntroductionToTiddlyWiki
|
||||
hint-selector: .tc-story-river div[data-tiddler-title='$:/ControlPanel'] .tc-btn-\%24\%3A\%2Fcore\%2Fui\%2FButtons\%2Fclose
|
||||
step-success-filter: [[$:/StoryList]!contains[$:/ControlPanel]]
|
||||
|
||||
<<tour-task "Now close the control panel">>
|
||||
|
||||
Use the {{$:/core/images/close-button|0.65em}} button in the top right corner of the control panel tiddler.
|
||||
@@ -0,0 +1,25 @@
|
||||
title: $:/plugins/tiddlywiki/tour/introduction-to-tiddlywiki/steps/closing-tiddlers
|
||||
caption: Closing tiddlers
|
||||
tags: $:/tags/Tour/IntroductionToTiddlyWiki
|
||||
display-mode: fullscreen
|
||||
enter-actions: <$action-setfield $tiddler="$:/temp/Tour/DemoStoryList" list="$:/plugins/tiddlywiki/tour/introduction-to-tiddlywiki/tiddlers/Jupiter $:/plugins/tiddlywiki/tour/introduction-to-tiddlywiki/tiddlers/Saturn"/>
|
||||
step-success-filter: [list[$:/temp/Tour/DemoStoryList]count[]match[0]]
|
||||
|
||||
\procedure tour-simplified-tiddler-close-button() yes
|
||||
|
||||
In the top right corner of each tiddler there is a button marked {{$:/core/images/close-button|0.65em}} that can be used to close them when you are finished with them.
|
||||
|
||||
<<tour-task "Close both of these tiddlers">>
|
||||
|
||||
Closing a tiddler does not delete it or alter it in any way. It just removes it from the display.
|
||||
|
||||
<$navigator story="$:/temp/Tour/DemoStoryList" history="$:/temp/Tour/DemoHistoryList" openLinkFromInsideRiver="below">
|
||||
|
||||
<$list
|
||||
filter="[list[$:/temp/Tour/DemoStoryList]]"
|
||||
history="$:/temp/Tour/DemoHistoryList"
|
||||
template="$:/plugins/tiddlywiki/tour/simplified-tiddler"
|
||||
storyview="classic"
|
||||
/>
|
||||
|
||||
</$navigator>
|
||||
@@ -0,0 +1,11 @@
|
||||
title: $:/plugins/tiddlywiki/tour/introduction-to-tiddlywiki/steps/create-tiddler
|
||||
caption: Creating Tiddlers
|
||||
tags: $:/tags/Tour/IntroductionToTiddlyWiki
|
||||
hint-selector: .tc-story-river div[data-tiddler-title="Draft of 'New Tiddler'"] input[value]:not([value="Congratulations"])
|
||||
hint-selector-fallback-1: .tc-story-river div[data-tiddler-title='Draft of \'New Tiddler\''] .tc-btn-\%24\%3A\%2Fcore\%2Fui\%2FButtons\%2Fsave
|
||||
hint-selector-fallback-2: .tc-btn-\%24\%3A\%2Fcore\%2Fui\%2FButtons\%2Fnew-tiddler
|
||||
step-success-filter: [list[$:/StoryList]match[Congratulations]]
|
||||
|
||||
<<tour-task "Create a tiddler titled 'Congratulations'">>
|
||||
|
||||
Use the {{$:/core/images/new-button|0.65em}} button to create the new tiddler, then type correct "title". Finally, click the {{$:/core/images/done-button|0.65em}} button.
|
||||
@@ -0,0 +1,10 @@
|
||||
title: $:/plugins/tiddlywiki/tour/introduction-to-tiddlywiki/steps/end-of-fullscreen
|
||||
caption: Going Deeper
|
||||
tags: $:/tags/Tour/IntroductionToTiddlyWiki
|
||||
display-mode: fullscreen
|
||||
|
||||
Congratulations!
|
||||
|
||||
You have completed the first part of this tour.
|
||||
|
||||
Now we are going guide you through using {{$:/config/Tours/IntroductionToTiddlyWiki/ProductName}}.
|
||||
@@ -0,0 +1,9 @@
|
||||
title: $:/plugins/tiddlywiki/tour/introduction-to-tiddlywiki/steps/finished
|
||||
caption: Congratulations
|
||||
tags: $:/tags/Tour/IntroductionToTiddlyWiki
|
||||
|
||||
You have completed the tour.
|
||||
|
||||
You can choose to take another tour:
|
||||
|
||||
<<tour-chooser filter:"[all[shadows+tiddlers]tag[$:/tags/Tour]] -[<currentTour>]">>
|
||||
@@ -0,0 +1,23 @@
|
||||
title: $:/plugins/tiddlywiki/tour/introduction-to-tiddlywiki/steps/links
|
||||
caption: Linking tiddlers
|
||||
tags: $:/tags/Tour/IntroductionToTiddlyWiki
|
||||
display-mode: fullscreen
|
||||
enter-actions: <$action-setfield $tiddler="$:/temp/Tour/DemoStoryList" list="$:/plugins/tiddlywiki/tour/introduction-to-tiddlywiki/tiddlers/Jupiter"/>
|
||||
step-success-filter: [[$:/temp/Tour/DemoStoryList]contains[$:/plugins/tiddlywiki/tour/introduction-to-tiddlywiki/tiddlers/Saturn]]
|
||||
|
||||
Links allow you to decide if you want more information on a particular area or term as you go.
|
||||
|
||||
<<tour-task "Click the blue link to open the tiddler 'Saturn'">>
|
||||
|
||||
Notice how the new tiddler opens alongside the old one. This allows you to scroll back up to retrace your steps.
|
||||
|
||||
<$navigator story="$:/temp/Tour/DemoStoryList" history="$:/temp/Tour/DemoHistoryList" openLinkFromInsideRiver="below">
|
||||
|
||||
<$list
|
||||
filter="[list[$:/temp/Tour/DemoStoryList]]"
|
||||
history="$:/temp/Tour/DemoHistoryList"
|
||||
template="$:/plugins/tiddlywiki/tour/simplified-tiddler"
|
||||
storyview="classic"
|
||||
/>
|
||||
|
||||
</$navigator>
|
||||
@@ -0,0 +1,9 @@
|
||||
title: $:/plugins/tiddlywiki/tour/introduction-to-tiddlywiki/steps/open-control-panel
|
||||
caption: Open the control panel
|
||||
tags: $:/tags/Tour/IntroductionToTiddlyWiki
|
||||
hint-selector: .tc-btn-\%24\%3A\%2Fcore\%2Fui\%2FButtons\%2Fcontrol-panel
|
||||
step-success-filter: [[$:/StoryList]contains[$:/ControlPanel]]
|
||||
|
||||
<<tour-task "Open the control panel">>
|
||||
|
||||
Click the {{$:/core/images/options-button|0.65em}} icon in the sidebar at the right.
|
||||
@@ -0,0 +1,9 @@
|
||||
title: $:/plugins/tiddlywiki/tour/introduction-to-tiddlywiki/steps/recent
|
||||
caption: Finding recent tiddlers
|
||||
tags: $:/tags/Tour/IntroductionToTiddlyWiki
|
||||
hint-selector: .tc-sidebar-tabs-main .tc-timeline > .tc-menu-list-item:nth-child(1) .tc-menu-list-subitem:nth-child(1) .tc-tiddlylink
|
||||
hint-selector-fallback-1: .tc-sidebar-tabs-main button:nth-child(3)
|
||||
step-success-filter: [list[$:/StoryList]match<step-success-filter-var>]
|
||||
step-success-filter-var: [all[tiddlers]!is[system]!sort[modified]]
|
||||
|
||||
<<tour-task "Use the ''Recent'' tab of the sidebar to open the most recently edited tiddler.">>
|
||||
@@ -0,0 +1,9 @@
|
||||
title: $:/plugins/tiddlywiki/tour/introduction-to-tiddlywiki/steps/search
|
||||
caption: Searching
|
||||
tags: $:/tags/Tour/IntroductionToTiddlyWiki
|
||||
hint-selector: .tc-sidebar-search .tc-popup-handle
|
||||
step-success-filter: [{$:/temp/search}match[help]]
|
||||
|
||||
<<tour-task "Search for the phrase 'help'">>
|
||||
|
||||
Type the phrase into the text box labelled "search" in the sidebar at the right.
|
||||
@@ -0,0 +1,26 @@
|
||||
title: $:/plugins/tiddlywiki/tour/introduction-to-tiddlywiki/steps/tags
|
||||
caption: Tagging tiddlers
|
||||
tags: $:/tags/Tour/IntroductionToTiddlyWiki
|
||||
display-mode: fullscreen
|
||||
enter-actions: <$action-setfield $tiddler="$:/temp/Tour/DemoStoryList" list="$:/plugins/tiddlywiki/tour/introduction-to-tiddlywiki/tiddlers/Mars"/>
|
||||
step-success-filter: [[$:/temp/Tour/DemoStoryList]contains[$:/plugins/tiddlywiki/tour/introduction-to-tiddlywiki/tiddlers/Saturn]]
|
||||
|
||||
Tiddlers may be categorised with one or more descriptive keywords or phrases called "tags". Tags can be used to search and navigate between tiddlers.
|
||||
|
||||
Click on the tag to display a dropdown menu. The menu is divided into two parts:
|
||||
|
||||
* At the top, there is a link to the tiddler with the same title as the tag. This is generally used to describe the tag or give an overview of its purpose
|
||||
* Beneath the link to the tag, there a list of links to the other tiddlers with the same tag
|
||||
|
||||
<<tour-task "Use the tag dropdown to open the tiddler 'Saturn'">>
|
||||
|
||||
<$navigator story="$:/temp/Tour/DemoStoryList" history="$:/temp/Tour/DemoHistoryList" openLinkFromInsideRiver="below">
|
||||
|
||||
<$list
|
||||
filter="[list[$:/temp/Tour/DemoStoryList]]"
|
||||
history="$:/temp/Tour/DemoHistoryList"
|
||||
template="$:/plugins/tiddlywiki/tour/simplified-tiddler-with-tags"
|
||||
storyview="classic"
|
||||
/>
|
||||
|
||||
</$navigator>
|
||||
@@ -0,0 +1,16 @@
|
||||
title: $:/plugins/tiddlywiki/tour/introduction-to-tiddlywiki/steps/tiddlers
|
||||
caption: How does it work?
|
||||
tags: $:/tags/Tour/IntroductionToTiddlyWiki
|
||||
display-mode: fullscreen
|
||||
|
||||
{{$:/config/Tours/IntroductionToTiddlyWiki/ProductName}} lets you collect and organise all kinds of information into interconnected bite-sized pieces called ''tiddlers''.
|
||||
|
||||
A tiddler is like an index card.
|
||||
|
||||
<$let tv-wikilinks="no">
|
||||
|
||||
{{$:/plugins/tiddlywiki/tour/introduction-to-tiddlywiki/tiddlers/Jupiter||$:/plugins/tiddlywiki/tour/simplified-tiddler}}
|
||||
|
||||
</$let>
|
||||
|
||||
Each tiddler must have a unique title that is used to distinguish it.
|
||||
@@ -0,0 +1,10 @@
|
||||
title: $:/plugins/tiddlywiki/tour/introduction-to-tiddlywiki/steps/welcome
|
||||
caption: Welcome
|
||||
tags: $:/tags/Tour/IntroductionToTiddlyWiki
|
||||
display-mode: fullscreen
|
||||
|
||||
!! An interactive tour of {{$:/config/Tours/IntroductionToTiddlyWiki/ProductName}}
|
||||
|
||||
Welcome to this tour of {{$:/config/Tours/IntroductionToTiddlyWiki/ProductName}}.
|
||||
|
||||
We hope you'll find {{$:/config/Tours/IntroductionToTiddlyWiki/ProductName}} a helpful and supportive tool. Let's get started!
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
title: $:/tags/Tour/IntroductionToTiddlyWiki
|
||||
list: $:/plugins/tiddlywiki/tour/introduction-to-tiddlywiki/steps/welcome $:/plugins/tiddlywiki/tour/introduction-to-tiddlywiki/steps/tiddlers $:/plugins/tiddlywiki/tour/introduction-to-tiddlywiki/steps/links $:/plugins/tiddlywiki/tour/introduction-to-tiddlywiki/steps/closing-tiddlers $:/plugins/tiddlywiki/tour/introduction-to-tiddlywiki/steps/tags $:/plugins/tiddlywiki/tour/introduction-to-tiddlywiki/steps/end-of-fullscreen $:/plugins/tiddlywiki/tour/introduction-to-tiddlywiki/steps/open-control-panel $:/plugins/tiddlywiki/tour/introduction-to-tiddlywiki/steps/close-control-panel $:/plugins/tiddlywiki/tour/introduction-to-tiddlywiki/steps/search $:/plugins/tiddlywiki/tour/introduction-to-tiddlywiki/steps/recent $:/plugins/tiddlywiki/tour/introduction-to-tiddlywiki/steps/create-tiddler $:/plugins/tiddlywiki/tour/introduction-to-tiddlywiki/steps/finished
|
||||
@@ -0,0 +1,5 @@
|
||||
title: $:/plugins/tiddlywiki/tour/using-tags/finished
|
||||
caption: Congratulations
|
||||
tags: $:/tags/Tour/UsingTags
|
||||
|
||||
<<tour-chooser filter:"[all[shadows+tiddlers]tag[$:/tags/Tour]] -[<currentTour>]">>
|
||||
@@ -0,0 +1,28 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg width="100%" height="100%" viewBox="0 0 500 335" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;">
|
||||
<g transform="matrix(0.488281,0,0,0.436198,0,0)">
|
||||
<rect id="Artboard1" x="0" y="0" width="1024" height="768" style="fill:none;"/>
|
||||
<clipPath id="_clip1">
|
||||
<rect id="Artboard11" serif:id="Artboard1" x="0" y="0" width="1024" height="768"/>
|
||||
</clipPath>
|
||||
<g clip-path="url(#_clip1)">
|
||||
<g transform="matrix(3.66495,0,0,4.10256,0,0.218772)">
|
||||
<g transform="matrix(1,0,0,1,-59.5095,-391.468)">
|
||||
<path d="M320.725,420.421C326.96,417.788 332.843,414.256 338.913,411.253C338.882,411.406 338.722,411.458 338.626,411.561C328.964,419.375 327.614,432.589 328.751,444.808C329.174,451.149 327.382,458.033 325.167,464.525C321.022,475.102 313.017,486.251 303.726,485.68C300.214,485.568 298.174,483.58 295.563,481.456C295.057,485.757 293.067,489.595 291.148,493.398C286.718,501.831 275.14,505.548 264.419,514.553C253.699,523.558 267.849,555.718 271.28,561.578C274.711,567.439 284.287,569.583 280.571,574.872C279.434,576.618 277.696,577.243 275.838,577.921L273.318,578.249C262.308,577.938 257.466,577.965 251.859,568.744L247.489,568.87C242.402,568.644 244.522,568.746 241.129,568.577C235.455,568.356 236.364,562.965 235.366,560.117C233.769,550.449 237.478,540.73 237.361,531.06C237.32,527.627 232.462,515.476 230.727,511.132C225.287,512.156 219.817,512.351 214.298,512.626C201.576,512.595 188.94,511.037 176.396,509.059C173.952,519.157 166.686,533.291 172.692,543.554C179.982,554.17 185.098,557.111 193.028,557.751C200.957,558.39 202.748,567.343 200.829,570.541C199.131,572.751 196.147,573.152 193.611,573.687L188.539,573.925C184.548,573.791 180.98,572.714 177.424,571.052C171.485,567.736 165.351,560.844 160.793,555.895C161.854,557.871 162.487,561.729 161.525,563.524C158.83,567.341 147.176,567.318 141.839,564.946C135.776,562.252 121.125,543.335 118.86,529.168C124.886,517.772 133.665,507.845 138.106,495.437C128.425,489.26 123.24,479.204 123.913,467.813L124.156,466.494C114.631,468.277 119.57,467.614 109.323,468.389C76.689,468.289 47.99,446.162 64.15,411.773C65.201,409.737 66.201,407.885 67.982,408.77C69.412,409.479 69.207,412.325 68.487,415.481C59.25,456.572 104.396,456.886 132.149,449.282C134.903,448.528 140.381,443.444 144.176,441.759C150.379,439.004 157.111,437.887 163.793,437.082C180.411,435.188 200.384,443.943 210.533,444.228C220.681,444.514 235.118,441.798 243.98,442.37C250.41,442.664 256.724,443.825 262.928,445.478C266.944,425.911 267.228,411.489 276.748,408.151C281.18,408.851 284.806,413.787 287.706,417.829L287.706,423.746C287.706,428.653 295.104,432.636 304.216,432.636C313.328,432.636 320.725,428.653 320.725,423.746L320.725,420.421ZM151.046,554.19L152.645,554.662C154.654,553.763 158.693,555.152 160.836,555.832C156.89,551.458 150.947,545.035 146.664,540.986C145.259,536.084 145.859,531.152 146.161,526.148L146.222,525.734C144.534,529.74 142.391,533.634 141.24,537.85C139.893,543.539 147.228,549.677 150.073,553.194L151.046,554.19Z" fill="red"/>
|
||||
</g>
|
||||
<g transform="matrix(2.12347,0,0,2.12347,219.225,-7.42467)">
|
||||
<g transform="matrix(1,0,0,0.666667,-0.185118,3.43957)">
|
||||
<path d="M0.667,9.362C0.576,9.293 0.518,9.153 0.518,9C0.518,8.847 0.576,8.707 0.667,8.638C2.756,7.072 10.971,0.911 12.065,0.09C12.14,0.033 12.23,0.033 12.306,0.09C13.399,0.911 21.614,7.072 23.703,8.638C23.794,8.707 23.852,8.847 23.852,9C23.852,9.153 23.794,9.293 23.703,9.362C21.614,10.928 13.399,17.089 12.306,17.91C12.23,17.967 12.14,17.967 12.065,17.91C10.971,17.089 2.756,10.928 0.667,9.362Z"/>
|
||||
</g>
|
||||
<g transform="matrix(1,0,0,1,1.77636e-15,4.43957)">
|
||||
<path d="M18.5,8.75L18.5,13.744C18.5,15.675 15.587,17.244 12,17.244C8.413,17.244 5.5,15.675 5.5,13.744L5.5,8.75L11.951,11.975C11.982,11.991 12.018,11.991 12.049,11.975L18.5,8.75Z"/>
|
||||
</g>
|
||||
<g transform="matrix(1,0,0,0.648293,19.2746,5.5086)">
|
||||
<path d="M2,6L2.207,11L1.526,14C1.526,14 1.524,14.709 2.5,14.717C3.421,14.724 3.5,14 3.5,14L2.707,11L3,6L2,6Z"/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 4.5 KiB |
@@ -0,0 +1,2 @@
|
||||
title: $:/plugins/tiddlywiki/tour/tags-tour-logo
|
||||
type: image/svg+xml
|
||||
@@ -0,0 +1,2 @@
|
||||
title: $:/tags/Tour/UsingTags
|
||||
list: $:/plugins/tiddlywiki/tour/using-tags/welcome $:/plugins/tiddlywiki/tour/using-tags/finished
|
||||
@@ -0,0 +1,7 @@
|
||||
title: $:/plugins/tiddlywiki/tour/using-tags
|
||||
tags: $:/tags/Tour
|
||||
tour-tag: $:/tags/Tour/UsingTags
|
||||
logo: $:/plugins/tiddlywiki/tour/tags-tour-logo
|
||||
description: Using Tags in ~TiddlyWiki
|
||||
|
||||
An introduction to using tags in ~TiddlyWiki
|
||||
@@ -0,0 +1,5 @@
|
||||
title: $:/plugins/tiddlywiki/tour/using-tags/welcome
|
||||
caption: Welcome
|
||||
tags: $:/tags/Tour/UsingTags
|
||||
|
||||
!! An introduction to using tags in ~TiddlyWiki
|
||||
@@ -0,0 +1,104 @@
|
||||
title: $:/plugins/tiddlywiki/tour/variables
|
||||
|
||||
\whitespace trim
|
||||
|
||||
<!--
|
||||
|
||||
The following state tiddlers control the tour. They should not be directly modified, but rather use the appropriate procedure to ensure that all the associated actions are performed.
|
||||
|
||||
* $:/config/CurrentTour: title of current tour definition tiddler
|
||||
* $:/state/tour/step: title of current step of the tour
|
||||
|
||||
These config tiddlers may be changed directly as required:
|
||||
|
||||
* $:/config/ShowTour: "show" (default) or "hide"
|
||||
* $:/config/AutoStartTour: "no" (default) or "yes"
|
||||
|
||||
-->
|
||||
|
||||
\function tour-current-tag()
|
||||
[{$:/config/CurrentTour}get[tour-tag]]
|
||||
\end
|
||||
|
||||
\procedure tour-filter-steps-by-condition()
|
||||
[<currentTiddler>has[condition]subfilter{!!condition}limit[1]] :else[<currentTiddler>!has[condition]then[true]]
|
||||
\end
|
||||
|
||||
\function tour-all-steps-filtered-by-condition()
|
||||
[all[shadows+tiddlers]tag<tour-current-tag>filter<tour-filter-steps-by-condition>]
|
||||
\end
|
||||
|
||||
\function tour-is-not-first-step()
|
||||
[function[tour-all-steps-filtered-by-condition]allbefore{$:/state/tour/step}count[]compare:number:gt[0]]
|
||||
\end
|
||||
|
||||
\function tour-is-last-step()
|
||||
[function[tour-all-steps-filtered-by-condition]allafter{$:/state/tour/step}count[]compare:number:eq[0]]
|
||||
\end
|
||||
|
||||
\function tour-is-not-last-step()
|
||||
[function[tour-all-steps-filtered-by-condition]allafter{$:/state/tour/step}count[]compare:number:gt[0]]
|
||||
\end
|
||||
|
||||
|
||||
\procedure tour-initialise-current-tour-step()
|
||||
\procedure tv-action-refresh-policy() always
|
||||
<$transclude $tiddler={{$:/state/tour/step}} $field="enter-actions"/>
|
||||
\end
|
||||
|
||||
\procedure tour-chooser(filter:"[all[shadows+tiddlers]tag[$:/tags/Tour]]")
|
||||
\procedure choose-tour-actions()
|
||||
<$transclude $variable="tour-start" title=<<currentTiddler>>/>
|
||||
\end choose-tour-actions
|
||||
<div class="tc-tour-panel-chooser-wrapper">
|
||||
<$list filter=<<filter>>>
|
||||
<div class="tc-tour-panel-chooser-item">
|
||||
<div class="tc-tour-panel-chooser-item-text">
|
||||
<$transclude $field="description">
|
||||
<$text text=<<currentTiddler>>/>
|
||||
</$transclude>
|
||||
</div>
|
||||
<$button class="tc-btn-invisible tc-tour-panel-chooser-start-button" actions=<<choose-tour-actions>>>
|
||||
start {{$:/core/images/chevron-right}}
|
||||
</$button>
|
||||
</div>
|
||||
</$list>
|
||||
</div>
|
||||
\end tour-chooser
|
||||
|
||||
\procedure tour-start(title,step)
|
||||
\procedure tv-action-refresh-policy() always
|
||||
<$action-setfield $tiddler="$:/config/CurrentTour" text=<<title>>/>
|
||||
<$transclude $variable="tour-restart" step=<<step>>/>
|
||||
\end
|
||||
|
||||
\procedure tour-restart(step)
|
||||
\procedure tv-action-refresh-policy() always
|
||||
<$action-setfield $tiddler="$:/config/ShowTour" text="show"/>
|
||||
<$action-setfield $tiddler="$:/state/tour/step" $field="text" $value={{{ [<step>!is[blank]] :else[function[tour-all-steps-filtered-by-condition]first[]] }}}/>
|
||||
<<tour-initialise-current-tour-step>>
|
||||
\end
|
||||
|
||||
\procedure tour-next-step()
|
||||
\procedure tv-action-refresh-policy() always
|
||||
<$action-setfield $tiddler="$:/state/tour/step" $field="text" $value={{{ [function[tour-all-steps-filtered-by-condition]allafter{$:/state/tour/step}else[$:/plugins/tiddlywiki/tour/introduction-to-tiddlywiki/steps/finished]] }}}/>
|
||||
<<tour-initialise-current-tour-step>>
|
||||
\end
|
||||
|
||||
\procedure tour-previous-step()
|
||||
\procedure tv-action-refresh-policy() always
|
||||
<$action-setfield $tiddler="$:/state/tour/step" $field="text" $value={{{ [function[tour-all-steps-filtered-by-condition]allbefore{$:/state/tour/step}last[]] :else[all[shadows+tiddlers]tag<tour-current-tag>first[]] }}}/>
|
||||
<<tour-initialise-current-tour-step>>
|
||||
\end
|
||||
|
||||
\procedure tour-display-current-tour()
|
||||
<$transclude $tiddler={{$:/config/CurrentTour}} $field="description">
|
||||
<$text text={{$:/config/CurrentTour}}/>
|
||||
</$transclude>
|
||||
\end
|
||||
|
||||
\procedure tour-task(text)
|
||||
<div class="tc-tour-task">
|
||||
{{$:/core/images/help}} <$transclude $variable="text" $mode="inline"/>
|
||||
</div>
|
||||
\end
|
||||
Reference in New Issue
Block a user