maker.js icon indicating copy to clipboard operation
maker.js copied to clipboard

Create Text with JSON model path

Open kamildul opened this issue 3 years ago • 9 comments

Hello, i have question, is it possible create text in json array (in php) and add text to canvas by 'toSVGPathData' ? i try similar to the points but it doesn't work :-(

Points:

$pathArray['models']['points']['paths']['point_'.$i]['type'] = 'circle';
$pathArray['models']['points']['paths']['point_'.$i]['origin'][0] = $getPointsByID[$i]['x'];
$pathArray['models']['points']['paths']['point_'.$i]['origin'][1] = $getPointsByID[$i]['y'];
$pathArray['models']['points']['paths']['point_'.$i]['radius'] = 0.1;

Text:

$pathArray['models']['texts']['paths']['text_'.$i]['type'] = 'text';
$pathArray['models']['texts']['paths']['text_'.$i]['value'] = 'Hello';
$pathArray['models']['texts']['paths']['text_'.$i]['fontSize'] = 500;

After get model paths with ajax i append path to the div element:

var height = $('.page-footer').offset().top - $('.frame-wrap').offset().top - $('.frame-wrap').outerHeight();
const sbp = require("svg-blueprint");
sbp.settings.axisColor = "red";
const makerjs = require('makerjs');
const blueprint = new sbp.Blueprint({
    parentSelector: "#canvas-makerjs",
    width: '100%',
    height: height+'px'
});						
const path = makerjs.exporter.toSVGPathData(data.routePath, { origin: [0, 0] });
blueprint.append('path', { d: path });
blueprint.fit();

Please HELP ME!

kamildul avatar Jun 29 '22 09:06 kamildul

Hello, can you provide just the json that is retrieved ?

danmarshall avatar Jun 29 '22 16:06 danmarshall

Yes, this is my json response:

{
	"valid": "true",
	"routePath": {
		"models": {
			"points": {
				"paths": {
					"point_0": {
						"type": "circle",
						"origin": [
							"2150.4739",
							"2203.4505"
						],
						"radius": 0.1
					},
					"point_1": {
						"type": "circle",
						"origin": [
							"2152.4739",
							"2203.4505"
						],
						"radius": 0.1
					},
					"point_2": {
						"type": "circle",
						"origin": [
							"2152.4739",
							"2201.4505"
						],
						"radius": 0.1
					},
					"point_3": {
						"type": "circle",
						"origin": [
							"2150.4739",
							"2201.4505"
						],
						"radius": 0.1
					},
					"point_4": {
						"type": "circle",
						"origin": [
							"2150.4739",
							"2203.4505"
						],
						"radius": 0.1
					}
				}
			},
			"lines": {
				"paths": {
					"line_0": {
						"type": "line",
						"origin": [
							"2150.4739",
							"2203.4505"
						],
						"end": [
							"2152.4739",
							"2203.4505"
						]
					},
					"line_1": {
						"type": "line",
						"origin": [
							"2152.4739",
							"2203.4505"
						],
						"end": [
							"2152.4739",
							"2201.4505"
						]
					},
					"line_2": {
						"type": "line",
						"origin": [
							"2152.4739",
							"2201.4505"
						],
						"end": [
							"2150.4739",
							"2201.4505"
						]
					},
					"line_3": {
						"type": "line",
						"origin": [
							"2150.4739",
							"2201.4505"
						],
						"end": [
							"2150.4739",
							"2203.4505"
						]
					}
				}
			},
			"texts": {
				"paths": {
					"text_0": {
						"type": "text",
						"value": "Hello0",
						"fontSize": 500
					},
					"text_1": {
						"type": "text",
						"value": "Hello1",
						"fontSize": 500
					},
					"text_2": {
						"type": "text",
						"value": "Hello2",
						"fontSize": 500
					},
					"text_3": {
						"type": "text",
						"value": "Hello3",
						"fontSize": 500
					},
					"text_4": {
						"type": "text",
						"value": "Hello4",
						"fontSize": 500
					}
				}
			}
		}
	}
}

kamildul avatar Jun 30 '22 08:06 kamildul

Here's a couple of things which you need to correct:

  1. Use numbers instead of strings. Your example:
{
  "type": "circle",
  "origin": ["2150.4739", "2203.4505"],
  "radius": 0.1
}

