aboutsummaryrefslogtreecommitdiff
path: root/client
diff options
context:
space:
mode:
authorrr-2016-05-29 12:29:24 +0200
committerrr-2016-05-29 12:41:22 +0200
commit9b0c2012a7798510f1350310c9de2449f16a3ef1 (patch)
tree4d856499ad97c8816d1bb95328943eb2dfce94aa /client
parent53fd6fb29bb489c112a87c5effaf6c650a1e5fba (diff)
client/home: show post notes (read-only)
Diffstat (limited to 'client')
-rw-r--r--client/css/colors.styl5
-rw-r--r--client/css/posts.styl24
-rw-r--r--client/js/controls/post_notes_overlay_control.js79
-rw-r--r--client/js/views/home_view.js6
4 files changed, 114 insertions, 0 deletions
diff --git a/client/css/colors.styl b/client/css/colors.styl
index d49033a..b4b2756 100644
--- a/client/css/colors.styl
+++ b/client/css/colors.styl
@@ -32,3 +32,8 @@ $new-tag-text-color = black
$default-tag-category-background-color = $active-tab-background-color
$duplicate-tag-background-color = #FDC
$duplicate-tag-text-color = black
+$note-overlay-background-color = rgba(255, 255, 255, 0.3)
+$note-overlay-border-color = rgba(0, 0, 0, 0.3)
+$note-text-background-color = lemonchiffon
+$note-text-border-color = black
+$note-text-text-color = black
diff --git a/client/css/posts.styl b/client/css/posts.styl
index 3ea0f8b..38123ca 100644
--- a/client/css/posts.styl
+++ b/client/css/posts.styl
@@ -27,3 +27,27 @@
bottom: 0
width: 100%
height: 100%
+
+ .notes
+ stroke-width: 1px
+ polygon
+ fill: $note-overlay-background-color
+ stroke: $note-overlay-border-color
+
+.note-text
+ position: absolute
+ max-width: 22.5em
+ margin-top: -0.5em
+ display: none
+
+ &>.wrapper
+ background: $note-text-background-color
+ padding: 0.5em
+ border: 1px solid $note-text-border-color
+ color: $note-text-text-color
+ margin-top: 1em
+
+ p:last-of-type
+ margin-bottom: 0
+ p:first-of-type
+ margin-top: 0
diff --git a/client/js/controls/post_notes_overlay_control.js b/client/js/controls/post_notes_overlay_control.js
new file mode 100644
index 0000000..945dab4
--- /dev/null
+++ b/client/js/controls/post_notes_overlay_control.js
@@ -0,0 +1,79 @@
+'use strict';
+
+const views = require('../util/views.js');
+const misc = require('../util/misc.js');
+const svgNS = 'http://www.w3.org/2000/svg';
+
+class PostNotesOverlayControl {
+ constructor(postOverlayNode, post) {
+ this._post = post;
+ this._postOverlayNode = postOverlayNode;
+ this._install();
+ }
+
+ _evtMouseEnter(e) {
+ const bodyRect = document.body.getBoundingClientRect();
+ const svgRect = this._svgNode.getBoundingClientRect();
+ const polygonRect = e.target.getBBox();
+ this._textNode.querySelector('.wrapper').innerHTML
+ = misc.formatMarkdown(e.target.getAttribute('data-text'));
+ this._textNode.style.left = (
+ svgRect.left + svgRect.width * polygonRect.x) + 'px';
+ this._textNode.style.top = (
+ svgRect.top + svgRect.height * (
+ polygonRect.y + polygonRect.height)) + 'px';
+ this._textNode.style.display = 'block';
+ }
+
+ _evtMouseLeave(e) {
+ const newElement = e.relatedTarget;
+ if (newElement === this._svgNode ||
+ (!this._svgNode.contains(newElement)
+ && !this._textNode.contains(newElement)
+ && newElement !== this._textNode)) {
+ this._textNode.style.display = 'none';
+ }
+ }
+
+ _install() {
+ this._svgNode = document.createElementNS(svgNS, 'svg');
+ this._svgNode.classList.add('notes');
+ this._svgNode.setAttribute('preserveAspectRatio', 'none');
+ this._svgNode.setAttribute('viewBox', '0 0 1 1');
+ for (let note of this._post.notes) {
+ const polygonNode = document.createElementNS(svgNS, 'polygon');
+ polygonNode.setAttribute(
+ 'vector-effect', 'non-scaling-stroke');
+ polygonNode.setAttribute(
+ 'stroke-alignment', 'inside');
+ polygonNode.setAttribute(
+ 'points', note.polygon.map(point => point.join(',')).join(' '));
+ polygonNode.setAttribute('data-text', note.text);
+ polygonNode.addEventListener(
+ 'mouseenter', e => this._evtMouseEnter(e));
+ polygonNode.addEventListener(
+ 'mouseleave', e => this._evtMouseLeave(e));
+ this._svgNode.appendChild(polygonNode);
+ }
+ this._postOverlayNode.appendChild(this._svgNode);
+
+ const wrapperNode = document.createElement('div');
+ wrapperNode.classList.add('wrapper');
+ this._textNode = document.createElement('div');
+ this._textNode.classList.add('note-text');
+ this._textNode.appendChild(wrapperNode);
+ this._textNode.addEventListener(
+ 'mouseleave', e => this._evtMouseLeave(e));
+ document.body.appendChild(this._textNode);
+
+ views.monitorNodeRemoval(
+ this._postOverlayNode, () => { this._uninstall(); });
+ }
+
+ _uninstall() {
+ this._postOverlayNode.removeChild(this._svgNode);
+ document.body.removeChild(this._textNode);
+ }
+};
+
+module.exports = PostNotesOverlayControl;
diff --git a/client/js/views/home_view.js b/client/js/views/home_view.js
index 1cf81cf..7b20f3b 100644
--- a/client/js/views/home_view.js
+++ b/client/js/views/home_view.js
@@ -5,6 +5,8 @@ const config = require('../config.js');
const misc = require('../util/misc.js');
const views = require('../util/views.js');
const PostContentControl = require('../controls/post_content_control.js');
+const PostNotesOverlayControl
+ = require('../controls/post_notes_overlay_control.js');
const TagAutoCompleteControl =
require('../controls/tag_auto_complete_control.js');
@@ -49,6 +51,10 @@ class HomeView {
window.innerHeight * 0.7,
];
});
+
+ new PostNotesOverlayControl(
+ postContainerNode.querySelector('.post-overlay'),
+ ctx.featuredPost);
}
}
}

© 2015 - 2026 Jakob L. Kreuze