- mongodb - 在 MongoDB mapreduce 中,如何展平值对象?
- javascript - 对象传播与 Object.assign
- html - 输入类型 ="submit"Vs 按钮标签它们可以互换吗?
- sql - 使用 MongoDB 而不是 MS SQL Server 的优缺点
我正在生成几个像这样的 svg 图像:
<svg version="1.1" viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg">
<style type="text/css">
text {
font-family: Helvetica;
font-size: 60px;
paint-order: stroke;
stroke: #000000;
stroke-width: 6px;
stroke-linecap: butt;
stroke-linejoin: miter;
font-weight: 800;
}
</style>
<g stroke="lightgray" stroke-dasharray="1,1" stroke-width="1" transform="scale(4, 4)">
<line x1="0" y1="0" x2="256" y2="256"/>
<line x1="256" y1="0" x2="0" y2="256"/>
<line x1="128" y1="0" x2="128" y2="256"/>
<line x1="0" y1="128" x2="256" y2="128"/>
</g>
<g transform="scale(1, -1) translate(0, -900)">
<path d="M 128 445 Q 222 525 301 653 Q 319 685 334 709 L 343 725 Q 351 746 367 763 Q 376 772 374 782 Q 374 791 361 801 Q 327 827 298 819 Q 290 819 293 806 Q 310 732 219 604 L 171 539 Q 133 492 33 396 Q 26 392 35 390 Q 43 390 110 431 L 128 445 Z" fill="#cc2f00"/>
<path d="M 334 709 Q 386 675 447 629 Q 461 617 472 615 Q 478 615 482 624 Q 488 634 474 663 Q 459 700 343 725 C 314 731 309 725 334 709 Z" fill="#cc5e00"/>
<path d="M 253 553 Q 224 546 246 534 Q 276 517 325 531 Q 423 558 435 563 Q 439 567 439 572 Q 437 586 406 590 Q 388 593 316 566 L 253 553 Z" fill="#cc8d00"/>
<path d="M 147 441 Q 143 445 128 445 C 101 446 101 446 110 431 Q 125 406 140 365 Q 153 331 162 323 Q 174 311 176 321 Q 178 329 175 343 L 171 363 Q 161 394 153 422 C 148 441 148 441 147 441 Z" fill="#ccbc00"/>
<path d="M 255 464 Q 233 477 223 476 Q 213 475 180 456 Q 172 453 147 441 C 120 428 124 416 153 422 Q 161 423 181 431 Q 212 442 216 437 Q 221 433 216 383 C 213 353 241 353 245 383 Q 251 431 265 445 C 272 454 272 454 255 464 Z" fill="#adcc00"/>
<path d="M 175 343 Q 180 343 186 345 Q 216 357 254 367 Q 261 368 259 373 Q 259 377 245 383 L 216 383 Q 213 383 171 363 C 144 350 145 341 175 343 Z" fill="#7ecc00"/>
<path d="M 285 468 Q 261 473 255 470 Q 255 468 255 464 C 255 459 255 469 265 445 Q 272 429 278 405 Q 288 371 295 363 Q 305 352 310 361 Q 310 367 310 371 L 308 392 Q 298 434 298 450 C 297 465 297 465 285 468 Z" fill="#4ecc00"/>
<path d="M 374 410 Q 386 441 396 454 Q 404 463 406 466 C 413 475 413 475 398 484 L 374 498 Q 360 506 347 499 Q 327 482 285 468 C 257 458 270 438 298 450 Q 300 451 310 455 Q 351 468 355 462 Q 357 461 357 459 Q 359 445 342 406 C 330 378 363 382 374 410 Z" fill="#1fcc00"/>
<path d="M 310 371 Q 323 378 385 390 Q 392 391 392 398 Q 390 402 374 410 C 368 413 368 413 342 406 Q 333 404 308 392 C 281 379 283 358 310 371 Z" fill="#00cc10"/>
<path d="M 406 466 Q 424 400 427 396 Q 437 382 441 392 L 443 406 L 441 425 Q 434 470 433 482 C 432 494 432 494 420 500 Q 419 501 416 502 Q 398 508 394 504 Q 390 500 398 484 L 406 466 Z" fill="#00cc3f"/>
<path d="M 519 439 Q 529 478 541 490 Q 555 506 540 514 Q 514 526 506 528 Q 496 531 484 525 Q 454 510 420 500 C 391 491 403 477 433 482 Q 445 484 454 487 Q 490 496 495 490 Q 496 490 496 487 Q 500 472 490 439 C 482 410 511 410 519 439 Z" fill="#00cc6e"/>
<path d="M 443 406 Q 449 406 455 407 Q 490 416 527 419 Q 534 420 534 425 Q 534 429 519 439 C 519 439 519 439 490 439 Q 488 441 441 425 C 413 415 413 405 443 406 Z" fill="#00cc9d"/>
<path d="M 169 267 Q 151 272 139 272 Q 134 270 133 267 Q 132 264 139 246 Q 167 188 145 104 Q 129 91 142 62 Q 151 43 160 37 Q 166 27 173 32 Q 192 50 192 163 Q 192 202 192 242 C 192 261 192 261 169 267 Z" fill="#00cccc"/>
<path d="M 347 278 Q 402 290 419 284 Q 433 278 435 258 Q 439 207 429 114 Q 431 98 416 98 Q 396 98 386 100 Q 380 100 377 98 Q 369 94 398 69 Q 419 47 431 22 Q 441 15 451 20 Q 455 22 459 25 Q 480 58 482 158 Q 476 267 486 283 Q 494 292 488 302 Q 484 307 472 314 Q 437 333 419 323 Q 409 319 388 316 Q 271 292 169 267 C 140 260 164 232 192 242 Q 208 248 231 254 L 248 257 Q 272 265 323 274 L 347 278 Z" fill="#009dcc"/>
<path d="M 244 188 Q 235 186 214 178 Q 201 174 217 164 Q 226 158 246 163 L 274 170 L 332 184 L 367 190 Q 376 194 396 198 Q 402 199 406 202 Q 415 209 397 218 Q 379 227 368 223 L 332 216 Q 327 216 274 196 L 244 188 Z" fill="#006ecc"/>
<path d="M 231 254 Q 231 251 233 246 Q 241 216 244 188 L 246 163 Q 252 102 256 93 Q 265 78 270 87 Q 274 97 274 170 L 274 196 Q 274 208 275 218 Q 276 239 274 243 Q 271 250 248 257 C 229 263 229 263 231 254 Z" fill="#003fcc"/>
<path d="M 332 184 Q 332 80 342 71 Q 343 71 347 71 Q 351 73 354 81 Q 360 98 367 190 L 368 223 Q 368 229 372 243 Q 376 259 368 267 Q 355 276 347 278 C 319 288 317 289 323 274 Q 331 257 332 216 L 332 184 Z" fill="#0010cc"/>
<path d="M 698 651 L 862 688 Q 908 700 914 708 Q 923 714 918 723 Q 913 729 903 734 Q 864 751 825 733 Q 808 727 794 723 Q 696 689 582 674 Q 548 668 572 653 Q 606 634 659 641 L 698 651 Z" fill="#1f00cc"/>
<path d="M 657 540 Q 668 553 678 566 Q 699 594 712 608 Q 734 624 698 651 C 674 669 660 671 659 641 Q 659 617 641 563 Q 631 549 630 535 C 626 505 638 517 657 540 Z" fill="#4e00cc"/>
<path d="M 596 531 Q 594 533 591 535 Q 571 549 557 543 Q 555 541 555 536 Q 555 525 561 515 Q 582 472 572 295 Q 566 269 566 245 Q 566 198 586 180 Q 595 171 604 180 Q 611 192 612 201 L 613 229 Q 615 239 615 265 Q 613 294 613 308 L 613 331 L 613 406 L 613 431 Q 613 455 615 506 C 615 517 615 517 596 531 Z" fill="#7e00cc"/>
<path d="M 809 223 Q 809 216 817 201 Q 831 173 841 174 Q 855 176 869 209 Q 874 219 876 225 Q 882 242 878 272 Q 868 363 866 451 Q 866 463 868 472 Q 871 489 885 517 Q 892 533 886 539 Q 861 561 817 579 Q 802 583 780 576 Q 774 574 657 540 L 630 535 Q 608 533 596 531 C 566 527 585 503 615 506 Q 627 506 642 510 Q 710 527 768 538 Q 789 542 795 531 Q 809 514 811 453 Q 817 290 811 249 L 809 223 Z" fill="#ad00cc"/>
<path d="M 613 406 L 618 406 Q 686 417 747 423 Q 768 428 759 440 Q 749 452 727 456 Q 710 459 613 431 C 584 423 583 406 613 406 Z" fill="#cc00bc"/>
<path d="M 613 308 L 623 308 Q 708 317 761 319 Q 783 323 774 334 Q 762 357 718 354 Q 690 352 613 331 C 584 323 583 308 613 308 Z" fill="#cc008d"/>
<path d="M 612 201 L 621 201 L 809 223 C 839 226 835 232 811 249 Q 800 259 777 258 Q 753 257 613 229 C 584 223 582 201 612 201 Z" fill="#cc005e"/>
<path d="M 623 161 Q 608 95 455 -29 Q 447 -35 447 -37 Q 446 -41 460 -39 Q 480 -37 504 -27 Q 562 -4 640 76 Q 686 123 690 126 Q 695 131 697 137 Q 704 157 671 167 Q 652 174 641 174 Q 627 174 623 161 Z" fill="#cc002f"/>
<path d="M 757 157 Q 757 153 757 151 Q 758 140 774 118 Q 829 47 864 -7 Q 877 -29 892 -36 Q 898 -37 903 -33 Q 923 -23 917 25 Q 914 77 768 163 Q 761 169 757 157 Z" fill="#cc0000"/>
</g>
<g>
<text fill="#FFFFFF" x="306" y="131">1</text>
<text fill="#FFFFFF" x="343" y="231">2</text>
<text fill="#FFFFFF" x="247" y="396">3</text>
<text fill="#FFFFFF" x="119" y="511">4</text>
<text fill="#FFFFFF" x="157" y="511">5</text>
<text fill="#FFFFFF" x="180" y="591">6</text>
<text fill="#FFFFFF" x="261" y="473">7</text>
<text fill="#FFFFFF" x="294" y="472">8</text>
<text fill="#FFFFFF" x="312" y="564">9</text>
<text fill="#FFFFFF" x="399" y="420">10</text>
<text fill="#FFFFFF" x="428" y="421">11</text>
<text fill="#FFFFFF" x="449" y="509">12</text>
<text fill="#FFFFFF" x="140" y="655">13</text>
<text fill="#FFFFFF" x="176" y="654">14</text>
<text fill="#FFFFFF" x="226" y="747">15</text>
<text fill="#FFFFFF" x="236" y="669">16</text>
<text fill="#FFFFFF" x="330" y="649">17</text>
<text fill="#FFFFFF" x="574" y="255">18</text>
<text fill="#FFFFFF" x="667" y="284">19</text>
<text fill="#FFFFFF" x="563" y="383">20</text>
<text fill="#FFFFFF" x="601" y="395">21</text>
<text fill="#FFFFFF" x="616" y="508">22</text>
<text fill="#FFFFFF" x="618" y="606">23</text>
<text fill="#FFFFFF" x="617" y="712">24</text>
<text fill="#FFFFFF" x="680" y="777">25</text>
<text fill="#FFFFFF" x="766" y="766">26</text>
</g>
</svg>
这些 svg 是汉字的笔顺图。因此,图像以不同的颜色显示每个笔划,并且在每个笔划的起点处显示一个数字,以显示它们必须按什么顺序绘制。
我的方法的问题是数字可能重叠或彼此太接近,从而难以阅读。
我想实现一种算法,为每个坐标计算更好的位置。我正在考虑一些可以让您指定对起点的吸引力和对所有其他数字的所有坐标的排斥的东西。
这个算法是否已经存在并且有名字?用 JavaScript 怎么办?
这是一段代码,其中包含当前绘制数字的笔画起始位置的坐标:
let strokeStartPositions = [
[306, 131],
[343, 231],
[247, 396],
[119, 511],
[157, 511],
[180, 591],
[261, 473],
[294, 472],
[312, 564],
[399, 420],
[428, 421],
[449, 509],
[140, 655],
[176, 654],
[226, 747],
[236, 669],
[330, 649],
[574, 255],
[667, 284],
[563, 383],
[601, 395],
[616, 508],
[618, 606],
[617, 712],
[680, 777],
[766, 766]
]
function repositionAlgorithm(position, attractedTo, repulsedFrom) {
// ?
return position
}
let numberPositions = []
for (let [i,currentPosition] of strokeStartPositions.entries()) {
let oldX = currentPosition[0]
let oldY = currentPosition[1]
let repulsedFrom = strokeStartPositions.slice()
repulsedFrom.splice(i,1) // all positions but the current one
let attractedTo = [currentPosition]
let newPosition = repositionAlgorithm(currentPosition, attractedTo, repulsedFrom)
numberPositions[i] = newPosition
let newX = newPosition[0]
let newY = newPosition[1]
console.log(`Moved from (${oldX}|${oldY}) to (${newX}|${newY}).`)
}
减小两位数的文本大小在一定程度上有所帮助,但仍然会发生重叠,我无法真正进一步减小文本大小,因为它会变得不可读..
如果你想玩,这里有一个 fiddle :https://jsfiddle.net/t2o7p1ea/31/相关部分从第 62 行开始,到第 78 行结束。
编辑: I found a solution 没问题。但这并不完美。如果你能想出更好的东西。我很乐意将赏金奖励给你。
最佳答案
经过几天的折腾,我终于想出了一个可行的想法。
这个想法是:取所有笔划起点并假设它们是直径大致与 fontSize*digitAmount 一样大的圆。
while any circles intercept each other
iterate over all circles
iterate over all circles
if the circle of this iteration is the same as the circle of the outer iteration
skip this iteration (continue)
if circle of this and the outer iteration intercept
calculate a point that from the perspective of circle1
is about 1 pixel behind circle 2
and move circle2 to that new position
calculate a point that from the perspective of circle2
is about 1 pixel behind circle 1
and move circle1 to that new position
(我决定逐个像素地移动它们,以便每个圆圈在每次更改后都会进行迭代以使用react,以防现在拦截新圆圈。)
在调整和微调参数后,我得到了一个看起来很不错的结果。它仍然不完美,因为我将数字视为圆圈,如果我把圆圈做得太大,数字会永远被推来推去,循环不会结束。
此外,我重新使用彩色数字并将边框改为白色而不是黑色以提高可读性。
//#!/usr/bin/env node
//const fs = require('fs-extra')
//const readline = require('readline')
const strokeData = {"character":"龥","strokes":["M 128 445 Q 222 525 301 653 Q 319 685 334 709 L 343 725 Q 351 746 367 763 Q 376 772 374 782 Q 374 791 361 801 Q 327 827 298 819 Q 290 819 293 806 Q 310 732 219 604 L 171 539 Q 133 492 33 396 Q 26 392 35 390 Q 43 390 110 431 L 128 445 Z","M 334 709 Q 386 675 447 629 Q 461 617 472 615 Q 478 615 482 624 Q 488 634 474 663 Q 459 700 343 725 C 314 731 309 725 334 709 Z","M 253 553 Q 224 546 246 534 Q 276 517 325 531 Q 423 558 435 563 Q 439 567 439 572 Q 437 586 406 590 Q 388 593 316 566 L 253 553 Z","M 147 441 Q 143 445 128 445 C 101 446 101 446 110 431 Q 125 406 140 365 Q 153 331 162 323 Q 174 311 176 321 Q 178 329 175 343 L 171 363 Q 161 394 153 422 C 148 441 148 441 147 441 Z","M 255 464 Q 233 477 223 476 Q 213 475 180 456 Q 172 453 147 441 C 120 428 124 416 153 422 Q 161 423 181 431 Q 212 442 216 437 Q 221 433 216 383 C 213 353 241 353 245 383 Q 251 431 265 445 C 272 454 272 454 255 464 Z","M 175 343 Q 180 343 186 345 Q 216 357 254 367 Q 261 368 259 373 Q 259 377 245 383 L 216 383 Q 213 383 171 363 C 144 350 145 341 175 343 Z","M 285 468 Q 261 473 255 470 Q 255 468 255 464 C 255 459 255 469 265 445 Q 272 429 278 405 Q 288 371 295 363 Q 305 352 310 361 Q 310 367 310 371 L 308 392 Q 298 434 298 450 C 297 465 297 465 285 468 Z","M 374 410 Q 386 441 396 454 Q 404 463 406 466 C 413 475 413 475 398 484 L 374 498 Q 360 506 347 499 Q 327 482 285 468 C 257 458 270 438 298 450 Q 300 451 310 455 Q 351 468 355 462 Q 357 461 357 459 Q 359 445 342 406 C 330 378 363 382 374 410 Z","M 310 371 Q 323 378 385 390 Q 392 391 392 398 Q 390 402 374 410 C 368 413 368 413 342 406 Q 333 404 308 392 C 281 379 283 358 310 371 Z","M 406 466 Q 424 400 427 396 Q 437 382 441 392 L 443 406 L 441 425 Q 434 470 433 482 C 432 494 432 494 420 500 Q 419 501 416 502 Q 398 508 394 504 Q 390 500 398 484 L 406 466 Z","M 519 439 Q 529 478 541 490 Q 555 506 540 514 Q 514 526 506 528 Q 496 531 484 525 Q 454 510 420 500 C 391 491 403 477 433 482 Q 445 484 454 487 Q 490 496 495 490 Q 496 490 496 487 Q 500 472 490 439 C 482 410 511 410 519 439 Z","M 443 406 Q 449 406 455 407 Q 490 416 527 419 Q 534 420 534 425 Q 534 429 519 439 C 519 439 519 439 490 439 Q 488 441 441 425 C 413 415 413 405 443 406 Z","M 169 267 Q 151 272 139 272 Q 134 270 133 267 Q 132 264 139 246 Q 167 188 145 104 Q 129 91 142 62 Q 151 43 160 37 Q 166 27 173 32 Q 192 50 192 163 Q 192 202 192 242 C 192 261 192 261 169 267 Z","M 347 278 Q 402 290 419 284 Q 433 278 435 258 Q 439 207 429 114 Q 431 98 416 98 Q 396 98 386 100 Q 380 100 377 98 Q 369 94 398 69 Q 419 47 431 22 Q 441 15 451 20 Q 455 22 459 25 Q 480 58 482 158 Q 476 267 486 283 Q 494 292 488 302 Q 484 307 472 314 Q 437 333 419 323 Q 409 319 388 316 Q 271 292 169 267 C 140 260 164 232 192 242 Q 208 248 231 254 L 248 257 Q 272 265 323 274 L 347 278 Z","M 244 188 Q 235 186 214 178 Q 201 174 217 164 Q 226 158 246 163 L 274 170 L 332 184 L 367 190 Q 376 194 396 198 Q 402 199 406 202 Q 415 209 397 218 Q 379 227 368 223 L 332 216 Q 327 216 274 196 L 244 188 Z","M 231 254 Q 231 251 233 246 Q 241 216 244 188 L 246 163 Q 252 102 256 93 Q 265 78 270 87 Q 274 97 274 170 L 274 196 Q 274 208 275 218 Q 276 239 274 243 Q 271 250 248 257 C 229 263 229 263 231 254 Z","M 332 184 Q 332 80 342 71 Q 343 71 347 71 Q 351 73 354 81 Q 360 98 367 190 L 368 223 Q 368 229 372 243 Q 376 259 368 267 Q 355 276 347 278 C 319 288 317 289 323 274 Q 331 257 332 216 L 332 184 Z","M 698 651 L 862 688 Q 908 700 914 708 Q 923 714 918 723 Q 913 729 903 734 Q 864 751 825 733 Q 808 727 794 723 Q 696 689 582 674 Q 548 668 572 653 Q 606 634 659 641 L 698 651 Z","M 657 540 Q 668 553 678 566 Q 699 594 712 608 Q 734 624 698 651 C 674 669 660 671 659 641 Q 659 617 641 563 Q 631 549 630 535 C 626 505 638 517 657 540 Z","M 596 531 Q 594 533 591 535 Q 571 549 557 543 Q 555 541 555 536 Q 555 525 561 515 Q 582 472 572 295 Q 566 269 566 245 Q 566 198 586 180 Q 595 171 604 180 Q 611 192 612 201 L 613 229 Q 615 239 615 265 Q 613 294 613 308 L 613 331 L 613 406 L 613 431 Q 613 455 615 506 C 615 517 615 517 596 531 Z","M 809 223 Q 809 216 817 201 Q 831 173 841 174 Q 855 176 869 209 Q 874 219 876 225 Q 882 242 878 272 Q 868 363 866 451 Q 866 463 868 472 Q 871 489 885 517 Q 892 533 886 539 Q 861 561 817 579 Q 802 583 780 576 Q 774 574 657 540 L 630 535 Q 608 533 596 531 C 566 527 585 503 615 506 Q 627 506 642 510 Q 710 527 768 538 Q 789 542 795 531 Q 809 514 811 453 Q 817 290 811 249 L 809 223 Z","M 613 406 L 618 406 Q 686 417 747 423 Q 768 428 759 440 Q 749 452 727 456 Q 710 459 613 431 C 584 423 583 406 613 406 Z","M 613 308 L 623 308 Q 708 317 761 319 Q 783 323 774 334 Q 762 357 718 354 Q 690 352 613 331 C 584 323 583 308 613 308 Z","M 612 201 L 621 201 L 809 223 C 839 226 835 232 811 249 Q 800 259 777 258 Q 753 257 613 229 C 584 223 582 201 612 201 Z","M 623 161 Q 608 95 455 -29 Q 447 -35 447 -37 Q 446 -41 460 -39 Q 480 -37 504 -27 Q 562 -4 640 76 Q 686 123 690 126 Q 695 131 697 137 Q 704 157 671 167 Q 652 174 641 174 Q 627 174 623 161 Z","M 757 157 Q 757 153 757 151 Q 758 140 774 118 Q 829 47 864 -7 Q 877 -29 892 -36 Q 898 -37 903 -33 Q 923 -23 917 25 Q 914 77 768 163 Q 761 169 757 157 Z"],"medians":[[[306,809],[331,777],[299,694],[261,628],[204,549],[134,471],[36,394]],[[343,709],[352,714],[418,680],[449,658],[470,627]],[[247,544],[296,542],[396,571],[430,571]],[[119,429],[133,427],[170,326]],[[157,429],[195,452],[229,454],[238,443],[232,399],[223,394]],[[180,349],[185,359],[223,372],[254,372]],[[261,467],[274,459],[282,444],[303,366]],[[294,468],[302,463],[319,466],[353,482],[378,469],[365,424],[346,415]],[[312,376],[342,394],[386,397]],[[399,500],[418,476],[436,400]],[[428,499],[438,494],[495,510],[511,504],[517,496],[513,469],[509,453],[497,445]],[[449,411],[455,420],[472,424],[512,429],[528,425]],[[140,265],[165,240],[171,216],[174,151],[162,84],[168,40]],[[176,266],[196,259],[400,303],[434,303],[452,293],[458,266],[459,170],[452,94],[438,71],[383,94]],[[226,173],[325,199],[399,208]],[[236,251],[256,233],[264,91]],[[330,271],[351,252],[345,75]],[[574,665],[607,659],[648,661],[853,714],[907,718]],[[667,636],[685,620],[651,553],[636,541]],[[563,537],[592,497],[590,223],[595,187]],[[601,525],[632,521],[792,558],[815,551],[843,521],[837,466],[846,276],[841,185]],[[616,412],[628,424],[686,434],[729,439],[750,433]],[[618,314],[628,322],[706,335],[741,336],[766,328]],[[617,208],[629,219],[775,239],[792,239],[800,230]],[[680,143],[651,136],[615,87],[554,27],[503,-10],[454,-36]],[[766,154],[877,36],[893,-2],[894,-22]]]}
const colorSaturation = 100 // 0-255
const colorLightness = 40 // 0-255
const fontSize = 80
const fontBorderWidth = 8
// helper function
function hslToRgb(h, s, l) { // To generate rainbow colors
h /= 360
s /= 100
l /= 100
let r, g, b
if (s === 0) {
r = g = b = l // achromatic
} else {
const hue2rgb = (p, q, t) => {
if (t < 0) t += 1
if (t > 1) t -= 1
if (t < 1 / 6) return p + (q - p) * 6 * t
if (t < 1 / 2) return q
if (t < 2 / 3) return p + (q - p) * (2 / 3 - t) * 6
return p
}
const q = l < 0.5 ? l * (1 + s) : l + s - l * s
const p = 2 * l - q
r = hue2rgb(p, q, h + 1 / 3)
g = hue2rgb(p, q, h)
b = hue2rgb(p, q, h - 1 / 3)
}
const toHex = x => {
const hex = Math.round(x * 255).toString(16)
return hex.length === 1 ? '0' + hex : hex
}
return `#${toHex(r)}${toHex(g)}${toHex(b)}`
}
// helper function
function circlesIntersect(circle1, circle2) {
const deltaX = circle1.x - circle2.x
const deltaY = circle1.y - circle2.y
const rSum = circle1.r + circle2.r
return deltaX*deltaX + deltaY*deltaY <= rSum * rSum
}
// helper function
function anyCircleIntersects(circleArr) {
for (const circle1 of circleArr) {
for (const circle2 of circleArr) {
if (circle1 !== circle2) {
if (circlesIntersect(circle1,circle2))
return true
}
}
}
}
// helper function
function calculate_point_on_other_side_of_p2(p1, p2, distance_p2_to_p3) {
const deltaX = p1[0]-p2[0]
const deltaY = p1[1]-p2[1]
const distance_p1_to_p2 = Math.sqrt(deltaX*deltaX + deltaY*deltaY)
const scale = distance_p2_to_p3 / distance_p1_to_p2
let p3 = []
p3[0] = p2[0] - deltaX * scale
p3[1] = p2[1] - deltaY * scale
return p3
}
//const lineReader = readline.createInterface({
// input: fs.createReadStream('../graphics.txt')
//})
//lineReader.on('line', line => {
//const item = JSON.parse(line)
const item = strokeData
const charCode = item.character.charCodeAt()
const startingPoints = item.medians.map(i=>({x:i[0][0],y:i[0][1]}))
let pathes = ``
let strokeStartPositions = []
for (const [i,stroke] of item.strokes.entries()) {
const strokeColor = hslToRgb(360/item.strokes.length*(i+1), colorSaturation, colorLightness)
pathes += ` <path d="${stroke}" fill="${strokeColor}"/>\n`
let x = startingPoints[i].x
x = i<9 ? x-fontSize/4 : x-fontSize/2
//x = x-fontSize/2
let y = 900+fontSize/2-startingPoints[i].y
//y = y-fontSize/2
strokeStartPositions[i] = [x, y]
}
const t0 = Date.now()
// while any circles intercept each other
while (anyCircleIntersects(strokeStartPositions.map((pos,i)=>{return {r:i<9 ? fontSize/2.5 : fontSize/1.75, x:pos[0], y:pos[1]}}))) {
if (Date.now() > t0+5000) {
alert("Timeout!")
break
}
// iterate over all circles
for (const [i,p1] of strokeStartPositions.entries()) {
const p1X = p1[0]
const p1Y = p1[1]
const p1Radius = i<9 ? fontSize/2.5 : fontSize/1.75
// iterate over all circles
for (const [j,p2] of strokeStartPositions.entries()) {
if (i === j) // if the circle of this iteration is the same as the circle of the outer iteration
continue // skip this iteration (continue)
const p2X = p2[0]
const p2Y = p2[1]
// If for some reason 2 circles are on the exact same position, move one of them a little
if (p1X === p2X && p1Y === p2Y)
p2[0] = p2[0]+1 // p2[1] = p2[1]+1
const p2Radius = j<9 ? fontSize/2.5 : fontSize/1.75
// if the circle of this and the outer iteration intercept
if (circlesIntersect({r:p1Radius, x:p1X, y:p1Y}, {r:p2Radius, x:p2X, y:p2Y})) {
// calculate a point that from the perspective of circle1
// is about 1 pixel behind circle 2
let newP2 = calculate_point_on_other_side_of_p2(p1, p2, 1)
// calculate a point that from the perspective of circle2
// is about 1 pixel behind circle 1
let newP1 = calculate_point_on_other_side_of_p2(p2, p1, 1)
// and move circle2 to the newP2 position
strokeStartPositions[i][0] = Math.round(newP1[0])
strokeStartPositions[i][1] = Math.round(newP1[1])
// and move circle1 to the newP1 position
strokeStartPositions[j][0] = Math.round(newP2[0])
strokeStartPositions[j][1] = Math.round(newP2[1])
}
}
}
}
let texts = ``
for (const [i,pos] of strokeStartPositions.entries()) {
const textColor = hslToRgb(360/strokeStartPositions.length*(i+1), colorSaturation, colorLightness)
//const textColor = '#FFFFFF'
const x = pos[0]
const y = pos[1]
texts += ` <text fill="${textColor}" x="${x}" y="${y}">${i+1}</text>\n`
}
const newSvgContent = `<svg version="1.1" viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg">
<style type="text/css">
text {
font-family: Helvetica;
font-size: ${fontSize}px;
paint-order: stroke;
stroke: #FFFFFF;
stroke-width: ${fontBorderWidth}px;
stroke-linecap: butt;
stroke-linejoin: miter;
font-weight: bold;
}
</style>
<g stroke="lightgray" stroke-dasharray="1,1" stroke-width="1" transform="scale(4, 4)">
<line x1="0" y1="0" x2="256" y2="256"/>
<line x1="256" y1="0" x2="0" y2="256"/>
<line x1="128" y1="0" x2="128" y2="256"/>
<line x1="0" y1="128" x2="256" y2="128"/>
</g>
<g transform="scale(1, -1) translate(0, -900)">
${pathes} </g>
<g>
${texts} </g>
</svg>`
const svgEl = document.createElementNS("http://www.w3.org/2000/svg", "svg")
svgEl.innerHTML = newSvgContent
document.body.appendChild(svgEl)
//fs.outputFile(`../svgs-still/${charCode}-still.svg`, newSvgContent).then(() => {
// //console.log(`../svgs-still/${charCode}-still.svg written`) // logging severely reduces performance
//}).catch(e=>console.error(new Error(e)))
//})
html, body {
width: 100%;
height: 100%;
}
svg {
width: 100%;
height: 100%;
}
关于javascript - 使坐标被某些其他坐标吸引/排斥,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52248233/
我正在尝试使用 html5 canvas 绘制网络 worker 。工作人员无权访问 DOM,因此我无法从网络工作人员在 Canvas 上绘图。 This other stack overflow q
按照目前的情况,这个问题不适合我们的问答形式。我们希望答案得到事实、引用或专业知识的支持,但这个问题可能会引发辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visit the
我修改了smbrown.wordpress.com上发布的代码它可以使用 Last.fm API 提取热门轨道,如下所示: #!/usr/bin/python import time impor
我是一名优秀的程序员,十分优秀!