snap remove library examples javascript css node.js svg

remove - svg javascript library



Voltear la mayor parte de una imagen svg, pero no el texto dentro de ella (4)

Tengo una gran colección de imágenes svg como esta:

<svg version="1.1" viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg"> <g stroke="lightgray" stroke-dasharray="1,1" stroke-width="1" transform="scale(4, 4)"> <line x1="0" y1="0" x2="256" y2="256"></line> <line x1="256" y1="0" x2="0" y2="256"></line> <line x1="128" y1="0" x2="128" y2="256"></line> <line x1="0" y1="128" x2="256" y2="128"></line> </g> <g transform="scale(1, -1) translate(0, -900)"> <style> .stroke1 {fill: #BF0909;} .stroke2 {fill: #BFBF09;} .stroke3 {fill: #09BF09;} .stroke4 {fill: #09BFBF;} .stroke5 {fill: #0909BF;} .stroke6 {fill: #BF09BF;} .stroke7 {fill: #BFBFBF;} .stroke8 {fill: #090909;} </style> <path class="stroke1" d="M 272 567 Q 306 613 342 669 Q 370 718 395 743 Q 405 753 400 769 Q 396 782 365 808 Q 337 827 316 828 Q 297 827 305 802 Q 318 769 306 741 Q 267 647 207 560 Q 150 476 72 385 Q 60 375 58 367 Q 54 355 70 358 Q 82 359 109 384 Q 155 421 213 493 Q 226 509 241 527 L 272 567 Z" fill="#BF0909"></path> <path class="stroke2" d="M 241 527 Q 262 506 258 375 Q 258 374 258 370 Q 254 253 221 135 Q 215 114 224 80 Q 236 44 248 32 Q 267 16 279 44 Q 294 86 294 134 Q 303 420 314 485 Q 321 515 295 543 Q 289 549 272 567 C 251 589 227 553 241 527 Z" fill="lightgray"></path> <path class="stroke3" d="M 521 560 Q 561 621 602 708 Q 620 751 638 773 Q 645 786 639 799 Q 633 811 602 830 Q 572 846 554 843 Q 535 839 546 817 Q 561 795 552 757 Q 513 619 407 448 Q 398 436 397 430 Q 394 418 409 423 Q 439 432 503 532 L 521 560 Z" fill="lightgray"></path> <path class="stroke4" d="M 503 532 Q 527 510 555 520 Q 795 608 782 549 Q 783 543 743 468 Q 736 458 741 453 Q 745 447 756 459 Q 852 532 894 549 Q 904 552 905 561 Q 906 574 876 592 Q 852 605 828 621 Q 800 637 783 630 Q 686 590 521 560 C 492 555 479 550 503 532 Z" fill="lightgray"></path> <path class="stroke5" d="M 568 72 Q 531 81 494 91 Q 482 94 483 86 Q 484 79 494 71 Q 569 7 596 -33 Q 611 -49 626 -36 Q 659 -3 661 82 Q 655 149 655 345 Q 656 382 667 407 Q 676 426 659 439 Q 634 461 604 470 Q 585 477 577 469 Q 571 462 582 447 Q 619 384 603 127 Q 597 82 589 74 Q 582 67 568 72 Z" fill="lightgray"></path> <path class="stroke6" d="M 444 320 Q 419 262 385 208 Q 364 180 381 144 Q 388 128 409 139 Q 460 181 468 264 Q 472 295 467 319 Q 463 328 456 328 Q 449 327 444 320 Z" fill="lightgray"></path> <path class="stroke7" d="M 738 307 Q 789 249 847 168 Q 860 146 876 139 Q 885 138 893 146 Q 908 159 900 204 Q 891 264 743 338 Q 734 345 731 332 Q 728 319 738 307 Z" fill="lightgray"></path> </g> </svg>

y una lista de coordenadas para cada imagen en la que se debe dibujar un número (vea los elementos de texto del siguiente código SVG). El problema es: cuando agrego los elementos de texto requeridos, se voltean vertical y horizontalmente:

