@ -0,0 +1,667 @@
// 本文件由FirstUI授权予新疆天衡创新研究院有限公司( 手机号: 18 6 14 0 7 25 49, 身份证尾号: 5A07X5) 专用, 请尊重知识产权, 勿私下传播, 违者追究法律责任。
import FillStylePattern from './FillStylePattern' ;
import FillStyleLinearGradient from './FillStyleLinearGradient' ;
import FillStyleRadialGradient from './FillStyleRadialGradient' ;
import GImage from '../env/image.js' ;
import {
ArrayBufferToBase64 ,
Base64ToUint8ClampedArray
} from '../env/tool.js' ;
export default class CanvasRenderingContext2D {
_drawCommands = '' ;
_globalAlpha = 1.0 ;
_fillStyle = 'rgb(0,0,0)' ;
_strokeStyle = 'rgb(0,0,0)' ;
_lineWidth = 1 ;
_lineCap = 'butt' ;
_lineJoin = 'miter' ;
_miterLimit = 10 ;
_globalCompositeOperation = 'source-over' ;
_textAlign = 'start' ;
_textBaseline = 'alphabetic' ;
_font = '10px sans-serif' ;
_savedGlobalAlpha = [ ] ;
timer = null ;
componentId = null ;
_notCommitDrawImageCache = [ ] ;
_needRedrawImageCache = [ ] ;
_redrawCommands = '' ;
_autoSaveContext = true ;
// _imageMap = new GHashMap();
// _textureMap = new GHashMap();
constructor ( ) {
this . className = 'CanvasRenderingContext2D' ;
//this.save()
}
setFillStyle ( value ) {
this . fillStyle = value ;
}
set fillStyle ( value ) {
this . _fillStyle = value ;
if ( typeof ( value ) == 'string' ) {
this . _drawCommands = this . _drawCommands . concat ( "F" + value + ";" ) ;
} else if ( value instanceof FillStylePattern ) {
const image = value . _img ;
if ( ! image . complete ) {
image . onload = ( ) => {
var index = this . _needRedrawImageCache . indexOf ( image ) ;
if ( index > - 1 ) {
this . _needRedrawImageCache . splice ( index , 1 ) ;
CanvasRenderingContext2D . GBridge . bindImageTexture ( this . componentId , image . src , image . _id ) ;
this . _redrawflush ( true ) ;
}
}
this . _notCommitDrawImageCache . push ( image ) ;
} else {
CanvasRenderingContext2D . GBridge . bindImageTexture ( this . componentId , image . src , image . _id ) ;
}
//CanvasRenderingContext2D.GBridge.bindImageTexture(this.componentId, image.src, image._id);
this . _drawCommands = this . _drawCommands . concat ( "G" + image . _id + "," + value . _style + ";" ) ;
} else if ( value instanceof FillStyleLinearGradient ) {
var command = "D" + value . _start _pos . _x . toFixed ( 2 ) + "," + value . _start _pos . _y . toFixed ( 2 ) + "," +
value . _end _pos . _x . toFixed ( 2 ) + "," + value . _end _pos . _y . toFixed ( 2 ) + "," +
value . _stop _count ;
for ( var i = 0 ; i < value . _stop _count ; ++ i ) {
command += ( "," + value . _stops [ i ] . _pos + "," + value . _stops [ i ] . _color ) ;
}
this . _drawCommands = this . _drawCommands . concat ( command + ";" ) ;
} else if ( value instanceof FillStyleRadialGradient ) {
var command = "H" + value . _start _pos . _x . toFixed ( 2 ) + "," + value . _start _pos . _y . toFixed ( 2 ) + "," + value . _start _pos . _r
. toFixed ( 2 ) + "," +
value . _end _pos . _x . toFixed ( 2 ) + "," + value . _end _pos . _y . toFixed ( 2 ) + "," + value . _end _pos . _r . toFixed ( 2 ) + "," +
value . _stop _count ;
for ( var i = 0 ; i < value . _stop _count ; ++ i ) {
command += ( "," + value . _stops [ i ] . _pos + "," + value . _stops [ i ] . _color ) ;
}
this . _drawCommands = this . _drawCommands . concat ( command + ";" ) ;
}
}
get fillStyle ( ) {
return this . _fillStyle ;
}
get globalAlpha ( ) {
return this . _globalAlpha ;
}
setGlobalAlpha ( value ) {
this . globalAlpha = value ;
}
set globalAlpha ( value ) {
this . _globalAlpha = value ;
this . _drawCommands = this . _drawCommands . concat ( "a" + value . toFixed ( 2 ) + ";" ) ;
}
get strokeStyle ( ) {
return this . _strokeStyle ;
}
setStrokeStyle ( value ) {
this . strokeStyle = value ;
}
set strokeStyle ( value ) {
this . _strokeStyle = value ;
if ( typeof ( value ) == 'string' ) {
this . _drawCommands = this . _drawCommands . concat ( "S" + value + ";" ) ;
} else if ( value instanceof FillStylePattern ) {
CanvasRenderingContext2D . GBridge . bindImageTexture ( this . componentId , image . src , image . _id ) ;
this . _drawCommands = this . _drawCommands . concat ( "G" + image . _id + "," + value . _style + ";" ) ;
} else if ( value instanceof FillStyleLinearGradient ) {
var command = "D" + value . _start _pos . _x . toFixed ( 2 ) + "," + value . _start _pos . _y . toFixed ( 2 ) + "," +
value . _end _pos . _x . toFixed ( 2 ) + "," + value . _end _pos . _y . toFixed ( 2 ) + "," +
value . _stop _count ;
for ( var i = 0 ; i < value . _stop _count ; ++ i ) {
command += ( "," + value . _stops [ i ] . _pos + "," + value . _stops [ i ] . _color ) ;
}
this . _drawCommands = this . _drawCommands . concat ( command + ";" ) ;
} else if ( value instanceof FillStyleRadialGradient ) {
var command = "H" + value . _start _pos . _x . toFixed ( 2 ) + "," + value . _start _pos . _y . toFixed ( 2 ) + "," + value . _start _pos . _r
. toFixed ( 2 ) + "," +
value . _end _pos . _x . toFixed ( 2 ) + "," + value . _end _pos . _y + "," . toFixed ( 2 ) + value . _end _pos . _r . toFixed ( 2 ) + "," +
value . _stop _count ;
for ( var i = 0 ; i < value . _stop _count ; ++ i ) {
command += ( "," + value . _stops [ i ] . _pos + "," + value . _stops [ i ] . _color ) ;
}
this . _drawCommands = this . _drawCommands . concat ( command + ";" ) ;
}
}
get lineWidth ( ) {
return this . _lineWidth ;
}
setLineWidth ( value ) {
this . lineWidth = value ;
}
set lineWidth ( value ) {
this . _lineWidth = value ;
this . _drawCommands = this . _drawCommands . concat ( "W" + value + ";" ) ;
}
get lineCap ( ) {
return this . _lineCap ;
}
setLineCap ( value ) {
this . lineCap = value ;
}
set lineCap ( value ) {
this . _lineCap = value ;
this . _drawCommands = this . _drawCommands . concat ( "C" + value + ";" ) ;
}
get lineJoin ( ) {
return this . _lineJoin ;
}
setLineJoin ( value ) {
this . lineJoin = value
}
set lineJoin ( value ) {
this . _lineJoin = value ;
this . _drawCommands = this . _drawCommands . concat ( "J" + value + ";" ) ;
}
get miterLimit ( ) {
return this . _miterLimit ;
}
setMiterLimit ( value ) {
this . miterLimit = value
}
set miterLimit ( value ) {
this . _miterLimit = value ;
this . _drawCommands = this . _drawCommands . concat ( "M" + value + ";" ) ;
}
get globalCompositeOperation ( ) {
return this . _globalCompositeOperation ;
}
set globalCompositeOperation ( value ) {
this . _globalCompositeOperation = value ;
let mode = 0 ;
switch ( value ) {
case "source-over" :
mode = 0 ;
break ;
case "source-atop" :
mode = 5 ;
break ;
case "source-in" :
mode = 0 ;
break ;
case "source-out" :
mode = 2 ;
break ;
case "destination-over" :
mode = 4 ;
break ;
case "destination-atop" :
mode = 4 ;
break ;
case "destination-in" :
mode = 4 ;
break ;
case "destination-out" :
mode = 3 ;
break ;
case "lighter" :
mode = 1 ;
break ;
case "copy" :
mode = 2 ;
break ;
case "xor" :
mode = 6 ;
break ;
default :
mode = 0 ;
}
this . _drawCommands = this . _drawCommands . concat ( "B" + mode + ";" ) ;
}
get textAlign ( ) {
return this . _textAlign ;
}
setTextAlign ( value ) {
this . textAlign = value
}
set textAlign ( value ) {
this . _textAlign = value ;
let Align = 0 ;
switch ( value ) {
case "start" :
Align = 0 ;
break ;
case "end" :
Align = 1 ;
break ;
case "left" :
Align = 2 ;
break ;
case "center" :
Align = 3 ;
break ;
case "right" :
Align = 4 ;
break ;
default :
Align = 0 ;
}
this . _drawCommands = this . _drawCommands . concat ( "A" + Align + ";" ) ;
}
get textBaseline ( ) {
return this . _textBaseline ;
}
setTextBaseline ( value ) {
this . textBaseline = value
}
set textBaseline ( value ) {
this . _textBaseline = value ;
let baseline = 0 ;
switch ( value ) {
case "alphabetic" :
baseline = 0 ;
break ;
case "middle" :
baseline = 1 ;
break ;
case "top" :
baseline = 2 ;
break ;
case "hanging" :
baseline = 3 ;
break ;
case "bottom" :
baseline = 4 ;
break ;
case "ideographic" :
baseline = 5 ;
break ;
default :
baseline = 0 ;
break ;
}
this . _drawCommands = this . _drawCommands . concat ( "E" + baseline + ";" ) ;
}
get font ( ) {
return this . _font ;
}
setFontSize ( size ) {
var str = this . _font ;
var strs = str . trim ( ) . split ( /\s+/ ) ;
for ( var i = 0 ; i < strs . length ; i ++ ) {
var values = [ "normal" , "italic" , "oblique" , "normal" , "small-caps" , "normal" , "bold" ,
"bolder" , "lighter" , "100" , "200" , "300" , "400" , "500" , "600" , "700" , "800" , "900" ,
"normal" , "ultra-condensed" , "extra-condensed" , "condensed" , "semi-condensed" ,
"semi-expanded" , "expanded" , "extra-expanded" , "ultra-expanded"
] ;
if ( - 1 == values . indexOf ( strs [ i ] . trim ( ) ) ) {
if ( typeof size === 'string' ) {
strs [ i ] = size ;
} else if ( typeof size === 'number' ) {
strs [ i ] = String ( size ) + 'px' ;
}
break ;
}
}
this . font = strs . join ( " " ) ;
}
set font ( value ) {
this . _font = value ;
this . _drawCommands = this . _drawCommands . concat ( "j" + value + ";" ) ;
}
setTransform ( a , b , c , d , tx , ty ) {
this . _drawCommands = this . _drawCommands . concat ( "t" +
( a === 1 ? "1" : a . toFixed ( 2 ) ) + "," +
( b === 0 ? "0" : b . toFixed ( 2 ) ) + "," +
( c === 0 ? "0" : c . toFixed ( 2 ) ) + "," +
( d === 1 ? "1" : d . toFixed ( 2 ) ) + "," + tx . toFixed ( 2 ) + "," + ty . toFixed ( 2 ) + ";" ) ;
}
transform ( a , b , c , d , tx , ty ) {
this . _drawCommands = this . _drawCommands . concat ( "f" +
( a === 1 ? "1" : a . toFixed ( 2 ) ) + "," +
( b === 0 ? "0" : b . toFixed ( 2 ) ) + "," +
( c === 0 ? "0" : c . toFixed ( 2 ) ) + "," +
( d === 1 ? "1" : d . toFixed ( 2 ) ) + "," + tx + "," + ty + ";" ) ;
}
resetTransform ( ) {
this . _drawCommands = this . _drawCommands . concat ( "m;" ) ;
}
scale ( a , d ) {
this . _drawCommands = this . _drawCommands . concat ( "k" + a . toFixed ( 2 ) + "," +
d . toFixed ( 2 ) + ";" ) ;
}
rotate ( angle ) {
this . _drawCommands = this . _drawCommands
. concat ( "r" + angle . toFixed ( 6 ) + ";" ) ;
}
translate ( tx , ty ) {
this . _drawCommands = this . _drawCommands . concat ( "l" + tx . toFixed ( 2 ) + "," + ty . toFixed ( 2 ) + ";" ) ;
}
save ( ) {
this . _savedGlobalAlpha . push ( this . _globalAlpha ) ;
this . _drawCommands = this . _drawCommands . concat ( "v;" ) ;
}
restore ( ) {
this . _drawCommands = this . _drawCommands . concat ( "e;" ) ;
this . _globalAlpha = this . _savedGlobalAlpha . pop ( ) ;
}
createPattern ( img , pattern ) {
if ( typeof img === 'string' ) {
var imgObj = new GImage ( ) ;
imgObj . src = img ;
img = imgObj ;
}
return new FillStylePattern ( img , pattern ) ;
}
createLinearGradient ( x0 , y0 , x1 , y1 ) {
return new FillStyleLinearGradient ( x0 , y0 , x1 , y1 ) ;
}
createRadialGradient = function ( x0 , y0 , r0 , x1 , y1 , r1 ) {
return new FillStyleRadialGradient ( x0 , y0 , r0 , x1 , y1 , r1 ) ;
} ;
createCircularGradient = function ( x0 , y0 , r0 ) {
return new FillStyleRadialGradient ( x0 , y0 , 0 , x0 , y0 , r0 ) ;
} ;
strokeRect ( x , y , w , h ) {
this . _drawCommands = this . _drawCommands . concat ( "s" + x + "," + y + "," + w + "," + h + ";" ) ;
}
clearRect ( x , y , w , h ) {
this . _drawCommands = this . _drawCommands . concat ( "c" + x + "," + y + "," + w +
"," + h + ";" ) ;
}
clip ( ) {
this . _drawCommands = this . _drawCommands . concat ( "p;" ) ;
}
resetClip ( ) {
this . _drawCommands = this . _drawCommands . concat ( "q;" ) ;
}
closePath ( ) {
this . _drawCommands = this . _drawCommands . concat ( "o;" ) ;
}
moveTo ( x , y ) {
this . _drawCommands = this . _drawCommands . concat ( "g" + x . toFixed ( 2 ) + "," + y . toFixed ( 2 ) + ";" ) ;
}
lineTo ( x , y ) {
this . _drawCommands = this . _drawCommands . concat ( "i" + x . toFixed ( 2 ) + "," + y . toFixed ( 2 ) + ";" ) ;
}
quadraticCurveTo = function ( cpx , cpy , x , y ) {
this . _drawCommands = this . _drawCommands . concat ( "u" + cpx + "," + cpy + "," + x + "," + y + ";" ) ;
}
bezierCurveTo ( cp1x , cp1y , cp2x , cp2y , x , y , ) {
this . _drawCommands = this . _drawCommands . concat (
"z" + cp1x . toFixed ( 2 ) + "," + cp1y . toFixed ( 2 ) + "," + cp2x . toFixed ( 2 ) + "," + cp2y . toFixed ( 2 ) + "," +
x . toFixed ( 2 ) + "," + y . toFixed ( 2 ) + ";" ) ;
}
arcTo ( x1 , y1 , x2 , y2 , radius ) {
this . _drawCommands = this . _drawCommands . concat ( "h" + x1 + "," + y1 + "," + x2 + "," + y2 + "," + radius + ";" ) ;
}
beginPath ( ) {
this . _drawCommands = this . _drawCommands . concat ( "b;" ) ;
}
fillRect ( x , y , w , h ) {
this . _drawCommands = this . _drawCommands . concat ( "n" + x + "," + y + "," + w +
"," + h + ";" ) ;
}
rect ( x , y , w , h ) {
this . _drawCommands = this . _drawCommands . concat ( "w" + x + "," + y + "," + w + "," + h + ";" ) ;
}
fill ( ) {
this . _drawCommands = this . _drawCommands . concat ( "L;" ) ;
}
stroke ( path ) {
this . _drawCommands = this . _drawCommands . concat ( "x;" ) ;
}
arc ( x , y , radius , startAngle , endAngle , anticlockwise ) {
let ianticlockwise = 0 ;
if ( anticlockwise ) {
ianticlockwise = 1 ;
}
this . _drawCommands = this . _drawCommands . concat (
"y" + x . toFixed ( 2 ) + "," + y . toFixed ( 2 ) + "," +
radius . toFixed ( 2 ) + "," + startAngle + "," + endAngle + "," + ianticlockwise +
";"
) ;
}
fillText ( text , x , y ) {
let tmptext = text . replace ( /!/g , "!!" ) ;
tmptext = tmptext . replace ( /,/g , "!," ) ;
tmptext = tmptext . replace ( /;/g , "!;" ) ;
this . _drawCommands = this . _drawCommands . concat ( "T" + tmptext + "," + x + "," + y + ",0.0;" ) ;
}
strokeText = function ( text , x , y ) {
let tmptext = text . replace ( /!/g , "!!" ) ;
tmptext = tmptext . replace ( /,/g , "!," ) ;
tmptext = tmptext . replace ( /;/g , "!;" ) ;
this . _drawCommands = this . _drawCommands . concat ( "U" + tmptext + "," + x + "," + y + ",0.0;" ) ;
}
measureText ( text ) {
return CanvasRenderingContext2D . GBridge . measureText ( text , this . font , this . componentId ) ;
}
isPointInPath = function ( x , y ) {
throw new Error ( 'GCanvas not supported yet' ) ;
}
drawImage ( image , sx , sy , sw , sh , dx , dy , dw , dh ) {
if ( typeof image === 'string' ) {
var imgObj = new GImage ( ) ;
imgObj . src = image ;
image = imgObj ;
}
if ( image instanceof GImage ) {
if ( ! image . complete ) {
imgObj . onload = ( ) => {
var index = this . _needRedrawImageCache . indexOf ( image ) ;
if ( index > - 1 ) {
this . _needRedrawImageCache . splice ( index , 1 ) ;
CanvasRenderingContext2D . GBridge . bindImageTexture ( this . componentId , image . src , image . _id ) ;
this . _redrawflush ( true ) ;
}
}
this . _notCommitDrawImageCache . push ( image ) ;
} else {
CanvasRenderingContext2D . GBridge . bindImageTexture ( this . componentId , image . src , image . _id ) ;
}
var srcArgs = [ image , sx , sy , sw , sh , dx , dy , dw , dh ] ;
var args = [ ] ;
for ( var arg in srcArgs ) {
if ( typeof ( srcArgs [ arg ] ) != 'undefined' ) {
args . push ( srcArgs [ arg ] ) ;
}
}
this . _ _drawImage . apply ( this , args ) ;
//this.__drawImage(image,sx, sy, sw, sh, dx, dy, dw, dh);
}
}
_ _drawImage ( image , sx , sy , sw , sh , dx , dy , dw , dh ) {
const numArgs = arguments . length ;
function drawImageCommands ( ) {
if ( numArgs === 3 ) {
const x = parseFloat ( sx ) || 0.0 ;
const y = parseFloat ( sy ) || 0.0 ;
return ( "d" + image . _id + ",0,0," +
image . width + "," + image . height + "," +
x + "," + y + "," + image . width + "," + image . height + ";" ) ;
} else if ( numArgs === 5 ) {
const x = parseFloat ( sx ) || 0.0 ;
const y = parseFloat ( sy ) || 0.0 ;
const width = parseInt ( sw ) || image . width ;
const height = parseInt ( sh ) || image . height ;
return ( "d" + image . _id + ",0,0," +
image . width + "," + image . height + "," +
x + "," + y + "," + width + "," + height + ";" ) ;
} else if ( numArgs === 9 ) {
sx = parseFloat ( sx ) || 0.0 ;
sy = parseFloat ( sy ) || 0.0 ;
sw = parseInt ( sw ) || image . width ;
sh = parseInt ( sh ) || image . height ;
dx = parseFloat ( dx ) || 0.0 ;
dy = parseFloat ( dy ) || 0.0 ;
dw = parseInt ( dw ) || image . width ;
dh = parseInt ( dh ) || image . height ;
return ( "d" + image . _id + "," +
sx + "," + sy + "," + sw + "," + sh + "," +
dx + "," + dy + "," + dw + "," + dh + ";" ) ;
}
}
this . _drawCommands += drawImageCommands ( ) ;
}
_flush ( reserve , callback ) {
const commands = this . _drawCommands ;
this . _drawCommands = '' ;
CanvasRenderingContext2D . GBridge . render2d ( this . componentId , commands , callback ) ;
this . _needRender = false ;
}
_redrawflush ( reserve , callback ) {
const commands = this . _redrawCommands ;
CanvasRenderingContext2D . GBridge . render2d ( this . componentId , commands , callback ) ;
if ( this . _needRedrawImageCache . length == 0 ) {
this . _redrawCommands = '' ;
}
}
draw ( reserve , callback ) {
if ( ! reserve ) {
this . _globalAlpha = this . _savedGlobalAlpha . pop ( ) ;
this . _savedGlobalAlpha . push ( this . _globalAlpha ) ;
this . _redrawCommands = this . _drawCommands ;
this . _needRedrawImageCache = this . _notCommitDrawImageCache ;
if ( this . _autoSaveContext ) {
this . _drawCommands = ( "v;" + this . _drawCommands ) ;
this . _autoSaveContext = false ;
} else {
this . _drawCommands = ( "e;X;v;" + this . _drawCommands ) ;
}
} else {
this . _needRedrawImageCache = this . _needRedrawImageCache . concat ( this . _notCommitDrawImageCache ) ;
this . _redrawCommands += this . _drawCommands ;
if ( this . _autoSaveContext ) {
this . _drawCommands = ( "v;" + this . _drawCommands ) ;
this . _autoSaveContext = false ;
}
}
this . _notCommitDrawImageCache = [ ] ;
if ( this . _flush ) {
this . _flush ( reserve , callback ) ;
}
}
getImageData ( x , y , w , h , callback ) {
CanvasRenderingContext2D . GBridge . getImageData ( this . componentId , x , y , w , h , function ( res ) {
res . data = Base64ToUint8ClampedArray ( res . data ) ;
if ( typeof ( callback ) == 'function' ) {
callback ( res ) ;
}
} ) ;
}
putImageData ( data , x , y , w , h , callback ) {
if ( data instanceof Uint8ClampedArray ) {
data = ArrayBufferToBase64 ( data ) ;
CanvasRenderingContext2D . GBridge . putImageData ( this . componentId , data , x , y , w , h , function ( res ) {
if ( typeof ( callback ) == 'function' ) {
callback ( res ) ;
}
} ) ;
}
}
toTempFilePath ( x , y , width , height , destWidth , destHeight , fileType , quality , callback ) {
CanvasRenderingContext2D . GBridge . toTempFilePath ( this . componentId , x , y , width , height , destWidth , destHeight ,
fileType , quality ,
function ( res ) {
if ( typeof ( callback ) == 'function' ) {
callback ( res ) ;
}
} ) ;
}
}