microsoft / maker.js

📐⚙ 2D vector line drawing and shape modeling for CNC and laser cutters.
http://maker.js.org
Apache License 2.0
1.75k stars 265 forks source link

MakerJS + OpentypeJS + VueJS : how to create text using a loaded font ? #379

Closed tkinte closed 5 years ago

danmarshall commented 5 years ago

Hello, can you provide specific details on what you are trying to achieve? Also, it would be helpful if you can state what you have tried and what didn't work about it. Thanks!

tkinte commented 5 years ago

Hello. What I am struggling with is load a font and assign it to a variable outside de callback function. In the context of a Vuejs Component (Vue CLI 3 + webpack@4.26.1)

1° Not sure if I can use opentypejs.loadSync(...) from within a Vuejs Component. It could be the more straight way. But the following code throws an error

... let model = { models: {}} var opentype = require('opentype.js') let font = opentype.loadSync('/fonts/FiraSansOT-Medium.otf') console.log('loaded font : ' , font) this.font = font let textModel = new makerjs.models.Text(font, 'Hello', 40) alert(JSON.stringify(textModel)) model.models.hello = textModel ...

vue.runtime.esm.js?2b0e:1737 TypeError: **fs.readFileSync is not a function** at Module.loadSync (opentype.js?5f78:397) at VueComponent.toSVGLogoOutlineAndShape (maker.vue?a535:94) at Watcher.get (vue.runtime.esm.js?2b0e:3138) at Watcher.evaluate (vue.runtime.esm.js?2b0e:3245) at VueComponent.computedGetter [as toSVGLogoOutlineAndShape] (vue.runtime.esm.js?2b0e:3503) at Object.get (vue.runtime.esm.js?2b0e:1916) at Proxy.render (eval at ./node_modules/cache-loader/dist/cjs.js?{"cacheDirectory":"node_modules/.cache/vue-loader","cacheIdentifier":"9f3de012-vue-loader-template"}!./node_modules/vue-loader/lib/loaders/templateLoader.js?!./node_modules/cache-loader/dist/cjs.js?!./node_modules/vue-loader/lib/index.js?!./src/components/maker/maker.vue?vue&type=template&id=32c77459&scoped=true&lang=html& (app.js:2263), <anonymous>:12:49) at VueComponent.Vue._render (vue.runtime.esm.js?2b0e:4540) at VueComponent.updateComponent (vue.runtime.esm.js?2b0e:2784) at Watcher.get (vue.runtime.esm.js?2b0e:3138)

2° opentype.load does the job, but I am strunggling with a scoping issue. How to assign the loaded font outside the callback function.

var opentype = require('opentype.js') var fs = require('fs') var path = require('path') opentype.load('/fonts/FiraSansOT-Medium.otf', function (err, font) { if (err) { alert('Could not load font: ' + err) } else { // Use your font here. console.log("loaded the font",font) this.font = font } })

The arrow function also does not help to assign outside the callback

`var opentype = require("opentype.js") var fs = require("fs") var path = require("path") let that = this opentype.load("/fonts/FiraSansOT-Medium.otf", (err, font) => { if (err) { alert("Could not load font: " + err) } else { // Use your font here. console.log("loaded the font",font) that.font = font console.log("in that.font", that.font) // ok

      console.log("in this.font", this.font) // ok
    }
  })
  console.log("after that.font",that.font) // null

  console.log("after this.font",this.font) // null
}`

So, Can I use loadSync from whithin a Vuejs component ? If not, how can I assign the loaded font outside the callback scope ?

Thank you in advance.

Best regards.

Tshitshi

fdb commented 5 years ago
  1. fs.loadSync only works in Node.js
  2. You would do that with a standard callback function. I don't know Vue, but here's what I would use in a global context:
let gFont = null;
opentype.load('yourfont.otf', (err, font) => {
  // Check err
  gFont = font;
  // Call update function...
});
tkinte commented 5 years ago

Thank you very much for the help.

I got it now. I have to redesign the rendering flow of my Vue component.

All the logic requiring the font load must take place inside de callback function, when the font loaded.

Best regards.