<svg version="1.1" viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg"> <g stroke="lightgray" stroke-dasharray="1,1" stroke-width="1" transform="scale(4, 4)"> <line x1="0" y1="0" x2="256" y2="256"></line> <line x1="256" y1="0" x2="0" y2="256"></line> <line x1="128" y1="0" x2="128" y2="256"></line> <line x1="0" y1="128" x2="256" y2="128"></line> </g> <g transform="scale(1, -1) translate(0, -900)"> <style> .stroke1 {fill: #BF0909;} .stroke2 {fill: #BFBF09;} .stroke3 {fill: #09BF09;} .stroke4 {fill: #09BFBF;} .stroke5 {fill: #0909BF;} .stroke6 {fill: #BF09BF;} .stroke7 {fill: #BFBFBF;} .stroke8 {fill: #090909;} text { font-family: Helvetica; font-size: 80px; fill: #FFFFFF; paint-order: stroke; stroke: #000000; stroke-width: 4px; stroke-linecap: butt; stroke-linejoin: miter; font-weight: 800; } </style> <path class="stroke1" d="M 272 567 Q 306 613 342 669 Q 370 718 395 743 Q 405 753 400 769 Q 396 782 365 808 Q 337 827 316 828 Q 297 827 305 802 Q 318 769 306 741 Q 267 647 207 560 Q 150 476 72 385 Q 60 375 58 367 Q 54 355 70 358 Q 82 359 109 384 Q 155 421 213 493 Q 226 509 241 527 L 272 567 Z" fill="#BF0909"></path> <path class="stroke2" d="M 241 527 Q 262 506 258 375 Q 258 374 258 370 Q 254 253 221 135 Q 215 114 224 80 Q 236 44 248 32 Q 267 16 279 44 Q 294 86 294 134 Q 303 420 314 485 Q 321 515 295 543 Q 289 549 272 567 C 251 589 227 553 241 527 Z" fill="lightgray"></path> <path class="stroke3" d="M 521 560 Q 561 621 602 708 Q 620 751 638 773 Q 645 786 639 799 Q 633 811 602 830 Q 572 846 554 843 Q 535 839 546 817 Q 561 795 552 757 Q 513 619 407 448 Q 398 436 397 430 Q 394 418 409 423 Q 439 432 503 532 L 521 560 Z" fill="lightgray"></path> <path class="stroke4" d="M 503 532 Q 527 510 555 520 Q 795 608 782 549 Q 783 543 743 468 Q 736 458 741 453 Q 745 447 756 459 Q 852 532 894 549 Q 904 552 905 561 Q 906 574 876 592 Q 852 605 828 621 Q 800 637 783 630 Q 686 590 521 560 C 492 555 479 550 503 532 Z" fill="lightgray"></path> <path class="stroke5" d="M 568 72 Q 531 81 494 91 Q 482 94 483 86 Q 484 79 494 71 Q 569 7 596 -33 Q 611 -49 626 -36 Q 659 -3 661 82 Q 655 149 655 345 Q 656 382 667 407 Q 676 426 659 439 Q 634 461 604 470 Q 585 477 577 469 Q 571 462 582 447 Q 619 384 603 127 Q 597 82 589 74 Q 582 67 568 72 Z" fill="lightgray"></path> <path class="stroke6" d="M 444 320 Q 419 262 385 208 Q 364 180 381 144 Q 388 128 409 139 Q 460 181 468 264 Q 472 295 467 319 Q 463 328 456 328 Q 449 327 444 320 Z" fill="lightgray"></path> <path class="stroke7" d="M 738 307 Q 789 249 847 168 Q 860 146 876 139 Q 885 138 893 146 Q 908 159 900 204 Q 891 264 743 338 Q 734 345 731 332 Q 728 319 738 307 Z" fill="lightgray"></path> <text x="317" y="812">1</text> <text x="273" y="558">2</text> <text x="556" y="828">3</text> <text x="513" y="532">4</text> <text x="586" y="463">5</text> <text x="455" y="316">6</text> <text x="742" y="326">7</text> </g> </svg>

Simplemente no puedo encontrar una manera de hacer que el texto se muestre en la posición correcta sin que se haya volteado horizontal y verticalmente. Ya intenté envolver el texto en otra etiqueta G y hacer la transformación de nuevo, revertirlo, pero luego el texto desaparecería. También intenté mover el texto fuera de la etiqueta g original, pero luego mis coordenadas ya no son válidas ...

Edición: estoy buscando una manera de generar los svgs de manera que sean compatibles con Safari (en Windows), Chrome y Firefox.

Edit2: Desafortunadamente, no puedo usar transform-box porque necesito un navegador basado en Safari que no lo admita.


Espero que esto ayude:

text:nth-child(1) { transform: scale(1, -1); transform-origin: 317px 812px;/*same as text coords*/ dominant-baseline: hanging; }

