less copy protection, more size visualization
您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
 
 
 

730 行
22 KiB

  1. function makeObject(name, viewInfo) {
  2. views = {};
  3. Object.entries(viewInfo).forEach(([key, value]) => {
  4. views[key] = {
  5. attributes: {
  6. height: {
  7. name: "Height",
  8. power: 1,
  9. type: "length",
  10. base: value.height
  11. }
  12. },
  13. image: value.image,
  14. name: value.name,
  15. rename: value.rename
  16. }
  17. if (value.mass) {
  18. views[key].attributes.mass = {
  19. name: "Mass",
  20. power: 3,
  21. type: "mass",
  22. base: value.mass
  23. };
  24. }
  25. if (value.volume) {
  26. views[key].attributes.capacity = {
  27. name: "Volume",
  28. power: 3,
  29. type: "volume",
  30. base: value.volume
  31. }
  32. }
  33. });
  34. return makeEntity({ name: name }, views);
  35. }
  36. SHOE_REFERENCE = 60
  37. function addShoeView(object, name, points) {
  38. object[name] = {
  39. height: math.unit(points / SHOE_REFERENCE, "inches"),
  40. image: { source: "./media/objects/shoes/shoe_" + name + ".svg" },
  41. name: name.replace(/-/g, " ").replace(/\b\w/g, x => x.toUpperCase()),
  42. rename: true
  43. }
  44. }
  45. function makeHeight(info, category, prefix = "", type = "objects") {
  46. const views = {};
  47. info.forEach(object => {
  48. let src;
  49. // this lets us provide our own source if needed
  50. // useful for reusing existing art
  51. if (object[3]) {
  52. src = object[3];
  53. } else {
  54. src = "./media/" + type + "/" + category.replace(/ /g, "-").toLowerCase() + "/" + prefix + object[0] + ".svg";
  55. }
  56. views[object[0]] = {
  57. height: math.unit(object[1], object[2]),
  58. image: { source: src },
  59. name: object[0].replace(/-/g, " ").replace(/\b\w/g, x => x.toUpperCase()),
  60. rename: true
  61. }
  62. });
  63. return {
  64. name: category,
  65. constructor: () => makeObject(
  66. category,
  67. views
  68. )
  69. }
  70. }
  71. function makeHeightWeight(info, category, prefix = "", type = "objects") {
  72. const views = {};
  73. info.forEach(object => {
  74. let src;
  75. // this lets us provide our own source if needed
  76. // useful for reusing existing art
  77. if (object[5]) {
  78. src = object[5];
  79. } else {
  80. src = "./media/" + type + "/" + category.replace(/ /g, "-").toLowerCase() + "/" + prefix + object[0] + ".svg";
  81. }
  82. views[object[0]] = {
  83. height: math.unit(object[1], object[2]),
  84. mass: math.unit(object[3], object[4]),
  85. image: { source: src },
  86. name: object[0].replace(/-/g, " ").replace(/\b\w/g, x => x.toUpperCase()),
  87. rename: true
  88. }
  89. });
  90. return {
  91. name: category,
  92. constructor: () => makeObject(
  93. category,
  94. views
  95. )
  96. }
  97. }
  98. function makeHeightWeightSphere(info, category, prefix = "", type = "objects") {
  99. const views = {};
  100. info.forEach(object => {
  101. let src;
  102. // this lets us provide our own source if needed
  103. // useful for reusing existing art
  104. if (object[5]) {
  105. src = object[5];
  106. } else {
  107. src = "./media/" + type + "/" + category.replace(/ /g, "-").toLowerCase() + "/" + prefix + object[0] + ".svg";
  108. }
  109. views[object[0]] = {
  110. height: math.unit(object[1], object[2]),
  111. mass: math.unit(object[3], object[4]),
  112. volume: math.unit(Math.PI * 4 / 3 * Math.pow((object[1]/2), 3), object[2] + "^3"),
  113. image: { source: src },
  114. name: object[0].replace(/-/g, " ").replace(/\b\w/g, x => x.toUpperCase()),
  115. rename: true
  116. }
  117. });
  118. return {
  119. name: category,
  120. constructor: () => makeObject(
  121. category,
  122. views
  123. )
  124. }
  125. }
  126. function makeShoes() {
  127. const views = {};
  128. [
  129. ["flip-flops", 154.239],
  130. ["knee-boots", 841.827],
  131. ["trainers", 260.607],
  132. ["stilettos", 418.839]
  133. ].forEach(shoe => {
  134. addShoeView(views, shoe[0], shoe[1])
  135. });
  136. return {
  137. name: "Shoes",
  138. constructor: () => makeObject(
  139. "Shoes",
  140. views
  141. )
  142. }
  143. }
  144. function makeObjects() {
  145. const results = [];
  146. results.push({
  147. name: "Soda Can",
  148. constructor: () => makeObject(
  149. "Soda Can",
  150. {
  151. front: {
  152. height: math.unit(4.83, "inches"),
  153. mass: math.unit(15, "grams"),
  154. image: { source: "./media/objects/soda-can.svg" },
  155. name: "Side"
  156. }
  157. }
  158. )
  159. });
  160. results.push({
  161. name: "Sewing Pin",
  162. constructor: () => makeObject(
  163. "Sewing Pin",
  164. {
  165. side: {
  166. height: math.unit(1.5, "inches"),
  167. image: { source: "./media/objects/sewing-pin.svg" },
  168. name: "Side"
  169. },
  170. top: {
  171. height: math.unit(2, "millimeters"),
  172. image: { source: "./media/objects/pin-head.svg" },
  173. name: "Head"
  174. }
  175. }
  176. )
  177. });
  178. results.push({
  179. name: "Lamp",
  180. constructor: () => makeObject(
  181. "Lamp",
  182. {
  183. lamp: {
  184. height: math.unit(30, "inches"),
  185. mass: math.unit(10, "lbs"),
  186. image: { source: "./media/objects/lamp.svg" },
  187. name: "Lamp"
  188. }
  189. }
  190. )
  191. });
  192. results.push({
  193. name: "Nail Polish",
  194. constructor: () => makeObject(
  195. "Nail Polish",
  196. {
  197. bottle: {
  198. height: math.unit(3.25, "inches"),
  199. mass: math.unit(66, "g"),
  200. image: { source: "./media/objects/nail-polish.svg" },
  201. name: "Bottle"
  202. }
  203. }
  204. )
  205. });
  206. results.push({
  207. name: "Shot Glass",
  208. constructor: () => makeObject(
  209. "Shot Glass",
  210. {
  211. glass: {
  212. height: math.unit(2 + 3 / 8, "inches"),
  213. mass: math.unit(75, "g"),
  214. image: { source: "./media/objects/shot-glass.svg" },
  215. name: "Bottle"
  216. }
  217. }
  218. )
  219. });
  220. results.push({
  221. name: "Beer Bottle",
  222. constructor: () => makeObject(
  223. "Beer Bottle",
  224. {
  225. longneck: {
  226. height: math.unit(9, "inches"),
  227. mass: math.unit(200, "g"),
  228. image: { source: "./media/objects/beer-bottle.svg" },
  229. name: "Longneck Bottle"
  230. }
  231. }
  232. )
  233. });
  234. results.push({
  235. name: "Coin",
  236. constructor: () => makeObject(
  237. "Coin",
  238. {
  239. penny: {
  240. height: math.unit(0.75, "inches"),
  241. mass: math.unit(2.5, "g"),
  242. image: { source: "./media/objects/circle.svg" },
  243. name: "Penny",
  244. rename: true
  245. },
  246. nickel: {
  247. height: math.unit(0.835, "inches"),
  248. mass: math.unit(5, "g"),
  249. image: { source: "./media/objects/circle.svg" },
  250. name: "Nickel",
  251. rename: true
  252. },
  253. dime: {
  254. height: math.unit(0.705, "inches"),
  255. mass: math.unit(2.268, "g"),
  256. image: { source: "./media/objects/circle.svg" },
  257. name: "Dime",
  258. rename: true
  259. },
  260. quarter: {
  261. height: math.unit(0.955, "inches"),
  262. mass: math.unit(5.67, "g"),
  263. image: { source: "./media/objects/circle.svg" },
  264. name: "Quarter",
  265. rename: true
  266. },
  267. dollar: {
  268. height: math.unit(1.043, "inches"),
  269. mass: math.unit(8.1, "g"),
  270. image: { source: "./media/objects/circle.svg" },
  271. name: "Dollar Coin",
  272. rename: true
  273. },
  274. }
  275. )
  276. });
  277. results.push({
  278. name: "Pencil",
  279. constructor: () => makeObject(
  280. "Pencil",
  281. {
  282. pencil: {
  283. height: math.unit(7.5, "inches"),
  284. mass: math.unit(7, "g"),
  285. image: { source: "./media/objects/pencil.svg" },
  286. name: "Pencil"
  287. }
  288. }
  289. )
  290. });
  291. results.push({
  292. name: "Balls",
  293. constructor: () => makeObject(
  294. "Balls",
  295. {
  296. golf: {
  297. height: math.unit(1.62, "inches"),
  298. mass: math.unit(45, "g"),
  299. image: { source: "./media/objects/circle.svg" },
  300. name: "Golfball",
  301. rename: true
  302. },
  303. tennis: {
  304. height: math.unit(2.6, "inches"),
  305. mass: math.unit(57, "g"),
  306. image: { source: "./media/objects/circle.svg" },
  307. name: "Tennisball",
  308. rename: true
  309. },
  310. baseball: {
  311. height: math.unit(2.9, "inches"),
  312. mass: math.unit(145, "g"),
  313. image: { source: "./media/objects/circle.svg" },
  314. name: "Baseball",
  315. rename: true
  316. },
  317. volleyball: {
  318. height: math.unit(8, "inches"),
  319. mass: math.unit(270, "g"),
  320. image: { source: "./media/objects/circle.svg" },
  321. name: "Volleyball",
  322. rename: true
  323. }
  324. }
  325. )
  326. });
  327. results.push({
  328. name: "Paperclip",
  329. constructor: () => makeObject(
  330. "Paperclip",
  331. {
  332. paperclip: {
  333. height: math.unit(1.834, "inches"),
  334. mass: math.unit(1, "g"),
  335. image: { source: "./media/objects/paperclip.svg" },
  336. name: "Paperclip"
  337. }
  338. }
  339. )
  340. });
  341. results.push({
  342. name: "Pebbles",
  343. constructor: () => makeObject(
  344. "Pebbles",
  345. {
  346. gravelGrain: {
  347. height: math.unit(20, "mm"),
  348. image: { source: "./media/objects/pebble.svg" },
  349. name: "Grain of gravel",
  350. rename: true
  351. },
  352. sandGrain: {
  353. height: math.unit(0.5, "mm"),
  354. image: { source: "./media/objects/pebble.svg" },
  355. name: "Grain of sand",
  356. rename: true
  357. },
  358. siltGrain: {
  359. height: math.unit(0.03, "mm"),
  360. image: { source: "./media/objects/pebble.svg" },
  361. name: "Grain of silt",
  362. rename: true
  363. },
  364. }
  365. )
  366. });
  367. results.push({
  368. name: "Credit Card",
  369. constructor: () => makeObject(
  370. "Credit Card",
  371. {
  372. creditCard: {
  373. height: math.unit(53.98, "mm"),
  374. image: { source: "./media/objects/credit-card.svg" },
  375. name: "Credit card",
  376. },
  377. creditCardVertical: {
  378. height: math.unit(85.60, "mm"),
  379. image: { source: "./media/objects/credit-card-vertical.svg" },
  380. name: "Credit card (vertical)",
  381. },
  382. }
  383. )
  384. });
  385. results.push({
  386. name: "Molecular",
  387. constructor: () => makeObject(
  388. "Molecular",
  389. {
  390. hydrogen: {
  391. height: math.unit(1.06e-10, "m"),
  392. mass: math.unit(1, "dalton"),
  393. image: { source: "./media/objects/circle.svg" },
  394. name: "Hydrogen atom",
  395. rename: true
  396. },
  397. proton: {
  398. height: math.unit(0.877e-15, "m"),
  399. mass: math.unit(1, "dalton"),
  400. image: { source: "./media/objects/circle.svg" },
  401. name: "Proton",
  402. rename: true
  403. },
  404. }
  405. )
  406. });
  407. results.push(makeShoes());
  408. results.push({
  409. name: "Flagpole",
  410. constructor: () => makeObject(
  411. "Flagpole",
  412. {
  413. residential: {
  414. height: math.unit(20, "feet"),
  415. image: { source: "./media/objects/flagpole.svg" },
  416. name: "Residential"
  417. },
  418. medium: {
  419. height: math.unit(50, "feet"),
  420. image: { source: "./media/objects/flagpole.svg" },
  421. name: "Medium"
  422. },
  423. large: {
  424. height: math.unit(100, "feet"),
  425. image: { source: "./media/objects/flagpole.svg" },
  426. name: "Large"
  427. },
  428. }
  429. )
  430. });
  431. results.push({
  432. name: "Vending Machine",
  433. constructor: () => makeObject(
  434. "Vending Machine",
  435. {
  436. object: {
  437. height: math.unit(183, "cm"),
  438. mass: math.unit(347, "kg"),
  439. image: { source: "./media/objects/vending-machine.svg" },
  440. name: "Vending Machine"
  441. }
  442. }
  443. )
  444. })
  445. results.push({
  446. name: "International Space Station",
  447. constructor: () => makeObject(
  448. "International Space Station",
  449. {
  450. object: {
  451. height: math.unit(209, "feet"),
  452. mass: math.unit(925300, "lbs"),
  453. image: { source: "./media/objects/international-space-station.svg" },
  454. name: "International Space Station"
  455. }
  456. }
  457. )
  458. })
  459. results.push(makeHeight(
  460. [
  461. ["king", 4, "inches"],
  462. ["queen", 351 / 407 * 4, "inches"],
  463. ["bishop", 340 / 407 * 4, "inches"],
  464. ["knight", 309 / 407 * 4, "inches"],
  465. ["rook", 271 / 407 * 4, "inches"],
  466. ["pawn", 197 / 407 * 4, "inches"],
  467. ],
  468. "Chess Pieces",
  469. "chess_"
  470. ));
  471. results.push({
  472. name: "Strand",
  473. constructor: () => {
  474. views = {};
  475. viewInfo = {
  476. opticalFibre: {
  477. name: "Optical Fibre",
  478. thickness: math.unit(0.375, "mm")
  479. },
  480. hair: {
  481. name: "Hair",
  482. thickness: math.unit(0.07, "mm")
  483. },
  484. spiderSilk: {
  485. name: "Spider Silk",
  486. thickness: math.unit(0.003, "mm")
  487. },
  488. suspensionCables: {
  489. name: "Suspension Bridge Cables",
  490. thickness: math.unit(3, "feet")
  491. },
  492. capillary: {
  493. name: "Capillary",
  494. thickness: math.unit(7.5, "micrometers")
  495. },
  496. vein: {
  497. name: "Vein",
  498. thickness: math.unit(10, "mm")
  499. },
  500. thread: {
  501. name: "Thread",
  502. thickness: math.unit(0.4, "mm")
  503. },
  504. powerCord: {
  505. name: "Power Cord",
  506. thickness: math.unit(0.25, "inches")
  507. },
  508. pianoWireBass: {
  509. name: "Piano Wire (Bass)",
  510. thickness: math.unit(8.5, "mm")
  511. },
  512. pianoWireTreble: {
  513. name: "Piano Wire (Treble)",
  514. thickness: math.unit(0.85, "mm")
  515. },
  516. guitarString: {
  517. name: "Guitar String",
  518. thickness: math.unit(0.03, "inches")
  519. },
  520. powerLineThin: {
  521. name: "Power Line (Thin)",
  522. thickness: math.unit(0.325, "inches")
  523. },
  524. powerLineThick: {
  525. name: "Power Line (Thick)",
  526. thickness: math.unit(0.720, "inches")
  527. },
  528. carbonNanotube: {
  529. name: "Carbon Nanotube",
  530. thickness: math.unit(4, "nm")
  531. }
  532. }
  533. Object.entries(viewInfo).forEach(([key, value]) => {
  534. views[key] = {
  535. attributes: {
  536. height: {
  537. name: "Height",
  538. power: 1,
  539. type: "length",
  540. base: math.multiply(value.thickness, 253.4385 / 5)
  541. },
  542. thickness: {
  543. name: "Thickness",
  544. power: 1,
  545. type: "length",
  546. base: value.thickness
  547. },
  548. },
  549. image: {
  550. source: "./media/objects/strand.svg"
  551. },
  552. name: value.name,
  553. rename: true
  554. }
  555. if (value.mass) {
  556. views[key].attributes.mass = {
  557. name: "Mass",
  558. power: 3,
  559. type: "mass",
  560. base: value.mass
  561. };
  562. }
  563. });
  564. return makeEntity({ name: "Strand" }, views);
  565. }
  566. })
  567. results.push(makeHeight(
  568. [
  569. ["animal-cell", 25, "micrometers"],
  570. ["plant-cell", 75, "micrometers"],
  571. ["mitochondria", 0.5, "micrometer"],
  572. ["bacteria", 0.3, "micrometer"],
  573. ["red-blood-cell", 6.5, "micrometer"],
  574. ["white-blood-cell", 13, "micrometer"],
  575. ["amoeba-proteus", 500, "micrometers"],
  576. ["chaos-carolinensis", 1500, "micrometers"]
  577. ],
  578. "Cells",
  579. "cell_"
  580. ))
  581. results.push(makeHeight(
  582. [
  583. ["stop-sign", 36, "inches"],
  584. ["yield-sign", 36, "inches"],
  585. ["pedestrian-crossing", 30, "inches"],
  586. ["highway-exit", 150, "inches"]
  587. ],
  588. "Signs",
  589. ""
  590. ))
  591. results.push({
  592. name: "Game Consoles",
  593. constructor: () => makeVehicleGroup([
  594. {
  595. name: "Switch",
  596. mass: math.unit(10.48, "ounces"),
  597. sides: {
  598. "Front": { height: math.unit(4.01, "inches") },
  599. "Top": { height: math.unit(1.13, "inches") },
  600. "Side": { height: math.unit(4.01, "inches") },
  601. }
  602. }
  603. ],
  604. "Game Consoles",
  605. "",
  606. "objects")
  607. })
  608. results.push({
  609. name: "Electromagnetic Waves",
  610. constructor: () => {
  611. views = {};
  612. viewInfo = [
  613. ["Gamma rays", math.unit(1, "pm")],
  614. ["Hard X-rays", math.unit(20, "pm")],
  615. ["Soft X-rays", math.unit(1, "nm")],
  616. ["Extreme-ultraviolet", math.unit(50, "nm")],
  617. ["UVC", math.unit(200, "nm")],
  618. ["UVB", math.unit(295, "nm")],
  619. ["UVA", math.unit(350, "nm")],
  620. ["Violet", math.unit(415, "nm")],
  621. ["Blue", math.unit(470, "nm")],
  622. ["Cyan", math.unit(490, "nm")],
  623. ["Green", math.unit(530, "nm")],
  624. ["Yellow", math.unit(580, "nm")],
  625. ["Orange", math.unit(610, "nm")],
  626. ["Red", math.unit(690, "nm")],
  627. ["Near-infrared", math.unit(1.2, "um")],
  628. ["Short-wavelength infrared", math.unit(2.2, "um")],
  629. ["Mid-wavelength infrared", math.unit(6.5, "um")],
  630. ["Long-wavelength infrared", math.unit(12, "um")],
  631. ["Far infrared", math.unit(500, "um")],
  632. ["D-band microwaves (mm-wave)", math.unit(2, "mm")],
  633. ["S-band microwaves (ovens, wifi)", math.unit(11, "cm")],
  634. ["L-band microwaves (GPS)", math.unit(22, "cm")],
  635. ["UHF", math.unit(50, "cm")],
  636. ["FM radio", math.unit(3.5, "m")],
  637. ["VHF", math.unit(5, "m")],
  638. ["HF", math.unit(50, "m")],
  639. ["AM radio", math.unit(250, "m")],
  640. ["MF", math.unit(500, "m")],
  641. ["LF", math.unit(5, "km")],
  642. ["VLF", math.unit(50, "km")],
  643. ["ULF", math.unit(500, "km")],
  644. ["SLF", math.unit(5000, "km")],
  645. ["ELF", math.unit(50000, "km")],
  646. ]
  647. viewInfo.forEach(([name, length]) => {
  648. views[name] = {
  649. attributes: {
  650. height: {
  651. name: "Height",
  652. power: 1,
  653. type: "length",
  654. base: math.multiply(length, 2)
  655. }
  656. },
  657. image: {
  658. source: "./media/objects/sine-wave.svg"
  659. },
  660. name: name,
  661. rename: true,
  662. default: name === "Green"
  663. }
  664. });
  665. return makeEntity({ name: "Electromagnetic Waves" }, views);
  666. }
  667. })
  668. results.sort((b1, b2) => {
  669. e1 = b1.constructor();
  670. e2 = b2.constructor();
  671. return -math.subtract(e1.views[e1.defaultView].height, e2.views[e2.defaultView].height).value;
  672. });
  673. return results;
  674. }