Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
170 changes: 111 additions & 59 deletions src/app/components/fabric-post/fabric-post.component.ts
Original file line number Diff line number Diff line change
@@ -1,117 +1,157 @@
import { Component, Inject } from '@angular/core';
import { fabric } from 'fabric';
import { POST_DEFAULT_BORDER, POST_DEFAULT_BORDER_THICKNESS } from 'src/app/utils/constants';
import {
POST_DEFAULT_BORDER,
POST_DEFAULT_BORDER_THICKNESS,
} from 'src/app/utils/constants';
import { FabricUtils } from 'src/app/utils/FabricUtils';

const AUTHOR_OFFSET = 65
const DESC_OFFSET = 80
const CONTENT_EXTRA_HEIGHT = 55
const AUTHOR_OFFSET = 65;
const DESC_OFFSET = 80;
const CONTENT_EXTRA_HEIGHT = 55;

@Component({
selector: 'app-fabric-post',
templateUrl: './fabric-post.component.html',
styleUrls: ['./fabric-post.component.scss']
styleUrls: ['./fabric-post.component.scss'],
})
export class FabricPostComponent extends fabric.Group {
constructor(
@Inject(Object) options: any,
) {
var fabricUtils: FabricUtils = new FabricUtils();
var title = new fabric.Textbox(
fabricUtils.wrapCanvasText(options.title, 140, 0),
{
name: 'title',
width: 280,
left: 18,
top: 60,
fontSize: 18,
fontWeight: 'bold',
fontFamily: 'Helvetica',
fill: '#000000',
splitByGrapheme: true,
}
);

constructor(@Inject(Object) options:any) {
var title = new fabric.Textbox(options.title, {
name: 'title',
width: 280,
left: 18,
top: 60,
fontSize: 18,
fontWeight: 'bold',
fontFamily: 'Helvetica',
fill: '#000000',
splitByGrapheme: true
});

var author = new fabric.Textbox(options.author, {
name: 'author',
width: 300,
left: 18,
top: title.getScaledHeight() + AUTHOR_OFFSET,
fontSize: 13,
fontFamily: 'Helvetica',
fill: '#555555',
splitByGrapheme: true,
});
var author = new fabric.Textbox(
fabricUtils.wrapCanvasText(options.author, 200, 0),
{
name: 'author',
width: 300,
left: 18,
top: title.getScaledHeight() + AUTHOR_OFFSET,
fontSize: 13,
fontFamily: 'Helvetica',
fill: '#555555',
splitByGrapheme: true,
}
);

var desc = new fabric.Textbox(options.desc.length > 200 ? options.desc.substr(0, 200) + '...' : options.desc, {
name: 'desc',
width: 300,
left: 18,
top: author.getScaledHeight() + title.getScaledHeight() + DESC_OFFSET,
fontSize: 15,
fontFamily: 'Helvetica',
fill: '#000000',
splitByGrapheme: true
});
var desc = new fabric.Textbox(
fabricUtils.wrapCanvasText(
options.desc.length > 200
? options.desc.substr(0, 200) + '...'
: options.desc,
200,
0
),
{
name: 'desc',
width: 300,
left: 18,
top: author.getScaledHeight() + title.getScaledHeight() + DESC_OFFSET,
fontSize: 15,
fontFamily: 'Helvetica',
fill: '#000000',
splitByGrapheme: true,
}
);

var commentButton = new fabric.Textbox('💬', {
name: 'comment',
width: 55,
top: title.getScaledHeight() + author.getScaledHeight() + desc.getScaledHeight() + 90,
left: 170 ,
top:
title.getScaledHeight() +
author.getScaledHeight() +
desc.getScaledHeight() +
90,
left: 170,
fontSize: 20,
fontFamily: 'Helvetica',
fill: '#000000',
splitByGrapheme: true,
opacity:0
opacity: 0,
});

var commentCount = new fabric.Textbox('0', {
name: 'commentCount',
width: 55,
top: title.getScaledHeight() + author.getScaledHeight() + desc.getScaledHeight() + 90,
top:
title.getScaledHeight() +
author.getScaledHeight() +
desc.getScaledHeight() +
90,
left: (commentButton.left ?? 0) + 28,
fontSize: 20,
fontFamily: 'Helvetica',
fill: '#555555',
splitByGrapheme: true,
opacity:0
opacity: 0,
});

var likeButton = new fabric.Textbox('👍🏼', {
name: 'like',
width: 55,
top: title.getScaledHeight() + author.getScaledHeight() + desc.getScaledHeight() + 90,
left: (commentCount.left??0) +45,
top:
title.getScaledHeight() +
author.getScaledHeight() +
desc.getScaledHeight() +
90,
left: (commentCount.left ?? 0) + 45,
fontSize: 20,
fontFamily: 'Helvetica',
fill: '#000000',
splitByGrapheme: true
splitByGrapheme: true,
});

var likeCount = new fabric.Textbox('0', {
name: 'likeCount',
width: 55,
top: title.getScaledHeight() + author.getScaledHeight() + desc.getScaledHeight() + 90,
top:
title.getScaledHeight() +
author.getScaledHeight() +
desc.getScaledHeight() +
90,
left: (likeButton.left ?? 0) + 28,
fontSize: 20,
fontFamily: 'Helvetica',
fill: '#555555',
splitByGrapheme: true
splitByGrapheme: true,
});



var content = new fabric.Rect({
name: 'content',
top: 40,
width: 330,
height: title.getScaledHeight() + author.getScaledHeight() + desc.getScaledHeight() + commentButton.getScaledHeight() + CONTENT_EXTRA_HEIGHT,
height:
title.getScaledHeight() +
author.getScaledHeight() +
desc.getScaledHeight() +
commentButton.getScaledHeight() +
CONTENT_EXTRA_HEIGHT,
fill: options.color,
rx: 20,
rx: 20,
ry: 20,
strokeWidth: options.strokeWidth ?? POST_DEFAULT_BORDER_THICKNESS,
stroke: options.stroke ?? POST_DEFAULT_BORDER,
});

const groupOptions = {
name: 'post',
left: options.left - (330 / 2),
top: options.top - ((content.height ?? 0) / 2),
left: options.left - 330 / 2,
top: options.top - (content.height ?? 0) / 2,
hasControls: false,
transparentCorners: false,
cornerSize: 7,
Expand All @@ -123,8 +163,20 @@ export class FabricPostComponent extends fabric.Group {
tags: options.tags,
subTargetCheck: true,
authorID: options.authorID,
}
};

super([content, title, author, desc, likeButton, likeCount, commentButton, commentCount], groupOptions);
};
}
super(
[
content,
title,
author,
desc,
likeButton,
likeCount,
commentButton,
commentCount,
],
groupOptions
);
}
}
56 changes: 56 additions & 0 deletions src/app/utils/FabricUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,62 @@ export class FabricUtils {
this._canvas = surface;
}

