Skip to content

Commit

Permalink
feat: add cursor avatar to cursor and resize on zoom level
Browse files Browse the repository at this point in the history
  • Loading branch information
Ramiro Sanchez Balo authored and rsanchezbalo committed Dec 16, 2024
1 parent 8f1b6dd commit 5ae10b4
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,11 @@
height: 0;
pointer-events: none;
position: absolute;
transform-origin: top left;
width: 0;
z-index: var(--board-tools-layer);


span {
background-color: var(--primary-color);
border-radius: 4px;
Expand All @@ -22,11 +24,22 @@
pointer-events: none;
position: absolute;
top: -5px;
transform-origin: top left;
width: 24px;
z-index: var(--board-tools-layer);
}

.cursor-avatar {
border: 2px solid var(--primary-color);
border-radius: 100%;
overflow: hidden;
top: -6px;
left: 4px;
}

}

.icon-svg {
fill: var(--black);
}

Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,15 @@ import {
ChangeDetectionStrategy,
inject,
computed,
effect,
signal,
} from '@angular/core';

import { BoardFacade } from '../../../../services/board-facade.service';
import { toSignal } from '@angular/core/rxjs-interop';
import { Store } from '@ngrx/store';
import { pageFeature } from '../../reducers/page.reducer';
import { CommonModule } from '@angular/common';

@Component({
selector: 'tapiz-cursors',
Expand All @@ -16,22 +21,35 @@ import { toSignal } from '@angular/core/rxjs-interop';
@if (user.cursor) {
<div
class="cursor"
[style.transform]="'scale(' + scale() + ')'"
[style.top.px]="user.cursor.y"
[style.left.px]="user.cursor.x">
<span>{{ user.name.charAt(0).toUpperCase() }}</span>
<span
[ngClass]="{'cursor-avatar': user.picture}"
[style.transform]="'scale(' + scale() + ')'">
@if (user.picture) {
<img [src]="user.picture" alt="{{ user.name }}" />
} @else {
{{ user.name.charAt(0).toUpperCase() }}
}
</span>
</div>
}
}
}
`,
styleUrls: ['./cursors.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush,
imports: [],
imports: [CommonModule],
})
export class CursorsComponent {
#store = inject(Store);
#boardFacade = inject(BoardFacade);

users = toSignal(this.#boardFacade.selectCursors());
userZoom = this.#store.selectSignal(pageFeature.selectZoom);

scale = signal(1);
#settings = toSignal(this.#boardFacade.getSettings());

showCursors = computed(() => {
Expand All @@ -40,7 +58,22 @@ export class CursorsComponent {
if (!settings) {
return true;
}

return !settings.content.anonymousMode;
});

// Calculate the scale of the cursor based on the user's zoom level
calcScale = computed(() => {
const zoom = Math.max(this.userZoom(), 0.1);
const constant = 0.3;
const baseSize = 0.8;
const total = baseSize + (constant / zoom);

return Math.min(total, 2.5);
});

constructor() {
effect(() => {
this.scale.set(this.calcScale());
});
}
}
13 changes: 9 additions & 4 deletions apps/web/src/app/services/board-facade.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,20 +90,25 @@ export class BoardFacade {
map((nodes) => nodes.find((it) => it.id === id)),
);
}

selectCursors() {
return this.getUsers().pipe(
concatLatestFrom(() => this.store.select(pageFeature.selectUserId)),
map(([users, currentUser]) => {
concatLatestFrom(() => [this.store.select(pageFeature.selectUserId), this.store.select(pageFeature.selectBoardUsers)]),
map(([users, currentUser, boardUsers]) => {
console.log('users board facade', users);
return users.filter((user) => {
return (
!!user.content.cursor &&
user.content.connected &&
user.id !== currentUser
);
}).map((user) => {
const boardUser = boardUsers.find((bu) => bu.id === user.id);
return {
...user.content,
picture: boardUser?.picture
};
});
}),
map((nodes) => nodes.map((it) => it.content)),
);
}

Expand Down

0 comments on commit 5ae10b4

Please sign in to comment.