client/home: show post notes (read-only)
This commit is contained in:
parent
53fd6fb29b
commit
9b0c2012a7
4 changed files with 114 additions and 0 deletions
|
@ -32,3 +32,8 @@ $new-tag-text-color = black
|
||||||
$default-tag-category-background-color = $active-tab-background-color
|
$default-tag-category-background-color = $active-tab-background-color
|
||||||
$duplicate-tag-background-color = #FDC
|
$duplicate-tag-background-color = #FDC
|
||||||
$duplicate-tag-text-color = black
|
$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
|
||||||
|
|
|
@ -27,3 +27,27 @@
|
||||||
bottom: 0
|
bottom: 0
|
||||||
width: 100%
|
width: 100%
|
||||||
height: 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
|
||||||
|
|
79
client/js/controls/post_notes_overlay_control.js
Normal file
79
client/js/controls/post_notes_overlay_control.js
Normal file
|
@ -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;
|
|
@ -5,6 +5,8 @@ const config = require('../config.js');
|
||||||
const misc = require('../util/misc.js');
|
const misc = require('../util/misc.js');
|
||||||
const views = require('../util/views.js');
|
const views = require('../util/views.js');
|
||||||
const PostContentControl = require('../controls/post_content_control.js');
|
const PostContentControl = require('../controls/post_content_control.js');
|
||||||
|
const PostNotesOverlayControl
|
||||||
|
= require('../controls/post_notes_overlay_control.js');
|
||||||
const TagAutoCompleteControl =
|
const TagAutoCompleteControl =
|
||||||
require('../controls/tag_auto_complete_control.js');
|
require('../controls/tag_auto_complete_control.js');
|
||||||
|
|
||||||
|
@ -49,6 +51,10 @@ class HomeView {
|
||||||
window.innerHeight * 0.7,
|
window.innerHeight * 0.7,
|
||||||
];
|
];
|
||||||
});
|
});
|
||||||
|
|
||||||
|
new PostNotesOverlayControl(
|
||||||
|
postContainerNode.querySelector('.post-overlay'),
|
||||||
|
ctx.featuredPost);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue