1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044 |
- import beziercurve from '../bezier-curve'
- import {
- calcLength,
- getPointOnQuadraticBezier,
- getTensionPointsClosed,
- expandPoints
- } from '../bezier-curve/core/path2d'
- import {
- deepClone,
- eliminateBlur,
- checkPointIsInCircle,
- getTwoPointDistance,
- checkPointIsInSector,
- getRegularPolygonPoints,
- checkPointIsInPolygon,
- checkPointIsNearPolyline,
- checkPointIsInRect
- } from '../plugin/util'
- import {
- drawPolylinePath,
- drawBezierCurvePath
- } from '../plugin/canvas'
- const {
- polylineToBezierCurve,
- bezierCurveToPolyline
- } = beziercurve
- export const circle = {
- shape: {
- rx: 0,
- ry: 0,
- r: 0
- },
- validator({
- shape
- }) {
- const {
- rx,
- ry,
- r
- } = shape
- if (typeof rx !== 'number' || typeof ry !== 'number' || typeof r !== 'number') {
- console.error('Circle shape configuration is abnormal!')
- return false
- }
- return true
- },
- draw({
- ctx
- }, {
- shape
- }) {
- ctx.beginPath()
- const {
- rx,
- ry,
- r
- } = shape
- ctx.arc(rx, ry, r > 0 ? r : 0.01, 0, Math.PI * 2)
- ctx.fill()
- ctx.stroke()
- ctx.closePath()
- // ctx.draw()
- },
- hoverCheck(position, {
- shape
- }) {
- const {
- rx,
- ry,
- r
- } = shape
- return checkPointIsInCircle(position, rx, ry, r)
- },
- setGraphCenter(e, {
- shape,
- style
- }) {
- const {
- rx,
- ry
- } = shape
- style.graphCenter = [rx, ry]
- },
- move({
- movementX,
- movementY
- }, {
- shape
- }) {
- this.attr('shape', {
- rx: shape.rx + movementX,
- ry: shape.ry + movementY
- })
- }
- }
- export const ellipse = {
- shape: {
- rx: 0,
- ry: 0,
- hr: 0,
- vr: 0
- },
- validator({
- shape
- }) {
- const {
- rx,
- ry,
- hr,
- vr
- } = shape
- if (typeof rx !== 'number' || typeof ry !== 'number' || typeof hr !== 'number' || typeof vr !== 'number') {
- console.error('Ellipse shape configuration is abnormal!')
- return false
- }
- return true
- },
- draw({
- ctx
- }, {
- shape
- }) {
- ctx.beginPath()
- let {
- rx,
- ry,
- hr,
- vr
- } = shape
- ctx.ellipse(rx, ry, hr > 0 ? hr : 0.01, vr > 0 ? vr : 0.01, 0, 0, Math.PI * 2)
- ctx.fill()
- ctx.stroke()
- ctx.closePath()
- // ctx.draw()
- },
- hoverCheck(position, {
- shape
- }) {
- const {
- rx,
- ry,
- hr,
- vr
- } = shape
- const a = Math.max(hr, vr)
- const b = Math.min(hr, vr)
- const c = Math.sqrt(a * a - b * b)
- const leftFocusPoint = [rx - c, ry]
- const rightFocusPoint = [rx + c, ry]
- const distance = getTwoPointDistance(position, leftFocusPoint) + getTwoPointDistance(position,
- rightFocusPoint)
- return distance <= 2 * a
- },
- setGraphCenter(e, {
- shape,
- style
- }) {
- const {
- rx,
- ry
- } = shape
- style.graphCenter = [rx, ry]
- },
- move({
- movementX,
- movementY
- }, {
- shape
- }) {
- this.attr('shape', {
- rx: shape.rx + movementX,
- ry: shape.ry + movementY
- })
- }
- }
- export const rect = {
- shape: {
- x: 0,
- y: 0,
- w: 0,
- h: 0
- },
- validator({
- shape
- }) {
- const {
- x,
- y,
- w,
- h
- } = shape
- if (typeof x !== 'number' || typeof y !== 'number' || typeof w !== 'number' || typeof h !== 'number') {
- console.error('Rect shape configuration is abnormal!')
- return false
- }
- return true
- },
- draw({
- ctx
- }, {
- shape
- }) {
- ctx.beginPath()
- let {
- x,
- y,
- w,
- h
- } = shape
- ctx.rect(x, y, w, h)
- ctx.fill()
- ctx.stroke()
- ctx.closePath()
- // ctx.draw()
- },
- hoverCheck(position, {
- shape
- }) {
- let {
- x,
- y,
- w,
- h
- } = shape
- return checkPointIsInRect(position, x, y, w, h)
- },
- setGraphCenter(e, {
- shape,
- style
- }) {
- const {
- x,
- y,
- w,
- h
- } = shape
- style.graphCenter = [x + w / 2, y + h / 2]
- },
- move({
- movementX,
- movementY
- }, {
- shape
- }) {
- this.attr('shape', {
- x: shape.x + movementX,
- y: shape.y + movementY
- })
- }
- }
- export const rectRound = {
- shape: {
- x: 0,
- y: 0,
- w: 0,
- h: 0,
- radius:[0,0,0,0],
- close:false,//true时为填充,否则描边。
- },
- validator({
- shape
- }) {
- const {
- x,
- y,
- w,
- h
- } = shape
- if (typeof x !== 'number' || typeof y !== 'number' || typeof w !== 'number' || typeof h !== 'number') {
- console.error('Rect shape configuration is abnormal!')
- return false
- }
- return true
- },
- draw({
- ctx
- }, {
- shape
- }) {
- ctx.beginPath()
- let {
- x,
- y,
- w,
- h,
- radius,
- close
- } = shape
-
- if(typeof radius ==='number'){
- radius = [radius,radius,radius,radius]
- }
- const cxt = ctx;
- let width = w,height = h;
- var r0 = radius[0],r1 = radius[1],r2 = radius[2],r3 = radius[3];
- cxt.beginPath();
- //从右下角顺时针绘制,弧度从0到1/2PI
- cxt.arc(width - r0+x, height - r0+y, r0, 0, Math.PI / 2);
-
- //矩形下边线
- cxt.lineTo(r1+x, height+y);
-
- //左下角圆弧,弧度从1/2PI到PI
- cxt.arc(r1+x, height - r1+y, r1, Math.PI / 2, Math.PI);
-
- //矩形左边线
- cxt.lineTo(x, r2+y);
-
- //左上角圆弧,弧度从PI到3/2PI
- cxt.arc(r2+x, r2+y, r2, Math.PI, Math.PI * 3 / 2);
-
- //上边线
- cxt.lineTo(width - r3+x, y);
-
- //右上角圆弧
- cxt.arc(width - r3+x, r3+y, r3, Math.PI * 3 / 2, Math.PI * 2);
-
- //右边线
- cxt.lineTo(width+x, height+y-r0);
- ctx.stroke()
- if(close){
- ctx.fill()
- }
- cxt.closePath();
- },
- hoverCheck(position, {
- shape,style,
- }) {
- let {
- x,
- y,
- w,
- h
- } = shape
- let {lineWidth} = style;
- return checkPointIsInRect(position, x-lineWidth, y-lineWidth, w+lineWidth, h+lineWidth)
- },
- setGraphCenter(e, {
- shape,
- style
- }) {
- const {
- x,
- y,
- w,
- h
- } = shape
- style.graphCenter = [x + w / 2, y + h / 2]
- },
- move({
- movementX,
- movementY
- }, {
- shape
- }) {
- this.attr('shape', {
- x: shape.x + movementX,
- y: shape.y + movementY
- })
- }
- }
- export const ring = {
- shape: {
- rx: 0,
- ry: 0,
- r: 0
- },
- validator({
- shape
- }) {
- const {
- rx,
- ry,
- r
- } = shape
- if (typeof rx !== 'number' || typeof ry !== 'number' || typeof r !== 'number') {
- console.error('Ring shape configuration is abnormal!')
- return false
- }
- return true
- },
- draw({
- ctx
- }, {
- shape
- }) {
- ctx.beginPath()
- const {
- rx,
- ry,
- r
- } = shape
- ctx.arc(rx, ry, r > 0 ? r : 0.01, 0, Math.PI * 2)
- ctx.stroke()
- ctx.closePath()
- // ctx.draw()
- },
- hoverCheck(position, {
- shape,
- style
- }) {
- const {
- rx,
- ry,
- r
- } = shape
- const {
- lineWidth
- } = style
- const halfLineWidth = lineWidth / 2
- const minDistance = r - halfLineWidth
- const maxDistance = r + halfLineWidth
- const distance = getTwoPointDistance(position, [rx, ry])
- return (distance >= minDistance && distance <= maxDistance)
- },
- setGraphCenter(e, {
- shape,
- style
- }) {
- const {
- rx,
- ry
- } = shape
- style.graphCenter = [rx, ry]
- },
- move({
- movementX,
- movementY
- }, {
- shape
- }) {
- this.attr('shape', {
- rx: shape.rx + movementX,
- ry: shape.ry + movementY
- })
- }
- }
- export const arc = {
- shape: {
- rx: 0,
- ry: 0,
- r: 0,
- startAngle: 0,
- endAngle: 0,
- clockWise: true
- },
- validator({
- shape
- }) {
- const keys = ['rx', 'ry', 'r', 'startAngle', 'endAngle']
- if (keys.find(key => typeof shape[key] !== 'number')) {
- console.error('Arc shape configuration is abnormal!')
- return false
- }
- return true
- },
- draw({
- ctx
- }, {
- shape
- }) {
- ctx.beginPath()
- const {
- rx,
- ry,
- r,
- startAngle,
- endAngle,
- clockWise
- } = shape
- ctx.arc(rx, ry, r > 0 ? r : 0.001, startAngle, endAngle, !clockWise)
- ctx.stroke()
- ctx.closePath()
- // ctx.draw(true)
- },
- hoverCheck(position, {
- shape,
- style
- }) {
- const {
- rx,
- ry,
- r,
- startAngle,
- endAngle,
- clockWise
- } = shape
- const {
- lineWidth
- } = style
- const halfLineWidth = lineWidth / 2
- const insideRadius = r - halfLineWidth
- const outsideRadius = r + halfLineWidth
- return !checkPointIsInSector(position, rx, ry, insideRadius, startAngle, endAngle, clockWise) &&
- checkPointIsInSector(position, rx, ry, outsideRadius, startAngle, endAngle, clockWise)
- },
- setGraphCenter(e, {
- shape,
- style
- }) {
- const {
- rx,
- ry
- } = shape
- style.graphCenter = [rx, ry]
- },
- move({
- movementX,
- movementY
- }, {
- shape
- }) {
- this.attr('shape', {
- rx: shape.rx + movementX,
- ry: shape.ry + movementY
- })
- }
- }
- export const sector = {
- shape: {
- rx: 0,
- ry: 0,
- r: 0,
- startAngle: 0,
- endAngle: 0,
- clockWise: true
- },
- validator({
- shape
- }) {
- const keys = ['rx', 'ry', 'r', 'startAngle', 'endAngle']
- if (keys.find(key => typeof shape[key] !== 'number')) {
- console.error('Sector shape configuration is abnormal!')
- return false
- }
- return true
- },
- draw({
- ctx
- }, {
- shape
- }) {
- ctx.beginPath()
- const {
- rx,
- ry,
- r,
- startAngle,
- endAngle,
- clockWise
- } = shape
- ctx.arc(rx, ry, r > 0 ? r : 0.01, startAngle, endAngle, !clockWise)
- ctx.lineTo(rx, ry)
- ctx.closePath()
- ctx.stroke()
- ctx.fill()
- // ctx.draw()
- },
- hoverCheck(position, {
- shape
- }) {
- const {
- rx,
- ry,
- r,
- startAngle,
- endAngle,
- clockWise
- } = shape
- return checkPointIsInSector(position, rx, ry, r, startAngle, endAngle, clockWise)
- },
- setGraphCenter(e, {
- shape,
- style
- }) {
- const {
- rx,
- ry
- } = shape
- style.graphCenter = [rx, ry]
- },
- move({
- movementX,
- movementY
- }, {
- shape
- }) {
- const {
- rx,
- ry
- } = shape
- this.attr('shape', {
- rx: rx + movementX,
- ry: ry + movementY
- })
- }
- }
- export const regPolygon = {
- shape: {
- rx: 0,
- ry: 0,
- r: 0,
- side: 0
- },
- validator({
- shape
- }) {
- const {
- side
- } = shape
- const keys = ['rx', 'ry', 'r', 'side']
- if (keys.find(key => typeof shape[key] !== 'number')) {
- console.error('RegPolygon shape configuration is abnormal!')
- return false
- }
- if (side < 3) {
- console.error('RegPolygon at least trigon!')
- return false
- }
- return true
- },
- draw({
- ctx
- }, {
- shape,
- cache
- }) {
- ctx.beginPath()
- const {
- rx,
- ry,
- r,
- side
- } = shape
- if (!cache.points || cache.rx !== rx || cache.ry !== ry || cache.r !== r || cache.side !== side) {
- const points = getRegularPolygonPoints(rx, ry, r, side)
- Object.assign(cache, {
- points,
- rx,
- ry,
- r,
- side
- })
- }
- const {
- points
- } = cache
- drawPolylinePath(ctx, points)
- ctx.closePath()
- ctx.stroke()
- ctx.fill()
- // ctx.draw()
- },
- hoverCheck(position, {
- cache
- }) {
- let {
- points
- } = cache
- return checkPointIsInPolygon(position, points)
- },
- setGraphCenter(e, {
- shape,
- style
- }) {
- const {
- rx,
- ry
- } = shape
- style.graphCenter = [rx, ry]
- },
- move({
- movementX,
- movementY
- }, {
- shape,
- cache
- }) {
- const {
- rx,
- ry
- } = shape
- cache.rx += movementX
- cache.ry += movementY
- this.attr('shape', {
- rx: rx + movementX,
- ry: ry + movementY
- })
- cache.points = cache.points.map(([x, y]) => [x + movementX, y + movementY])
- }
- }
- export const polyline = {
- shape: {
- points: [],
- close: false
- },
- validator({
- shape
- }) {
- const {
- points
- } = shape
- if (!(points instanceof Array)) {
- console.error('Polyline points should be an array!')
- return false
- }
- return true
- },
- draw({
- ctx
- }, {
- shape,
- style: {
- lineWidth
- }
- }) {
- ctx.beginPath()
- let {
- points,
- close
- } = shape
- if (lineWidth === 1) points = eliminateBlur(points)
- drawPolylinePath(ctx, points)
- if (close) {
- ctx.closePath()
- ctx.fill()
- ctx.stroke()
- } else {
- ctx.stroke()
- }
- // ctx.draw()
- },
- hoverCheck(position, {
- shape,
- style
- }) {
- const {
- points,
- close
- } = shape
- const {
- lineWidth
- } = style
- if (close) {
- return checkPointIsInPolygon(position, points)
- } else {
- return checkPointIsNearPolyline(position, points, lineWidth)
- }
- },
- setGraphCenter(e, {
- shape,
- style
- }) {
- const {
- points
- } = shape
- style.graphCenter = points[0]
- },
- move({
- movementX,
- movementY
- }, {
- shape
- }) {
- const {
- points
- } = shape
- const moveAfterPoints = points.map(([x, y]) => [x + movementX, y + movementY])
- this.attr('shape', {
- points: moveAfterPoints
- })
- }
- }
- export const smoothline = {
- shape: {
- points: [],
- close: false
- },
- validator({
- shape
- }) {
- const {
- points
- } = shape
- if (!(points instanceof Array)) {
- console.error('Smoothline points should be an array!')
- return false
- }
- return true
- },
- draw({
- ctx
- }, {
- shape,
- cache
- }) {
- const {
- points,
- close
- } = shape
- if (!cache.points || cache.points.toString() !== points.toString()) {
- const bezierCurve = polylineToBezierCurve(points, close)
- const hoverPoints = bezierCurveToPolyline(bezierCurve)
- Object.assign(cache, {
- points: deepClone(points, true),
- bezierCurve,
- hoverPoints
- })
- }
- const {
- bezierCurve
- } = cache
- ctx.beginPath()
- drawBezierCurvePath(ctx, bezierCurve.slice(1), bezierCurve[0])
- if (close) {
- ctx.closePath()
- ctx.fill()
- ctx.stroke()
- } else {
- ctx.stroke()
- }
- // ctx.draw()
- },
- hoverCheck(position, {
- cache,
- shape,
- style
- }) {
- const {
- hoverPoints
- } = cache
- const {
- close
- } = shape
- const {
- lineWidth
- } = style
- if (close) {
- return checkPointIsInPolygon(position, hoverPoints)
- } else {
- return checkPointIsNearPolyline(position, hoverPoints, lineWidth)
- }
- },
- setGraphCenter(e, {
- shape,
- style
- }) {
- const {
- points
- } = shape
- style.graphCenter = points[0]
- },
- move({
- movementX,
- movementY
- }, {
- shape,
- cache
- }) {
- const {
- points
- } = shape
- const moveAfterPoints = points.map(([x, y]) => [x + movementX, y + movementY])
- cache.points = moveAfterPoints
- const [fx, fy] = cache.bezierCurve[0]
- const curves = cache.bezierCurve.slice(1)
- cache.bezierCurve = [
- [fx + movementX, fy + movementY],
- ...curves.map(curve => curve.map(([x, y]) => [x + movementX, y + movementY]))
- ]
- cache.hoverPoints = cache.hoverPoints.map(([x, y]) => [x + movementX, y + movementY])
- this.attr('shape', {
- points: moveAfterPoints
- })
- }
- }
- export const bezierCurve = {
- shape: {
- points: [],
- close: false
- },
- validator({
- shape
- }) {
- const {
- points
- } = shape
- if (!(points instanceof Array)) {
- console.error('BezierCurve points should be an array!')
- return false
- }
- return true
- },
- draw({
- ctx
- }, {
- shape,
- cache
- }) {
- let {
- points,
- close
- } = shape
- if (!cache.points || cache.points.toString() !== points.toString()) {
- const hoverPoints = bezierCurveToPolyline(points, 20)
- Object.assign(cache, {
- points: deepClone(points, true),
- hoverPoints
- })
- }
- ctx.beginPath()
- drawBezierCurvePath(ctx, points.slice(1), points[0])
- if (close) {
- ctx.closePath()
- ctx.fill()
- ctx.stroke()
- } else {
- ctx.stroke()
- }
- // ctx.draw()
- },
- hoverCheck(position, {
- cache,
- shape,
- style
- }) {
- const {
- hoverPoints
- } = cache
- const {
- close
- } = shape
- const {
- lineWidth
- } = style
- if (close) {
- return checkPointIsInPolygon(position, hoverPoints)
- } else {
- return checkPointIsNearPolyline(position, hoverPoints, lineWidth)
- }
- },
- setGraphCenter(e, {
- shape,
- style
- }) {
- const {
- points
- } = shape
- style.graphCenter = points[0]
- },
- move({
- movementX,
- movementY
- }, {
- shape,
- cache
- }) {
- const {
- points
- } = shape
- const [fx, fy] = points[0]
- const curves = points.slice(1)
- const bezierCurve = [
- [fx + movementX, fy + movementY],
- ...curves.map(curve => curve.map(([x, y]) => [x + movementX, y + movementY]))
- ]
- cache.points = bezierCurve
- cache.hoverPoints = cache.hoverPoints.map(([x, y]) => [x + movementX, y + movementY])
- this.attr('shape', {
- points: bezierCurve
- })
- }
- }
- export const text = {
- shape: {
- content: '',
- position: [],
- x: 0,
- y: 0,
- rowGap: 0
- },
- validator({
- shape,
- style
- }, ctx) {
- const {
- content,
- position,
- rowGap
- } = shape
- if (typeof content !== 'string') {
- console.error('Text content should be a string!')
- return false
- }
- if (!(position instanceof Array)) {
- console.error('Text position should be an array!')
- return false
- }
- if (typeof rowGap !== 'number') {
- console.error('Text rowGap should be a number!')
- return false
- }
- this.textWidth = 0
- this.textHeight = 0
- return true
- },
- measureSize(ctx, text) {
- var _context = ctx,
- fontSize = this.fontSize(),
- metrics;
- _context.save();
- _context.font = ctx.font;
- metrics = _context.measureText(text + "");
- _context.restore();
- return {
- width: metrics.width,
- height: fontSize,
- };
- },
- draw({
- ctx,
- area
- }, {
- shape,
- style
- }) {
- let {
- content,
- position,
- maxWidth,
- rowGap,
- } = shape
- let {
- lineWidth
- } = style;
- const {
- textBaseline,
- font,
- } = ctx
- const [w, h] = area
- const fontSize = parseInt(font.replace(/\D/g, ''))
- let [x, y] = position
- content = content.split('\n')
- const rowNum = content.length
- const lineHeight = fontSize + rowGap
- const allHeight = rowNum * lineHeight - rowGap
- let offset = 0
- if (textBaseline === 'middle') {
- offset = allHeight / 2
- y += fontSize / 2
- }
- if (textBaseline === 'bottom') {
- offset = allHeight
- y += fontSize
- }
- position = new Array(rowNum).fill(0).map((foo, i) => [x, y + i * lineHeight - offset])
- if (typeof maxWidth == 'undefined' || !maxWidth) maxWidth = w
- // #ifdef H5
- maxWidth = maxWidth * ctx.dpr
-
- // #endif
- let maxwi = []
- ctx.beginPath()
- content.forEach((text, i) => {
- ctx.fillText(text, ...position[i], maxWidth)
- if (lineWidth > 0) {
- ctx.strokeText(text, ...position[i], maxWidth)
- }
- maxwi.push(ctx.measureText(text + "").width)
- })
- ctx.closePath()
- this.textWidth = Math.max(...maxwi)
-
- this.textHeight = allHeight
- },
- hoverCheck(position, {
- cache,
- shape,
- style
- }) {
- const [x, y] = shape.position;
- const {
- textBaseline
- } = style;
- var w = this?.textWidth ?? 0;
- var h = this?.textHeight ?? 0;
- let isCheck = false;
- if (textBaseline == 'top') {
- if (position[0] >= x && position[0] <= x + w && position[1] >= y && position[1] <= y + h) {
- isCheck = true;
- }
- } else if (textBaseline == 'bottom') {
- if (position[0] >= x && position[0] <= x + w && position[1] >= y + h && position[1] <= y + h * 2) {
- isCheck = true;
- }
- } else if (textBaseline == 'middle') {
- if (position[0] >= x && position[0] <= x + w && position[1] >= y - h / 2 && position[1] <= y + h - h /
- 2) {
- isCheck = true;
- }
- }
- return isCheck;
- },
- setGraphCenter(e, {
- shape,
- style
- }) {
- const {
- position
- } = shape
- style.graphCenter = [...position]
- },
- move({
- movementX,
- movementY
- }, {
- shape
- }) {
- const {
- position: [x, y]
- } = shape
- this.attr('shape', {
- position: [x + movementX, y + movementY]
- })
- }
- }
- export const path = {
- shape: {
- points: [],
- close: false
- },
- validator({
- shape
- }) {
- const {
- points
- } = shape
- if (!(points instanceof Array)) {
- console.error('Polyline points should be an array!')
- return false
- }
- return true
- },
- draw({
- ctx
- }, {
- shape,
- style: {
- lineWidth
- }
- }) {
- ctx.beginPath()
- let {
- points,
- close
- } = shape
- if (lineWidth === 1) points = eliminateBlur(points)
- drawPolylinePath(ctx, points)
- if (close) {
- ctx.closePath()
- ctx.fill()
- ctx.stroke()
- } else {
- ctx.stroke()
- }
- ctx.draw()
- },
- hoverCheck(position, {
- shape,
- style
- }) {
- const {
- points,
- close
- } = shape
- const {
- lineWidth
- } = style
- if (close) {
- return checkPointIsInPolygon(position, points)
- } else {
- return checkPointIsNearPolyline(position, points, lineWidth)
- }
- },
- setGraphCenter(e, {
- shape,
- style
- }) {
- const {
- points
- } = shape
- style.graphCenter = points[0]
- },
- move({
- movementX,
- movementY
- }, {
- shape
- }) {
- const {
- points
- } = shape
- const moveAfterPoints = points.map(([x, y]) => [x + movementX, y + movementY])
- this.attr('shape', {
- points: moveAfterPoints
- })
- }
- }
- export const image = {
- shape: {
- x: 0,
- y: 0,
- w: 0,
- h: 0,
- sx: 0,
- sy: 0,
- src: ''
- },
- validator({
- shape
- }) {
- const {
- x,
- y,
- w,
- h,
- src
- } = shape
- if (typeof x !== 'number' || typeof y !== 'number' || typeof w !== 'number' || typeof h !== 'number' || !
- src) {
- console.error('image x,y,w,h,src必填。')
- return false
- }
- return true
- },
- draw({
- ctx,
- cav
- }, {
- shape
- }) {
- let {
- x,
- y,
- w,
- h,
- sx,
- sy,
- src
- } = shape
- let t = this;
- // #ifdef MP-WEIXIN
- //1加载中,2加载完成,3从未加载。
- if (typeof this['isLoad'] == 'undefined' || this['isLoad'] == 3) {
-
- this['isLoad'] = 1;
- const bg = cav.createImage()
- bg.onload = () => {
- setTimeout(function() {
- console.warn('tm-render:图片加载完成')
- ctx.drawImage(bg, x, y, w, h)
- t['isLoad'] = 2;
- shape.src = bg
- if(t?.load){
- t.load();
- }
- }, 400)
- }
- bg.onerror = () => t['isLoad'] = 3
- bg.src = src;
- }
- if (this['isLoad'] == 2) {
-
- ctx.drawImage(src, x, y, w, h)
-
- } else {
- console.log('image loadding...');
- }
- // #endif
- // #ifndef MP-WEIXIN
-
- if(typeof this['isLoad'] =='undefined') this['isLoad'] = 3;
- if(this['isLoad']===3){
- this['isLoad'] = 1;
-
- setTimeout(()=>{
- t['isLoad'] = 2;
- if(this?.load){
- this.load();
- }
- },1200)
- }
-
- ctx.drawImage(src, x, y, w, h, sx, sy)
-
- // #endif
- },
- hoverCheck(position, {
- shape
- }) {
- let {
- x,
- y,
- w,
- h
- } = shape
- return checkPointIsInRect(position, x, y, w, h)
- },
- setGraphCenter(e, {
- shape,
- style
- }) {
- const {
- x,
- y,
- w,
- h
- } = shape
- style.graphCenter = [x + w / 2, y + h / 2]
- },
- move({
- movementX,
- movementY
- }, {
- shape
- }) {
- this.attr('shape', {
- x: shape.x + movementX,
- y: shape.y + movementY
- })
- }
- }
- export const star = {
- shape: {
- points: [],
- close: false,
- x: 0,
- y: 0,
- numPoints: 5, //星星的角数量
- innerRadius: 40, //内部凹进去的比例
- outerRadius: 70, //角向外凸出的比例。
- },
- validator({
- shape
- }) {
- const {
- points,
- x,
- y
- } = shape
- if (typeof x !== 'number' || typeof y !== 'number') {
- console.error('Polyline points should be an array!')
- return false
- }
- return true
- },
- draw({
- ctx
- }, {
- shape,
- style: {
- lineWidth
- }
- }) {
- let context = ctx;
- let {
- points,
- close,
- x,
- y,
- numPoints,
- innerRadius,
- outerRadius
- } = shape;
- context.beginPath();
- context.moveTo(x, y - outerRadius);
- points.push([x, y - outerRadius])
- for (var n = 1; n <= numPoints * 2; n++) {
- var radius = n % 2 === 0 ? outerRadius : innerRadius;
- var x2 = radius * Math.sin((n * Math.PI) / numPoints);
- var y2 = -1 * radius * Math.cos((n * Math.PI) / numPoints);
- context.lineTo(x2 + x, y2 + y);
- points.push([x2 + x, y2 + y])
- }
- this.shape.points = points;
- if (lineWidth === 1) points = eliminateBlur(points)
- if (close) {
- ctx.closePath()
- ctx.fill()
- ctx.stroke()
- } else {
- ctx.stroke()
- }
- // ctx.draw()
- },
- hoverCheck(position, {
- shape,
- style
- }) {
- const {
- points,
- close
- } = shape
- const {
- lineWidth
- } = style
- if (close) {
- return checkPointIsInPolygon(position, points)
- } else {
- return checkPointIsNearPolyline(position, points, lineWidth)
- }
- },
- setGraphCenter(e, {
- shape,
- style
- }) {
- const {
- points
- } = shape
- style.graphCenter = points[0]
- },
- move({
- movementX,
- movementY
- }, {
- shape
- }) {
- const {
- points
- } = shape
- const moveAfterPoints = points.map(([x, y]) => [x + movementX, y + movementY])
- this.attr('shape', {
- points: moveAfterPoints
- })
- }
- }
- export const arrow = {
- shape: {
- points: [],
- close: true,
- x: 0,
- y: 0,
- tension: 0, //弯曲程度。
- pointerLength: 0, //箭头指针长度。
- pointerWidth: 0, //箭头指针宽度。
- pointerAtBeginning: false, //我们需要在两边画指针吗?默认值为 false。
- pointerAtEnding: true, //结束端显示箭头。
- hitPoints: [], //检测命中点。
- },
- validator({
- shape
- }) {
- const {
- points,
- x,
- y,
- close,
- tension,
- pointerLength,
- pointerWidth,
- pointerAtBeginning,
- pointerAtEnding
- } = shape
- if (typeof x !== 'number' || typeof y !== 'number') {
- console.error('Polyline points should be an array!')
- return false
- }
- return true
- },
- draw({
- ctx
- }, {
- shape,
- style: {
- lineWidth
- }
- }) {
- let context = ctx;
- let {
- points,
- x,
- y,
- close,
- tension,
- pointerLength,
- pointerWidth,
- pointerAtBeginning,
- pointerAtEnding
- } = shape
- let old_x = points[2] - points[0]
- let old_y = points[3] - points[1]
- points[0] = this.shape.x
- points[1] = this.shape.y
- points[2] = this.shape.x + old_x
- points[3] = this.shape.y + old_y
- var PI2 = Math.PI * 2;
- var tp = points;
- var fromTension = tension !== 0 && points.length > 4;
- if (fromTension) {
- if (close) {
- tp = getTensionPointsClosed(points, tension);
- } else {
- tp = expandPoints(points, tension);
- }
- console.log(tp);
- }
- var length = pointerLength;
- var n = points.length;
- var dx, dy;
- if (fromTension) {
- const lp = [
- tp[tp.length - 4],
- tp[tp.length - 3],
- tp[tp.length - 2],
- tp[tp.length - 1],
- points[n - 2],
- points[n - 1],
- ];
- const lastLength = calcLength(tp[tp.length - 4], tp[tp.length - 3], 'C', lp);
- const previous = getPointOnQuadraticBezier(Math.min(1, 1 - length / lastLength), lp[0], lp[1], lp[2],
- lp[3], lp[4], lp[5]);
- dx = points[n - 2] - previous.x;
- dy = points[n - 1] - previous.y;
- } else {
- dx = points[n - 2] - points[n - 4];
- dy = points[n - 1] - points[n - 3];
- }
- var radians = (Math.atan2(dy, dx) + PI2) % PI2;
- var width = pointerWidth;
- this.shape.hitPoints = []
- ctx.save();
- ctx.beginPath();
- ctx.moveTo(points[0], points[1]);
- // #ifdef H5 || APP-VUE
- ctx.lineTo(points[2], points[3]);
- // #endif
- // #ifdef MP
- ctx.lineTo(points[2], points[3]);
- // #endif
- ctx.closePath();
- if (pointerAtEnding) {
- ctx.translate(points[n - 2], points[n - 1]);
- ctx.rotate(radians);
- // #ifdef H5 || APP-VUE
- ctx.moveTo(points[2], points[3]);
- ctx.lineTo(points[2], points[3] - width / 2);
- ctx.lineTo(length + points[2], points[3]);
- ctx.lineTo(points[2], width / 2 + points[3]);
- // #endif
- // #ifdef MP
- ctx.moveTo(0, 0);
- ctx.lineTo(-length, width / 2);
- ctx.lineTo(-length, -width / 2);
- // #endif
- ctx.closePath();
- ctx.restore();
- this.shape.hitPoints.push([points[2], points[3] - width / 2]);
- this.shape.hitPoints.push([length + points[2], points[3]]);
- this.shape.hitPoints.push([points[2], width / 2 + points[3]]);
- }
- if (pointerAtBeginning) {
- if (pointerAtBeginning) {
- ctx.save();
- }
- ctx.translate(x, y);
- if (fromTension) {
- dx = (tp[0] + tp[2]) / 2 - points[0];
- dy = (tp[1] + tp[3]) / 2 - points[1];
- } else {
- dx = points[2] - points[0];
- dy = points[3] - points[1];
- }
- ctx.rotate((Math.atan2(-dy, -dx) + PI2) % PI2);
- // #ifdef H5 || APP-VUE
- ctx.moveTo(points[0], points[1]);
- ctx.lineTo(points[0], points[1] - width / 2);
- ctx.lineTo(-length + points[0], points[1]);
- ctx.lineTo(points[0], width / 2 + points[1]);
- // #endif
- // #ifdef MP
- ctx.moveTo(0, 0);
- ctx.lineTo(-length, width / 2);
- ctx.lineTo(-length, -width / 2);
- // #endif
- ctx.closePath();
- ctx.restore();
- }
- if (close) {
- ctx.fill()
- ctx.stroke()
- } else {
- ctx.stroke()
- }
- },
- hoverCheck(position, {
- shape,
- style
- }) {
- const {
- points,
- hitPoints,
- close,
- pointerLength,
- pointerWidth
- } = shape
- const {
- lineWidth
- } = style
- // if (close) {
- // console.log( checkPointIsInPolygon(position, hitPoints));
- // return checkPointIsInPolygon(position, hitPoints)
- // } else {
- // return checkPointIsNearPolyline(position, hitPoints, lineWidth)
- // }
- // #ifdef H5 || APP-VUE
- return checkPointIsInRect(position, points[2], points[3] - pointerWidth / 2, pointerLength, pointerWidth)
- // #endif
- // #ifdef MP
- return checkPointIsInRect(position, points[2] - pointerLength, points[3] - pointerWidth / 2, pointerLength,
- pointerWidth)
- // #endif
- },
- setGraphCenter(e, {
- shape,
- style
- }) {
- const {
- points
- } = shape
- style.graphCenter = points[0]
- },
- move({
- movementX,
- movementY
- }, {
- shape
- }) {
- const {
- points
- } = shape
- const moveAfterPoints = points.map(([x, y]) => [x + movementX, y + movementY])
- this.attr('shape', {
- points: moveAfterPoints
- })
- }
- }
- const graphs = new Map([
- ['rectRound', rectRound],
- ['arrow', arrow],
- ['star', star],
- ['image', image],
- ['path', path],
- ['circle', circle],
- ['ellipse', ellipse],
- ['rect', rect],
- ['ring', ring],
- ['arc', arc],
- ['sector', sector],
- ['regPolygon', regPolygon],
- ['polyline', polyline],
- ['smoothline', smoothline],
- ['bezierCurve', bezierCurve],
- ['text', text]
- ])
- export default graphs
- /**
- * @description Extend new graph
- * @param {String} name Name of Graph
- * @param {Object} config Configuration of Graph
- * @return {Undefined} Void
- */
- export function extendNewGraph(name, config) {
- if (!name || !config) {
- console.error('ExtendNewGraph Missing Parameters!')
- return
- }
- if (!config.shape) {
- console.error('Required attribute of shape to extendNewGraph!')
- return
- }
- if (!config.validator) {
- console.error('Required function of validator to extendNewGraph!')
- return
- }
- if (!config.draw) {
- console.error('Required function of draw to extendNewGraph!')
- return
- }
- graphs.set(name, config)
- }
|