diff --git a/src/client/canvas.ts b/src/client/canvas.ts index c393445..b2bb8a7 100644 --- a/src/client/canvas.ts +++ b/src/client/canvas.ts @@ -39,6 +39,8 @@ export class ViewCanvas { private _screencursory = 0; private _dragging = false; + private _pinching = false; + private _previousPinchLength = 0; constructor() {} @@ -102,12 +104,12 @@ export class ViewCanvas { this._wrapper.append(this.picker.element); document.body.append(this._wrapper); - this._wrapper.addEventListener('pointermove', (ev: MouseEvent) => { + const dragEvent = (x: number, y: number) => { const currentX = this._mousex; const currentY = this._mousey; - this._mousex = ev.clientX; - this._mousey = ev.clientY; + this._mousex = x; + this._mousey = y; const offsetX = currentX - this._mousex; const offsetY = currentY - this._mousey; @@ -128,7 +130,11 @@ export class ViewCanvas { this.moveCanvas(); this.moveCursor(); } - }); + }; + + this._wrapper.addEventListener('mousemove', (ev: MouseEvent) => + dragEvent(ev.clientX, ev.clientY), + ); this._wrapper.addEventListener('mousedown', (ev: MouseEvent) => { this._mousex = ev.clientX; @@ -145,10 +151,42 @@ export class ViewCanvas { this._mousex = touch.pageX; this._mousey = touch.pageY; this._dragging = true; + + if (ev.touches.length === 2) { + this._pinching = true; + } + }); + + this._wrapper.addEventListener('touchmove', (ev: TouchEvent) => { + ev.preventDefault(); + + if (ev.touches.length === 2 && this._pinching) { + const pinchScale = Math.hypot( + ev.touches[0].pageX - ev.touches[1].pageX, + ev.touches[0].pageY - ev.touches[1].pageY, + ); + + if (this._previousPinchLength) { + const delta = pinchScale / this._previousPinchLength; + const scaleX = (ev.touches[0].clientX - this._posx) / this._zoom; + const scaleY = (ev.touches[0].clientY - this._posy) / this._zoom; + + delta > 0 ? (this._zoom *= delta) : (this._zoom /= delta); + this._zoom = clamp(this._zoom, 1, 100); + + this._posx = ev.touches[0].clientX - scaleX * this._zoom; + this._posy = ev.touches[0].clientY - scaleY * this._zoom; + } + this._previousPinchLength = pinchScale; + } + + dragEvent(ev.touches[0].clientX, ev.touches[0].clientY); }); this._wrapper.addEventListener('touchend', (ev: TouchEvent) => { this._dragging = false; + this._pinching = false; + this._previousPinchLength = 0; }); this._wrapper.addEventListener('pointerleave', (ev: MouseEvent) => { diff --git a/src/server/index.ts b/src/server/index.ts index 1a4db2f..9520a63 100644 --- a/src/server/index.ts +++ b/src/server/index.ts @@ -174,7 +174,7 @@ setInterval(() => { /// canvas.initialize().then(() => - server.listen(config.server.port, 'localhost', () => { + server.listen(config.server.port, '0.0.0.0', () => { console.log(`Listening at http://localhost:${config.server.port}/`); }), ); diff --git a/webpack.config.js b/webpack.config.js index 27be07e..dc3daca 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -25,7 +25,9 @@ module.exports = { resolve: { extensions: ['.ts', '.js'], }, - plugins: [new HtmlWebpackPlugin(), new MiniCssExtractPlugin()], + plugins: [new HtmlWebpackPlugin({ + title: 'IcyDraw canvas - Draw together!' + }), new MiniCssExtractPlugin()], output: { path: path.resolve(__dirname, 'dist', 'public'), filename: 'bundle.js',