stickers: text editing

This commit is contained in:
muerwre 2018-12-05 16:00:37 +07:00
parent fa9bff5756
commit f183c8593d
6 changed files with 130 additions and 21 deletions

View file

@ -9,7 +9,7 @@ module.exports.parseRoute = route => route.filter(el => (
));
module.exports.parseStickers = stickers => stickers.filter(el => (
Object.keys(el).length === 3
Object.keys(el).length === 4
&& el.latlng
&& Object.keys(el.latlng).length === 2
&& el.latlng.lat
@ -19,6 +19,7 @@ module.exports.parseStickers = stickers => stickers.filter(el => (
&& parseInt(el.latlng.lng, 10) > 0
&& parseInt(el.latlng.lng, 10) < 1000
));
// .map(el => ((el.text && String(el.text).substr(0, 100)) || ''));
module.exports.parseString = (value, size) => (value && String(value).substr(0, size)) || '';
module.exports.parseNumber = (value, min, max) => (value && Number(value) && Math.min(max, Math.max(min, value))) || 0;

View file

@ -0,0 +1,44 @@
import React from 'react';
type State = {
text: String,
}
export class StickerDesc extends React.PureComponent<void, State> {
state = {
text: this.props.value,
};
setText = e => {
this.setState({ text: e.target.value });
this.props.onChange(e.target.value);
};
blockMouse = e => e.stopPropagation(); // todo: pass here locker for moving markers from Sticker.js
render() {
const { text } = this.state;
return (
<div
className="sticker-desc"
onMouseDown={this.blockMouse}
onMouseUp={this.blockMouse}
>
<div className="sticker-desc-sizer">
<span
dangerouslySetInnerHTML={{
__html: (text.replace(/\n$/, '\n&nbsp;').replace(/\n/g, '<br />') || '&nbsp;')
}}
/>
<textarea
onChange={this.setText}
value={text}
onMouseDown={this.blockMouse}
onDragStart={this.blockMouse}
/>
</div>
</div>
)
}
}

View file

@ -6,7 +6,7 @@ import { Router } from '$modules/Router';
import { DEFAULT_LOGO } from '$constants/logos';
import { parseStickerAngle, parseStickerStyle } from '$utils/import';
import { getUrlData, pushPath } from '$utils/history';
import { getUrlData } from '$utils/history';
import { store } from '$redux/store';
import {
resetSaveDialog,
@ -236,6 +236,7 @@ export class Editor {
latlng: sticker.latlng,
angle: parseStickerAngle({ sticker, version }),
sticker: parseStickerStyle({ sticker, version }),
text: sticker.text,
}));
}

View file

