30
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

クソアプリ2Advent Calendar 2019

Day 5

ソースコード共有サービス emoscode (エモすこ)のせわしない新機能

Last updated at Posted at 2019-12-04

先日 emoscode(エモすこ) というWebサービスをリリースしました。詳しくはひとり開発アドベントカレンダーに投稿した12/4の記事をご覧ください。

お気づきの方もおられると思いますが、このサービス、コメントの数が増えてくると重大な問題が発生しています。そう、「コメントに隠れてソースコードが見辛い」というものです。当初のGUIではそれぞれのコメントをドラッグ移動で動かしてやらないと、その下に隠れているコードを見る事ができませんでした。

このたび、これを解決する画期的な新機能をリリースいたしました。それではご覧ください。

emoscode201911205-2.gif

一気にせわしなくなりましたね! 師走だけに!

コメントの物理っぽい挙動はこんな感じのコードになっています。
これを requestAnimationFrame() に設定した関数から呼び出しています。

caption.ts

export class Caption
{
        :
    updatePosition(): void {
        if (this.arrow == null) return;
        if (draggingArrow == this.idComment) return;
        if (this.isEditing) return;
        const posCaption = this.getRect().getCenter();
        const velocityTick = this.velocity.getScaled(timeElapsedSecond);
        const posCaptionNext = posCaption.getAdded(velocityTick);
        const posMarker = this.arrow.rectText.getCenter();
        const vecNext = posMarker.getSubtracted(posCaptionNext);
        const lengthNext = vecNext.getLength();
        const unitVecNext = vecNext.getNormalized();
        const initLength = this.arrow.initLength;
        const magnitudeToModify = (lengthNext - initLength) * 0.1;
        const velocityTickNext = velocityTick.getAdded(unitVecNext.getScaled(magnitudeToModify));
        this.velocity = velocityTickNext.getScaled(1.0 / timeElapsedSecond);        
        this.setLeftTopPosition(this.x + velocityTickNext.x, this.y + velocityTickNext.y);
    }
        :
}

上記コードで使用している2次元ベクトル・矩形クラスは以下のようなコードになっています。当初出来合いのライブラリを探したのですが Javascript/Typescript で目的に沿うシンプルなものが見当たらず、結局自作しました。

rect.ts
export class Vector2
{
	x: number = 0.0;
	y: number = 0.0;

	constructor(x: number, y: number)
	{
		this.x = x;
		this.y = y;
	}

	setX(x: number): void
	{
		this.x = x;
	}

	setY(y: number): void
	{
		this.y = y;
	}
	
	w(): number
	{
		return this.x;
	}
	
	h(): number
	{
		return this.y;
	}
	
	clone(): Vector2
	{
		return new Vector2(this.x, this.y);
	}
	
	getSquaredLength(): number
	{
		return this.x * this.x + this.y * this.y;
	}

	getLength(): number
	{
		return Math.sqrt(this.getSquaredLength());
	}

	scale(s: number): void
	{
		this.x *= s;
		this.y *= s;
	}
	
	getScaled(s: number): Vector2
	{
		let ret = this.clone();
		ret.scale(s);
		return ret;
	}
	
	add(vec: Vector2): void
	{
		this.x += vec.x;
		this.y += vec.y;
	}

	getAdded(vec: Vector2): Vector2
	{
		let ret = this.clone();
		ret.add(vec);
		return ret;
	}
	
	subtract(vec: Vector2): void
	{
		this.x -= vec.x;
		this.y -= vec.y;
	}
	
	getSubtracted(vec: Vector2): Vector2
	{
		let ret = this.clone();
		ret.subtract(vec);
		return ret;
	}
	
	normalize(): void
	{
		let length = this.getLength();
		let inversedLength = 1.0 / length;
		this.scale(inversedLength);
	}
	
	getNormalized(): Vector2
	{
		let ret = this.clone();
		ret.normalize();
		return ret;
	}
	
	getPerpendicular(): Vector2
	{
		return new Vector2(this.y, -this.x);
	}		
}

export class Rect2
{
	posLeftTop: Vector2;
	size: Vector2;
	constructor(posLeftTop: Vector2, size: Vector2)
	{
		this.posLeftTop = posLeftTop;
		this.size = size;
	}
	
	getCenter(): Vector2
	{
		return this.posLeftTop.getAdded(this.size.getScaled(0.5));
	}
	
	setPosition(posLeftTop: Vector2): void
	{
		this.posLeftTop = posLeftTop;
	}
	
	getNearestX(x: number): number
	{
		let distanceXLeft = Math.abs(x - this.posLeftTop.x);
		let rightX = this.posLeftTop.x + this.size.w();
		let distanceXRight = Math.abs(x - rightX);
		return distanceXLeft < distanceXRight ? this.posLeftTop.x : rightX;
	}

	getNearestY(y: number): number
	{
		let distanceYTop = Math.abs(y - this.posLeftTop.y);
		let bottomY = this.posLeftTop.y + this.size.h();
		let distanceYBottom = Math.abs(y - bottomY);
		return distanceYTop < distanceYBottom ? this.posLeftTop.y : bottomY;
	}
}

以上となります!

30
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
30
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?