<svg version="1.1" viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg"> <g stroke="lightgray" stroke-dasharray="1,1" stroke-width="1" transform="scale(4, 4)"> <line x1="0" y1="0" x2="256" y2="256"></line> <line x1="256" y1="0" x2="0" y2="256"></line> <line x1="128" y1="0" x2="128" y2="256"></line> <line x1="0" y1="128" x2="256" y2="128"></line> </g> <g transform="scale(1, -1) translate(0, -900)"> <style> .stroke1 {fill: #BF0909;} .stroke2 {fill: #BFBF09;} .stroke3 {fill: #09BF09;} .stroke4 {fill: #09BFBF;} .stroke5 {fill: #0909BF;} .stroke6 {fill: #BF09BF;} .stroke7 {fill: #BFBFBF;} .stroke8 {fill: #090909;} text { font-family: Helvetica; font-size: 80px; fill: #FFFFFF; paint-order: stroke; stroke: #000000; stroke-width: 4px; stroke-linecap: butt; stroke-linejoin: miter; font-weight: 800; } </style> <path class="stroke1" d="M 272 567 Q 306 613 342 669 Q 370 718 395 743 Q 405 753 400 769 Q 396 782 365 808 Q 337 827 316 828 Q 297 827 305 802 Q 318 769 306 741 Q 267 647 207 560 Q 150 476 72 385 Q 60 375 58 367 Q 54 355 70 358 Q 82 359 109 384 Q 155 421 213 493 Q 226 509 241 527 L 272 567 Z" fill="#BF0909"></path> <path class="stroke2" d="M 241 527 Q 262 506 258 375 Q 258 374 258 370 Q 254 253 221 135 Q 215 114 224 80 Q 236 44 248 32 Q 267 16 279 44 Q 294 86 294 134 Q 303 420 314 485 Q 321 515 295 543 Q 289 549 272 567 C 251 589 227 553 241 527 Z" fill="lightgray"></path> <path class="stroke3" d="M 521 560 Q 561 621 602 708 Q 620 751 638 773 Q 645 786 639 799 Q 633 811 602 830 Q 572 846 554 843 Q 535 839 546 817 Q 561 795 552 757 Q 513 619 407 448 Q 398 436 397 430 Q 394 418 409 423 Q 439 432 503 532 L 521 560 Z" fill="lightgray"></path> <path class="stroke4" d="M 503 532 Q 527 510 555 520 Q 795 608 782 549 Q 783 543 743 468 Q 736 458 741 453 Q 745 447 756 459 Q 852 532 894 549 Q 904 552 905 561 Q 906 574 876 592 Q 852 605 828 621 Q 800 637 783 630 Q 686 590 521 560 C 492 555 479 550 503 532 Z" fill="lightgray"></path> <path class="stroke5" d="M 568 72 Q 531 81 494 91 Q 482 94 483 86 Q 484 79 494 71 Q 569 7 596 -33 Q 611 -49 626 -36 Q 659 -3 661 82 Q 655 149 655 345 Q 656 382 667 407 Q 676 426 659 439 Q 634 461 604 470 Q 585 477 577 469 Q 571 462 582 447 Q 619 384 603 127 Q 597 82 589 74 Q 582 67 568 72 Z" fill="lightgray"></path> <path class="stroke6" d="M 444 320 Q 419 262 385 208 Q 364 180 381 144 Q 388 128 409 139 Q 460 181 468 264 Q 472 295 467 319 Q 463 328 456 328 Q 449 327 444 320 Z" fill="lightgray"></path> <path class="stroke7" d="M 738 307 Q 789 249 847 168 Q 860 146 876 139 Q 885 138 893 146 Q 908 159 900 204 Q 891 264 743 338 Q 734 345 731 332 Q 728 319 738 307 Z" fill="lightgray"></path> <g> <text x="317" y="812">1</text> <text x="273" y="558">2</text> <text x="556" y="828">3</text> <text x="513" y="532">4</text> <text x="586" y="463">5</text> <text x="455" y="316">6</text> <text x="742" y="326">7</text> </g> </g> </svg>

Desafortunadamente, esto funciona en Chrome y Firefox pero no en Safari. No revisé Edge y IE.


Manipulando el SVG, todo lo que necesitas hacer es

  • Mueva los elementos <text> fuera del grupo con el atributo de transform
  • volver a calcular el atributo y con

    y -> 940 - y

    Esto supone que el atributo de transformación siempre es transform="scale(1, -1) translate(0, -900)" y el tamaño de fuente 80px . Una fórmula general sería

    y -> (negative y translation + font size / 2) - y

Aquí hay un script de nodo que utiliza cheerio para cambiar los archivos existentes:

const cheerio = require(''cheerio''); const $ = cheerio.load(xmlText, { xmlMode: true }); function flipTextInPlace ($) { $(''text'').each(() => { const y = $(this).attr(''y''); $(this).attr(''y'', 940 - y); }).appendTo(''svg''); }


Podrías usar css transform en tus nodos de texto.

Editar

Inspirado en la respuesta de @enxaneta, puedes ejecutar este pequeño script

const text = document.querySelectorAll("text"); text.forEach(function(el){ el.style.transformOrigin = el.getAttribute(''x'')+''px ''+el.getAttribute(''y'')+''px''; el.style.transform = "scale(1,-1)"; });