@ -5,11 +5,14 @@ import { DomMarker } from '$utils/DomMarker';
import { STICKERS } from '$constants/stickers';
import ReactDOM from 'react-dom';
import { StickerDesc } from '$components/StickerDesc';
import classnames from 'classnames';
export class Sticker {
constructor({
latlng, deleteSticker, map, lockMapClicks, sticker, triggerOnChange, angle = 2.2
latlng, deleteSticker, map, lockMapClicks, sticker, triggerOnChange, angle = 2.2, text = '',
}) {
this.text = text;
this.latlng = latlng;
this.angle = angle;
this.isDragging = false;
@ -17,7 +20,7 @@ export class Sticker {
this.sticker = sticker;
this.editable = true;
this.triggerOnChange = triggerOnChange;
this.direction = 'right';
this.deleteSticker = deleteSticker;
this.lockMapClicks = lockMapClicks;
@ -29,11 +32,12 @@ export class Sticker {
ref={el => { this.stickerArrow = el; }}
/>
<div
className="sticker-label"
className={classnames('sticker-label', {})}
ref={el => { this.stickerImage = el; }}
onMouseDown={this.onDragStart}
onMouseUp={this.onDragStop}
>
<StickerDesc value={this.text} onChange={this.setText} />
{this.generateStickerSVG(sticker)}
<div
className="sticker-delete"
@ -80,13 +84,16 @@ export class Sticker {
this.triggerOnChange();
}
setText = text => {
this.text = text;
};
onDelete = () => {
this.triggerOnChange();
if (!this.isDragging) this.deleteSticker(this);
};
onDragStart = e => {
console.log('drag start');
this.preventPropagations(e);
this.isDragging = true;
@ -132,13 +139,20 @@ export class Sticker {
};
setAngle = angle => {
const rad = 56;
const mrad = 76;
const x = ((Math.cos(angle + 3.14) * rad) - 30);
const y = ((Math.sin(angle + 3.14) * rad) - 30);
const direction = (angle > -(Math.PI / 2) && angle < (Math.PI / 2)) ? 'left' : 'right';
const ax = ((Math.cos(angle + 3.4) * mrad) - 12);
const ay = ((Math.sin(angle + 3.4) * mrad) - 12);
if (direction !== this.direction) {
this.direction = direction;
this.stickerImage.className = `sticker-label ${direction}`;
}
const rad = 56;
// const mrad = 76;
const x = ((Math.cos(angle + Math.PI) * rad) - 30);
const y = ((Math.sin(angle + Math.PI) * rad) - 30);
// const ax = ((Math.cos(angle + 3.4) * mrad) - 12);
// const ay = ((Math.sin(angle + 3.4) * mrad) - 12);
this.stickerImage.style.left = 6 + x;
this.stickerImage.style.top = 6 + y;
@ -146,7 +160,7 @@ export class Sticker {
// this.stickerDelete.style.left = ax;
// this.stickerDelete.style.top = ay;
this.stickerArrow.style.transform = `rotate(${angle + 3.14}rad)`;
this.stickerArrow.style.transform = `rotate(${angle + Math.PI}rad)`;
};
generateStickerSVG = ({ set, sticker }) => (
@ -163,6 +177,7 @@ export class Sticker {
angle: this.angle,
latlng: { ...this.marker.getLatLng() },
sticker: this.sticker,
text: this.text,
});
stopEditing = () => {

View file

@ -20,7 +20,7 @@ export class Stickers {
// this.createSticker({ latlng });
// };
createSticker = ({ latlng, sticker, angle = 2.2 }) => {
createSticker = ({ latlng, sticker, angle = 2.2, text = '' }) => {
const marker = new Sticker({
latlng,
angle,
@ -29,6 +29,7 @@ export class Stickers {
lockMapClicks: this.lockMapClicks,
sticker,
triggerOnChange: this.triggerOnChange,
text,
});
this.stickers.push(marker);

View file

@ -19,7 +19,7 @@
position: absolute;
border-radius: 40px;
opacity: 0.25;
transform: scale(0.6);
transform: scale(0.5);
transition: opacity 250ms, transform 500ms;
}
@ -69,8 +69,8 @@
//}
svg {
left: -12px;
top: -12px;
left: -8px;
top: -8px;
position: relative;
z-index: 0;
}
@ -78,12 +78,20 @@
.sticker-image {
width: 72px;
height: 72px;
left: -8px;
top: -8px;
left: -12px;
top: -12px;
position: relative;
z-index: 0;
background-size: cover;
}
&.left {
.sticker-desc {
padding: 10px 36px 10px 10px;
left: auto;
right: 24px;
}
}
}
.sticker-arrow {
@ -116,8 +124,8 @@
transform: scale(1);
opacity: 1;
pointer-events: all;
left: 42px;
top: 0;
left: 28px;
top: -16px;
z-index: 20;
&:hover {
@ -151,3 +159,42 @@
z-index: 2;
}
}
.sticker-desc {
min-width: 60px;
height: auto;
background: #222222;
position: absolute;
top: 50%;
left: 24px;
transform: translate3d(0, -50%, 0);
color: white;
box-sizing: border-box;
padding: 10px 10px 10px 36px;
}
.sticker-desc-sizer {
position: relative;
width: 100%;
height: 100%;
color: rgba(0,0,0,0);
white-space: nowrap;
padding: 1px;
textarea {
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
font: inherit;
padding: 0;
border: none;
background: none;
color: white;
resize: none;
outline: none;
overflow: hidden;
}
}