Gebbrich letters when using fabricjs with nodejs - node.js

i'm trying to use fabric in my nodejs backend which is deployed in an alpine image ( node version 8.15 )
so i've made a function responsible for creating the template as the following
const creatCardTemplate = function(user){
let canvas = new fabric.Canvas(null, {width: 650, height: 400});
canvas.backgroundColor="#fff";
let company=user.company?user.company.companyName:"YOUR COMPANY";
let text = new fabric.IText(company,{fontSize:30,top:100,textAlign:'center',fontWeight:'bold'});
canvas.add(text);
canvas.centerObjectH(text);
text = new fabric.IText(user.first_name+" "+user.last_name,{fontSize:26,top:140,textAlign:'center',fontWeight:'bold'});
canvas.add(text);
canvas.centerObjectH(text);
:::: etc
canvas.renderAll();
return canvas;
}
a quite normal code and then i just generate a PNG image from it
let canvas = creatCardTemplate(user);
let image = canvas.toDataURL({ format: 'png'});
that's all,it works fine in my local machine but my problem is that when i deploy it the png result is so gebbrich like this
i tried many solutions like changing the creation method ( i tried to create the canvas by loading a json data ) also i tried to change the font family to Arial but always the same damn squares

After a lot of struggling i found the issue, the issue was that alpine image came without any font installed ( as we know that Fabric will use the browser fonts if it was installed in a front end framework) but in my case it was installed with nodejs (backend) so it will use the fonts available in the system.
So i've installed some fonts and added them to be used by Fabric as the following:
first of all we need to import
const { registerFont, createCanvas } = require('canvas')
then we add our desired font
registerFont('helpers/fonts/Roboto-Regular.ttf', { family: 'Roboto' })
then we have just to use it :)
let text = new fabric.IText("hello",{fontSize:30,top:100,textAlign:'center',fontFamily:'Roboto

Related

Changing color of specific elements of 3D model using ifcLoader of three.js

I have an ifc file for a 3D model, and I'm trying to make different elements of the model different colors. I'm using the IFC.js web-ifc-three IFCLoader for three.js. There are multiple examples of how to use the library but when I try to change colors for the elements based on a list of expressIDs there aren't any changes. I've tried making a subset with a specific material after the model is loaded, but that doesn't work either.
I use:
//Sets up the IFC loading
var ifcModels = [];
var ifcLoader = new IFCLoader();
ifcLoader.ifcManager.setWasmPath("./three/examples/jsm/loaders/ifc/");
ifcLoader.load("./models/rac_advanced_sample_project.ifc", (ifcModel) => {
ifcModels.push(ifcModel);
console.log(ifcModels[0]);
scene.add(ifcModel)
});
const initMaterial = new THREE.MeshLambertMaterial({
transparent: true,
opacity: 0.6,
color: 0x008000,
depthTest: false
});
console.log(ifcModels);
console.log(ifcModels[0]);
ifcLoader.ifcManager.createSubset({
modelID: ifcModels[0].modelID,
ids: [281144],
material: initMaterial,
scene: scene,
removePrevious: true
});
to try to change the color of an element where its expressID is 281144, for example.
This is the code from one of their examples that I base the rest of my code off of:
highlighting-single example
Does anyone know how to do this/has been able to do this?

Need to dispaly svg on an image in Xamarin

I have an url that gets team logos but it returns svg https://www.mlbstatic.com/team-logos/141.svg.
How can i display this in a Image for xamarin forms?
Searched and only found complex huge amounts of code.
looking for
Download image -- I have this but what do i need to save it in GetResponsestream preferrable i would like to stay in memory and not write to disk or file.
Attach it to an image to display.
Thanks.
Ok, thought i would post my solution here.
I used SkiSharp:
SkiaSharp.Extended.Svg.SKSvg svg = new SkiaSharp.Extended.Svg.SKSvg();
using (WebClient client = new WebClient())
{
// ie for theurl: https://www.mlbstatic.com/team-logos/141.svg
svg.Load(new MemoryStream(client.DownloadData(new Uri(theurl))));
var bitmap = new SKBitmap((int)svg.CanvasSize.Width, (int)svg.CanvasSize.Height);
var canvas = new SKCanvas(bitmap);
canvas.DrawPicture(svg.Picture);
canvas.Flush();
canvas.Save();
string filename = "";
using (var image = SKImage.FromBitmap(bitmap))
using (var data = image.Encode(SKEncodedImageFormat.Png, 80))
{
// save the data to a stream
filename = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "temp.png");
using (var stream = File.OpenWrite(filename ))
{
data.SaveTo(stream);
}
}
}
use FileName from above to assign source to Xamarin image.
this accomplished the task with the least amount of code lines i tried.

IText, batik and vaadin charts scales wrong on linux

I've been having some trouble getting my charts out to PDF.
Recently i posted this: Generating PDF with iText and batik which was solved as suggested with some tweaking to the scales.
I run amy testenviroment on a local glassfishserver on a windows 10 machine, and when I export to PDF I actually get a pretty result now.
But when I pushed the results to the RHEL server, the results differed. The charts shown on the website is great, but when I export to pdf, I get this:
As you can see, the title is pushed down, for some reason the Y-axis with labels are cropped, and the data-labels are squished together. I've tried playing around with different scales, with and without scaletofit, scaletoabsolute and so on, but no matter what I do, it keeps doing that weird thing.
Does anybody has any idea whats going on - and even better, how to fix it? I've doublechecked that phantomjs is the same version, to make sure the SVG is the right one-.
The code is as follows:
private Image createSvgImage(PdfContentByte contentByte, Chart chart) throws IOException {
Configuration configuration = chart.getConfiguration();
configuration.setExporting(false);
SVGGenerator generator = SVGGenerator.getInstance();
generator.withHeigth(600);
generator.withWidth(1200);
String svg = generator.generate(configuration);
Image image = drawUnscaledSvg(contentByte, svg);
image.scaleToFit(800, 370);
configuration.setExporting(true);
return image;
}
private Image drawUnscaledSvg(PdfContentByte contentByte, String svgStr) throws IOException {
GraphicsNode imageGraphics = buildBatikGraphicsNode(svgStr);
float width = 1200;
float height = 600;
PdfTemplate template = contentByte.createTemplate(width, height);
Graphics2D graphics = template.createGraphics(width, height);
try {
imageGraphics.paint(graphics);
graphics.translate(-10, -10);
return new ImgTemplate(template);
} catch (BadElementException e) {
throw new RuntimeException("Couldn't generate PDF from SVG", e);
} finally {
graphics.dispose();
}
}
private GraphicsNode buildBatikGraphicsNode(String svgStr) throws IOException {
UserAgent agent = new UserAgentAdapter();
SVGDocument svgdoc = createSVGDocument(svgStr, agent);
DocumentLoader loader = new DocumentLoader(agent);
BridgeContext bridgeContext = new BridgeContext(agent, loader);
bridgeContext.setDynamicState(BridgeContext.STATIC);
GVTBuilder builder = new GVTBuilder();
GraphicsNode imageGraphics = builder.build(bridgeContext, svgdoc);
return imageGraphics;
}
private SVGDocument createSVGDocument(String svg, UserAgent agent)
throws IOException {
SVGDocumentFactory documentFactory = new SAXSVGDocumentFactory(
agent.getXMLParserClassName(), true);
SVGDocument svgdoc = documentFactory.createSVGDocument(null,
new StringReader(svg));
return svgdoc;
}
UPDATE I've tried reading a SVG file from disk, that I knew was correct, and that is put correctly within the PDF. So the problem lies somewhere within the SVG Generator. Anyone knows about this?
Using an older version of PhantomJS (1.9.8) fixes the problem.
I've made a ticket with Vaadin.

How to add custom content in fabric.Image()

I am trying to use the following suggested way to store canvas in the server:
Fabric.js - how to save canvas on server with custom attributes
But in my case, I am loading an image from a url like:
fabric.Image.fromURL(url, function(image) {
image.alt = product.skuId;
image.productClass = product.productClass;
canvas.add(image);
}, {
crossOrigin: "Annoymous"
});
But when I try to store the same in the db the newer attributes are not stored.
Is there a way to store custom attribute (or even "alt") in the DB?
Edit:
Created a fiddle with what I tried:
https://jsfiddle.net/anjhawar/dpyb7cf7/
When we press save the canvas is dumped in the local storage, but when we check the "objects" array we do not get the custom attributes i.e. "id" and "alt", as per the example.
Am I missing something?
Here my solution to store custom attribute (id).
fabric.Image.fromURL(link, function(img) {
img.set({
id : 'image_'+index,
width : canvas.width / 2,
height : canvas.height / 2
});
canvas.add(img).renderAll().setActiveObject(img);
});
For quick review here is a working code : http://jsfiddle.net/mullainathan/dpyb7cf7/1

Cant quite nail scaling the game on mobile. Its not showing all of the game but only part of the game

this.scale.scaleMode = Phaser.ScaleManager.SHOW_ALL;
this.scale.pageAlignHorizontally = true;
this.scale.pageAlignVertically = true;
this.scale.refresh();
Its a tiny game code which I have uploaded on http://scaleissue.site44.com/ so pls use browser dev tools to have a look.
As you will notice when u go to dev tools and choose mobile emulation (iphone 4, 5, 6 - landscape orientation only), the screen only shows the top-left corner of the actual game with scroll bars when in fact it should have scaled the game such that all of the game was being shown on the screen since I used
this.scale.scaleMode = Phaser.ScaleManager.SHOW_ALL;
(you might have to reload page to notice this issue when in dev tools). I tried the game on real mobile and still the same issue.
All relevant scaling code is under boot.js
Please help as I cant quite nail the issue having tried several scaling modes.
You can try to resize the canvas:
var width=window.innerWidth,
height=window.innerHeight,
dpr=window.devicePixelRatio || 1;
var game = window.game[NAMESPACE].game = new Phaser.Game(1024, 480, Phaser.AUTO, 'gameDiv');
var mainState = {
preload : function () {
game.scale.scaleMode = Phaser.ScaleManager.RESIZE ;
//game.canvas.style.width=width+'px';
game.canvas.style.height=height+'px';
},
create : function () {
this.stage.backgroundColor = '#0000db';
},
update : function () {}
};
//initialising Phaser
game.state.add('main', mainState);
game.state.start('main');
The rationale behind this code: The canvas.width value (which is a number) sets the size of the game, while the canvas.style.width value (which is a string) sets the size of the canvas element. To avoid deformations you should maintain the same ratio (in your case, the ratio is 1024/480) in both values. If you set the ScaleManager as RESIZE then this ratio is maintained automatically, that's the reason why I'm only setting the height.

Resources