text{ dominant-baseline:central; }

<svg version="1.1" viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg"> <g stroke="lightgray" stroke-dasharray="1,1" stroke-width="1" transform="scale(4, 4)"> <line x1="0" y1="0" x2="256" y2="256"></line> <line x1="256" y1="0" x2="0" y2="256"></line> <line x1="128" y1="0" x2="128" y2="256"></line> <line x1="0" y1="128" x2="256" y2="128"></line> </g> <g transform="scale(1, -1) translate(0, -900)"> <style> .stroke1 {fill: #BF0909;} .stroke2 {fill: #BFBF09;} .stroke3 {fill: #09BF09;} .stroke4 {fill: #09BFBF;} .stroke5 {fill: #0909BF;} .stroke6 {fill: #BF09BF;} .stroke7 {fill: #BFBFBF;} .stroke8 {fill: #090909;} text { font-family: Helvetica; font-size: 80px; fill: #FFFFFF; paint-order: stroke; stroke: #000000; stroke-width: 4px; stroke-linecap: butt; stroke-linejoin: miter; font-weight: 800; } </style> <path class="stroke1" d="M 272 567 Q 306 613 342 669 Q 370 718 395 743 Q 405 753 400 769 Q 396 782 365 808 Q 337 827 316 828 Q 297 827 305 802 Q 318 769 306 741 Q 267 647 207 560 Q 150 476 72 385 Q 60 375 58 367 Q 54 355 70 358 Q 82 359 109 384 Q 155 421 213 493 Q 226 509 241 527 L 272 567 Z" fill="#BF0909"></path> <path class="stroke2" d="M 241 527 Q 262 506 258 375 Q 258 374 258 370 Q 254 253 221 135 Q 215 114 224 80 Q 236 44 248 32 Q 267 16 279 44 Q 294 86 294 134 Q 303 420 314 485 Q 321 515 295 543 Q 289 549 272 567 C 251 589 227 553 241 527 Z" fill="lightgray"></path> <path class="stroke3" d="M 521 560 Q 561 621 602 708 Q 620 751 638 773 Q 645 786 639 799 Q 633 811 602 830 Q 572 846 554 843 Q 535 839 546 817 Q 561 795 552 757 Q 513 619 407 448 Q 398 436 397 430 Q 394 418 409 423 Q 439 432 503 532 L 521 560 Z" fill="lightgray"></path> <path class="stroke4" d="M 503 532 Q 527 510 555 520 Q 795 608 782 549 Q 783 543 743 468 Q 736 458 741 453 Q 745 447 756 459 Q 852 532 894 549 Q 904 552 905 561 Q 906 574 876 592 Q 852 605 828 621 Q 800 637 783 630 Q 686 590 521 560 C 492 555 479 550 503 532 Z" fill="lightgray"></path> <path class="stroke5" d="M 568 72 Q 531 81 494 91 Q 482 94 483 86 Q 484 79 494 71 Q 569 7 596 -33 Q 611 -49 626 -36 Q 659 -3 661 82 Q 655 149 655 345 Q 656 382 667 407 Q 676 426 659 439 Q 634 461 604 470 Q 585 477 577 469 Q 571 462 582 447 Q 619 384 603 127 Q 597 82 589 74 Q 582 67 568 72 Z" fill="lightgray"></path> <path class="stroke6" d="M 444 320 Q 419 262 385 208 Q 364 180 381 144 Q 388 128 409 139 Q 460 181 468 264 Q 472 295 467 319 Q 463 328 456 328 Q 449 327 444 320 Z" fill="lightgray"></path> <path class="stroke7" d="M 738 307 Q 789 249 847 168 Q 860 146 876 139 Q 885 138 893 146 Q 908 159 900 204 Q 891 264 743 338 Q 734 345 731 332 Q 728 319 738 307 Z" fill="lightgray"></path> <text x="317" y="812">1</text> <text x="273" y="558">2</text> <text x="556" y="828">3</text> <text x="513" y="532">4</text> <text x="586" y="463">5</text> <text x="455" y="316">6</text> <text x="742" y="326">7</text> </g> </svg>


</path> </g> <g> <text x="317" y="812">1</text> <text x="273" y="500">2</text> <text x="556" y="828">3</text> <text x="513" y="532">4</text> <text x="586" y="463">5</text> <text x="455" y="316">6</text> <text x="742" y="326">7</text> </g> </svg> <script> var elements = document.querySelectorAll(''*[y]''); for (var i = 0; i < elements.length; i++) elements[i].setAttribute(''y'', 958-(elements[i].getAttribute(''y''))); </script>

958 proviene de: 900 (transformación inicial) + 58 (altura de caracteres).