Should be changed to:

{
  "type": "circle",
  "origin": [2150.4739, 2203.4505],
  "radius": 0.1
}
  1. There is no text type of path. By passing these to makerjs.exporter.toSVGPathData, it is causing a NaN to be present in your boundary calculation (causing the actual rendering to be very small). You can keep these as data in your JSON if you like, but move them out of the models subtree that is passed to the exporter function.
{
    "type": "text",
    "value": "Hello0",
    "fontSize": 500
}

You may want to look at captions for annotating with text. Or loading a font to render letterform outlines.

After correcting these, I was able to get this rendering: image

danmarshall avatar Jun 30 '22 20:06 danmarshall

Hello Dan! thank you for your help. I don't have a problem with circle and line - it works but i have problem with add text to canvas with other elementes. I do not know how write texts in there. Example i have

obraz

But i want have:

obraz

I would like to generate these texts via json as well as other elements in my canvas

kamildul avatar Jul 01 '22 07:07 kamildul

First you will need to decide to use either captions or font-based Text outline models.

If you decide to use captions, remember that you get only one caption per model. So, for multiple captions, just add more models. If you want to generate them on the server side, here's an example of the serialized JSON for a caption property on a model object:

  "caption": {
    "text": "a square",
    "anchor": {
      "type": "line",
      "origin": [
        0,
        50
      ],
      "end": [
        100,
        50
      ]
    }
  },

Also note that captions currently do not allow a font size to be specified. This is to reduce complexity, and to ensure that captions remain visible at any zoom level or scaling with unit type conversions.

If you need to specify the exact font and size (and are willing to have text converted to a bunch of raw lines & arcs), you'll need to load a font and then use the built-in Text model. Also note that you will get only outlines of letters, not filled as in your example. This is not something that you'll be able to do on the server side (unless you rewrite opentype.js and Maker.js in PHP 🤐 ). So, I would recommend passing your text specifications in a property that is a sibling to the model object, then modifying the model object on the client side JavaScript and creating Text models then.

danmarshall avatar Jul 02 '22 03:07 danmarshall

Hello Dan, i tried for captions but it not working :-(

My Json response

{
	"models": {
		"caption": {
			"paths": {
				"text": "a square",
				"anchor": {
					"type": "line",
					"origin": [
						0,
						50
					],
					"end": [
						100,
						50
					]
				}
			}
		}
	}
}

My result:

obraz

kamildul avatar Jul 04 '22 09:07 kamildul

You have a model named “caption” with a “paths” property. You can name your model anything you like, but to avoid confusion for the moment, do not name it “caption”. Then you need a “caption” property on that model.

Your json will work if you change “paths” to “caption”.

danmarshall avatar Jul 04 '22 18:07 danmarshall

Hello Dan,

it not working :-(

My JS:

var height = $('.page-footer').offset().top - $('.frame-wrap').offset().top - $('.frame-wrap').outerHeight();
						const sbp = require("svg-blueprint");
						sbp.settings.axisColor = "red";
						
						const makerjs = require('makerjs');
						
						const blueprint = new sbp.Blueprint({
						  parentSelector: "#canvas-makerjs",
						  width: '100%',
						  height: height+'px'
						});	


						const path = makerjs.exporter.toSVGPathData(data.routePath, { origin: [0, 0] });
						blueprint.append('path', { d: path });
						blueprint.fit();

My Json response:

       {
		"models": {
			"test": {
				"caption": {
					"text": "a square",
					"anchor": {
						"type": "line",
						"origin": [
							0,
							50
						],
						"end": [
							100,
							50
						]
					}
				}
			}
		}
       }

Result:

image

I check what give me "path = makerjs.exporter.toSVGPathData(data.routePath, { origin: [0, 0] });" , result in console.log or alert is "undefined"

kamildul avatar Jul 05 '22 08:07 kamildul

Captions are only exported as SVG, they are output as SVG elements:

<text alignment-baseline="middle" text-anchor="middle" transform="rotate(0,50,50)" x="50" y="50">a square</text>

So you may try makerjs.exporter.toSVG. If you want your text as SVG path data, you'll need to use fonts and the Text model.

danmarshall avatar Jul 05 '22 18:07 danmarshall