123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794 |
- <!--
- * @Author: LiZhiWei
- * @Date: 2025-04-10 14:38:27
- * @LastEditors: LiZhiWei
- * @LastEditTime: 2025-04-25 08:43:54
- * @Description:
- -->
- <template>
- <div id="pptx-container" ref="pptxContainer" class="pptx-container"></div>
- </template>
- <script setup>
- import { ref, watch, onMounted } from "vue"
- const props = defineProps({
- pptxJson: Object,
- })
- const pptxContainer = ref(null)
- // 渲染幻灯片
- const renderSlides = () => {
- if (!pptxContainer.value || !props.pptxJson) return
- pptxContainer.value.innerHTML = ""
- const { size, slides } = props.pptxJson
- slides.forEach((slide, index) => {
- const slideElement = createSlideElement(size.width, size.height)
- applySlideBackground(slideElement, slide.fill)
- if (slide.layoutElements && Array.isArray(slide.layoutElements)) {
- processElements(slide.layoutElements, index + 1)
- slide.layoutElements.forEach((element) => {
- const el = createElementByType(element)
- if (!el) return
- slideElement.appendChild(el)
- })
- }
- // 渲染幻灯片元素
- if (slide.elements && Array.isArray(slide.elements)) {
- processElements(slide.elements, index + 1)
- slide.elements.forEach((element) => {
- const el = createElementByType(element)
- if (!el) return
- slideElement.appendChild(el)
- })
- }
- // 添加幻灯片到容器
- pptxContainer.value.appendChild(slideElement)
- })
- // 为所有p标签应用样式
- const pTags = pptxContainer.value.querySelectorAll("p")
- pTags.forEach((p) => {
- p.style.margin = "0px"
- p.style.padding = "0px"
- p.style.wordBreak = "break-word"
- p.style.lineHeight = "1"
- })
- const ulTags = pptxContainer.value.querySelectorAll("ul")
- ulTags.forEach((ul) => {
- ul.style.wordBreak = "break-word"
- ul.style.lineHeight = "1"
- ul.style.padding = "auto 0px"
- ul.style.margin = "0px"
- })
- const olTags = pptxContainer.value.querySelectorAll("ol")
- olTags.forEach((ol) => {
- ol.style.margin = "0px"
- ol.style.padding = "auto 0px"
- ol.style.wordBreak = "break-word"
- ol.style.lineHeight = "1"
- })
- }
- // 创建幻灯片元素
- const createSlideElement = (width, height) => {
- const slideElement = document.createElement("div")
- slideElement.className = "slide"
- slideElement.style.position = "relative"
- slideElement.style.width = width + "px"
- slideElement.style.height = height + "px"
- slideElement.style.border = "1px solid #ccc"
- slideElement.style.margin = "0px auto"
- slideElement.style.marginBottom = "20px"
- slideElement.style.overflow = "hidden"
- return slideElement
- }
- // 应用幻灯片背景
- const applySlideBackground = (slideElement, fill) => {
- if (!fill) return
- if (fill.type === "gradient") {
- const { colors, path, rot } = fill.value
- if (colors && colors.length >= 2) {
- const gradientType = path === "rect" ? "linear" : "radial"
- const gradientAngle =
- gradientType === "linear" ? (90 - (rot || 0)) % 360 : rot || 0
- let gradientString = `${gradientType}-gradient(`
- if (gradientType === "linear") {
- gradientString += `${gradientAngle}deg, `
- }
- colors.forEach((color, i) => {
- gradientString += `${color.color} ${color.pos}${
- i < colors.length - 1 ? ", " : ""
- }`
- })
- gradientString += ")"
- slideElement.style.background = gradientString
- }
- } else if (fill.type === "color") {
- slideElement.style.backgroundColor = fill.value || "#FFFFFF"
- } else if (fill.type === "image" && fill.value.picBase64) {
- // 设置背景图片
- slideElement.style.backgroundImage = `url(${fill.value.picBase64})`
- slideElement.style.backgroundSize = "cover"
- slideElement.style.backgroundPosition = "center"
- slideElement.style.backgroundRepeat = "no-repeat"
- // 如果有背景图片的混合模式
- if (fill.value.blendMode) {
- slideElement.style.backgroundBlendMode = fill.value.blendMode
- }
- // 如果有透明度设置
- if (fill.value.opacity !== undefined) {
- slideElement.style.opacity = fill.value.opacity
- }
- }
- }
- // 根据元素类型创建DOM元素
- const createElementByType = (element) => {
- switch (element.type) {
- case "image":
- return createImageElement(element)
- case "video":
- return createVideoElement(element)
- case "audio":
- return createAudioElement(element)
- case "shape":
- return createShapeElement(element)
- case "table":
- return createTableElement(element)
- case "chart":
- return createChartElement(element)
- case "diagram":
- return createDiagramElement(element)
- case "math":
- return createMathElement(element)
- case "group":
- return createGroupElement(element)
- default:
- return createTextElement(element)
- }
- }
- // 创建组合元素
- const createGroupElement = (element) => {
- // 创建组合容器
- const groupContainer = document.createElement("div")
- groupContainer.className = "group-element"
- groupContainer.style.position = "absolute"
- groupContainer.style.top = element.top + "px"
- groupContainer.style.left = element.left + "px"
- groupContainer.style.width = element.width + "px"
- groupContainer.style.height = element.height + "px"
- groupContainer.style.zIndex = element.order
- groupContainer.style.transformOrigin = "center center"
- // 创建内部容器来处理子元素
- const innerContainer = document.createElement("div")
- innerContainer.style.position = "relative"
- innerContainer.style.width = "100%"
- innerContainer.style.height = "100%"
- // 应用旋转变换
- if (element.rotate) {
- groupContainer.style.transform = `rotate(${element.rotate}deg)`
- }
- // 应用其他样式属性
- if (element.opacity !== undefined) {
- groupContainer.style.opacity = element.opacity
- }
- // 递归渲染组内的所有子元素
- if (element.elements && Array.isArray(element.elements)) {
- element.elements.forEach((childElement) => {
- const childCopy = JSON.parse(JSON.stringify(childElement))
- const childEl = createElementByType(childCopy)
- if (childEl) {
- innerContainer.appendChild(childEl)
- }
- })
- }
- groupContainer.appendChild(innerContainer)
- return groupContainer
- }
- // 创建图像元素
- const createImageElement = (element) => {
- const img = document.createElement("img")
- img.src = element.src
- img.style.width = element.width + "px"
- img.style.height = element.height + "px"
- img.style.objectFit = "cover" // 保持图像的宽高比并填充容器
- img.style.position = "absolute"
- img.style.top = `${element.top}px`
- img.style.left = `${element.left}px`
- img.style.zIndex = element.order
- return img
- }
- // 创建视频元素
- const createVideoElement = (element) => {
- const el = document.createElement("video")
- el.src = element.blob
- el.controls = true
- el.style.width = element.width + "px"
- el.style.height = element.height + "px"
- el.style.position = "absolute"
- el.style.top = element.top + "px"
- el.style.left = element.left + "px"
- el.style.zIndex = element.order
- return el
- }
- // 创建音频元素
- const createAudioElement = (element) => {
- const el = document.createElement("audio")
- el.src = element.blob
- el.controls = true
- el.style.height = element.height + "px"
- el.style.position = "absolute"
- el.style.top = element.top + "px"
- el.style.left = element.left + "px"
- el.style.zIndex = element.order
- return el
- }
- // 创建形状元素
- const createShapeElement = (element) => {
- const el = document.createElement("div")
- el.style.position = "absolute"
- el.style.top = element.top + "px"
- el.style.left = element.left + "px"
- el.style.width = element.width + "px"
- el.style.height = element.height + "px"
- el.style.zIndex = element.order
- el.style.overflow = "visible"
- if (element.height === 0) {
- // 如果高度为0,直接在div上绘制边框
- el.style.borderTop = `${element.borderWidth || 1}px ${
- element.borderType || "solid"
- } ${element.borderColor || "#000"}`
- }
- // 使用SVG绘制形状
- const svg = document.createElementNS("http://www.w3.org/2000/svg", "svg")
- svg.setAttribute("width", "100%")
- svg.setAttribute("height", "100%")
- svg.setAttribute("viewBox", `0 0 ${element.width} ${element.height}`)
- svg.style.overflow = "visible"
- const setBackground = (element, shape) => {
- if (element.fill && element.fill.type) {
- // 设置填充色
- if (element.fill.type === "color") {
- shape.setAttribute("fill", element.fill.value || "transparent")
- } else if (element.fill.type === "gradient") {
- // 渐变填充
- const { colors, path, rot } = element.fill.value
- if (colors && colors.length >= 2) {
- const gradientType = path === "rect" ? "linear" : "radial"
- const gradientAngle =
- gradientType === "linear" ? (90 - (rot || 0)) % 360 : rot || 0
- let gradientString = `${gradientType}-gradient(`
- if (gradientType === "linear") {
- gradientString += `${gradientAngle}deg, `
- }
- colors.forEach((color, i) => {
- gradientString += `${color.color} ${color.pos}${
- i < colors.length - 1 ? ", " : ""
- }`
- })
- gradientString += ")"
- // 创建渐变定义
- const gradientDef = document.createElementNS(
- "http://www.w3.org/2000/svg",
- "defs"
- )
- const gradientEl = document.createElementNS(
- "http://www.w3.org/2000/svg",
- gradientType === "linear" ? "linearGradient" : "radialGradient"
- )
- const gradientId = `gradient-${Date.now()}-${Math.random()
- .toString(36)
- .substr(2, 9)}`
- gradientEl.setAttribute("id", gradientId)
- // 设置渐变属性
- if (gradientType === "linear") {
- gradientEl.setAttribute(
- "gradientTransform",
- `rotate(${gradientAngle})`
- )
- }
- // 添加渐变色标
- colors.forEach((color) => {
- const stop = document.createElementNS(
- "http://www.w3.org/2000/svg",
- "stop"
- )
- stop.setAttribute("offset", color.pos)
- stop.setAttribute("stop-color", color.color)
- gradientEl.appendChild(stop)
- })
- gradientDef.appendChild(gradientEl)
- svg.appendChild(gradientDef)
- // 应用渐变
- shape.setAttribute("fill", `url(#${gradientId})`)
- }
- } else if (element.fill.type === "image") {
- // 创建图案填充
- const pattern = document.createElementNS(
- "http://www.w3.org/2000/svg",
- "pattern"
- )
- const patternId = `pattern-${Date.now()}-${Math.random()
- .toString(36)
- .substr(2, 9)}`
- pattern.setAttribute("id", patternId)
- pattern.setAttribute("patternUnits", "userSpaceOnUse")
- pattern.setAttribute("width", "100%")
- pattern.setAttribute("height", "100%")
- // 创建图片元素
- const image = document.createElementNS(
- "http://www.w3.org/2000/svg",
- "image"
- )
- image.setAttribute("width", "100%")
- image.setAttribute("height", "100%")
- image.setAttribute("preserveAspectRatio", "xMidYMid slice")
- image.setAttributeNS(
- "http://www.w3.org/1999/xlink",
- "href",
- element.fill.value.picBase64
- )
- pattern.appendChild(image)
- // 添加pattern到defs
- const defs = document.createElementNS(
- "http://www.w3.org/2000/svg",
- "defs"
- )
- defs.appendChild(pattern)
- svg.appendChild(defs)
- // 应用图案填充
- shape.setAttribute("fill", `url(#${patternId})`)
- } else {
- shape.setAttribute("fill", "transparent")
- }
- } else {
- shape.setAttribute("fill", "#ffffff00")
- }
- }
- // 根据形状类型创建不同的SVG元素
- switch (element.shapType) {
- case "roundRect":
- const radius = Math.min(element.width, element.height) * 0.1
- const roundRect = document.createElementNS(
- "http://www.w3.org/2000/svg",
- "rect"
- )
- roundRect.setAttribute("x", 0)
- roundRect.setAttribute("y", 0)
- roundRect.setAttribute("width", element.width)
- roundRect.setAttribute("height", element.height)
- roundRect.setAttribute("rx", radius)
- roundRect.setAttribute("ry", radius)
- // 设置填充色
- setBackground(element, roundRect)
- // 设置边框
- if (element.borderWidth > 0) {
- roundRect.setAttribute("stroke", element.borderColor || "#000")
- roundRect.setAttribute("stroke-width", element.borderWidth || 1)
- roundRect.setAttribute("stroke-linejoin", "round") // 设置连接处为圆角
- roundRect.setAttribute("vector-effect", "non-scaling-stroke") // 防止边框宽度变形
- roundRect.setAttribute("shape-rendering", "geometricPrecision") // 提高渲染精度
- // 处理虚线边框
- if (
- element.borderType === "dotted" ||
- element.borderType === "dashed"
- ) {
- if (element.borderStrokeDasharray) {
- roundRect.setAttribute(
- "stroke-dasharray",
- element.borderStrokeDasharray
- )
- } else if (element.borderType === "dotted") {
- roundRect.setAttribute("stroke-dasharray", "1, 3")
- } else if (element.borderType === "dashed") {
- roundRect.setAttribute("stroke-dasharray", "5, 5")
- }
- }
- }
- svg.appendChild(roundRect)
- break
- case "snip1Rect":
- // 使用path元素绘制剪去单角的矩形
- const snip1Rect = document.createElementNS(
- "http://www.w3.org/2000/svg",
- "path"
- )
- // 计算剪角的大小,通常为矩形较短边的20%
- const snipSize = Math.min(element.width, element.height) * 0.35
- // 绘制路径:从左上角开始,顺时针方向,右上角被剪去
- snip1Rect.setAttribute(
- "d",
- `M0,0 ` +
- `L${element.width - snipSize},0 ` +
- `L${element.width},${snipSize} ` +
- `L${element.width},${element.height} ` +
- `L0,${element.height} ` +
- `Z`
- )
- // 设置填充色
- setBackground(element, snip1Rect)
- // 设置边框
- if (element.borderWidth > 0) {
- snip1Rect.setAttribute("stroke", element.borderColor || "#000")
- snip1Rect.setAttribute("stroke-width", element.borderWidth || 1)
- // 处理虚线边框
- if (
- element.borderType === "dotted" ||
- element.borderType === "dashed"
- ) {
- if (element.borderStrokeDasharray) {
- snip1Rect.setAttribute(
- "stroke-dasharray",
- element.borderStrokeDasharray
- )
- } else if (element.borderType === "dotted") {
- snip1Rect.setAttribute("stroke-dasharray", "1, 3")
- } else if (element.borderType === "dashed") {
- snip1Rect.setAttribute("stroke-dasharray", "5, 5")
- }
- }
- }
- svg.appendChild(snip1Rect)
- break
- case "snip2SameRect":
- // 使用path元素绘制剪去四个角的矩形
- const snip2SameRect = document.createElementNS(
- "http://www.w3.org/2000/svg",
- "path"
- )
- // 计算剪角的大小,通常为矩形较短边的20%
- const snip2Size = Math.min(element.width, element.height) * 0.35
- // 绘制路径:从左上角开始,顺时针方向,剪去四个角
- snip2SameRect.setAttribute(
- "d",
- `M${snip2Size},0 ` +
- `L${element.width - snip2Size},0 ` +
- `L${element.width},${snip2Size} ` +
- `L${element.width},${element.height - snip2Size} ` +
- `L${element.width - snip2Size},${element.height} ` +
- `L${snip2Size},${element.height} ` +
- `L0,${element.height - snip2Size} ` +
- `L0,${snip2Size} ` +
- `Z`
- )
- // 设置填充色
- setBackground(element, snip2SameRect)
- // 设置边框
- if (element.borderWidth > 0) {
- snip2SameRect.setAttribute("stroke", element.borderColor || "#000")
- snip2SameRect.setAttribute("stroke-width", element.borderWidth || 1)
- // 处理虚线边框
- if (
- element.borderType === "dotted" ||
- element.borderType === "dashed"
- ) {
- if (element.borderStrokeDasharray) {
- snip2SameRect.setAttribute(
- "stroke-dasharray",
- element.borderStrokeDasharray
- )
- } else if (element.borderType === "dotted") {
- snip2SameRect.setAttribute("stroke-dasharray", "2, 2")
- snip2SameRect.setAttribute("stroke-linecap", "round")
- } else if (element.borderType === "dashed") {
- snip2SameRect.setAttribute("stroke-dasharray", "6, 3")
- }
- }
- // 添加这些属性以确保边框正确渲染
- snip2SameRect.setAttribute("vector-effect", "non-scaling-stroke")
- snip2SameRect.setAttribute("shape-rendering", "geometricPrecision")
- }
- svg.appendChild(snip2SameRect)
- break
- case "line":
- // 创建直线连接符
- const line = document.createElementNS(
- "http://www.w3.org/2000/svg",
- "line"
- )
- // 设置SVG的最小高度为1px
- const svgHeight = element.height > 0 ? element.height : 1
- svg.setAttribute("height", svgHeight + "px")
- // 设置线条的起点和终点
- line.setAttribute("x1", 0)
- line.setAttribute("y1", 0)
- line.setAttribute("x2", element.width)
- line.setAttribute("y2", svgHeight)
- // 确保边框颜色和宽度被正确设置
- line.setAttribute("stroke", element.borderColor || "#000")
- line.setAttribute("stroke-width", element.borderWidth || 1)
- // 处理虚线样式
- if (element.borderType === "dotted" || element.borderType === "dashed") {
- if (element.borderStrokeDasharray) {
- line.setAttribute("stroke-dasharray", element.borderStrokeDasharray)
- } else if (element.borderType === "dotted") {
- line.setAttribute("stroke-dasharray", "2, 2")
- line.setAttribute("stroke-linecap", "round") // 添加圆角端点使点线更明显
- } else if (element.borderType === "dashed") {
- line.setAttribute("stroke-dasharray", "6, 3")
- }
- }
- // 确保线条正确渲染
- line.setAttribute("vector-effect", "non-scaling-stroke") // 防止缩放影响线条宽度
- svg.appendChild(line)
- break
- case "snip2DiagRect":
- // 使用path元素绘制剪去右上角和左下角的矩形
- const snip2DiagRect = document.createElementNS(
- "http://www.w3.org/2000/svg",
- "path"
- )
- // 计算剪角的大小,通常为矩形较短边的35%
- const snipDiagSize = Math.min(element.width, element.height) * 0.35
- // 绘制路径:从左上角开始,顺时针方向,右上角和左下角被剪去
- snip2DiagRect.setAttribute(
- "d",
- `M0,0 ` +
- `L${element.width - snipDiagSize},0 ` +
- `L${element.width},${snipDiagSize} ` +
- `L${element.width},${element.height} ` +
- `L${snipDiagSize},${element.height} ` +
- `L0,${element.height - snipDiagSize} ` +
- `Z`
- )
- // 设置填充色
- setBackground(element, snip2DiagRect)
- // 设置边框
- if (element.borderWidth > 0) {
- snip2DiagRect.setAttribute("stroke", element.borderColor || "#000")
- snip2DiagRect.setAttribute("stroke-width", element.borderWidth || 1)
- // 处理虚线边框
- if (
- element.borderType === "dotted" ||
- element.borderType === "dashed"
- ) {
- if (element.borderStrokeDasharray) {
- snip2DiagRect.setAttribute(
- "stroke-dasharray",
- element.borderStrokeDasharray
- )
- } else if (element.borderType === "dotted") {
- snip2DiagRect.setAttribute("stroke-dasharray", "2, 2")
- snip2DiagRect.setAttribute("stroke-linecap", "round")
- } else if (element.borderType === "dashed") {
- snip2DiagRect.setAttribute("stroke-dasharray", "6, 3")
- }
- }
- // 添加这些属性以确保边框正确渲染
- snip2DiagRect.setAttribute("vector-effect", "non-scaling-stroke")
- snip2DiagRect.setAttribute("shape-rendering", "geometricPrecision")
- }
- svg.appendChild(snip2DiagRect)
- break
- case "snipRoundRect":
- const snipRoundRect = document.createElementNS(
- "http://www.w3.org/2000/svg",
- "path"
- )
- // 计算剪切大小和圆角大小
- const snipSize2 = Math.min(element.width, element.height) * 0.4
- const roundSize = Math.min(element.width, element.height) * 0.5
- // 绘制路径:从左上角开始,顺时针方向,左上为圆角,右上为剪切角
- snipRoundRect.setAttribute(
- "d",
- `M${roundSize},0 ` +
- `L${element.width - snipSize2},0 ` +
- `L${element.width},${snipSize2} ` +
- `L${element.width},${element.height} ` +
- `L0,${element.height} ` +
- `L0,${roundSize} ` +
- `A${roundSize},${roundSize} 0 0,1 ${roundSize},0 ` +
- `Z`
- )
- // 设置填充色
- setBackground(element, snipRoundRect)
- // 设置边框
- if (element.borderWidth > 0) {
- snipRoundRect.setAttribute("stroke", element.borderColor || "#000")
- snipRoundRect.setAttribute("stroke-width", element.borderWidth || 1)
- // 处理虚线边框
- if (
- element.borderType === "dotted" ||
- element.borderType === "dashed"
- ) {
- if (element.borderStrokeDasharray) {
- snipRoundRect.setAttribute(
- "stroke-dasharray",
- element.borderStrokeDasharray
- )
- } else if (element.borderType === "dotted") {
- snipRoundRect.setAttribute("stroke-dasharray", "2, 2")
- snipRoundRect.setAttribute("stroke-linecap", "round")
- } else if (element.borderType === "dashed") {
- snipRoundRect.setAttribute("stroke-dasharray", "6, 3")
- }
- }
- snipRoundRect.setAttribute("vector-effect", "non-scaling-stroke")
- snipRoundRect.setAttribute("shape-rendering", "geometricPrecision")
- }
- svg.appendChild(snipRoundRect)
- break
- case "round1Rect":
- const round1Rect = document.createElementNS(
- "http://www.w3.org/2000/svg",
- "path"
- )
- // 计算圆角大小
- const round1Size = Math.min(element.width, element.height) * 0.5
- // 绘制路径:从左上角开始,顺时针方向,右上角为圆角
- round1Rect.setAttribute(
- "d",
- `M0,0 ` +
- `L${element.width - round1Size},0 ` +
- `Q${element.width},0 ${element.width},${round1Size} ` +
- `L${element.width},${element.height} ` +
- `L0,${element.height} ` +
- `Z`
- )
- // 设置填充色
- setBackground(element, round1Rect)
- // 设置边框
- if (element.borderWidth > 0) {
- round1Rect.setAttribute("stroke", element.borderColor || "#000")
- round1Rect.setAttribute("stroke-width", element.borderWidth || 1)
- // 处理虚线边框
- if (
- element.borderType === "dotted" ||
- element.borderType === "dashed"
- ) {
- if (element.borderStrokeDasharray) {
- round1Rect.setAttribute("stroke-dasharray", "40,15,5,15")
- } else if (element.borderType === "dotted") {
- round1Rect.setAttribute("stroke-dasharray", "2, 2")
- round1Rect.setAttribute("stroke-linecap", "round")
- } else if (element.borderType === "dashed") {
- round1Rect.setAttribute("stroke-dasharray", "6, 3")
- }
- }
- round1Rect.setAttribute("vector-effect", "non-scaling-stroke")
- round1Rect.setAttribute("shape-rendering", "geometricPrecision")
- }
- svg.appendChild(round1Rect)
- break
- case "ellipse":
- case "circle":
- const ellipse = document.createElementNS(
- "http://www.w3.org/2000/svg",
- "ellipse"
- )
- ellipse.setAttribute("cx", element.width / 2)
- ellipse.setAttribute("cy", element.height / 2)
- ellipse.setAttribute("rx", element.width / 2)
- ellipse.setAttribute("ry", element.height / 2)
- // 设置填充色
- setBackground(element, ellipse)
- // 设置边框
- if (element.borderWidth > 0) {
- ellipse.setAttribute("stroke", element.borderColor || "#000")
- ellipse.setAttribute("stroke-width", element.borderWidth || 1)
- // 处理虚线边框
- if (
- element.borderType === "dotted" ||
- element.borderType === "dashed"
- ) {
- if (element.borderStrokeDasharray) {
- ellipse.setAttribute(
- "stroke-dasharray",
- element.borderStrokeDasharray
- )
- } else if (element.borderType === "dotted") {
- ellipse.setAttribute("stroke-dasharray", "1, 3")
- } else if (element.borderType === "dashed") {
- ellipse.setAttribute("stroke-dasharray", "5, 5")
- }
- }
- }
- svg.appendChild(ellipse)
- break
- case "round2SameRect":
- const round2SameRect = document.createElementNS(
- "http://www.w3.org/2000/svg",
- "path"
- )
- // 计算圆角大小
- const round2Size = Math.min(element.width, element.height) * 0.5
- // 绘制路径:从左上角开始,顺时针方向,左上和右上为圆角
- round2SameRect.setAttribute(
- "d",
- `M${round2Size},0 ` +
- `L${element.width - round2Size},0 ` +
- `Q${element.width},0 ${element.width},${round2Size} ` +
- `L${element.width},${element.height} ` +
- `L0,${element.height} ` +
- `L0,${round2Size} ` +
- `Q0,0 ${round2Size},0 ` +
- `Z`
- )
- // 设置填充色
- setBackground(element, round2SameRect)
- // 设置边框
- if (element.borderWidth > 0) {
- round2SameRect.setAttribute("stroke", element.borderColor || "#000")
- round2SameRect.setAttribute("stroke-width", element.borderWidth || 1)
- // 处理虚线边框
- if (
- element.borderType === "dotted" ||
- element.borderType === "dashed"
- ) {
- if (element.borderStrokeDasharray) {
- round2SameRect.setAttribute(
- "stroke-dasharray",
- element.borderStrokeDasharray
- )
- } else if (element.borderType === "dotted") {
- round2SameRect.setAttribute("stroke-dasharray", "2, 2")
- round2SameRect.setAttribute("stroke-linecap", "round")
- } else if (element.borderType === "dashed") {
- round2SameRect.setAttribute("stroke-dasharray", "6, 3")
- }
- }
- round2SameRect.setAttribute("vector-effect", "non-scaling-stroke")
- round2SameRect.setAttribute("shape-rendering", "geometricPrecision")
- }
- svg.appendChild(round2SameRect)
- break
- case "round2DiagRect":
- const round2DiagRect = document.createElementNS(
- "http://www.w3.org/2000/svg",
- "path"
- )
- // 计算圆角大小
- const round2DiagSize = Math.min(element.width, element.height) * 0.5
- // 绘制路径:从左上角开始,顺时针方向,左上和右下为圆角
- round2DiagRect.setAttribute(
- "d",
- `M${round2DiagSize},0 ` +
- `L${element.width},0 ` +
- `L${element.width},${element.height - round2DiagSize} ` +
- `Q${element.width},${element.height} ${
- element.width - round2DiagSize
- },${element.height} ` +
- `L0,${element.height} ` +
- `L0,${round2DiagSize} ` +
- `Q0,0 ${round2DiagSize},0 ` +
- `Z`
- )
- // 设置填充色
- setBackground(element, round2DiagRect)
- // 设置边框
- if (element.borderWidth > 0) {
- round2DiagRect.setAttribute("stroke", element.borderColor || "#000")
- round2DiagRect.setAttribute("stroke-width", element.borderWidth || 1)
- // 处理虚线边框
- if (
- element.borderType === "dotted" ||
- element.borderType === "dashed"
- ) {
- if (element.borderStrokeDasharray) {
- round2DiagRect.setAttribute(
- "stroke-dasharray",
- element.borderStrokeDasharray
- )
- } else if (element.borderType === "dotted") {
- round2DiagRect.setAttribute("stroke-dasharray", "2, 2")
- round2DiagRect.setAttribute("stroke-linecap", "round")
- } else if (element.borderType === "dashed") {
- round2DiagRect.setAttribute("stroke-dasharray", "6, 3")
- }
- }
- round2DiagRect.setAttribute("vector-effect", "non-scaling-stroke")
- round2DiagRect.setAttribute("shape-rendering", "geometricPrecision")
- }
- svg.appendChild(round2DiagRect)
- break
- case "triangle":
- const triangle = document.createElementNS(
- "http://www.w3.org/2000/svg",
- "polygon"
- )
- triangle.setAttribute(
- "points",
- `${element.width / 2},0 ${element.width},${element.height} 0,${
- element.height
- }`
- )
- // 设置填充色
- setBackground(element, triangle)
- // 设置边框
- if (element.borderWidth > 0) {
- triangle.setAttribute("stroke", element.borderColor || "#000")
- triangle.setAttribute("stroke-width", element.borderWidth || 1)
- // 处理虚线边框
- if (
- element.borderType === "dotted" ||
- element.borderType === "dashed"
- ) {
- if (element.borderStrokeDasharray) {
- triangle.setAttribute(
- "stroke-dasharray",
- element.borderStrokeDasharray
- )
- } else if (element.borderType === "dotted") {
- triangle.setAttribute("stroke-dasharray", "1, 3")
- } else if (element.borderType === "dashed") {
- triangle.setAttribute("stroke-dasharray", "5, 5")
- }
- }
- }
- svg.appendChild(triangle)
- break
- case "arc":
- const arc = document.createElementNS("http://www.w3.org/2000/svg", "path")
- // 计算弧形的参数
- const arcRadius = Math.min(element.width, element.height) / 2
- // 绘制弧形路径
- arc.setAttribute(
- "d",
- `M${arcRadius},0 ` +
- `A${arcRadius},${arcRadius} 0 1 1 ${arcRadius * 0.15},${
- arcRadius * 0.5
- }`
- )
- // 设置填充色
- arc.setAttribute("fill", "transparent")
- // 设置边框
- if (element.borderWidth > 0) {
- arc.setAttribute("stroke", element.borderColor || "#000")
- arc.setAttribute("stroke-width", element.borderWidth || 0.5)
- // 处理虚线边框
- if (
- element.borderType === "dotted" ||
- element.borderType === "dashed"
- ) {
- if (element.borderStrokeDasharray) {
- arc.setAttribute("stroke-dasharray", element.borderStrokeDasharray)
- } else if (element.borderType === "dotted") {
- arc.setAttribute("stroke-dasharray", "2, 2")
- arc.setAttribute("stroke-linecap", "round")
- } else if (element.borderType === "dashed") {
- arc.setAttribute("stroke-dasharray", "6, 3")
- }
- }
- arc.setAttribute("vector-effect", "non-scaling-stroke")
- arc.setAttribute("shape-rendering", "geometricPrecision")
- } else {
- arc.setAttribute("stroke", element.borderColor || "#000")
- arc.setAttribute("stroke-width", 0.5)
- }
- svg.appendChild(arc)
- break
- case "custom":
- const customPath = document.createElementNS(
- "http://www.w3.org/2000/svg",
- "path"
- )
- // 直接使用传入的 path 数据
- customPath.setAttribute("d", element.path || "")
- // 设置填充色
- setBackground(element, customPath)
- // 设置边框
- if (element.borderWidth > 0) {
- customPath.setAttribute("stroke", element.borderColor || "#000")
- customPath.setAttribute("stroke-width", element.borderWidth || 1)
- // 处理虚线边框
- if (
- element.borderType === "dotted" ||
- element.borderType === "dashed"
- ) {
- if (element.borderStrokeDasharray) {
- customPath.setAttribute(
- "stroke-dasharray",
- element.borderStrokeDasharray
- )
- } else if (element.borderType === "dotted") {
- customPath.setAttribute("stroke-dasharray", "2, 2")
- customPath.setAttribute("stroke-linecap", "round")
- } else if (element.borderType === "dashed") {
- customPath.setAttribute("stroke-dasharray", "6, 3")
- }
- }
- customPath.setAttribute("vector-effect", "non-scaling-stroke")
- customPath.setAttribute("shape-rendering", "geometricPrecision")
- }
- svg.appendChild(customPath)
- break
- case "teardrop":
- const teardrop = document.createElementNS(
- "http://www.w3.org/2000/svg",
- "path"
- )
- // 计算泪珠形状的参数
- const tdCenterX = element.width / 2
- const tdCenterY = element.height / 2
- const tdRadiusX = element.width / 2
- const tdRadiusY = element.height / 2
- // 使用相对比例计算控制点
- teardrop.setAttribute(
- "d",
- `M${tdCenterX * 2} ${tdCenterY} ` +
- `A ${tdRadiusX} ${tdRadiusY} 0 1 1 ${tdCenterX} 0 ` +
- `Q${tdCenterX * 1.7},0 ${tdCenterX * 2.1},${-tdCenterY * 0.1} ` +
- `Q${tdCenterX * 2},${tdCenterY * 0.29} ${tdCenterX * 2},${tdCenterY}`
- )
- // 设置填充色
- setBackground(element, teardrop)
- // 设置边框样式
- if (element.borderWidth > 0) {
- teardrop.setAttribute("stroke", element.borderColor || "#000")
- teardrop.setAttribute("stroke-width", element.borderWidth || 1)
- teardrop.setAttribute("stroke-linejoin", "round")
- // 处理虚线边框
- if (
- element.borderType === "dotted" ||
- element.borderType === "dashed"
- ) {
- // ... 原有的虚线边框处理代码 ...
- }
- }
- svg.appendChild(teardrop)
- break
- case "decagon":
- const decagon = document.createElementNS(
- "http://www.w3.org/2000/svg",
- "polygon"
- )
- // 计算十边形的顶点
- let decagonPoints = ""
- for (let i = 0; i < 10; i++) {
- const angle = (i * 2 * Math.PI) / 10 - Math.PI / 2 // 从顶部开始
- const x = element.width / 2 + (element.width / 2) * Math.cos(angle)
- const y = element.height / 2 + (element.height / 2) * Math.sin(angle)
- decagonPoints += `${x},${y} `
- }
- decagon.setAttribute("points", decagonPoints.trim())
- // 设置填充色
- setBackground(element, decagon)
- // 设置边框
- if (element.borderWidth > 0) {
- decagon.setAttribute("stroke", element.borderColor || "#000")
- decagon.setAttribute("stroke-width", element.borderWidth || 1)
- // 处理虚线边框
- if (
- element.borderType === "dotted" ||
- element.borderType === "dashed"
- ) {
- if (element.borderStrokeDasharray) {
- decagon.setAttribute(
- "stroke-dasharray",
- element.borderStrokeDasharray
- )
- } else if (element.borderType === "dotted") {
- decagon.setAttribute("stroke-dasharray", "1, 3")
- } else if (element.borderType === "dashed") {
- decagon.setAttribute("stroke-dasharray", "5, 5")
- }
- }
- }
- svg.appendChild(decagon)
- break
- case "pentagon":
- const pentagon = document.createElementNS(
- "http://www.w3.org/2000/svg",
- "polygon"
- )
- pentagon.setAttribute(
- "points",
- `${element.width / 2},0 ${element.width},${element.height * 0.38} ` +
- `${element.width * 0.82},${element.height} ${element.width * 0.18},${
- element.height
- } ` +
- `0,${element.height * 0.38}`
- )
- // 设置填充色
- setBackground(element, pentagon)
- // 设置边框
- if (element.borderWidth > 0) {
- pentagon.setAttribute("stroke", element.borderColor || "#000")
- pentagon.setAttribute("stroke-width", element.borderWidth || 1)
- // 处理虚线边框
- if (
- element.borderType === "dotted" ||
- element.borderType === "dashed"
- ) {
- if (element.borderStrokeDasharray) {
- pentagon.setAttribute(
- "stroke-dasharray",
- element.borderStrokeDasharray
- )
- } else if (element.borderType === "dotted") {
- pentagon.setAttribute("stroke-dasharray", "1, 3")
- } else if (element.borderType === "dashed") {
- pentagon.setAttribute("stroke-dasharray", "5, 5")
- }
- }
- }
- svg.appendChild(pentagon)
- break
- case "pie":
- const pie = document.createElementNS("http://www.w3.org/2000/svg", "path")
- // 使用提供的路径数据,但保留元素的宽高比例
- const centerX = element.width / 2
- const centerY = element.height / 2
- const radius2 = Math.min(element.width, element.height) / 2
- // 绘制饼图,使用类似提供的路径数据
- pie.setAttribute(
- "d",
- `M${centerX},${centerY} ` +
- `L${centerX * 1.85},${centerY * 1.52} ` +
- `A${radius2},${radius2} 0 1,1 ${centerX * 1.56},${centerY * 0.17} ` +
- `Z`
- )
- // 设置填充色
- setBackground(element, pie)
- // 设置边框
- if (element.borderWidth > 0) {
- pie.setAttribute("stroke", element.borderColor || "#000")
- pie.setAttribute("stroke-width", element.borderWidth || 1)
- // 处理虚线边框
- if (
- element.borderType === "dotted" ||
- element.borderType === "dashed"
- ) {
- if (element.borderStrokeDasharray) {
- pie.setAttribute("stroke-dasharray", element.borderStrokeDasharray)
- } else if (element.borderType === "dotted") {
- pie.setAttribute("stroke-dasharray", "2, 2")
- pie.setAttribute("stroke-linecap", "round")
- } else if (element.borderType === "dashed") {
- pie.setAttribute("stroke-dasharray", "6, 3")
- }
- }
- pie.setAttribute("vector-effect", "non-scaling-stroke")
- pie.setAttribute("shape-rendering", "geometricPrecision")
- }
- svg.appendChild(pie)
- break
- case "chord":
- const chord = document.createElementNS(
- "http://www.w3.org/2000/svg",
- "path"
- )
- // 计算弦形的参数
- const chordRadiusX = element.width * 0.4
- const chordRadiusY = element.height * 0.4
- // 绘制弦形 - 使用更大的圆弧和不同的起始/结束点
- chord.setAttribute(
- "d",
- `M${element.width * 0.4},${element.height * 0.9} ` +
- `A ${chordRadiusX} ${chordRadiusY} 0 1 1 ${element.width * 0.8},${
- element.height * 0.5
- } ` +
- `Z`
- )
- // 设置填充色
- setBackground(element, chord)
- // 设置边框
- if (element.borderWidth > 0) {
- chord.setAttribute("stroke", element.borderColor || "#000")
- chord.setAttribute("stroke-width", element.borderWidth || 1)
- // 处理虚线边框
- if (
- element.borderType === "dotted" ||
- element.borderType === "dashed"
- ) {
- if (element.borderStrokeDasharray) {
- chord.setAttribute(
- "stroke-dasharray",
- element.borderStrokeDasharray
- )
- } else if (element.borderType === "dotted") {
- chord.setAttribute("stroke-dasharray", "2, 2")
- chord.setAttribute("stroke-linecap", "round")
- } else if (element.borderType === "dashed") {
- chord.setAttribute("stroke-dasharray", "6, 3")
- }
- }
- chord.setAttribute("vector-effect", "non-scaling-stroke")
- chord.setAttribute("shape-rendering", "geometricPrecision")
- }
- svg.appendChild(chord)
- break
- case "heptagon":
- const heptagon = document.createElementNS(
- "http://www.w3.org/2000/svg",
- "polygon"
- )
- // 计算七边形的顶点
- let heptagonPoints = ""
- for (let i = 0; i < 7; i++) {
- const angle = (i * 2 * Math.PI) / 7 - Math.PI / 2 // 从顶部开始
- const x = element.width / 2 + (element.width / 2) * Math.cos(angle)
- const y = element.height / 2 + (element.height / 2) * Math.sin(angle)
- heptagonPoints += `${x},${y} `
- }
- heptagon.setAttribute("points", heptagonPoints.trim())
- // 设置填充色
- setBackground(element, heptagon)
- // 设置边框
- if (element.borderWidth > 0) {
- heptagon.setAttribute("stroke", element.borderColor || "#000")
- heptagon.setAttribute("stroke-width", element.borderWidth || 1)
- // 处理虚线边框
- if (
- element.borderType === "dotted" ||
- element.borderType === "dashed"
- ) {
- if (element.borderStrokeDasharray) {
- heptagon.setAttribute(
- "stroke-dasharray",
- element.borderStrokeDasharray
- )
- } else if (element.borderType === "dotted") {
- heptagon.setAttribute("stroke-dasharray", "1, 3")
- } else if (element.borderType === "dashed") {
- heptagon.setAttribute("stroke-dasharray", "5, 5")
- }
- }
- }
- svg.appendChild(heptagon)
- break
- case "hexagon":
- const hexagon = document.createElementNS(
- "http://www.w3.org/2000/svg",
- "polygon"
- )
- hexagon.setAttribute(
- "points",
- `${element.width * 0.25},0 ${element.width * 0.75},0 ${element.width},${
- element.height * 0.5
- } ` +
- `${element.width * 0.75},${element.height} ${element.width * 0.25},${
- element.height
- } 0,${element.height * 0.5}`
- )
- // 设置填充色
- setBackground(element, hexagon)
- // 设置边框
- if (element.borderWidth > 0) {
- hexagon.setAttribute("stroke", element.borderColor || "#000")
- hexagon.setAttribute("stroke-width", element.borderWidth || 1)
- // 处理虚线边框
- if (
- element.borderType === "dotted" ||
- element.borderType === "dashed"
- ) {
- if (element.borderStrokeDasharray) {
- hexagon.setAttribute(
- "stroke-dasharray",
- element.borderStrokeDasharray
- )
- } else if (element.borderType === "dotted") {
- hexagon.setAttribute("stroke-dasharray", "1, 3")
- } else if (element.borderType === "dashed") {
- hexagon.setAttribute("stroke-dasharray", "5, 5")
- }
- }
- }
- svg.appendChild(hexagon)
- break
- case "octagon":
- const octagon = document.createElementNS(
- "http://www.w3.org/2000/svg",
- "polygon"
- )
- octagon.setAttribute(
- "points",
- `${element.width * 0.3},0 ${element.width * 0.7},0 ${element.width},${
- element.height * 0.3
- } ` +
- `${element.width},${element.height * 0.7} ${element.width * 0.7},${
- element.height
- } ` +
- `${element.width * 0.3},${element.height} 0,${
- element.height * 0.7
- } 0,${element.height * 0.3}`
- )
- // 设置填充色
- setBackground(element, octagon)
- // 设置边框
- if (element.borderWidth > 0) {
- octagon.setAttribute("stroke", element.borderColor || "#000")
- octagon.setAttribute("stroke-width", element.borderWidth || 1)
- // 处理虚线边框
- if (
- element.borderType === "dotted" ||
- element.borderType === "dashed"
- ) {
- if (element.borderStrokeDasharray) {
- octagon.setAttribute(
- "stroke-dasharray",
- element.borderStrokeDasharray
- )
- } else if (element.borderType === "dotted") {
- octagon.setAttribute("stroke-dasharray", "1, 3")
- } else if (element.borderType === "dashed") {
- octagon.setAttribute("stroke-dasharray", "5, 5")
- }
- }
- }
- svg.appendChild(octagon)
- break
- case "trapezoid":
- const trapezoid = document.createElementNS(
- "http://www.w3.org/2000/svg",
- "polygon"
- )
- trapezoid.setAttribute(
- "points",
- `${element.width * 0.2},0 ${element.width * 0.8},0 ${element.width},${
- element.height
- } 0,${element.height}`
- )
- // 设置填充色
- setBackground(element, trapezoid)
- // 设置边框
- if (element.borderWidth > 0) {
- trapezoid.setAttribute("stroke", element.borderColor || "#000")
- trapezoid.setAttribute("stroke-width", element.borderWidth || 1)
- // 处理虚线边框
- if (
- element.borderType === "dotted" ||
- element.borderType === "dashed"
- ) {
- if (element.borderStrokeDasharray) {
- trapezoid.setAttribute(
- "stroke-dasharray",
- element.borderStrokeDasharray
- )
- } else if (element.borderType === "dotted") {
- trapezoid.setAttribute("stroke-dasharray", "1, 3")
- } else if (element.borderType === "dashed") {
- trapezoid.setAttribute("stroke-dasharray", "5, 5")
- }
- }
- }
- svg.appendChild(trapezoid)
- break
- case "diamond":
- const diamond = document.createElementNS(
- "http://www.w3.org/2000/svg",
- "polygon"
- )
- diamond.setAttribute(
- "points",
- `${element.width / 2},0 ${element.width},${element.height / 2} ${
- element.width / 2
- },${element.height} 0,${element.height / 2}`
- )
- // 设置填充色
- setBackground(element, diamond)
- // 设置边框
- if (element.borderWidth > 0) {
- diamond.setAttribute("stroke", element.borderColor || "#000")
- diamond.setAttribute("stroke-width", element.borderWidth || 1)
- // 处理虚线边框
- if (
- element.borderType === "dotted" ||
- element.borderType === "dashed"
- ) {
- if (element.borderStrokeDasharray) {
- diamond.setAttribute(
- "stroke-dasharray",
- element.borderStrokeDasharray
- )
- } else if (element.borderType === "dotted") {
- diamond.setAttribute("stroke-dasharray", "1, 3")
- } else if (element.borderType === "dashed") {
- diamond.setAttribute("stroke-dasharray", "5, 5")
- }
- }
- }
- svg.appendChild(diamond)
- break
- case "dodecagon":
- const dodecagon = document.createElementNS(
- "http://www.w3.org/2000/svg",
- "polygon"
- )
- // 计算十二边形的顶点
- let dodecagonPoints = ""
- for (let i = 0; i < 12; i++) {
- const angle = (i * 2 * Math.PI) / 12 - Math.PI / 2 // 从顶部开始
- const x = element.width / 2 + (element.width / 2) * Math.cos(angle)
- const y = element.height / 2 + (element.height / 2) * Math.sin(angle)
- dodecagonPoints += `${x},${y} `
- }
- dodecagon.setAttribute("points", dodecagonPoints.trim())
- // 设置填充色
- setBackground(element, dodecagon)
- // 设置边框
- if (element.borderWidth > 0) {
- dodecagon.setAttribute("stroke", element.borderColor || "#000")
- dodecagon.setAttribute("stroke-width", element.borderWidth || 1)
- // 处理虚线边框
- if (
- element.borderType === "dotted" ||
- element.borderType === "dashed"
- ) {
- if (element.borderStrokeDasharray) {
- dodecagon.setAttribute(
- "stroke-dasharray",
- element.borderStrokeDasharray
- )
- } else if (element.borderType === "dotted") {
- dodecagon.setAttribute("stroke-dasharray", "1, 3")
- } else if (element.borderType === "dashed") {
- dodecagon.setAttribute("stroke-dasharray", "5, 5")
- }
- }
- }
- svg.appendChild(dodecagon)
- break
- case "halfFrame":
- // 创建外框和内框
- const outerRect2 = document.createElementNS(
- "http://www.w3.org/2000/svg",
- "path"
- )
- const innerRect2 = document.createElementNS(
- "http://www.w3.org/2000/svg",
- "path"
- )
- // 计算内框的边距
- const frameWidth2 = element.width / 9
- // 绘制外框的左边和上边
- outerRect2.setAttribute(
- "d",
- `M0,${element.height} L0,0 L${element.width},0`
- )
- // 绘制内框的左边和上边,注意起点位置调整
- innerRect2.setAttribute(
- "d",
- `M${frameWidth2},${element.height - frameWidth2} ` +
- `L${frameWidth2},${frameWidth2} ` +
- `L${element.width - frameWidth2},${frameWidth2}`
- )
- // 设置填充色
- if (element.fill && element.fill.type === "color") {
- // 创建一个填充用的路径
- const fillPath = document.createElementNS(
- "http://www.w3.org/2000/svg",
- "path"
- )
- fillPath.setAttribute(
- "d",
- `M${frameWidth2},${frameWidth2} ` +
- `L${element.width - frameWidth2},${frameWidth2} ` +
- `L${element.width},0 ` +
- `L0,0 ` +
- `L0,${element.height} ` +
- `L${frameWidth2},${element.height - frameWidth2} Z`
- )
- fillPath.setAttribute("fill", element.fill.value || "transparent")
- svg.appendChild(fillPath)
- outerRect2.setAttribute("fill", "none")
- innerRect2.setAttribute("fill", "none")
- } else {
- outerRect2.setAttribute("fill", "none")
- innerRect2.setAttribute("fill", "none")
- }
- // 设置边框
- if (element.borderWidth > 0) {
- const borderColor = element.borderColor || "#000"
- const borderWidth = element.borderWidth || 1
- outerRect2.setAttribute("stroke", borderColor)
- outerRect2.setAttribute("stroke-width", borderWidth)
- innerRect2.setAttribute("stroke", borderColor)
- innerRect2.setAttribute("stroke-width", borderWidth)
- // 处理虚线边框
- if (
- element.borderType === "dotted" ||
- element.borderType === "dashed"
- ) {
- if (element.borderStrokeDasharray) {
- const dashArray = element.borderStrokeDasharray
- outerRect2.setAttribute("stroke-dasharray", dashArray)
- innerRect2.setAttribute("stroke-dasharray", dashArray)
- } else if (element.borderType === "dotted") {
- outerRect2.setAttribute("stroke-dasharray", "1, 3")
- innerRect2.setAttribute("stroke-dasharray", "1, 3")
- } else if (element.borderType === "dashed") {
- outerRect2.setAttribute("stroke-dasharray", "5, 5")
- innerRect2.setAttribute("stroke-dasharray", "5, 5")
- }
- }
- }
- svg.appendChild(outerRect2)
- svg.appendChild(innerRect2)
- break
- case "corner":
- const corner = document.createElementNS(
- "http://www.w3.org/2000/svg",
- "path"
- )
- corner.setAttribute(
- "d",
- `M0,0 ` +
- `L0,${element.height} ` +
- `L${element.width},${element.height} ` +
- `L${element.width},${element.height * 0.6} ` +
- `L${element.width * 0.4},${element.height * 0.6} ` +
- `L${element.width * 0.4},0 Z`
- )
- // 设置填充色
- setBackground(element, corner)
- // 设置边框
- if (element.borderWidth > 0) {
- corner.setAttribute("stroke", element.borderColor || "#000")
- corner.setAttribute("stroke-width", element.borderWidth || 1)
- // 处理虚线边框
- if (
- element.borderType === "dotted" ||
- element.borderType === "dashed"
- ) {
- if (element.borderStrokeDasharray) {
- corner.setAttribute(
- "stroke-dasharray",
- element.borderStrokeDasharray
- )
- } else if (element.borderType === "dotted") {
- corner.setAttribute("stroke-dasharray", "1, 3")
- } else if (element.borderType === "dashed") {
- corner.setAttribute("stroke-dasharray", "5, 5")
- }
- }
- }
- svg.appendChild(corner)
- break
- case "diagStripe":
- const diagStripe = document.createElementNS(
- "http://www.w3.org/2000/svg",
- "path"
- )
- // 绘制斜纹路径
- diagStripe.setAttribute(
- "d",
- `M${element.width * 0.4},0 ` +
- `L${element.width},0 ` +
- `L0,${element.height} ` +
- `L0,${element.height * 0.4} Z`
- )
- // 设置填充色
- setBackground(element, diagStripe)
- // 设置边框
- if (element.borderWidth > 0) {
- diagStripe.setAttribute("stroke", element.borderColor || "#000")
- diagStripe.setAttribute("stroke-width", element.borderWidth || 1)
- diagStripe.setAttribute("stroke-linejoin", "round")
- // 处理虚线边框
- if (
- element.borderType === "dotted" ||
- element.borderType === "dashed"
- ) {
- if (element.borderStrokeDasharray) {
- diagStripe.setAttribute(
- "stroke-dasharray",
- element.borderStrokeDasharray
- )
- } else if (element.borderType === "dotted") {
- diagStripe.setAttribute("stroke-dasharray", "1, 3")
- } else if (element.borderType === "dashed") {
- diagStripe.setAttribute("stroke-dasharray", "5, 5")
- }
- }
- }
- svg.appendChild(diagStripe)
- break
- case "plus":
- const plus = document.createElementNS(
- "http://www.w3.org/2000/svg",
- "polygon"
- )
- plus.setAttribute(
- "points",
- `${element.width * 0.4},0 ` +
- `${element.width * 0.6},0 ` +
- `${element.width * 0.6},${element.height * 0.4} ` +
- `${element.width},${element.height * 0.4} ` +
- `${element.width},${element.height * 0.6} ` +
- `${element.width * 0.6},${element.height * 0.6} ` +
- `${element.width * 0.6},${element.height} ` +
- `${element.width * 0.4},${element.height} ` +
- `${element.width * 0.4},${element.height * 0.6} ` +
- `0,${element.height * 0.6} ` +
- `0,${element.height * 0.4} ` +
- `${element.width * 0.4},${element.height * 0.4}`
- )
- // 设置填充色
- setBackground(element, plus)
- // 设置边框
- if (element.borderWidth > 0) {
- plus.setAttribute("stroke", element.borderColor || "#000")
- plus.setAttribute("stroke-width", element.borderWidth || 1)
- // 处理虚线边框
- if (
- element.borderType === "dotted" ||
- element.borderType === "dashed"
- ) {
- if (element.borderStrokeDasharray) {
- plus.setAttribute("stroke-dasharray", element.borderStrokeDasharray)
- } else if (element.borderType === "dotted") {
- plus.setAttribute("stroke-dasharray", "1, 3")
- } else if (element.borderType === "dashed") {
- plus.setAttribute("stroke-dasharray", "5, 5")
- }
- }
- }
- svg.appendChild(plus)
- break
- case "can":
- const can = document.createElementNS("http://www.w3.org/2000/svg", "g")
- // 创建圆柱体的主体部分
- const cylinderBody = document.createElementNS(
- "http://www.w3.org/2000/svg",
- "path"
- )
- cylinderBody.setAttribute(
- "d",
- `M0,${element.height * 0.15} ` +
- `A${element.width / 2},${element.height * 0.15} 0 0 1 ${
- element.width
- },${element.height * 0.15} ` +
- `V${element.height * 0.85} ` +
- `A${element.width / 2},${element.height * 0.15} 0 0 1 0,${
- element.height * 0.85
- } Z`
- )
- // 创建顶部椭圆
- const topEllipse = document.createElementNS(
- "http://www.w3.org/2000/svg",
- "ellipse"
- )
- topEllipse.setAttribute("cx", element.width / 2)
- topEllipse.setAttribute("cy", element.height * 0.15)
- topEllipse.setAttribute("rx", element.width / 2)
- topEllipse.setAttribute("ry", element.height * 0.15)
- // 设置填充色
- setBackground(element, cylinderBody)
- setBackground(element, topEllipse)
- // 设置边框
- if (element.borderWidth > 0) {
- const borderColor = element.borderColor || "#000"
- const borderWidth = element.borderWidth || 1
- cylinderBody.setAttribute("stroke", borderColor)
- cylinderBody.setAttribute("stroke-width", borderWidth)
- topEllipse.setAttribute("stroke", borderColor)
- topEllipse.setAttribute("stroke-width", borderWidth)
- // 处理虚线边框
- if (
- element.borderType === "dotted" ||
- element.borderType === "dashed"
- ) {
- if (element.borderStrokeDasharray) {
- const dashArray = element.borderStrokeDasharray
- cylinderBody.setAttribute("stroke-dasharray", dashArray)
- topEllipse.setAttribute("stroke-dasharray", dashArray)
- } else if (element.borderType === "dotted") {
- cylinderBody.setAttribute("stroke-dasharray", "1, 3")
- topEllipse.setAttribute("stroke-dasharray", "1, 3")
- } else if (element.borderType === "dashed") {
- cylinderBody.setAttribute("stroke-dasharray", "5, 5")
- topEllipse.setAttribute("stroke-dasharray", "5, 5")
- }
- }
- }
- can.appendChild(cylinderBody)
- can.appendChild(topEllipse)
- svg.appendChild(can)
- break
- case "cube":
- const cube = document.createElementNS("http://www.w3.org/2000/svg", "g")
- // 计算关键点坐标
- const offset = element.width * 0.2
- const frontX = offset
- const frontY = offset
- const frontW = element.width - offset
- const frontH = element.height
- // 设置立方体的三个面的路径
- const frontFace = document.createElementNS(
- "http://www.w3.org/2000/svg",
- "path"
- )
- frontFace.setAttribute(
- "d",
- `M${frontX},${frontY} ` +
- `L${frontW},${frontY} ` +
- `L${frontW},${frontH} ` +
- `L${frontX},${frontH} Z`
- )
- const rightFace = document.createElementNS(
- "http://www.w3.org/2000/svg",
- "path"
- )
- rightFace.setAttribute(
- "d",
- `M${frontW},${frontY} ` +
- `L${element.width},0 ` +
- `L${element.width},${element.height - offset} ` +
- `L${frontW},${frontH} Z`
- )
- const topFace = document.createElementNS(
- "http://www.w3.org/2000/svg",
- "path"
- )
- topFace.setAttribute(
- "d",
- `M${frontX},${frontY} ` +
- `L${frontW - offset - frontX},0 ` + // 修改这里:改为从(0,0)开始
- `L${element.width - offset},0 ` + // 修改这里:使用 offset 来计算右上角的位置
- `L${element.width},0 ` +
- `L${frontW},${frontY} Z`
- )
- // 设置填充色
- if (element.fill && element.fill.type === "color") {
- const fillColor = element.fill.value || "transparent"
- frontFace.setAttribute("fill", fillColor)
- rightFace.setAttribute("fill", this.adjustBrightness(fillColor, 0.8))
- topFace.setAttribute("fill", this.adjustBrightness(fillColor, 1.2))
- } else {
- frontFace.setAttribute("fill", "transparent")
- rightFace.setAttribute("fill", "transparent")
- topFace.setAttribute("fill", "transparent")
- }
- // 设置边框
- if (element.borderWidth > 0) {
- const borderColor = element.borderColor || "#000"
- const borderWidth = element.borderWidth || 1
- frontFace.setAttribute("stroke", borderColor)
- frontFace.setAttribute("stroke-width", borderWidth)
- rightFace.setAttribute("stroke", borderColor)
- rightFace.setAttribute("stroke-width", borderWidth)
- topFace.setAttribute("stroke", borderColor)
- topFace.setAttribute("stroke-width", borderWidth)
- if (
- element.borderType === "dotted" ||
- element.borderType === "dashed"
- ) {
- const dashArray =
- element.borderStrokeDasharray ||
- (element.borderType === "dotted" ? "1, 3" : "5, 5")
- frontFace.setAttribute("stroke-dasharray", dashArray)
- rightFace.setAttribute("stroke-dasharray", dashArray)
- topFace.setAttribute("stroke-dasharray", dashArray)
- }
- }
- // 按正确的顺序添加面(从后到前)
- cube.appendChild(rightFace)
- cube.appendChild(topFace)
- cube.appendChild(frontFace)
- svg.appendChild(cube)
- break
- case "bevel":
- const bevel = document.createElementNS("http://www.w3.org/2000/svg", "g")
- // 计算关键点坐标
- const bevelOffset = element.width * 0.2
- const smallRectX = bevelOffset
- const smallRectY = bevelOffset
- const smallRectW = element.width - 2 * bevelOffset
- const smallRectH = element.height - 2 * bevelOffset
- // 绘制顶部小矩形
- const topRect = document.createElementNS(
- "http://www.w3.org/2000/svg",
- "rect"
- )
- topRect.setAttribute("x", smallRectX)
- topRect.setAttribute("y", smallRectY)
- topRect.setAttribute("width", smallRectW)
- topRect.setAttribute("height", smallRectH)
- // 绘制四个梯形
- const topTrapezoid = document.createElementNS(
- "http://www.w3.org/2000/svg",
- "path"
- )
- topTrapezoid.setAttribute(
- "d",
- `M0,0 L${element.width},0 L${
- element.width - bevelOffset
- },${bevelOffset} L${bevelOffset},${bevelOffset} Z`
- )
- const bottomTrapezoid = document.createElementNS(
- "http://www.w3.org/2000/svg",
- "path"
- )
- bottomTrapezoid.setAttribute(
- "d",
- `M${bevelOffset},${element.height - bevelOffset} L${
- element.width - bevelOffset
- },${element.height - bevelOffset} L${element.width},${
- element.height
- } L0,${element.height} Z`
- )
- const leftTrapezoid = document.createElementNS(
- "http://www.w3.org/2000/svg",
- "path"
- )
- leftTrapezoid.setAttribute(
- "d",
- `M0,0 L${bevelOffset},${bevelOffset} L${bevelOffset},${
- element.height - bevelOffset
- } L0,${element.height} Z`
- )
- const rightTrapezoid = document.createElementNS(
- "http://www.w3.org/2000/svg",
- "path"
- )
- rightTrapezoid.setAttribute(
- "d",
- `M${element.width},0 L${element.width},${element.height} L${
- element.width - bevelOffset
- },${element.height - bevelOffset} L${
- element.width - bevelOffset
- },${bevelOffset} Z`
- )
- // 设置填充色
- if (element.fill && element.fill.type === "color") {
- const fillColor = element.fill.value || "transparent"
- topRect.setAttribute("fill", fillColor)
- topTrapezoid.setAttribute("fill", this.adjustBrightness(fillColor, 1.2))
- bottomTrapezoid.setAttribute(
- "fill",
- this.adjustBrightness(fillColor, 0.8)
- )
- leftTrapezoid.setAttribute(
- "fill",
- this.adjustBrightness(fillColor, 0.9)
- )
- rightTrapezoid.setAttribute(
- "fill",
- this.adjustBrightness(fillColor, 0.7)
- )
- } else {
- topRect.setAttribute("fill", "transparent")
- topTrapezoid.setAttribute("fill", "transparent")
- bottomTrapezoid.setAttribute("fill", "transparent")
- leftTrapezoid.setAttribute("fill", "transparent")
- rightTrapezoid.setAttribute("fill", "transparent")
- }
- // 设置边框
- if (element.borderWidth > 0) {
- const borderColor = element.borderColor || "#000"
- const borderWidth = element.borderWidth || 1
- const parts = [
- topRect,
- topTrapezoid,
- bottomTrapezoid,
- leftTrapezoid,
- rightTrapezoid,
- ]
- parts.forEach((part) => {
- part.setAttribute("stroke", borderColor)
- part.setAttribute("stroke-width", borderWidth)
- if (
- element.borderType === "dotted" ||
- element.borderType === "dashed"
- ) {
- const dashArray =
- element.borderStrokeDasharray ||
- (element.borderType === "dotted" ? "1, 3" : "5, 5")
- part.setAttribute("stroke-dasharray", dashArray)
- }
- })
- }
- // 按正确的顺序添加面(从后到前)
- bevel.appendChild(bottomTrapezoid)
- bevel.appendChild(leftTrapezoid)
- bevel.appendChild(rightTrapezoid)
- bevel.appendChild(topTrapezoid)
- bevel.appendChild(topRect)
- svg.appendChild(bevel)
- break
- case "donut":
- const donut = document.createElementNS("http://www.w3.org/2000/svg", "g")
- // 外圆
- const outerCircle = document.createElementNS(
- "http://www.w3.org/2000/svg",
- "circle"
- )
- outerCircle.setAttribute("cx", element.width / 2)
- outerCircle.setAttribute("cy", element.height / 2)
- outerCircle.setAttribute("r", Math.min(element.width, element.height) / 2)
- // 内圆
- const innerCircle = document.createElementNS(
- "http://www.w3.org/2000/svg",
- "circle"
- )
- innerCircle.setAttribute("cx", element.width / 2)
- innerCircle.setAttribute("cy", element.height / 2)
- innerCircle.setAttribute("r", Math.min(element.width, element.height) / 4)
- // 设置填充色
- setBackground(element, outerCircle)
- innerCircle.setAttribute("fill", "white")
- // 设置边框
- if (element.borderWidth > 0) {
- const borderColor = element.borderColor || "#000"
- const borderWidth = element.borderWidth || 1
- outerCircle.setAttribute("stroke", borderColor)
- outerCircle.setAttribute("stroke-width", borderWidth)
- innerCircle.setAttribute("stroke", borderColor)
- innerCircle.setAttribute("stroke-width", borderWidth)
- if (
- element.borderType === "dotted" ||
- element.borderType === "dashed"
- ) {
- const dashArray =
- element.borderStrokeDasharray ||
- (element.borderType === "dotted" ? "1, 3" : "5, 5")
- outerCircle.setAttribute("stroke-dasharray", dashArray)
- innerCircle.setAttribute("stroke-dasharray", dashArray)
- }
- }
- donut.appendChild(outerCircle)
- donut.appendChild(innerCircle)
- svg.appendChild(donut)
- break
- case "noSmoking":
- const noSmoking = document.createElementNS(
- "http://www.w3.org/2000/svg",
- "g"
- )
- // 创建路径
- const path = document.createElementNS(
- "http://www.w3.org/2000/svg",
- "path"
- )
- path.setAttribute(
- "d",
- "M0,70 A77,70 0 1,1 0,71 Z M123.80284467265982,99.39738105155146 A57.5386,50.5386 0 0 0 45.160427644134444,27.90427466198293 Z M30.197155327340184,40.602618948448544 A57.5386,50.5386 0 0 0 108.83957235586556,112.09572533801708 Z"
- )
- path.setAttribute("fill", "rgba(255,217,102,1)")
- path.setAttribute("stroke", "rgba(23,44,81,1)")
- path.setAttribute("stroke-width", "1px")
- path.setAttribute("stroke-dasharray", "")
- path.setAttribute("stroke-linecap", "butt")
- path.setAttribute("stroke-linejoin", "round")
- noSmoking.appendChild(path)
- svg.appendChild(noSmoking)
- break
- case "rightArrow":
- const rightArrow = document.createElementNS(
- "http://www.w3.org/2000/svg",
- "polygon"
- )
- rightArrow.setAttribute(
- "points",
- `0,${element.height * 0.3} ${element.width * 0.7},${
- element.height * 0.3
- } ` +
- `${element.width * 0.7},0 ${element.width},${element.height * 0.5} ` +
- `${element.width * 0.7},${element.height} ${element.width * 0.7},${
- element.height * 0.7
- } ` +
- `0,${element.height * 0.7}`
- )
- // 设置填充色
- setBackground(element, rightArrow)
- // 设置边框
- if (element.borderWidth > 0) {
- rightArrow.setAttribute("stroke", element.borderColor || "#000")
- rightArrow.setAttribute("stroke-width", element.borderWidth || 1)
- // 处理虚线边框
- if (
- element.borderType === "dotted" ||
- element.borderType === "dashed"
- ) {
- if (element.borderStrokeDasharray) {
- rightArrow.setAttribute(
- "stroke-dasharray",
- element.borderStrokeDasharray
- )
- } else if (element.borderType === "dotted") {
- rightArrow.setAttribute("stroke-dasharray", "1, 3")
- } else if (element.borderType === "dashed") {
- rightArrow.setAttribute("stroke-dasharray", "5, 5")
- }
- }
- }
- svg.appendChild(rightArrow)
- break
- case "leftArrow":
- const leftArrow = document.createElementNS(
- "http://www.w3.org/2000/svg",
- "polygon"
- )
- leftArrow.setAttribute(
- "points",
- `${element.width},${element.height * 0.3} ${element.width * 0.3},${
- element.height * 0.3
- } ` +
- `${element.width * 0.3},0 0,${element.height * 0.5} ` +
- `${element.width * 0.3},${element.height} ${element.width * 0.3},${
- element.height * 0.7
- } ` +
- `${element.width},${element.height * 0.7}`
- )
- // 设置填充色
- setBackground(element, leftArrow)
- // 设置边框
- if (element.borderWidth > 0) {
- leftArrow.setAttribute("stroke", element.borderColor || "#000")
- leftArrow.setAttribute("stroke-width", element.borderWidth || 1)
- // 处理虚线边框
- if (
- element.borderType === "dotted" ||
- element.borderType === "dashed"
- ) {
- if (element.borderStrokeDasharray) {
- leftArrow.setAttribute(
- "stroke-dasharray",
- element.borderStrokeDasharray
- )
- } else if (element.borderType === "dotted") {
- leftArrow.setAttribute("stroke-dasharray", "1, 3")
- } else if (element.borderType === "dashed") {
- leftArrow.setAttribute("stroke-dasharray", "5, 5")
- }
- }
- }
- svg.appendChild(leftArrow)
- break
- case "upArrow":
- const upArrow = document.createElementNS(
- "http://www.w3.org/2000/svg",
- "polygon"
- )
- upArrow.setAttribute(
- "points",
- `${element.width * 0.3},${element.height} ${element.width * 0.3},${
- element.height * 0.3
- } ` +
- `0,${element.height * 0.3} ${element.width * 0.5},0 ` +
- `${element.width},${element.height * 0.3} ${element.width * 0.7},${
- element.height * 0.3
- } ` +
- `${element.width * 0.7},${element.height}`
- )
- // 设置填充色
- setBackground(element, upArrow)
- // 设置边框
- if (element.borderWidth > 0) {
- upArrow.setAttribute("stroke", element.borderColor || "#000")
- upArrow.setAttribute("stroke-width", element.borderWidth || 1)
- // 处理虚线边框
- if (
- element.borderType === "dotted" ||
- element.borderType === "dashed"
- ) {
- if (element.borderStrokeDasharray) {
- upArrow.setAttribute(
- "stroke-dasharray",
- element.borderStrokeDasharray
- )
- } else if (element.borderType === "dotted") {
- upArrow.setAttribute("stroke-dasharray", "1, 3")
- } else if (element.borderType === "dashed") {
- upArrow.setAttribute("stroke-dasharray", "5, 5")
- }
- }
- }
- svg.appendChild(upArrow)
- break
- case "downArrow":
- const downArrow = document.createElementNS(
- "http://www.w3.org/2000/svg",
- "polygon"
- )
- downArrow.setAttribute(
- "points",
- `${element.width * 0.3},0 ${element.width * 0.3},${
- element.height * 0.7
- } ` +
- `0,${element.height * 0.7} ${element.width * 0.5},${
- element.height
- } ` +
- `${element.width},${element.height * 0.7} ${element.width * 0.7},${
- element.height * 0.7
- } ` +
- `${element.width * 0.7},0`
- )
- // 设置填充色
- setBackground(element, downArrow)
- // 设置边框
- if (element.borderWidth > 0) {
- downArrow.setAttribute("stroke", element.borderColor || "#000")
- downArrow.setAttribute("stroke-width", element.borderWidth || 1)
- // 处理虚线边框
- if (
- element.borderType === "dotted" ||
- element.borderType === "dashed"
- ) {
- if (element.borderStrokeDasharray) {
- downArrow.setAttribute(
- "stroke-dasharray",
- element.borderStrokeDasharray
- )
- } else if (element.borderType === "dotted") {
- downArrow.setAttribute("stroke-dasharray", "1, 3")
- } else if (element.borderType === "dashed") {
- downArrow.setAttribute("stroke-dasharray", "5, 5")
- }
- }
- }
- svg.appendChild(downArrow)
- break
- case "leftRightArrow":
- const leftRightArrow = document.createElementNS(
- "http://www.w3.org/2000/svg",
- "polygon"
- )
- leftRightArrow.setAttribute(
- "points",
- `0,${element.height * 0.5} ${element.width * 0.2},${
- element.height * 0.2
- } ` +
- `${element.width * 0.2},${element.height * 0.4} ${
- element.width * 0.8
- },${element.height * 0.4} ` +
- `${element.width * 0.8},${element.height * 0.2} ${element.width},${
- element.height * 0.5
- } ` +
- `${element.width * 0.8},${element.height * 0.8} ${
- element.width * 0.8
- },${element.height * 0.6} ` +
- `${element.width * 0.2},${element.height * 0.6} ${
- element.width * 0.2
- },${element.height * 0.8}`
- )
- // 设置填充色
- setBackground(element, leftRightArrow)
- // 设置边框
- if (element.borderWidth > 0) {
- leftRightArrow.setAttribute("stroke", element.borderColor || "#000")
- leftRightArrow.setAttribute("stroke-width", element.borderWidth || 1)
- // 处理虚线边框
- if (
- element.borderType === "dotted" ||
- element.borderType === "dashed"
- ) {
- if (element.borderStrokeDasharray) {
- leftRightArrow.setAttribute(
- "stroke-dasharray",
- element.borderStrokeDasharray
- )
- } else if (element.borderType === "dotted") {
- leftRightArrow.setAttribute("stroke-dasharray", "1, 3")
- } else if (element.borderType === "dashed") {
- leftRightArrow.setAttribute("stroke-dasharray", "5, 5")
- }
- }
- }
- svg.appendChild(leftRightArrow)
- break
- case "upDownArrow":
- const upDownArrow = document.createElementNS(
- "http://www.w3.org/2000/svg",
- "polygon"
- )
- upDownArrow.setAttribute(
- "points",
- `${element.width * 0.5},0 ${element.width * 0.3},${
- element.height * 0.2
- } ` +
- `${element.width * 0.4},${element.height * 0.2} ${
- element.width * 0.4
- },${element.height * 0.8} ` +
- `${element.width * 0.3},${element.height * 0.8} ${
- element.width * 0.5
- },${element.height} ` +
- `${element.width * 0.7},${element.height * 0.8} ${
- element.width * 0.6
- },${element.height * 0.8} ` +
- `${element.width * 0.6},${element.height * 0.2} ${
- element.width * 0.7
- },${element.height * 0.2}`
- )
- // 设置填充色
- setBackground(element, upDownArrow)
- // 设置边框
- if (element.borderWidth > 0) {
- upDownArrow.setAttribute("stroke", element.borderColor || "#000")
- upDownArrow.setAttribute("stroke-width", element.borderWidth || 1)
- // 处理虚线边框
- if (
- element.borderType === "dotted" ||
- element.borderType === "dashed"
- ) {
- if (element.borderStrokeDasharray) {
- upDownArrow.setAttribute(
- "stroke-dasharray",
- element.borderStrokeDasharray
- )
- } else if (element.borderType === "dotted") {
- upDownArrow.setAttribute("stroke-dasharray", "1, 3")
- } else if (element.borderType === "dashed") {
- upDownArrow.setAttribute("stroke-dasharray", "5, 5")
- }
- }
- }
- svg.appendChild(upDownArrow)
- break
- case "quadArrow":
- const quadArrow = document.createElementNS(
- "http://www.w3.org/2000/svg",
- "path"
- )
- // 计算缩放比例
- const scale = Math.min(element.width / 167, element.height / 121)
- const offsetX = (element.width - 167 * scale) / 2
- const offsetY = (element.height - 121 * scale) / 2
- // 构建路径数据
- const pathData = `
- M${offsetX},${60.5 * scale + offsetY}
- L${27.225 * scale + offsetX},${33.275 * scale + offsetY}
- L${27.225 * scale + offsetX},${46.8875 * scale + offsetY}
- L${69.8875 * scale + offsetX},${46.8875 * scale + offsetY}
- L${69.8875 * scale + offsetX},${27.225 * scale + offsetY}
- L${56.275 * scale + offsetX},${27.225 * scale + offsetY}
- L${83.5 * scale + offsetX},${offsetY}
- L${110.725 * scale + offsetX},${27.225 * scale + offsetY}
- L${97.1125 * scale + offsetX},${27.225 * scale + offsetY}
- L${97.1125 * scale + offsetX},${46.8875 * scale + offsetY}
- L${139.775 * scale + offsetX},${46.8875 * scale + offsetY}
- L${139.775 * scale + offsetX},${33.275 * scale + offsetY}
- L${167 * scale + offsetX},${60.5 * scale + offsetY}
- L${139.775 * scale + offsetX},${87.725 * scale + offsetY}
- L${139.775 * scale + offsetX},${74.1125 * scale + offsetY}
- L${97.1125 * scale + offsetX},${74.1125 * scale + offsetY}
- L${97.1125 * scale + offsetX},${93.775 * scale + offsetY}
- L${110.725 * scale + offsetX},${93.775 * scale + offsetY}
- L${83.5 * scale + offsetX},${121 * scale + offsetY}
- L${56.275 * scale + offsetX},${93.775 * scale + offsetY}
- L${69.8875 * scale + offsetX},${93.775 * scale + offsetY}
- L${69.8875 * scale + offsetX},${74.1125 * scale + offsetY}
- L${27.225 * scale + offsetX},${74.1125 * scale + offsetY}
- L${27.225 * scale + offsetX},${87.725 * scale + offsetY}
- Z`
- quadArrow.setAttribute("d", pathData)
- // 设置填充色
- setBackground(element, quadArrow)
- // 设置边框
- if (element.borderWidth > 0) {
- quadArrow.setAttribute("stroke", element.borderColor || "#000")
- quadArrow.setAttribute("stroke-width", element.borderWidth || 1)
- quadArrow.setAttribute("stroke-linecap", "butt")
- quadArrow.setAttribute("stroke-linejoin", "round")
- // 处理虚线边框
- if (
- element.borderType === "dotted" ||
- element.borderType === "dashed"
- ) {
- if (element.borderStrokeDasharray) {
- quadArrow.setAttribute(
- "stroke-dasharray",
- element.borderStrokeDasharray
- )
- } else if (element.borderType === "dotted") {
- quadArrow.setAttribute("stroke-dasharray", "1, 3")
- } else if (element.borderType === "dashed") {
- quadArrow.setAttribute("stroke-dasharray", "5, 5")
- }
- }
- }
- svg.appendChild(quadArrow)
- break
- case "leftRightUpArrow":
- const leftRightUpArrow = document.createElementNS(
- "http://www.w3.org/2000/svg",
- "path"
- )
- // 计算缩放比例
- const scale2 = Math.min(element.width / 167, element.height / 121)
- const offsetX2 = (element.width - 167 * scale2) / 2
- const offsetY2 = (element.height - 121 * scale2) / 2
- // 构建路径数据
- const pathData2 = `
- M${offsetX2},${60.5 * scale2 + offsetY2}
- L${27.225 * scale2 + offsetX2},${33.275 * scale2 + offsetY2}
- L${27.225 * scale2 + offsetX2},${46.8875 * scale2 + offsetY2}
- L${69.8875 * scale2 + offsetX2},${46.8875 * scale2 + offsetY2}
- L${69.8875 * scale2 + offsetX2},${27.225 * scale2 + offsetY2}
- L${56.275 * scale2 + offsetX2},${27.225 * scale2 + offsetY2}
- L${83.5 * scale2 + offsetX2},${offsetY2}
- L${110.725 * scale2 + offsetX2},${27.225 * scale2 + offsetY2}
- L${97.1125 * scale2 + offsetX2},${27.225 * scale2 + offsetY2}
- L${97.1125 * scale2 + offsetX2},${46.8875 * scale2 + offsetY2}
- L${139.775 * scale2 + offsetX2},${46.8875 * scale2 + offsetY2}
- L${139.775 * scale2 + offsetX2},${33.275 * scale2 + offsetY2}
- L${167 * scale2 + offsetX2},${60.5 * scale2 + offsetY2}
- L${139.775 * scale2 + offsetX2},${87.725 * scale2 + offsetY2}
- L${139.775 * scale2 + offsetX2},${74.1125 * scale2 + offsetY2}
- L${97.1125 * scale2 + offsetX2},${74.1125 * scale2 + offsetY2}
- L${69.8875 * scale2 + offsetX2},${74.1125 * scale2 + offsetY2}
- L${27.225 * scale2 + offsetX2},${74.1125 * scale2 + offsetY2}
- L${27.225 * scale2 + offsetX2},${87.725 * scale2 + offsetY2}
- Z`
- leftRightUpArrow.setAttribute("d", pathData2)
- // 设置填充色
- setBackground(element, leftRightUpArrow)
- // 设置边框
- if (element.borderWidth > 0) {
- leftRightUpArrow.setAttribute("stroke", element.borderColor || "#000")
- leftRightUpArrow.setAttribute("stroke-width", element.borderWidth || 1)
- leftRightUpArrow.setAttribute("stroke-linecap", "butt")
- leftRightUpArrow.setAttribute("stroke-linejoin", "round")
- // 处理虚线边框
- if (
- element.borderType === "dotted" ||
- element.borderType === "dashed"
- ) {
- if (element.borderStrokeDasharray) {
- leftRightUpArrow.setAttribute(
- "stroke-dasharray",
- element.borderStrokeDasharray
- )
- } else if (element.borderType === "dotted") {
- leftRightUpArrow.setAttribute("stroke-dasharray", "1, 3")
- } else if (element.borderType === "dashed") {
- leftRightUpArrow.setAttribute("stroke-dasharray", "5, 5")
- }
- }
- }
- svg.appendChild(leftRightUpArrow)
- break
- case "bentArrow":
- const bentArrow = document.createElementNS(
- "http://www.w3.org/2000/svg",
- "path"
- )
- // 构建路径数据
- const pathData3 = `
- M0,${element.height * 0.88}
- L0,${element.height * 0.495}
- A${element.width * 0.385} ${element.height * 0.385} 0 0 1 ${
- element.width * 0.385
- } ${element.height * 0.11}
- L${element.width * 0.67},${element.height * 0.11}
- L${element.width * 0.67},0
- L${element.width * 0.89},${element.height * 0.22}
- L${element.width * 0.67},${element.height * 0.44}
- L${element.width * 0.67},${element.height * 0.33}
- L${element.width * 0.385},${element.height * 0.33}
- A${element.width * 0.165} ${element.height * 0.165} 0 0 0 ${
- element.width * 0.22
- } ${element.height * 0.495}
- L${element.width * 0.22},${element.height * 0.88}
- Z`
- bentArrow.setAttribute("d", pathData3)
- // 设置填充色
- setBackground(element, bentArrow)
- // 设置边框
- if (element.borderWidth > 0) {
- bentArrow.setAttribute("stroke", element.borderColor || "#000")
- bentArrow.setAttribute("stroke-width", element.borderWidth || 1)
- bentArrow.setAttribute("stroke-linecap", "butt")
- bentArrow.setAttribute("stroke-linejoin", "round")
- // 处理虚线边框
- if (
- element.borderType === "dotted" ||
- element.borderType === "dashed"
- ) {
- if (element.borderStrokeDasharray) {
- bentArrow.setAttribute(
- "stroke-dasharray",
- element.borderStrokeDasharray
- )
- } else if (element.borderType === "dotted") {
- bentArrow.setAttribute("stroke-dasharray", "1, 3")
- } else if (element.borderType === "dashed") {
- bentArrow.setAttribute("stroke-dasharray", "5, 5")
- }
- }
- }
- svg.appendChild(bentArrow)
- break
- case "parallelogram":
- const parallelogram = document.createElementNS(
- "http://www.w3.org/2000/svg",
- "polygon"
- )
- parallelogram.setAttribute(
- "points",
- `${element.width * 0.25},0 ${element.width},0 ${element.width * 0.75},${
- element.height
- } 0,${element.height}`
- )
- // 设置填充色
- setBackground(element, parallelogram)
- // 设置边框
- if (element.borderWidth > 0) {
- parallelogram.setAttribute("stroke", element.borderColor || "#000")
- parallelogram.setAttribute("stroke-width", element.borderWidth || 1)
- // 处理虚线边框
- if (
- element.borderType === "dotted" ||
- element.borderType === "dashed"
- ) {
- if (element.borderStrokeDasharray) {
- parallelogram.setAttribute(
- "stroke-dasharray",
- element.borderStrokeDasharray
- )
- } else if (element.borderType === "dotted") {
- parallelogram.setAttribute("stroke-dasharray", "1, 3")
- } else if (element.borderType === "dashed") {
- parallelogram.setAttribute("stroke-dasharray", "5, 5")
- }
- }
- }
- svg.appendChild(parallelogram)
- break
- case "uturnArrow":
- const uturnArrow = document.createElementNS(
- "http://www.w3.org/2000/svg",
- "path"
- )
- // 构建路径数据
- const pathDataUturn = `
- M0,${element.height * 0.745}
- L0,${element.height * 0.179375}
- A${element.width * 0.179375} ${element.height * 0.179375} 0 0 1 ${
- element.width * 0.179375
- },0
- L${element.width * 0.179375},0
- A${element.width * 0.179375} ${element.height * 0.179375} 0 0 1 ${
- element.width * 0.359375
- },${element.height * 0.179375}
- L${element.width * 0.359375},${element.height * 0.205}
- L${element.width * 0.41},${element.height * 0.205}
- L${element.width * 0.3075},${element.height * 0.3075}
- L${element.width * 0.205},${element.height * 0.205}
- L${element.width * 0.25625},${element.height * 0.205}
- L${element.width * 0.25625},${element.height * 0.179375}
- A${element.width * 0.076875} ${element.height * 0.076875} 0 0 0 ${
- element.width * 0.179375
- },${element.height * 0.1025}
- L${element.width * 0.179375},${element.height * 0.1025}
- A${element.width * 0.076875} ${element.height * 0.076875} 0 0 0 ${
- element.width * 0.1025
- },${element.height * 0.179375}
- L${element.width * 0.1025},${element.height * 0.745}
- Z`
- uturnArrow.setAttribute("d", pathDataUturn)
- // 设置填充色
- setBackground(element, uturnArrow)
- // 设置边框
- if (element.borderWidth > 0) {
- uturnArrow.setAttribute("stroke", element.borderColor || "#000")
- uturnArrow.setAttribute("stroke-width", element.borderWidth || 1)
- uturnArrow.setAttribute("stroke-linecap", "butt")
- uturnArrow.setAttribute("stroke-linejoin", "round")
- // 处理虚线边框
- if (
- element.borderType === "dotted" ||
- element.borderType === "dashed"
- ) {
- if (element.borderStrokeDasharray) {
- uturnArrow.setAttribute(
- "stroke-dasharray",
- element.borderStrokeDasharray
- )
- } else if (element.borderType === "dotted") {
- uturnArrow.setAttribute("stroke-dasharray", "1, 3")
- } else if (element.borderType === "dashed") {
- uturnArrow.setAttribute("stroke-dasharray", "5, 5")
- }
- }
- }
- svg.appendChild(uturnArrow)
- break
- case "leftUpArrow":
- const leftUpArrow = document.createElementNS(
- "http://www.w3.org/2000/svg",
- "path"
- )
- // 使用提供的路径数据
- const pathDataLeftUp = `
- M0,${element.height * 0.65}
- L${element.width * 0.15},${element.height * 0.4}
- L${element.width * 0.15},${element.height * 0.55}
- L${element.width * 0.5},${element.height * 0.55}
- L${element.width * 0.5},${element.height * 0.1}
- L${element.width * 0.35},${element.height * 0.1}
- L${element.width * 0.65},0
- L${element.width * 0.85},${element.height * 0.1}
- L${element.width * 0.75},${element.height * 0.1}
- L${element.width * 0.75},${element.height * 0.85}
- L${element.width * 0.15},${element.height * 0.85}
- L${element.width * 0.15},${element.height * 1}
- Z`
- leftUpArrow.setAttribute("d", pathDataLeftUp)
- // 设置填充色
- setBackground(element, leftUpArrow)
- // 设置边框
- if (element.borderWidth > 0) {
- leftUpArrow.setAttribute("stroke", element.borderColor || "#000")
- leftUpArrow.setAttribute("stroke-width", element.borderWidth || 1)
- leftUpArrow.setAttribute("stroke-linecap", "butt")
- leftUpArrow.setAttribute("stroke-linejoin", "round")
- // 处理虚线边框
- if (
- element.borderType === "dotted" ||
- element.borderType === "dashed"
- ) {
- if (element.borderStrokeDasharray) {
- leftUpArrow.setAttribute(
- "stroke-dasharray",
- element.borderStrokeDasharray
- )
- } else if (element.borderType === "dotted") {
- leftUpArrow.setAttribute("stroke-dasharray", "1, 3")
- } else if (element.borderType === "dashed") {
- leftUpArrow.setAttribute("stroke-dasharray", "5, 5")
- }
- }
- }
- svg.appendChild(leftUpArrow)
- break
- case "bentUpArrow":
- const bentUpArrow = document.createElementNS(
- "http://www.w3.org/2000/svg",
- "path"
- )
- // 构建路径数据,去掉左侧箭头
- // 使用提供的路径数据
- const pathDataBentUp = `
- M0,${element.height * 0.89}
- L0,${element.height * 0.7}
- L${element.width * 0.575},${element.height * 0.7}
- L${element.width * 0.575},${element.height * 0.2}
- L${element.width * 0.46},${element.height * 0.2}
- L${element.width * 0.69},0
- L${element.width * 0.92},${element.height * 0.2}
- L${element.width * 0.805},${element.height * 0.2}
- L${element.width * 0.805},${element.height * 0.89}
- Z`
- bentUpArrow.setAttribute("d", pathDataBentUp)
- // 设置填充色
- setBackground(element, bentUpArrow)
- // 设置边框
- if (element.borderWidth > 0) {
- bentUpArrow.setAttribute("stroke", element.borderColor || "#000")
- bentUpArrow.setAttribute("stroke-width", element.borderWidth || 1)
- bentUpArrow.setAttribute("stroke-linecap", "butt")
- bentUpArrow.setAttribute("stroke-linejoin", "round")
- // 处理虚线边框
- if (
- element.borderType === "dotted" ||
- element.borderType === "dashed"
- ) {
- if (element.borderStrokeDasharray) {
- bentUpArrow.setAttribute(
- "stroke-dasharray",
- element.borderStrokeDasharray
- )
- } else if (element.borderType === "dotted") {
- bentUpArrow.setAttribute("stroke-dasharray", "1, 3")
- } else if (element.borderType === "dashed") {
- bentUpArrow.setAttribute("stroke-dasharray", "5, 5")
- }
- }
- }
- svg.appendChild(bentUpArrow)
- break
- case "curvedRightArrow":
- const curvedRightArrow = document.createElementNS(
- "http://www.w3.org/2000/svg",
- "path"
- )
- // 使用提供的路径数据
- const pathDataCurvedRight = `
- M${element.width},0
- A${element.width} ${element.height * 0.4} 0 0 0 0 ${
- element.height * 0.4
- }
- L0,${element.height * 0.5}
- A${element.width} ${element.height * 0.4} 0 0 1 ${element.width} ${
- element.height * 0.15
- }
- Z
- M0,${element.height * 0.4}
- A${element.width} ${element.height * 0.4} 0 0 0 ${
- element.width * 0.8
- } ${element.height * 0.8}
- L${element.width * 0.8},${element.height * 0.75}
- L${element.width},${element.height * 0.875}
- L${element.width * 0.8},${element.height * 1}
- L${element.width * 0.8},${element.height * 0.95}
- A${element.width} ${element.height * 0.4} 0 0 1 0 ${
- element.height * 0.5
- }
- Z`
- curvedRightArrow.setAttribute("d", pathDataCurvedRight)
- // 设置填充色
- setBackground(element, curvedRightArrow)
- // 设置边框
- if (element.borderWidth > 0) {
- curvedRightArrow.setAttribute("stroke", element.borderColor || "#000")
- curvedRightArrow.setAttribute("stroke-width", element.borderWidth || 1)
- curvedRightArrow.setAttribute("stroke-linecap", "butt")
- curvedRightArrow.setAttribute("stroke-linejoin", "round")
- // 处理虚线边框
- if (
- element.borderType === "dotted" ||
- element.borderType === "dashed"
- ) {
- if (element.borderStrokeDasharray) {
- curvedRightArrow.setAttribute(
- "stroke-dasharray",
- element.borderStrokeDasharray
- )
- } else if (element.borderType === "dotted") {
- curvedRightArrow.setAttribute("stroke-dasharray", "1, 3")
- } else if (element.borderType === "dashed") {
- curvedRightArrow.setAttribute("stroke-dasharray", "5, 5")
- }
- }
- }
- svg.appendChild(curvedRightArrow)
- break
- case "curvedLeftArrow":
- const curvedLeftArrow = document.createElementNS(
- "http://www.w3.org/2000/svg",
- "path"
- )
- // 定义左弧形箭头的路径数据
- const pathDataCurvedLeft = `
- M0,0
- A${element.width} ${element.height * 0.4} 0 0 1 ${element.width} ${
- element.height * 0.4
- }
- L${element.width},${element.height * 0.55}
- A${element.width} ${element.height * 0.4} 0 0 0 0 ${
- element.height * 0.15
- }
- Z
- M0,${element.height * 0.85}
- L${element.width * 0.25},${element.height * 0.65}
- L${element.width * 0.25},${element.height * 0.75}
- A${element.width} ${element.height * 0.4} 0 0 0 ${element.width} ${
- element.height * 0.4
- }
- L${element.width},${element.height * 0.5}
- L${element.width},${element.height * 0.5}
- A${element.width} ${element.height * 0.4} 0 0 1 ${
- element.width * 0.25
- } ${element.height * 0.9}
- L${element.width * 0.25},${element.height}
- Z`
- curvedLeftArrow.setAttribute("d", pathDataCurvedLeft)
- // 设置填充色
- setBackground(element, curvedLeftArrow)
- // 设置边框
- if (element.borderWidth > 0) {
- curvedLeftArrow.setAttribute("stroke", element.borderColor || "#000")
- curvedLeftArrow.setAttribute("stroke-width", element.borderWidth || 1)
- curvedLeftArrow.setAttribute("stroke-linecap", "butt")
- curvedLeftArrow.setAttribute("stroke-linejoin", "round")
- // 处理虚线边框
- if (
- element.borderType === "dotted" ||
- element.borderType === "dashed"
- ) {
- if (element.borderStrokeDasharray) {
- curvedLeftArrow.setAttribute(
- "stroke-dasharray",
- element.borderStrokeDasharray
- )
- } else if (element.borderType === "dotted") {
- curvedLeftArrow.setAttribute("stroke-dasharray", "1, 3")
- } else if (element.borderType === "dashed") {
- curvedLeftArrow.setAttribute("stroke-dasharray", "5, 5")
- }
- }
- }
- svg.appendChild(curvedLeftArrow)
- break
- case "curvedUpArrow":
- const curvedUpArrow = document.createElementNS(
- "http://www.w3.org/2000/svg",
- "path"
- )
- // 定义上弧形箭头的路径数据
- const pathDataCurvedUp = `
- M${element.width * 0.905},0
- L${element.width * 0.81},${element.height * 0.25}
- L${element.width * 0.857},${element.height * 0.25}
- A${element.width * 0.428} ${element.height} 0 0 1 ${
- element.width * 0.428
- },${element.height}
- L${element.width * 0.522},${element.height}
- A${element.width * 0.428} ${element.height} 0 0 0 ${
- element.width * 0.952
- },${element.height * 0.25}
- L${element.width},${element.height * 0.25}
- Z
- M${element.width * 0.094},0
- L0,0
- A${element.width * 0.428} ${element.height} 0 0 0 ${
- element.width * 0.428
- },${element.height}
- L${element.width * 0.522},${element.height}
- A${element.width * 0.428} ${element.height} 0 0 1 ${
- element.width * 0.094
- },0
- Z`
- curvedUpArrow.setAttribute("d", pathDataCurvedUp)
- // 设置填充色
- setBackground(element, curvedUpArrow)
- // 设置边框
- if (element.borderWidth > 0) {
- curvedUpArrow.setAttribute("stroke", element.borderColor || "#000")
- curvedUpArrow.setAttribute("stroke-width", element.borderWidth || 1)
- curvedUpArrow.setAttribute("stroke-linecap", "butt")
- curvedUpArrow.setAttribute("stroke-linejoin", "round")
- // 处理虚线边框
- if (
- element.borderType === "dotted" ||
- element.borderType === "dashed"
- ) {
- if (element.borderStrokeDasharray) {
- curvedUpArrow.setAttribute(
- "stroke-dasharray",
- element.borderStrokeDasharray
- )
- } else if (element.borderType === "dotted") {
- curvedUpArrow.setAttribute("stroke-dasharray", "1, 3")
- } else if (element.borderType === "dashed") {
- curvedUpArrow.setAttribute("stroke-dasharray", "5, 5")
- }
- }
- }
- svg.appendChild(curvedUpArrow)
- break
- case "curvedDownArrow":
- const curvedDownArrow = document.createElementNS(
- "http://www.w3.org/2000/svg",
- "path"
- )
- // 定义下弧形箭头的路径数据
- const pathDataCurvedDown = `
- M0,${element.height}
- L${element.width * 0.16},${element.height}
- A${element.width * 0.46} ${element.height} 0 0 1 ${
- element.width * 0.62
- },0
- L${element.width * 0.46},0
- A${element.width * 0.46} ${element.height} 0 0 0 0,${element.height}
- Z
- M${element.width},${element.height}
- L${element.width * 0.84},${element.height * 0.75}
- L${element.width * 0.92},${element.height * 0.75}
- A${element.width * 0.46} ${element.height} 0 0 0 ${
- element.width * 0.46
- },0
- L${element.width * 0.62},0
- A${element.width * 0.46} ${element.height} 0 0 1 ${
- element.width * 1.08
- },${element.height * 0.75}
- L${element.width * 1.16},${element.height * 0.75}
- Z`
- curvedDownArrow.setAttribute("d", pathDataCurvedDown)
- // 设置填充色
- setBackground(element, curvedDownArrow)
- // 设置边框
- if (element.borderWidth > 0) {
- curvedDownArrow.setAttribute("stroke", element.borderColor || "#000")
- curvedDownArrow.setAttribute("stroke-width", element.borderWidth || 1)
- curvedDownArrow.setAttribute("stroke-linecap", "butt")
- curvedDownArrow.setAttribute("stroke-linejoin", "round")
- // 处理虚线边框
- if (
- element.borderType === "dotted" ||
- element.borderType === "dashed"
- ) {
- if (element.borderStrokeDasharray) {
- curvedDownArrow.setAttribute(
- "stroke-dasharray",
- element.borderStrokeDasharray
- )
- } else if (element.borderType === "dotted") {
- curvedDownArrow.setAttribute("stroke-dasharray", "1, 3")
- } else if (element.borderType === "dashed") {
- curvedDownArrow.setAttribute("stroke-dasharray", "5, 5")
- }
- }
- }
- svg.appendChild(curvedDownArrow)
- break
- case "stripedRightArrow":
- const stripedRightArrow = document.createElementNS(
- "http://www.w3.org/2000/svg",
- "g"
- )
- // 主箭头部分
- const mainArrow = document.createElementNS(
- "http://www.w3.org/2000/svg",
- "path"
- )
- mainArrow.setAttribute(
- "d",
- `M${element.width * 0.062},${element.height * 0.25}
- L${element.width * 0.8},${element.height * 0.25}
- L${element.width * 0.8},0
- L${element.width},${element.height * 0.5}
- L${element.width * 0.8},${element.height}
- L${element.width * 0.8},${element.height * 0.75}
- L${element.width * 0.062},${element.height * 0.75}
- Z`
- )
- // 第一条尾部条纹
- const stripe1 = document.createElementNS(
- "http://www.w3.org/2000/svg",
- "path"
- )
- stripe1.setAttribute(
- "d",
- `M0,${element.height * 0.25}
- L${element.width * 0.012},${element.height * 0.25}
- L${element.width * 0.012},${element.height * 0.75}
- L0,${element.height * 0.75}
- Z`
- )
- // 第二条尾部条纹
- const stripe2 = document.createElementNS(
- "http://www.w3.org/2000/svg",
- "path"
- )
- stripe2.setAttribute(
- "d",
- `M${element.width * 0.025},${element.height * 0.25}
- L${element.width * 0.049},${element.height * 0.25}
- L${element.width * 0.049},${element.height * 0.75}
- L${element.width * 0.025},${element.height * 0.75}
- Z`
- )
- // 设置填充色
- setBackground(element, mainArrow)
- setBackground(element, stripe1)
- setBackground(element, stripe2)
- // 设置边框
- if (element.borderWidth > 0) {
- ;[mainArrow, stripe1, stripe2].forEach((path) => {
- path.setAttribute("stroke", element.borderColor || "#000")
- path.setAttribute("stroke-width", element.borderWidth || 1)
- path.setAttribute("stroke-linecap", "butt")
- path.setAttribute("stroke-linejoin", "round")
- // 处理虚线边框
- if (
- element.borderType === "dotted" ||
- element.borderType === "dashed"
- ) {
- if (element.borderStrokeDasharray) {
- path.setAttribute(
- "stroke-dasharray",
- element.borderStrokeDasharray
- )
- } else if (element.borderType === "dotted") {
- path.setAttribute("stroke-dasharray", "1, 3")
- } else if (element.borderType === "dashed") {
- path.setAttribute("stroke-dasharray", "5, 5")
- }
- }
- })
- }
- stripedRightArrow.appendChild(mainArrow)
- stripedRightArrow.appendChild(stripe1)
- stripedRightArrow.appendChild(stripe2)
- svg.appendChild(stripedRightArrow)
- break
- case "rightArrowCallout":
- const rightArrowCallout = document.createElementNS(
- "http://www.w3.org/2000/svg",
- "path"
- )
- rightArrowCallout.setAttribute(
- "d",
- `M0,0
- L${element.width * 0.44},0
- L${element.width * 0.44},${element.height * 0.375}
- L${element.width * 0.79},${element.height * 0.375}
- L${element.width * 0.79},${element.height * 0.25}
- L${element.width},${element.height * 0.5}
- L${element.width * 0.79},${element.height * 0.75}
- L${element.width * 0.79},${element.height * 0.625}
- L${element.width * 0.44},${element.height * 0.625}
- L${element.width * 0.44},${element.height}
- L0,${element.height}
- Z`
- )
- // 设置填充色
- setBackground(element, rightArrowCallout)
- // 设置边框
- if (element.borderWidth > 0) {
- rightArrowCallout.setAttribute("stroke", element.borderColor || "#000")
- rightArrowCallout.setAttribute("stroke-width", element.borderWidth || 1)
- rightArrowCallout.setAttribute("stroke-linecap", "butt")
- rightArrowCallout.setAttribute("stroke-linejoin", "round")
- // 处理虚线边框
- if (
- element.borderType === "dotted" ||
- element.borderType === "dashed"
- ) {
- if (element.borderStrokeDasharray) {
- rightArrowCallout.setAttribute(
- "stroke-dasharray",
- element.borderStrokeDasharray
- )
- } else if (element.borderType === "dotted") {
- rightArrowCallout.setAttribute("stroke-dasharray", "1, 3")
- } else if (element.borderType === "dashed") {
- rightArrowCallout.setAttribute("stroke-dasharray", "5, 5")
- }
- }
- }
- svg.appendChild(rightArrowCallout)
- break
- case "leftRightArrowCallout":
- const leftRightArrowCallout = document.createElementNS(
- "http://www.w3.org/2000/svg",
- "path"
- )
- leftRightArrowCallout.setAttribute(
- "d",
- `M0,${element.height * 0.5}
- L${element.width * 0.139},${element.height * 0.25}
- L${element.width * 0.139},${element.height * 0.375}
- L${element.width * 0.364},${element.height * 0.375}
- L${element.width * 0.364},0
- L${element.width * 0.636},0
- L${element.width * 0.636},${element.height * 0.375}
- L${element.width * 0.861},${element.height * 0.375}
- L${element.width * 0.861},${element.height * 0.25}
- L${element.width},${element.height * 0.5}
- L${element.width * 0.861},${element.height * 0.75}
- L${element.width * 0.861},${element.height * 0.625}
- L${element.width * 0.636},${element.height * 0.625}
- L${element.width * 0.636},${element.height}
- L${element.width * 0.364},${element.height}
- L${element.width * 0.364},${element.height * 0.625}
- L${element.width * 0.139},${element.height * 0.625}
- L${element.width * 0.139},${element.height * 0.75}
- Z`
- )
- // 设置填充色
- setBackground(element, leftRightArrowCallout)
- // 设置边框
- if (element.borderWidth > 0) {
- leftRightArrowCallout.setAttribute(
- "stroke",
- element.borderColor || "#000"
- )
- leftRightArrowCallout.setAttribute(
- "stroke-width",
- element.borderWidth || 1
- )
- leftRightArrowCallout.setAttribute("stroke-linecap", "butt")
- leftRightArrowCallout.setAttribute("stroke-linejoin", "round")
- // 处理虚线边框
- if (
- element.borderType === "dotted" ||
- element.borderType === "dashed"
- ) {
- if (element.borderStrokeDasharray) {
- leftRightArrowCallout.setAttribute(
- "stroke-dasharray",
- element.borderStrokeDasharray
- )
- } else if (element.borderType === "dotted") {
- leftRightArrowCallout.setAttribute("stroke-dasharray", "1, 3")
- } else if (element.borderType === "dashed") {
- leftRightArrowCallout.setAttribute("stroke-dasharray", "5, 5")
- }
- }
- }
- svg.appendChild(leftRightArrowCallout)
- break
- case "quadArrowCallout":
- const quadArrowCallout = document.createElementNS(
- "http://www.w3.org/2000/svg",
- "path"
- )
- quadArrowCallout.setAttribute(
- "d",
- `M0,${element.height * 0.5}
- L${element.width * 0.096},${element.height * 0.315}
- L${element.width * 0.096},${element.height * 0.407}
- L${element.width * 0.26},${element.height * 0.407}
- L${element.width * 0.26},${element.height * 0.259}
- L${element.width * 0.453},${element.height * 0.259}
- L${element.width * 0.453},${element.height * 0.185}
- L${element.width * 0.405},${element.height * 0.185}
- L${element.width * 0.5},0
- L${element.width * 0.595},${element.height * 0.185}
- L${element.width * 0.547},${element.height * 0.185}
- L${element.width * 0.547},${element.height * 0.259}
- L${element.width * 0.74},${element.height * 0.259}
- L${element.width * 0.74},${element.height * 0.407}
- L${element.width * 0.904},${element.height * 0.407}
- L${element.width * 0.904},${element.height * 0.315}
- L${element.width},${element.height * 0.5}
- L${element.width * 0.904},${element.height * 0.685}
- L${element.width * 0.904},${element.height * 0.593}
- L${element.width * 0.74},${element.height * 0.593}
- L${element.width * 0.74},${element.height * 0.741}
- L${element.width * 0.547},${element.height * 0.741}
- L${element.width * 0.547},${element.height * 0.815}
- L${element.width * 0.595},${element.height * 0.815}
- L${element.width * 0.5},${element.height}
- L${element.width * 0.405},${element.height * 0.815}
- L${element.width * 0.453},${element.height * 0.815}
- L${element.width * 0.453},${element.height * 0.741}
- L${element.width * 0.26},${element.height * 0.741}
- L${element.width * 0.26},${element.height * 0.593}
- L${element.width * 0.096},${element.height * 0.593}
- L${element.width * 0.096},${element.height * 0.685}
- Z`
- )
- // 设置填充色
- setBackground(element, quadArrowCallout)
- // 设置边框
- if (element.borderWidth > 0) {
- quadArrowCallout.setAttribute("stroke", element.borderColor || "#000")
- quadArrowCallout.setAttribute("stroke-width", element.borderWidth || 1)
- quadArrowCallout.setAttribute("stroke-linecap", "butt")
- quadArrowCallout.setAttribute("stroke-linejoin", "round")
- // 处理虚线边框
- if (
- element.borderType === "dotted" ||
- element.borderType === "dashed"
- ) {
- if (element.borderStrokeDasharray) {
- quadArrowCallout.setAttribute(
- "stroke-dasharray",
- element.borderStrokeDasharray
- )
- } else if (element.borderType === "dotted") {
- quadArrowCallout.setAttribute("stroke-dasharray", "1, 3")
- } else if (element.borderType === "dashed") {
- quadArrowCallout.setAttribute("stroke-dasharray", "5, 5")
- }
- }
- }
- svg.appendChild(quadArrowCallout)
- break
- case "leftArrowCallout":
- const leftArrowCallout = document.createElementNS(
- "http://www.w3.org/2000/svg",
- "path"
- )
- leftArrowCallout.setAttribute(
- "d",
- `M0,${element.height * 0.5}
- L${element.width * 0.183},${element.height * 0.25}
- L${element.width * 0.183},${element.height * 0.375}
- L${element.width * 0.35},${element.height * 0.375}
- L${element.width * 0.35},0
- L${element.width},0
- L${element.width},${element.height}
- L${element.width * 0.35},${element.height}
- L${element.width * 0.35},${element.height * 0.625}
- L${element.width * 0.183},${element.height * 0.625}
- L${element.width * 0.183},${element.height * 0.75}
- Z`
- )
- // 设置填充色
- setBackground(element, leftArrowCallout)
- // 设置边框
- if (element.borderWidth > 0) {
- leftArrowCallout.setAttribute("stroke", element.borderColor || "#000")
- leftArrowCallout.setAttribute("stroke-width", element.borderWidth || 1)
- leftArrowCallout.setAttribute("stroke-linecap", "butt")
- leftArrowCallout.setAttribute("stroke-linejoin", "round")
- // 处理虚线边框
- if (
- element.borderType === "dotted" ||
- element.borderType === "dashed"
- ) {
- if (element.borderStrokeDasharray) {
- leftArrowCallout.setAttribute(
- "stroke-dasharray",
- element.borderStrokeDasharray
- )
- } else if (element.borderType === "dotted") {
- leftArrowCallout.setAttribute("stroke-dasharray", "1, 3")
- } else if (element.borderType === "dashed") {
- leftArrowCallout.setAttribute("stroke-dasharray", "5, 5")
- }
- }
- }
- svg.appendChild(leftArrowCallout)
- break
- case "upArrowCallout":
- const upArrowCallout = document.createElementNS(
- "http://www.w3.org/2000/svg",
- "path"
- )
- upArrowCallout.setAttribute(
- "d",
- `M0,${element.height * 0.35}
- L${element.width * 0.41},${element.height * 0.35}
- L${element.width * 0.41},${element.height * 0.25}
- L${element.width * 0.32},${element.height * 0.25}
- L${element.width * 0.5},0
- L${element.width * 0.68},${element.height * 0.25}
- L${element.width * 0.59},${element.height * 0.25}
- L${element.width * 0.59},${element.height * 0.35}
- L${element.width},${element.height * 0.35}
- L${element.width},${element.height}
- L0,${element.height}
- Z`
- )
- // 设置填充色
- setBackground(element, upArrowCallout)
- // 设置边框
- if (element.borderWidth > 0) {
- upArrowCallout.setAttribute("stroke", element.borderColor || "#000")
- upArrowCallout.setAttribute("stroke-width", element.borderWidth || 1)
- upArrowCallout.setAttribute("stroke-linecap", "butt")
- upArrowCallout.setAttribute("stroke-linejoin", "round")
- // 处理虚线边框
- if (
- element.borderType === "dotted" ||
- element.borderType === "dashed"
- ) {
- if (element.borderStrokeDasharray) {
- upArrowCallout.setAttribute(
- "stroke-dasharray",
- element.borderStrokeDasharray
- )
- } else if (element.borderType === "dotted") {
- upArrowCallout.setAttribute("stroke-dasharray", "1, 3")
- } else if (element.borderType === "dashed") {
- upArrowCallout.setAttribute("stroke-dasharray", "5, 5")
- }
- }
- }
- svg.appendChild(upArrowCallout)
- break
- case "notchedRightArrow":
- const notchedRightArrow = document.createElementNS(
- "http://www.w3.org/2000/svg",
- "path"
- )
- notchedRightArrow.setAttribute(
- "d",
- `M0,${element.height * 0.25}
- L${element.width * 0.83},${element.height * 0.25}
- L${element.width * 0.83},0
- L${element.width},${element.height * 0.5}
- L${element.width * 0.83},${element.height}
- L${element.width * 0.83},${element.height * 0.75}
- L0,${element.height * 0.75}
- L${element.width * 0.086},${element.height * 0.5}
- Z`
- )
- // 设置填充色
- setBackground(element, notchedRightArrow)
- // 设置边框
- if (element.borderWidth > 0) {
- notchedRightArrow.setAttribute("stroke", element.borderColor || "#000")
- notchedRightArrow.setAttribute("stroke-width", element.borderWidth || 1)
- notchedRightArrow.setAttribute("stroke-linecap", "butt")
- notchedRightArrow.setAttribute("stroke-linejoin", "round")
- // 处理虚线边框
- if (
- element.borderType === "dotted" ||
- element.borderType === "dashed"
- ) {
- if (element.borderStrokeDasharray) {
- notchedRightArrow.setAttribute(
- "stroke-dasharray",
- element.borderStrokeDasharray
- )
- } else if (element.borderType === "dotted") {
- notchedRightArrow.setAttribute("stroke-dasharray", "1, 3")
- } else if (element.borderType === "dashed") {
- notchedRightArrow.setAttribute("stroke-dasharray", "5, 5")
- }
- }
- }
- svg.appendChild(notchedRightArrow)
- break
- case "homePlate":
- const homePlate = document.createElementNS(
- "http://www.w3.org/2000/svg",
- "path"
- )
- homePlate.setAttribute(
- "d",
- `M0,0
- L${element.width * 0.925},0
- L${element.width},${element.height * 0.5}
- L${element.width * 0.925},${element.height}
- L0,${element.height}
- Z`
- )
- // 设置填充色
- setBackground(element, homePlate)
- // 设置边框
- if (element.borderWidth > 0) {
- homePlate.setAttribute("stroke", element.borderColor || "#000")
- homePlate.setAttribute("stroke-width", element.borderWidth || 1)
- homePlate.setAttribute("stroke-linecap", "butt")
- homePlate.setAttribute("stroke-linejoin", "round")
- // 处理虚线边框
- if (
- element.borderType === "dotted" ||
- element.borderType === "dashed"
- ) {
- if (element.borderStrokeDasharray) {
- homePlate.setAttribute(
- "stroke-dasharray",
- element.borderStrokeDasharray
- )
- } else if (element.borderType === "dotted") {
- homePlate.setAttribute("stroke-dasharray", "1, 3")
- } else if (element.borderType === "dashed") {
- homePlate.setAttribute("stroke-dasharray", "5, 5")
- }
- }
- }
- svg.appendChild(homePlate)
- break
- case "rightTriangle":
- const rightTriangle = document.createElementNS(
- "http://www.w3.org/2000/svg",
- "polygon"
- )
- rightTriangle.setAttribute(
- "points",
- `0,0 ${element.width},${element.height} 0,${element.height}`
- )
- // 设置填充色
- setBackground(element, rightTriangle)
- // 设置边框
- if (element.borderWidth > 0) {
- rightTriangle.setAttribute("stroke", element.borderColor || "#000")
- rightTriangle.setAttribute("stroke-width", element.borderWidth || 1)
- // 处理虚线边框
- if (
- element.borderType === "dotted" ||
- element.borderType === "dashed"
- ) {
- if (element.borderStrokeDasharray) {
- rightTriangle.setAttribute(
- "stroke-dasharray",
- element.borderStrokeDasharray
- )
- } else if (element.borderType === "dotted") {
- rightTriangle.setAttribute("stroke-dasharray", "1, 3")
- } else if (element.borderType === "dashed") {
- rightTriangle.setAttribute("stroke-dasharray", "5, 5")
- }
- }
- }
- svg.appendChild(rightTriangle)
- break
- case "semiCircle":
- const semiCircle = document.createElementNS(
- "http://www.w3.org/2000/svg",
- "path"
- )
- semiCircle.setAttribute(
- "d",
- `M0,${element.height} A${element.width / 2},${element.height} 0 0,1 ${
- element.width
- },${element.height} Z`
- )
- // 设置填充色
- setBackground(element, semiCircle)
- // 设置边框
- if (element.borderWidth > 0) {
- semiCircle.setAttribute("stroke", element.borderColor || "#000")
- semiCircle.setAttribute("stroke-width", element.borderWidth || 1)
- // 处理虚线边框
- if (
- element.borderType === "dotted" ||
- element.borderType === "dashed"
- ) {
- if (element.borderStrokeDasharray) {
- semiCircle.setAttribute(
- "stroke-dasharray",
- element.borderStrokeDasharray
- )
- } else if (element.borderType === "dotted") {
- semiCircle.setAttribute("stroke-dasharray", "1, 3")
- } else if (element.borderType === "dashed") {
- semiCircle.setAttribute("stroke-dasharray", "5, 5")
- }
- }
- }
- svg.appendChild(semiCircle)
- break
- case "star":
- const star = document.createElementNS(
- "http://www.w3.org/2000/svg",
- "polygon"
- )
- const cx = element.width / 2
- const cy = element.height / 2
- const outerRadius = Math.min(element.width, element.height) / 2
- const innerRadius = outerRadius * 0.4
- let starPoints = ""
- for (let i = 0; i < 10; i++) {
- const radius = i % 2 === 0 ? outerRadius : innerRadius
- const angle = (Math.PI * i) / 5
- const x = cx + radius * Math.sin(angle)
- const y = cy - radius * Math.cos(angle)
- starPoints += `${x},${y} `
- }
- star.setAttribute("points", starPoints.trim())
- // 设置填充色
- setBackground(element, star)
- // 设置边框
- if (element.borderWidth > 0) {
- star.setAttribute("stroke", element.borderColor || "#000")
- star.setAttribute("stroke-width", element.borderWidth || 1)
- // 处理虚线边框
- if (
- element.borderType === "dotted" ||
- element.borderType === "dashed"
- ) {
- if (element.borderStrokeDasharray) {
- star.setAttribute("stroke-dasharray", element.borderStrokeDasharray)
- } else if (element.borderType === "dotted") {
- star.setAttribute("stroke-dasharray", "1, 3")
- } else if (element.borderType === "dashed") {
- star.setAttribute("stroke-dasharray", "5, 5")
- }
- }
- }
- svg.appendChild(star)
- break
- case "cross":
- const cross = document.createElementNS(
- "http://www.w3.org/2000/svg",
- "polygon"
- )
- cross.setAttribute(
- "points",
- `${element.width * 0.35},0 ${element.width * 0.65},0 ${
- element.width * 0.65
- },${element.height * 0.35} ` +
- `${element.width},${element.height * 0.35} ${element.width},${
- element.height * 0.65
- } ` +
- `${element.width * 0.65},${element.height * 0.65} ${
- element.width * 0.65
- },${element.height} ` +
- `${element.width * 0.35},${element.height} ${element.width * 0.35},${
- element.height * 0.65
- } ` +
- `0,${element.height * 0.65} 0,${element.height * 0.35} ${
- element.width * 0.35
- },${element.height * 0.35}`
- )
- // 设置填充色
- setBackground(element, cross)
- // 设置边框
- if (element.borderWidth > 0) {
- cross.setAttribute("stroke", element.borderColor || "#000")
- cross.setAttribute("stroke-width", element.borderWidth || 1)
- // 处理虚线边框
- if (
- element.borderType === "dotted" ||
- element.borderType === "dashed"
- ) {
- if (element.borderStrokeDasharray) {
- cross.setAttribute(
- "stroke-dasharray",
- element.borderStrokeDasharray
- )
- } else if (element.borderType === "dotted") {
- cross.setAttribute("stroke-dasharray", "1, 3")
- } else if (element.borderType === "dashed") {
- cross.setAttribute("stroke-dasharray", "5, 5")
- }
- }
- }
- svg.appendChild(cross)
- break
- case "chevron":
- const chevron = document.createElementNS(
- "http://www.w3.org/2000/svg",
- "polygon"
- )
- chevron.setAttribute(
- "points",
- `${element.width * 0.5},0 ${element.width},${element.height * 0.5} ` +
- `${element.width * 0.5},${element.height} ` +
- `0,${element.height} ${element.width * 0.5},${
- element.height * 0.5
- } 0,0`
- )
- // 设置填充色
- setBackground(element, chevron)
- // 设置边框
- if (element.borderWidth > 0) {
- chevron.setAttribute("stroke", element.borderColor || "#000")
- chevron.setAttribute("stroke-width", element.borderWidth || 1)
- // 处理虚线边框
- if (
- element.borderType === "dotted" ||
- element.borderType === "dashed"
- ) {
- if (element.borderStrokeDasharray) {
- chevron.setAttribute(
- "stroke-dasharray",
- element.borderStrokeDasharray
- )
- } else if (element.borderType === "dotted") {
- chevron.setAttribute("stroke-dasharray", "1, 3")
- } else if (element.borderType === "dashed") {
- chevron.setAttribute("stroke-dasharray", "5, 5")
- }
- }
- }
- svg.appendChild(chevron)
- break
- case "frame":
- // 创建外框和内框
- const outerRect = document.createElementNS(
- "http://www.w3.org/2000/svg",
- "rect"
- )
- outerRect.setAttribute("x", 0)
- outerRect.setAttribute("y", 0)
- outerRect.setAttribute("width", element.width)
- outerRect.setAttribute("height", element.height)
- const innerRect = document.createElementNS(
- "http://www.w3.org/2000/svg",
- "rect"
- )
- const frameWidth = element.width / 10
- innerRect.setAttribute("x", frameWidth)
- innerRect.setAttribute("y", frameWidth)
- innerRect.setAttribute("width", element.width - frameWidth * 2)
- innerRect.setAttribute("height", element.height - frameWidth * 2)
- // 设置填充色
- setBackground(element, outerRect)
- innerRect.setAttribute("fill", "white") // 内框为白色
- // 设置边框
- if (element.borderWidth > 0) {
- outerRect.setAttribute("stroke", element.borderColor || "#000")
- outerRect.setAttribute("stroke-width", element.borderWidth || 1)
- // 处理虚线边框
- if (
- element.borderType === "dotted" ||
- element.borderType === "dashed"
- ) {
- if (element.borderStrokeDasharray) {
- outerRect.setAttribute(
- "stroke-dasharray",
- element.borderStrokeDasharray
- )
- } else if (element.borderType === "dotted") {
- outerRect.setAttribute("stroke-dasharray", "1, 3")
- } else if (element.borderType === "dashed") {
- outerRect.setAttribute("stroke-dasharray", "5, 5")
- }
- }
- }
- svg.appendChild(outerRect)
- svg.appendChild(innerRect)
- break
- case "cloud":
- // 使用路径绘制云形
- const cloud = document.createElementNS(
- "http://www.w3.org/2000/svg",
- "path"
- )
- const w = element.width
- const h = element.height
- cloud.setAttribute(
- "d",
- `M${w * 0.2},${h * 0.6} ` +
- `C${w * 0.05},${h * 0.6} ${w * 0.05},${h * 0.3} ${w * 0.2},${
- h * 0.3
- } ` +
- `C${w * 0.2},${h * 0.1} ${w * 0.45},${h * 0.1} ${w * 0.5},${
- h * 0.3
- } ` +
- `C${w * 0.55},${h * 0.1} ${w * 0.8},${h * 0.1} ${w * 0.8},${
- h * 0.3
- } ` +
- `C${w * 0.95},${h * 0.3} ${w * 0.95},${h * 0.6} ${w * 0.8},${
- h * 0.6
- } ` +
- `L${w * 0.2},${h * 0.6} Z`
- )
- // 设置填充色
- setBackground(element, cloud)
- // 设置边框
- if (element.borderWidth > 0) {
- cloud.setAttribute("stroke", element.borderColor || "#000")
- cloud.setAttribute("stroke-width", element.borderWidth || 1)
- // 处理虚线边框
- if (
- element.borderType === "dotted" ||
- element.borderType === "dashed"
- ) {
- if (element.borderStrokeDasharray) {
- cloud.setAttribute(
- "stroke-dasharray",
- element.borderStrokeDasharray
- )
- } else if (element.borderType === "dotted") {
- cloud.setAttribute("stroke-dasharray", "1, 3")
- } else if (element.borderType === "dashed") {
- cloud.setAttribute("stroke-dasharray", "5, 5")
- }
- }
- }
- svg.appendChild(cloud)
- break
- case "blockArc":
- const blockArc = document.createElementNS(
- "http://www.w3.org/2000/svg",
- "path"
- )
- // 计算弧形参数
- const rx = element.width / 2
- const ry = element.height / 2
- const innerRatio = 0.86 // 根据示例计算的内弧半径比例
- const innerRx = rx * innerRatio
- const innerRy = ry * innerRatio
- // 构建路径
- const path2 = `
- M 0,${ry}
- A ${rx} ${ry} 0 1 1 ${element.width} ${ry}
- L ${element.width - (rx - innerRx)},${ry}
- A ${innerRx} ${innerRy} 0 1 0 ${rx - innerRx},${ry}
- Z`
- blockArc.setAttribute("d", path2.trim())
- // 设置填充色
- setBackground(element, blockArc)
- // 设置边框
- if (element.borderWidth > 0) {
- blockArc.setAttribute("stroke", element.borderColor || "#000")
- blockArc.setAttribute("stroke-width", element.borderWidth || 1)
- if (
- element.borderType === "dotted" ||
- element.borderType === "dashed"
- ) {
- if (element.borderStrokeDasharray) {
- blockArc.setAttribute(
- "stroke-dasharray",
- element.borderStrokeDasharray
- )
- } else if (element.borderType === "dotted") {
- blockArc.setAttribute("stroke-dasharray", "1, 3")
- } else if (element.borderType === "dashed") {
- blockArc.setAttribute("stroke-dasharray", "5, 5")
- }
- }
- }
- svg.appendChild(blockArc)
- break
- case "rect":
- default:
- const rect = document.createElementNS(
- "http://www.w3.org/2000/svg",
- "rect"
- )
- rect.setAttribute("x", 0)
- rect.setAttribute("y", 0)
- rect.setAttribute("width", element.width)
- rect.setAttribute("height", element.height)
- if (element.fill && element.fill.type) {
- // 设置填充色
- if (element.fill.type === "color") {
- rect.setAttribute("fill", element.fill.value || "transparent")
- } else if (element.fill.type === "gradient") {
- // 渐变填充
- const { colors, path, rot } = element.fill.value
- if (colors && colors.length >= 2) {
- const gradientType = path === "rect" ? "linear" : "radial"
- const gradientAngle =
- gradientType === "linear" ? (90 - (rot || 0)) % 360 : rot || 0
- let gradientString = `${gradientType}-gradient(`
- if (gradientType === "linear") {
- gradientString += `${gradientAngle}deg, `
- }
- colors.forEach((color, i) => {
- gradientString += `${color.color} ${color.pos}${
- i < colors.length - 1 ? ", " : ""
- }`
- })
- gradientString += ")"
- // 创建渐变定义
- const gradientDef = document.createElementNS(
- "http://www.w3.org/2000/svg",
- "defs"
- )
- const gradientEl = document.createElementNS(
- "http://www.w3.org/2000/svg",
- gradientType === "linear" ? "linearGradient" : "radialGradient"
- )
- const gradientId = `gradient-${Date.now()}-${Math.random()
- .toString(36)
- .substr(2, 9)}`
- gradientEl.setAttribute("id", gradientId)
- // 设置渐变属性
- if (gradientType === "linear") {
- gradientEl.setAttribute(
- "gradientTransform",
- `rotate(${gradientAngle})`
- )
- }
- // 添加渐变色标
- colors.forEach((color) => {
- const stop = document.createElementNS(
- "http://www.w3.org/2000/svg",
- "stop"
- )
- stop.setAttribute("offset", color.pos)
- stop.setAttribute("stop-color", color.color)
- gradientEl.appendChild(stop)
- })
- gradientDef.appendChild(gradientEl)
- svg.appendChild(gradientDef)
- // 应用渐变
- rect.setAttribute("fill", `url(#${gradientId})`)
- }
- } else if (element.fill.type === "image") {
- // 创建图案填充
- const pattern = document.createElementNS(
- "http://www.w3.org/2000/svg",
- "pattern"
- )
- const patternId = `pattern-${Date.now()}-${Math.random()
- .toString(36)
- .substr(2, 9)}`
- pattern.setAttribute("id", patternId)
- pattern.setAttribute("patternUnits", "userSpaceOnUse")
- pattern.setAttribute("width", "100%")
- pattern.setAttribute("height", "100%")
- // 创建图片元素
- const image = document.createElementNS(
- "http://www.w3.org/2000/svg",
- "image"
- )
- image.setAttribute("width", "100%")
- image.setAttribute("height", "100%")
- image.setAttribute("preserveAspectRatio", "xMidYMid slice")
- image.setAttributeNS(
- "http://www.w3.org/1999/xlink",
- "href",
- element.fill.value.picBase64
- )
- pattern.appendChild(image)
- // 添加pattern到defs
- const defs = document.createElementNS(
- "http://www.w3.org/2000/svg",
- "defs"
- )
- defs.appendChild(pattern)
- svg.appendChild(defs)
- // 应用图案填充
- rect.setAttribute("fill", `url(#${patternId})`)
- } else {
- rect.setAttribute("fill", "transparent")
- }
- } else {
- rect.setAttribute("fill", "#ffffff00")
- }
- // 设置边框
- if (element.borderWidth > 0) {
- rect.setAttribute("stroke", element.borderColor || "#000")
- rect.setAttribute("stroke-width", element.borderWidth || 1)
- // 处理虚线边框
- if (
- element.borderType === "dotted" ||
- element.borderType === "dashed"
- ) {
- if (element.borderStrokeDasharray) {
- rect.setAttribute("stroke-dasharray", element.borderStrokeDasharray)
- } else if (element.borderType === "dotted") {
- rect.setAttribute("stroke-dasharray", "1, 3")
- } else if (element.borderType === "dashed") {
- rect.setAttribute("stroke-dasharray", "5, 5")
- }
- }
- }
- svg.appendChild(rect)
- break
- }
- const transformList = []
- let rotateDeg = element.rotate || 0
- if (element.isFlipV) {
- transformList.push(`scaleY(-1)`)
- rotateDeg = -rotateDeg // 垂直翻转时反转旋转方向
- }
- if (element.isFlipH) {
- transformList.push(`scaleX(-1)`)
- rotateDeg = -rotateDeg // 水平翻转时反转旋转方向
- }
- if (element.rotate) {
- transformList.push(`rotate(${rotateDeg}deg)`)
- }
- if (transformList.length > 0) {
- el.style.transform = transformList.join(" ")
- el.style.transformOrigin = "center center"
- }
- el.appendChild(svg)
- // 设置形状内容
- if (element.content) {
- const contentContainer = document.createElement("div")
- contentContainer.innerHTML = this.convertPtToPxInContent(element.content)
- contentContainer.style.position = "absolute"
- contentContainer.style.width = element.width + "px"
- contentContainer.style.height = element.height + "px"
- contentContainer.style.top = "0px"
- contentContainer.style.left = "0px"
- contentContainer.style.display = "flex"
- contentContainer.style.alignItems = "center"
- contentContainer.style.justifyContent = "center"
- contentContainer.style.zIndex = element.order
- contentContainer.style.pointerEvents = "none"
- const transformList = []
- let rotateDeg = element.rotate || 0
- if (element.isFlipV) {
- transformList.push(`scaleY(-1)`)
- rotateDeg = -rotateDeg // 垂直翻转时反转旋转方向
- }
- if (element.isFlipH) {
- transformList.push(`scaleX(-1)`)
- rotateDeg = -rotateDeg // 水平翻转时反转旋转方向
- }
- if (element.rotate) {
- transformList.push(`rotate(${rotateDeg}deg)`)
- }
- if (transformList.length > 0) {
- contentContainer.style.transform = transformList.join(" ")
- contentContainer.style.transformOrigin = "center center"
- }
- el.appendChild(contentContainer)
- }
- return el
- }
- // 创建表格元素
- const createTableElement = (element) => {
- const el = document.createElement("div")
- el.style.position = "absolute"
- el.style.top = element.top + "px"
- el.style.left = element.left + "px"
- el.style.width = element.width + "px"
- el.style.height = element.height + "px"
- el.style.zIndex = element.order
- // 创建表格元素
- const table = document.createElement("table")
- table.style.width = element.width + "px"
- table.style.height = element.height + "px"
- table.style.borderCollapse = "collapse"
- table.style.tableLayout = "fixed"
- // 设置表格边框
- if (element.borders) {
- if (element.borders.all) {
- const border = element.borders.all
- table.style.border = `${border.borderWidth || 1}px ${
- border.borderType || "solid"
- } ${border.borderColor || "#000"}`
- } else {
- // 分别设置四边边框
- if (element.borders.top) {
- table.style.borderTop = `${element.borders.top.borderWidth || 1}px ${
- element.borders.top.borderType || "solid"
- } ${element.borders.top.borderColor || "#000"}`
- }
- if (element.borders.bottom) {
- table.style.borderBottom = `${
- element.borders.bottom.borderWidth || 1
- }px ${element.borders.bottom.borderType || "solid"} ${
- element.borders.bottom.borderColor || "#000"
- }`
- }
- if (element.borders.left) {
- table.style.borderLeft = `${element.borders.left.borderWidth || 1}px ${
- element.borders.left.borderType || "solid"
- } ${element.borders.left.borderColor || "#000"}`
- }
- if (element.borders.right) {
- table.style.borderRight = `${
- element.borders.right.borderWidth || 1
- }px ${element.borders.right.borderType || "solid"} ${
- element.borders.right.borderColor || "#000"
- }`
- }
- }
- }
- // 创建表格内容
- const tbody = document.createElement("tbody")
- // 处理表格数据
- if (element.data && element.data.length > 0) {
- element.data.forEach((rowData, rowIndex) => {
- const tr = document.createElement("tr")
- rowData.forEach((cell, colIndex) => {
- // 跳过被合并的单元格
- if (cell.hMerge) return
- const td = document.createElement("td")
- // 设置单元格内容
- if (cell.text) {
- td.innerHTML = this.convertPtToPxInContent(cell.text)
- }
- // 设置单元格样式
- td.style.padding = "0px"
- td.style.verticalAlign = "middle"
- // 设置文本样式
- if (cell.fontColor) td.style.color = cell.fontColor
- if (cell.fontSize) td.style.fontSize = cell.fontSize
- if (cell.fontFamily) td.style.fontFamily = cell.fontFamily
- if (cell.bold) td.style.fontWeight = "bold"
- if (cell.italic) td.style.fontStyle = "italic"
- if (cell.underline) td.style.textDecoration = "underline"
- if (cell.align) td.style.textAlign = cell.align
- // 设置背景色
- if (cell.fillColor) td.style.backgroundColor = cell.fillColor
- // 设置单元格边框
- if (cell.borders) {
- if (cell.borders.all) {
- const border = cell.borders.all
- td.style.border = `${border.borderWidth || 1}px ${
- border.borderType || "solid"
- } ${border.borderColor || "#000"}`
- } else {
- // 分别设置四边边框
- if (cell.borders.top) {
- td.style.borderTop = `${cell.borders.top.borderWidth || 1}px ${
- cell.borders.top.borderType || "solid"
- } ${cell.borders.top.borderColor || "#000"}`
- }
- if (cell.borders.bottom) {
- td.style.borderBottom = `${
- cell.borders.bottom.borderWidth || 1
- }px ${cell.borders.bottom.borderType || "solid"} ${
- cell.borders.bottom.borderColor || "#000"
- }`
- }
- if (cell.borders.left) {
- td.style.borderLeft = `${cell.borders.left.borderWidth || 1}px ${
- cell.borders.left.borderType || "solid"
- } ${cell.borders.left.borderColor || "#000"}`
- }
- if (cell.borders.right) {
- td.style.borderRight = `${
- cell.borders.right.borderWidth || 1
- }px ${cell.borders.right.borderType || "solid"} ${
- cell.borders.right.borderColor || "#000"
- }`
- }
- }
- }
- td.style.width = element.colWidths[colIndex] + "px"
- // 设置单元格合并
- if (cell.colSpan && cell.colSpan > 1) {
- td.colSpan = cell.colSpan
- td.style.width = element.colWidths[colIndex] * cell.colSpan + "px"
- }
- if (cell.rowSpan && cell.rowSpan > 1) {
- td.rowSpan = cell.rowSpan
- }
- tr.appendChild(td)
- })
- tr.style.height = element.rowHeights[rowIndex] + "px"
- tbody.appendChild(tr)
- })
- }
- table.appendChild(tbody)
- el.appendChild(table)
- return el
- }
- const createChartElement = (element) => {
- // 实现图表元素创建逻辑
- return document.createElement("div") // 临时返回空div
- }
- // 创建图表元素
- const createDiagramElement = (element) => {
- const el = document.createElement("div")
- el.style.position = "absolute"
- el.style.top = element.top + "px"
- el.style.left = element.left + "px"
- el.style.width = element.width + "px"
- el.style.height = element.height + "px"
- el.style.zIndex = element.order
- // 递归渲染SmartArt节点
- const renderDiagramNode = (node) => {
- const nodeEl = document.createElement("div")
- nodeEl.style.position = "absolute"
- nodeEl.style.left = node.left + "px"
- nodeEl.style.top = node.top + "px"
- nodeEl.style.width = node.width + "px"
- nodeEl.style.height = node.height + "px"
- // 设置边框
- if (node.borderWidth > 0) {
- nodeEl.style.border = `${node.borderWidth}px ${node.borderType} ${node.borderColor}`
- if (node.borderStrokeDasharray && node.borderStrokeDasharray !== "0") {
- nodeEl.style.borderStyle = "dashed"
- }
- }
- // 设置背景填充
- if (node.fill && node.fill.type === "color") {
- nodeEl.style.backgroundColor = node.fill.value
- }
- // 设置内容
- if (node.content) {
- nodeEl.innerHTML = convertPtToPxInContent(node.content)
- }
- // 设置垂直对齐
- if (node.vAlign === "mid") {
- nodeEl.style.display = "flex"
- nodeEl.style.alignItems = "center"
- nodeEl.style.justifyContent = "center"
- }
- // 设置翻转
- const transforms = []
- if (node.isFlipV) {
- transforms.push("scaleY(-1)")
- }
- if (node.isFlipH) {
- transforms.push("scaleX(-1)")
- }
- if (transforms.length > 0) {
- nodeEl.style.transform = transforms.join(" ")
- }
- return nodeEl
- }
- // 按照 order 排序元素
- const sortedElements = [...element.elements].sort((a, b) => a.order - b.order)
- // 渲染所有节点
- sortedElements.forEach((node) => {
- const nodeEl = renderDiagramNode(node)
- el.appendChild(nodeEl)
- })
- return el
- }
- // 创建数学公式元素
- const createMathElement = (element) => {
- const el = document.createElement("div")
- el.style.position = "absolute"
- el.style.top = element.top + "px"
- el.style.left = element.left + "px"
- el.style.width = element.width + "px"
- el.style.height = element.height + "px"
- el.style.zIndex = element.order
- // 应用旋转变换
- if (element.rotate) {
- el.style.transform = `rotate(${element.rotate}deg)`
- el.style.transformOrigin = "center center"
- }
- // 设置数学公式内容
- if (element.mathXml) {
- // 如果有MathML格式的内容
- try {
- // 创建MathML命名空间的元素
- const mathEl = document.createElementNS(
- "http://www.w3.org/1998/Math/MathML",
- "math"
- )
- mathEl.innerHTML = element.mathXml
- el.appendChild(mathEl)
- } catch (error) {
- console.error("创建MathML元素失败:", error)
- // 回退方案:直接显示文本
- el.textContent = element.text || "数学公式"
- }
- } else if (element.text) {
- // 如果只有文本内容
- el.textContent = element.text
- }
- // 应用样式
- if (element.style) {
- // 字体样式
- if (element.style.fontFamily) {
- el.style.fontFamily = element.style.fontFamily
- }
- // 字体大小
- if (element.style.fontSize) {
- el.style.fontSize = element.style.fontSize + "px"
- }
- // 字体颜色
- if (element.style.color) {
- el.style.color = element.style.color
- }
- }
- // 应用背景色
- if (element.fill && element.fill.type === "color") {
- el.style.backgroundColor = element.fill.value
- }
- // 应用边框
- if (element.borderColor && element.borderWidth) {
- el.style.border = `${element.borderWidth}px ${
- element.borderType || "solid"
- } ${element.borderColor}`
- }
- return el
- }
- // 创建文本元素
- const createTextElement = (element) => {
- const el = document.createElement("div")
- el.style.position = "absolute"
- el.style.top = element.top + "px"
- el.style.left = element.left + "px"
- el.style.width = element.width + "px"
- el.style.height = element.height + "px"
- el.style.zIndex = element.order
- el.style.overflow = "hidden"
- // 应用旋转变换
- if (element.rotate) {
- el.style.transform = `rotate(${element.rotate}deg)`
- el.style.transformOrigin = "center center"
- }
- // 应用文本内容
- if (element.text) {
- el.innerHTML = element.text
- }
- // 应用文本样式
- if (element.style) {
- // 字体样式
- if (element.style.fontFamily) {
- el.style.fontFamily = element.style.fontFamily
- }
- // 字体大小
- if (element.style.fontSize) {
- el.style.fontSize = element.style.fontSize + "px"
- }
- // 字体颜色
- if (element.style.color) {
- el.style.color = element.style.color
- }
- // 字体粗细
- if (element.style.fontWeight) {
- el.style.fontWeight = element.style.fontWeight
- }
- // 字体样式(斜体等)
- if (element.style.fontStyle) {
- el.style.fontStyle = element.style.fontStyle
- }
- // 文本装饰(下划线等)
- if (element.style.textDecoration) {
- el.style.textDecoration = element.style.textDecoration
- }
- // 文本对齐
- if (element.style.textAlign) {
- el.style.textAlign = element.style.textAlign
- }
- // 行高
- if (element.style.lineHeight) {
- el.style.lineHeight = element.style.lineHeight
- }
- // 字间距
- if (element.style.letterSpacing) {
- el.style.letterSpacing = element.style.letterSpacing + "px"
- }
- // 文本缩进
- if (element.style.textIndent) {
- el.style.textIndent = element.style.textIndent + "px"
- }
- // 垂直对齐
- if (element.style.verticalAlign) {
- el.style.verticalAlign = element.style.verticalAlign
- }
- }
- // 应用背景色
- if (element.fill && element.fill.type === "color") {
- el.style.backgroundColor = element.fill.value
- }
- // 应用边框
- if (element.borderColor && element.borderWidth) {
- el.style.border = `${element.borderWidth}px ${
- element.borderType || "solid"
- } ${element.borderColor}`
- }
- // 应用内边距
- if (element.padding) {
- el.style.padding = element.padding + "px"
- }
- return el
- }
- // 递归调整元素位置
- const adjustElementPosition = (element, parentElement) => {
- // 创建深拷贝,但保留特殊属性的引用
- const adjustedElement = JSON.parse(JSON.stringify(element))
- // 调整位置为相对于父组合元素的位置
- adjustedElement.top = element.top - parentElement.top
- adjustedElement.left = element.left - parentElement.left
- // 恢复特殊属性的引用
- const specialProps = [
- "src",
- "blob",
- "fill",
- "text",
- "path",
- "elements",
- "borderColor",
- "borderWidth",
- "borderType",
- ]
- specialProps.forEach((prop) => {
- if (element[prop] !== undefined) {
- adjustedElement[prop] = element[prop]
- }
- })
- // 如果是组合元素,递归处理其子元素
- if (element.type === "group" && element.elements) {
- adjustedElement.elements = element.elements.map((childElement) =>
- adjustElementPosition(childElement, {
- top: element.top,
- left: element.left,
- })
- )
- }
- return adjustedElement
- }
- // 绘制类别标签
- const drawCategoryLabels = (svg, categories, padding, groupWidth, barDir) => {
- if (!categories || !categories.length) return
- // 创建标签组
- const labelGroup = document.createElementNS("http://www.w3.org/2000/svg", "g")
- labelGroup.setAttribute("class", "category-labels")
- // 计算标签位置
- const isVertical = barDir === "vertical"
- const labelSpacing = groupWidth
- // 绘制每个类别标签
- categories.forEach((category, index) => {
- const label = document.createElementNS("http://www.w3.org/2000/svg", "text")
- // 设置标签文本
- label.textContent = category
- // 设置标签样式
- label.setAttribute("font-size", "12")
- label.setAttribute("text-anchor", isVertical ? "middle" : "start")
- // 设置标签位置
- if (isVertical) {
- // 垂直条形图,标签在底部
- label.setAttribute("x", padding + index * labelSpacing + labelSpacing / 2)
- label.setAttribute("y", svg.getAttribute("height") - padding / 3)
- label.setAttribute("dominant-baseline", "hanging")
- } else {
- // 水平条形图,标签在左侧
- label.setAttribute("x", padding / 2)
- label.setAttribute("y", padding + index * labelSpacing + labelSpacing / 2)
- label.setAttribute("dominant-baseline", "middle")
- label.setAttribute("text-anchor", "end")
- }
- // 添加标签到组
- labelGroup.appendChild(label)
- })
- // 将标签组添加到SVG
- svg.appendChild(labelGroup)
- return labelGroup
- }
- // 绘制网格线
- const drawGrid = (svg, padding, width, height, maxValue) => {
- // 创建网格组
- const gridGroup = document.createElementNS("http://www.w3.org/2000/svg", "g")
- gridGroup.setAttribute("class", "chart-grid")
- // 设置网格线样式
- const gridColor = "#e0e0e0"
- const gridWidth = 1
- // 计算网格间距
- const gridCount = 5 // 网格线数量
- const gridStep = (height - padding * 2) / gridCount
- // 绘制水平网格线
- for (let i = 0; i <= gridCount; i++) {
- const y = padding + i * gridStep
- const line = document.createElementNS("http://www.w3.org/2000/svg", "line")
- line.setAttribute("x1", padding)
- line.setAttribute("y1", y)
- line.setAttribute("x2", width - padding)
- line.setAttribute("y2", y)
- line.setAttribute("stroke", gridColor)
- line.setAttribute("stroke-width", gridWidth)
- // 如果是底线,加粗显示
- if (i === gridCount) {
- line.setAttribute("stroke-width", gridWidth * 2)
- line.setAttribute("stroke", "#aaa")
- }
- gridGroup.appendChild(line)
- // 添加刻度值(除了底线)
- if (i < gridCount) {
- const valueText = document.createElementNS(
- "http://www.w3.org/2000/svg",
- "text"
- )
- const value = Math.round((gridCount - i) * (maxValue / gridCount))
- valueText.textContent = value
- valueText.setAttribute("x", padding - 5)
- valueText.setAttribute("y", y)
- valueText.setAttribute("text-anchor", "end")
- valueText.setAttribute("dominant-baseline", "middle")
- valueText.setAttribute("font-size", "10")
- valueText.setAttribute("fill", "#666")
- gridGroup.appendChild(valueText)
- }
- }
- // 添加网格组到SVG
- svg.appendChild(gridGroup)
- return gridGroup
- }
- // 绘制图表图例
- const drawLegend = (svg, series, colors, padding) => {
- // 创建图例容器
- const legendGroup = document.createElementNS(
- "http://www.w3.org/2000/svg",
- "g"
- )
- legendGroup.setAttribute("class", "chart-legend")
- // 设置图例位置
- const legendX = padding
- const legendY = padding
- let currentY = legendY
- // 为每个系列创建图例项
- series.forEach((item, index) => {
- const itemGroup = document.createElementNS(
- "http://www.w3.org/2000/svg",
- "g"
- )
- itemGroup.setAttribute("transform", `translate(${legendX}, ${currentY})`)
- // 创建图例颜色标记
- const colorMark = document.createElementNS(
- "http://www.w3.org/2000/svg",
- "rect"
- )
- colorMark.setAttribute("width", "12")
- colorMark.setAttribute("height", "12")
- colorMark.setAttribute("fill", colors[index % colors.length])
- // 创建图例文本
- const text = document.createElementNS("http://www.w3.org/2000/svg", "text")
- text.setAttribute("x", "20")
- text.setAttribute("y", "10")
- text.setAttribute("font-size", "12")
- text.setAttribute("alignment-baseline", "middle")
- text.textContent = item.name || `系列 ${index + 1}`
- // 将元素添加到组中
- itemGroup.appendChild(colorMark)
- itemGroup.appendChild(text)
- legendGroup.appendChild(itemGroup)
- // 更新下一个图例项的Y坐标
- currentY += 20
- })
- // 将图例组添加到SVG中
- svg.appendChild(legendGroup)
- return legendGroup
- }
- // 调整颜色亮度
- const adjustBrightness = (color, factor) => {
- // 如果颜色为空或不是字符串,返回原值
- if (!color || typeof color !== "string") return color
- // 处理十六进制颜色
- if (color.startsWith("#")) {
- let hex = color.substring(1)
- // 处理简写形式 (#RGB)
- if (hex.length === 3) {
- hex = hex[0] + hex[0] + hex[1] + hex[1] + hex[2] + hex[2]
- }
- // 解析RGB值
- const r = parseInt(hex.substring(0, 2), 16)
- const g = parseInt(hex.substring(2, 4), 16)
- const b = parseInt(hex.substring(4, 6), 16)
- // 调整亮度
- const adjustedR = Math.min(255, Math.max(0, Math.round(r * factor)))
- const adjustedG = Math.min(255, Math.max(0, Math.round(g * factor)))
- const adjustedB = Math.min(255, Math.max(0, Math.round(b * factor)))
- // 转换回十六进制
- return `#${adjustedR.toString(16).padStart(2, "0")}${adjustedG
- .toString(16)
- .padStart(2, "0")}${adjustedB.toString(16).padStart(2, "0")}`
- }
- // 处理rgb/rgba颜色
- if (color.startsWith("rgb")) {
- const rgbMatch = color.match(
- /rgba?\((\d+),\s*(\d+),\s*(\d+)(?:,\s*([\d.]+))?\)/
- )
- if (rgbMatch) {
- const r = parseInt(rgbMatch[1])
- const g = parseInt(rgbMatch[2])
- const b = parseInt(rgbMatch[3])
- const a = rgbMatch[4] !== undefined ? parseFloat(rgbMatch[4]) : 1
- // 调整亮度
- const adjustedR = Math.min(255, Math.max(0, Math.round(r * factor)))
- const adjustedG = Math.min(255, Math.max(0, Math.round(g * factor)))
- const adjustedB = Math.min(255, Math.max(0, Math.round(b * factor)))
- // 返回调整后的颜色
- return a < 1
- ? `rgba(${adjustedR}, ${adjustedG}, ${adjustedB}, ${a})`
- : `rgb(${adjustedR}, ${adjustedG}, ${adjustedB})`
- }
- }
- // 如果不是支持的颜色格式,返回原值
- return color
- }
- const convertPtToPxInContent = (content) => {
- if (!content) return ""
- // 使用正则表达式查找所有包含pt单位的样式
- const ptRegex = /(\d+(\.\d+)?)pt/g
- // 将pt转换为px (1pt ≈ 1.33px)
- return content.replace(ptRegex, (match, value) => {
- const pxValue = Math.round(parseFloat(value) * 1.33 * 100) / 100
- return `${pxValue}px`
- })
- }
- const processElements = (elements, slideIndex) => {
- if (!elements || !Array.isArray(elements)) return
- // 对元素进行排序处理
- elements.sort((a, b) => a.order - b.order)
- // 处理每个元素
- elements.forEach((element) => {
- // 设置元素的幻灯片索引
- element.slideIndex = slideIndex
- // 处理元素中的子元素
- if (element.elements && Array.isArray(element.elements)) {
- processElements(element.elements, slideIndex)
- }
- // 处理特殊类型元素
- if (element.type === "group" && element.elements) {
- // 处理组元素
- element.elements.forEach((childElement) => {
- // 调整子元素位置为相对于组的位置
- childElement.top = (childElement.top || 0) + (element.top || 0)
- childElement.left = (childElement.left || 0) + (element.left || 0)
- })
- }
- // 处理图表元素
- if (element.type === "chart" && element.data) {
- // 确保图表数据格式正确
- if (!element.data.series) {
- element.data.series = []
- }
- // 处理图表系列数据
- element.data.series.forEach((series) => {
- if (!series.values) {
- series.values = []
- }
- })
- }
- })
- return elements
- }
- // 监听 pptxJson 变化
- watch(
- () => props.pptxJson,
- (newVal) => {
- if (newVal) {
- renderSlides()
- }
- },
- { deep: true }
- )
- // 组件挂载时渲染幻灯片
- onMounted(() => {
- renderSlides()
- })
- </script>
- <style scoped>
- .pptx-container {
- width: 100%;
- overflow-x: auto;
- padding: 20px 0;
- }
- </style>
|