123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150 |
- var THREEx = THREEx || {}
- //////////////////////////////////////////////////////////////////////////////////
- // Constructor //
- //////////////////////////////////////////////////////////////////////////////////
- /**
- * create a dynamic texture with a underlying canvas
- *
- * @param {Number} width width of the canvas
- * @param {Number} height height of the canvas
- */
- THREEx.DynamicTexture = function(width, height){
- var canvas = document.createElement( 'canvas' )
- canvas.width = width
- canvas.height = height
- this.canvas = canvas
- var context = canvas.getContext( '2d' )
- this.context = context
- var texture = new THREE.Texture(canvas)
- this.texture = texture
- }
- //////////////////////////////////////////////////////////////////////////////////
- // methods //
- //////////////////////////////////////////////////////////////////////////////////
- /**
- * clear the canvas
- *
- * @param {String*} fillStyle the fillStyle to clear with, if not provided, fallback on .clearRect
- * @return {THREEx.DynamicTexture} the object itself, for chained texture
- */
- THREEx.DynamicTexture.prototype.clear = function(fillStyle){
- // depends on fillStyle
- if( fillStyle !== undefined ){
- this.context.fillStyle = fillStyle
- this.context.fillRect(0,0,this.canvas.width, this.canvas.height)
- }else{
- this.context.clearRect(0,0,this.canvas.width, this.canvas.height)
- }
- // make the texture as .needsUpdate
- this.texture.needsUpdate = true;
- // for chained API
- return this;
- }
- /**
- * draw text
- *
- * @param {String} text - the text to display
- * @param {Number|undefined} x - if provided, it is the x where to draw, if not, the text is centered
- * @param {Number} y - the y where to draw the text
- * @param {String*} fillStyle - the fillStyle to clear with, if not provided, fallback on .clearRect
- * @param {String*} contextFont - the font to use
- * @return {THREEx.DynamicTexture} - the object itself, for chained texture
- */
- THREEx.DynamicTexture.prototype.drawText = function(text, x, y, fillStyle, contextFont){
- // set font if needed
- if( contextFont !== undefined ) this.context.font = contextFont;
- // if x isnt provided
- if( x === undefined || x === null ){
- var textSize = this.context.measureText(text);
- x = (this.canvas.width - textSize.width) / 2;
- }
- // actually draw the text
- this.context.fillStyle = fillStyle;
- this.context.fillText(text, x, y);
- // make the texture as .needsUpdate
- this.texture.needsUpdate = true;
- // for chained API
- return this;
- };
- THREEx.DynamicTexture.prototype.drawTextCooked = function(options){
- var context = this.context
- var canvas = this.canvas
- options = options || {}
- var text = options.text
- var params = {
- margin : options.margin !== undefined ? options.margin : 0.1,
- lineHeight : options.lineHeight !== undefined ? options.lineHeight : 0.1,
- align : options.align !== undefined ? options.align : 'left',
- fillStyle : options.fillStyle !== undefined ? options.fillStyle : 'black',
- font : options.font !== undefined ? options.font : "bold "+(0.2*512)+"px Arial",
- }
- // sanity check
- console.assert(typeof(text) === 'string')
- context.save()
- context.fillStyle = params.fillStyle;
- context.font = params.font;
- var y = (params.lineHeight + params.margin)*canvas.height
- while(text.length > 0 ){
- // compute the text for specifically this line
- var maxText = computeMaxTextLength(text)
- // update the remaining text
- text = text.substr(maxText.length)
- // compute x based on params.align
- var textSize = context.measureText(maxText);
- if( params.align === 'left' ){
- var x = params.margin*canvas.width
- }else if( params.align === 'right' ){
- var x = (1-params.margin)*canvas.width - textSize.width
- }else if( params.align === 'center' ){
- var x = (canvas.width - textSize.width) / 2;
- }else console.assert( false )
- // actually draw the text at the proper position
- this.context.fillText(maxText, x, y);
- // goto the next line
- y += params.lineHeight*canvas.height
- }
- context.restore()
- // make the texture as .needsUpdate
- this.texture.needsUpdate = true;
- // for chained API
- return this;
- function computeMaxTextLength(text){
- var maxText = ''
- var maxWidth = (1-params.margin*2)*canvas.width
- while( maxText.length !== text.length ){
- var textSize = context.measureText(maxText);
- if( textSize.width > maxWidth ) break;
- maxText += text.substr(maxText.length, 1)
- }
- return maxText
- }
- }
- /**
- * execute the drawImage on the internal context
- * the arguments are the same the official context2d.drawImage
- */
- THREEx.DynamicTexture.prototype.drawImage = function(/* same params as context2d.drawImage */){
- // call the drawImage
- this.context.drawImage.apply(this.context, arguments)
- // make the texture as .needsUpdate
- this.texture.needsUpdate = true;
- // for chained API
- return this;
- }
|