wrapCanvasText(t, maxW, maxH) {
this._canvas = new fabric.Canvas('c');
if (typeof maxH === 'undefined') {
maxH = 0;
}
var words = t.split(' ');
var formatted = '';
var context = this._canvas?.getContext();
context.font = t.fontSize + 'px ' + t.fontFamily;
var currentLine = '';

for (var n = 0; n < words.length; n++) {
var isNewLine = currentLine == '';
var testOverlap = currentLine + ' ' + words[n];

// are we over width?
var w = context.measureText(testOverlap).width;

if (w < maxW) {
// if not, keep adding words
currentLine += words[n] + ' ';
formatted += words[n] += ' ';
} else {
// if this hits, we got a word that need to be hypenated
if (isNewLine) {
var wordOverlap = '';

// test word length until its over maxW
for (var i = 0; i < words[n].length; ++i) {
wordOverlap += words[n].charAt(i);
var withHypeh = wordOverlap + '-';

if (context.measureText(withHypeh).width >= maxW) {
// add hyphen when splitting a word
withHypeh = wordOverlap.substr(0, wordOverlap.length - 2) + '-';
// update current word with remainder
words[n] = words[n].substr(
wordOverlap.length - 1,
words[n].length
);
formatted += withHypeh; // add hypenated word
break;
}
}
}
n--; // restart cycle
formatted += '\n';
currentLine = '';
}
}

formatted = formatted.substr(0, formatted.length - 1);
console.log(formatted);
return formatted;
}

setField(obj, key, value) {
obj.set(key, value);
fabric.util.object.extend(obj, { [key]: value });
Expand Down