Add 10 free animal live camera avatars

这个提交包含在:
cryptocommuniums-afk
2026-03-15 22:02:18 +08:00
父节点 139dc61b61
当前提交 fe5e539a47
修改 15 个文件,包含 186 行新增104 行删除

查看文件

@@ -0,0 +1,20 @@
Animal avatar SVG assets in this folder are sourced from Twemoji.
Source:
https://github.com/jdecked/twemoji
Selected assets:
- gorilla.svg
- monkey.svg
- dog.svg
- pig.svg
- cat.svg
- fox.svg
- panda.svg
- lion.svg
- tiger.svg
- rabbit.svg
License:
CC-BY 4.0
https://creativecommons.org/licenses/by/4.0/

查看文件

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 36 36"><path fill="#FFCC4D" d="M32.348 13.999s3.445-8.812 1.651-11.998c-.604-1.073-8 1.998-10.723 5.442 0 0-2.586-.86-5.276-.86s-5.276.86-5.276.86C10.001 3.999 2.605.928 2.001 2.001.207 5.187 3.652 13.999 3.652 13.999c-.897 1.722-1.233 4.345-1.555 7.16-.354 3.086.35 5.546.658 6.089.35.617 2.123 2.605 4.484 4.306 3.587 2.583 8.967 3.445 10.761 3.445s7.174-.861 10.761-3.445c2.361-1.701 4.134-3.689 4.484-4.306.308-.543 1.012-3.003.659-6.089-.324-2.814-.659-5.438-1.556-7.16z"/><path fill="#F18F26" d="M2.359 2.971c.2-.599 5.348 2.173 6.518 5.404 0 0-3.808 2.624-4.528 4.624 0 0-2.99-7.028-1.99-10.028z"/><path fill="#FFCC4D" d="M5.98 7.261c0-1.414 5.457 2.733 4.457 3.733s-1.255.72-2.255 1.72S5.98 8.261 5.98 7.261z"/><path fill="#F18F26" d="M33.641 2.971c-.2-.599-5.348 2.173-6.518 5.404 0 0 3.808 2.624 4.528 4.624 0 0 2.99-7.028 1.99-10.028z"/><path fill="#FFCC4D" d="M30.02 7.261c0-1.414-5.457 2.733-4.457 3.733s1.255.72 2.255 1.72 2.202-4.453 2.202-5.453z"/><path fill="#292F33" d="M14.001 20.001c0 1.105-.896 1.999-2 1.999s-2-.894-2-1.999c0-1.104.896-1.999 2-1.999s2 .896 2 1.999zm11.998 0c0 1.105-.896 1.999-2 1.999-1.105 0-2-.894-2-1.999 0-1.104.895-1.999 2-1.999s2 .896 2 1.999z"/><path fill="#FEE7B8" d="M2.201 30.458c-.148 0-.294-.065-.393-.19-.171-.217-.134-.531.083-.702.162-.127 4.02-3.12 10.648-2.605.275.021.481.261.46.536-.021.275-.257.501-.537.46-6.233-.474-9.915 2.366-9.951 2.395-.093.07-.202.106-.31.106zm8.868-4.663c-.049 0-.1-.007-.149-.022-4.79-1.497-8.737-.347-8.777-.336-.265.081-.543-.07-.623-.335-.079-.265.071-.543.335-.622.173-.052 4.286-1.247 9.362.338.264.083.411.363.328.627-.066.213-.263.35-.476.35zm22.73 4.663c.148 0 .294-.065.393-.19.171-.217.134-.531-.083-.702-.162-.127-4.02-3.12-10.648-2.605-.275.021-.481.261-.46.536.022.275.257.501.537.46 6.233-.474 9.915 2.366 9.951 2.395.093.07.202.106.31.106zm-8.868-4.663c.049 0 .1-.007.149-.022 4.79-1.497 8.737-.347 8.777-.336.265.081.543-.07.623-.335.079-.265-.071-.543-.335-.622-.173-.052-4.286-1.247-9.362.338-.264.083-.411.363-.328.627.066.213.263.35.476.35z"/><path fill="#67757F" d="M24.736 30.898c-.097-.258-.384-.392-.643-.294-.552.206-1.076.311-1.559.311-1.152 0-1.561-.306-2.033-.659-.451-.338-.956-.715-1.99-.803v-2.339c0-.276-.224-.5-.5-.5s-.5.224-.5.5v2.373c-.81.115-1.346.439-1.816.743-.568.367-1.059.685-2.083.685-.482 0-1.006-.104-1.558-.311-.258-.095-.547.035-.643.294-.097.259.035.547.293.644.664.247 1.306.373 1.907.373 1.319 0 2.014-.449 2.627-.845.524-.339.98-.631 1.848-.635.992.008 1.358.278 1.815.621.538.403 1.147.859 2.633.859.601 0 1.244-.126 1.908-.373.259-.097.391-.385.294-.644z"/><path fill="#E75A70" d="M19.4 24.807h-2.8c-.64 0-1.163.523-1.163 1.163 0 .639.523 1.163 1.163 1.163h.237v.345c0 .639.523 1.163 1.163 1.163s1.163-.523 1.163-1.163v-.345h.237c.639 0 1.163-.523 1.163-1.163s-.524-1.163-1.163-1.163z"/><path fill="#F18F26" d="M18.022 17.154c-.276 0-.5-.224-.5-.5V8.37c0-.276.224-.5.5-.5s.5.224.5.5v8.284c0 .277-.223.5-.5.5zM21 15.572c-.276 0-.5-.224-.5-.5 0-2.882 1.232-5.21 1.285-5.308.13-.244.435-.334.677-.204.243.13.334.433.204.677-.012.021-1.166 2.213-1.166 4.835 0 .276-.224.5-.5.5zm-6 0c-.276 0-.5-.224-.5-.5 0-2.623-1.155-4.814-1.167-4.835-.13-.244-.038-.546.205-.677.242-.131.545-.039.676.204.053.098 1.285 2.426 1.285 5.308.001.276-.223.5-.499.5z"/></svg>

之后

宽度:  |  高度:  |  大小: 3.3 KiB

查看文件

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 36 36"><path fill="#DD2E44" d="M15 27v6s0 3 3 3 3-3 3-3v-6h-6z"/><path fill="#BE1931" d="M15 33l.001.037c1.041-.035 2.016-.274 2.632-1.286.171-.281.563-.281.735 0 .616 1.011 1.591 1.251 2.632 1.286V27h-6v6z"/><path fill="#D99E82" d="M31.954 21.619c0 6.276-5 6.276-5 6.276h-18s-5 0-5-6.276c0-6.724 5-18.619 14-18.619s14 12.895 14 18.619z"/><path fill="#F4C7B5" d="M18 20c-7 0-10 3.527-10 6.395 0 3.037 2.462 5.5 5.5 5.5 1.605 0 3.042-.664 4.049-2.767.185-.386.716-.386.901 0 1.007 2.103 2.445 2.767 4.049 2.767 3.038 0 5.5-2.463 5.5-5.5C28 23.527 25 20 18 20z"/><path fill="#292F33" d="M15 22.895c-1 1 2 4 3 4s4-3 3-4-5-1-6 0zM13 19c-1.1 0-2-.9-2-2v-2c0-1.1.9-2 2-2s2 .9 2 2v2c0 1.1-.9 2-2 2zm10 0c-1.1 0-2-.9-2-2v-2c0-1.1.9-2 2-2s2 .9 2 2v2c0 1.1-.9 2-2 2z"/><path fill="#662113" d="M15 3.608C13.941 2.199 11.681.881 2.828 4.2-1.316 5.754.708 17.804 3.935 18.585c1.106 0 4.426 0 4.426-8.852 0-.22-.002-.423-.005-.625C10.35 6.298 12.5 4.857 15 3.608zm18.172.592C24.319.881 22.059 2.199 21 3.608c2.5 1.25 4.65 2.691 6.644 5.501-.003.201-.005.404-.005.625 0 8.852 3.319 8.852 4.426 8.852 3.227-.782 5.251-12.832 1.107-14.386z"/><circle fill="#D99E82" cx="23.5" cy="25.5" r=".5"/><circle fill="#D99E82" cx="11.5" cy="25.5" r=".5"/><circle fill="#D99E82" cx="25.5" cy="27.5" r=".5"/><circle fill="#D99E82" cx="10.5" cy="27.5" r=".5"/><circle fill="#D99E82" cx="23" cy="28" r="1"/><circle fill="#D99E82" cx="13" cy="28" r="1"/><path fill="#380F09" d="M9.883 7.232c-.259-.673-.634-1.397-1.176-1.939-.391-.391-1.023-.391-1.414 0s-.391 1.023 0 1.414c.57.57 1.066 1.934 1.068 2.346.145-.404.839-1.15 1.522-1.821zm16.217 0c.259-.672.634-1.397 1.176-1.939.391-.391 1.023-.391 1.414 0s.391 1.023 0 1.414c-.57.57-1.066 1.934-1.068 2.346-.145-.404-.839-1.15-1.522-1.821z"/></svg>

之后

宽度:  |  高度:  |  大小: 1.8 KiB

查看文件

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 36 36"><path fill="#F4900C" d="M13.431 9.802c.658 2.638-8.673 10.489-11.244 4.098C.696 10.197-.606 2.434.874 2.065c1.48-.368 11.9 5.098 12.557 7.737z"/><path fill="#A0041E" d="M11.437 10.355c.96 1.538-1.831 4.561-3.368 5.522-1.538.961-2.899-.552-4.414-4.414-.662-1.689-1.666-6.27-1.103-6.622.562-.351 7.924 3.976 8.885 5.514z"/><path fill="#F4900C" d="M22.557 9.802C21.9 12.441 31.23 20.291 33.802 13.9c1.49-3.703 2.792-11.466 1.312-11.835-1.48-.368-11.899 5.098-12.557 7.737z"/><path fill="#A0041E" d="M24.552 10.355c-.96 1.538 1.831 4.561 3.368 5.522 1.537.961 2.898-.552 4.413-4.414.662-1.688 1.666-6.269 1.104-6.621-.563-.352-7.924 3.975-8.885 5.513z"/><path fill="#F18F26" d="M32.347 26.912c0-.454-.188-1.091-.407-1.687.585.028 1.519.191 2.77.817-.008-.536-.118-.984-.273-1.393.041.02.075.034.116.055-1.103-3.31-3.309-5.517-3.309-5.517h2.206c-2.331-4.663-4.965-8.015-8.075-9.559-1.39-.873-3.688-1.338-7.373-1.339h-.003c-3.695 0-5.996.468-7.385 1.346-3.104 1.547-5.734 4.896-8.061 9.552H4.76s-2.207 2.206-3.311 5.517c.03-.015.055-.025.084-.04-.201.392-.307.847-.282 1.377 1.263-.632 2.217-.792 2.813-.818-.189.513-.343 1.044-.386 1.475-.123.371-.191.812-.135 1.343C6.75 26.584 8.25 26.792 10 27.667 11.213 31.29 14.206 34 18.001 34c3.793 0 6.746-2.794 7.958-6.416 1.458-1.25 3.708-.875 6.416.416.066-.414.036-.773-.036-1.093l.008.005z"/><path fill="#FFD983" d="M31.243 23.601c.006 0 1.108.003 3.309 1.103-1.249-2.839-7.525-4.07-9.931-3.291-1.171 1.954-1.281 5.003-3.383 6.622-1.741 1.431-4.713 1.458-6.479 0-2.345-1.924-2.559-5.813-3.382-6.622-2.407-.781-8.681.454-9.931 3.291 2.201-1.101 3.304-1.103 3.309-1.103 0 .001-1.103 2.208-1.103 3.311l.001-.001v.001c2.398-1.573 5.116-2.271 7.429-.452 1.666 7.921 12.293 7.545 13.833 0 2.314-1.818 5.03-1.122 7.429.452v-.001l.001.001c.002-1.103-1.101-3.311-1.102-3.311z"/><path fill="#272B2B" d="M11 17s0-1.5 1.5-1.5S14 17 14 17v1.5s0 1.5-1.5 1.5-1.5-1.5-1.5-1.5V17zm11 0s0-1.5 1.5-1.5S25 17 25 17v1.5s0 1.5-1.5 1.5-1.5-1.5-1.5-1.5V17zm-7.061 10.808c-1.021.208 2.041 3.968 3.062 3.968 1.02 0 4.082-3.76 3.062-3.968-1.021-.208-5.103-.208-6.124 0z"/></svg>

之后

宽度:  |  高度:  |  大小: 2.1 KiB

查看文件

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 36 36"><path fill="#31373D" d="M5 16c0-4-5-3-4 1s3 5 3 5l1-6zm26 0c0-4 5-3 4 1s-3 5-3 5l-1-6z"/><path fill="#31373D" d="M32.65 21.736c0 10.892-4.691 14.087-14.65 14.087-9.958 0-14.651-3.195-14.651-14.087S8.042.323 18 .323c9.959 0 14.65 10.521 14.65 21.413z"/><path fill="#66757F" d="M27.567 23c1.49-4.458 2.088-7.312-.443-7.312H8.876c-2.532 0-1.933 2.854-.444 7.312C3.504 34.201 17.166 34.823 18 34.823S32.303 33.764 27.567 23z"/><path fill="#31373D" d="M15 18.003c0 1.105-.896 2-2 2s-2-.895-2-2c0-1.104.896-1 2-1s2-.105 2 1zm10 0c0 1.105-.896 2-2 2s-2-.895-2-2c0-1.104.896-1 2-1s2-.105 2 1z"/><ellipse fill="#31373D" cx="15.572" cy="23.655" rx="1.428" ry="1"/><path fill="#31373D" d="M21.856 23.655c0 .553-.639 1-1.428 1-.79 0-1.429-.447-1.429-1 0-.553.639-1 1.429-1s1.428.448 1.428 1z"/><path fill="#99AAB5" d="M21.02 21.04c-1.965-.26-3.02.834-3.02.834s-1.055-1.094-3.021-.834c-3.156.417-3.285 3.287-1.939 3.105.766-.104.135-.938 1.713-1.556 1.579-.616 3.247.66 3.247.66s1.667-1.276 3.246-.659.947 1.452 1.714 1.556c1.346.181 1.218-2.689-1.94-3.106z"/><path fill="#31373D" d="M24.835 30.021c-1.209.323-3.204.596-6.835.596s-5.625-.272-6.835-.596c-3.205-.854-1.923-1.735 0-1.477 1.923.259 3.631.415 6.835.415 3.205 0 4.914-.156 6.835-.415 1.923-.258 3.204.623 0 1.477z"/><path fill="#66757F" d="M4.253 16.625c1.403-1.225-1.078-3.766-2.196-2.544-.341.373.921-.188 1.336 1.086.308.942.001 2.208.86 1.458zm27.493 0c-1.402-1.225 1.078-3.766 2.196-2.544.341.373-.921-.188-1.337 1.086-.306.942 0 2.208-.859 1.458z"/></svg>

之后

宽度:  |  高度:  |  大小: 1.5 KiB

查看文件

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 36 36"><path fill="#662113" d="M32.325 10.958s2.315.024 3.511 1.177c-.336-4.971-2.104-8.249-5.944-10.13-3.141-1.119-6.066 1.453-6.066 1.453s.862-1.99 2.19-2.746C23.789.236 21.146 0 18 0c-3.136 0-5.785.227-8.006.701 1.341.745 2.215 2.758 2.215 2.758S9.194.803 6 2.053C2.221 3.949.481 7.223.158 12.174c1.183-1.19 3.55-1.215 3.55-1.215S-.105 13.267.282 16.614c.387 2.947 1.394 5.967 2.879 8.722C3.039 22.15 5.917 20 5.917 20s-2.492 5.96-.581 8.738c1.935 2.542 4.313 4.641 6.976 5.916-.955-1.645-.136-3.044-.103-2.945.042.125.459 3.112 2.137 3.743 1.178.356 2.4.548 3.654.548 1.292 0 2.55-.207 3.761-.583 1.614-.691 2.024-3.585 2.064-3.708.032-.098.843 1.287-.09 2.921 2.706-1.309 5.118-3.463 7.064-6.073 1.699-2.846-.683-8.557-.683-8.557s2.85 2.13 2.757 5.288c1.556-2.906 2.585-6.104 2.911-9.2-.035-3.061-3.459-5.13-3.459-5.13z"/><path fill="#FFCC4D" d="M13.859 9.495c.596 2.392.16 4.422-2.231 5.017-2.392.596-6.363.087-6.958-2.304-.596-2.392.469-5.39 1.81-5.724 1.341-.334 6.784.62 7.379 3.011zm9.104 18.432c0 2.74-2.222 4.963-4.963 4.963s-4.963-2.223-4.963-4.963c0-2.741 2.223-4.964 4.963-4.964 2.741 0 4.963 2.222 4.963 4.964z"/><path fill="#DD2E44" d="M21.309 27.927c0 1.827-1.481 3.309-3.309 3.309s-3.309-1.481-3.309-3.309c0-1.827 1.481-3.31 3.309-3.31s3.309 1.483 3.309 3.31z"/><path fill="#E6AAAA" d="M11.052 8.997c.871 1.393.447 3.229-.946 4.1-1.394.871-2.608.797-3.479-.596-.871-1.394-.186-4.131.324-4.45.51-.319 3.23-.448 4.101.946z"/><path fill="#FFCC4D" d="M22.141 9.495c-.596 2.392-.159 4.422 2.232 5.017 2.392.596 6.363.087 6.959-2.304.596-2.392-.47-5.39-1.811-5.724-1.342-.334-6.786.62-7.38 3.011z"/><path fill="#E6AAAA" d="M24.948 8.997c-.871 1.393-.447 3.229.945 4.1 1.394.871 2.608.797 3.479-.596.871-1.394.185-4.131-.324-4.45-.51-.319-3.229-.448-4.1.946z"/><path fill="#FFCC4D" d="M18 7.125h-.002C5.167 7.126 7.125 12.083 8.5 18.667 9.875 25.25 10.384 27 10.384 27h15.228s.51-1.75 1.885-8.333C28.872 12.083 30.829 7.126 18 7.125z"/><path fill="#272B2B" d="M12 16s0-1.5 1.5-1.5S15 16 15 16v1.5s0 1.5-1.5 1.5-1.5-1.5-1.5-1.5V16zm9 0s0-1.5 1.5-1.5S24 16 24 16v1.5s0 1.5-1.5 1.5-1.5-1.5-1.5-1.5V16z"/><path fill="#FFE8B6" d="M20.168 21.521c-1.598 0-1.385.848-2.168 2.113-.783-1.266-.571-2.113-2.168-2.113-6.865 0-6.837.375-6.865 2.828-.058 4.986 2.802 6.132 5.257 6.06 1.597-.048 2.994-.88 3.777-2.131.783 1.251 2.179 2.083 3.776 2.131 2.455.072 5.315-1.073 5.257-6.06-.029-2.453-.001-2.828-6.866-2.828z"/><path fill="#272B2B" d="M14.582 21.411c-1.14.233 2.279 4.431 3.418 4.431s4.559-4.198 3.419-4.431c-1.14-.232-5.698-.232-6.837 0z"/><circle fill="#D99E82" cx="11.5" cy="24.5" r=".5"/><circle fill="#D99E82" cx="10.5" cy="26.5" r=".5"/><circle fill="#D99E82" cx="12.5" cy="27.5" r=".5"/><circle fill="#D99E82" cx="24.5" cy="24.5" r=".5"/><circle fill="#D99E82" cx="25.5" cy="26.5" r=".5"/><circle fill="#D99E82" cx="23.5" cy="27.5" r=".5"/></svg>

之后

宽度:  |  高度:  |  大小: 2.8 KiB

查看文件

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 36 36"><ellipse transform="rotate(-14.999 5.05 17.456)" fill="#D79E84" cx="5.05" cy="17.455" rx="3.818" ry="5.455"/><ellipse transform="rotate(-75.001 31.05 17.455)" fill="#D79E84" cx="31.05" cy="17.455" rx="5.455" ry="3.818"/><path fill="#BF6952" d="M19.018 36h-2.036C10.264 36 3.75 30.848 3.75 23.636c0-4.121 1.527-6.182 1.527-6.182s-.509-2.061-.509-4.121C4.768 7.152 11.282 2 18 2c6.718 0 13.232 6.182 13.232 11.333 0 2.061-.509 4.121-.509 4.121s1.527 2.061 1.527 6.182C32.25 30.848 25.736 36 19.018 36z"/><path fill="#D79E84" d="M30 16.042C30 12.153 26.825 9 22.909 9c-1.907 0-3.635.752-4.909 1.968C16.726 9.752 14.998 9 13.091 9 9.175 9 6 12.153 6 16.042c0 2.359 1.172 4.441 2.965 5.719-.503 1.238-.783 2.6-.783 4.031C8.182 31.476 12.578 35 18 35s9.818-3.524 9.818-9.208c0-1.431-.28-2.793-.783-4.031C28.828 20.483 30 18.4 30 16.042z"/><ellipse fill="#292F33" cx="13" cy="17" rx="2.25" ry="3.25"/><ellipse fill="#292F33" cx="23" cy="17" rx="2.25" ry="3.25"/><path fill="#642116" d="M18 32.727c2.838 0 5.254-1.505 6.162-3.61.375-.871-.262-1.844-1.21-1.844h-9.904c-.948 0-1.585.974-1.21 1.844.908 2.105 3.324 3.61 6.162 3.61z"/><circle fill="#642116" cx="16.25" cy="23" r="1"/><circle fill="#642116" cx="19.75" cy="23" r="1"/><path fill="#BF6952" d="M22.66.175s-5.455-1.091-7.636 2.182 4.364 1.091 4.364 1.091S20.478.175 22.66.175z"/></svg>

之后

宽度:  |  高度:  |  大小: 1.4 KiB

查看文件

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 36 36"><circle fill="#272B2B" cx="7" cy="6" r="6"/><circle fill="#272B2B" cx="29" cy="6" r="6"/><circle fill="#66757F" cx="7" cy="6" r="4"/><circle fill="#66757F" cx="29" cy="6" r="4"/><path fill="#EEE" d="M35 22c0 7-6.375 12-17 12S1 29 1 22C1 22 2.308 0 18 0s17 22 17 22z"/><circle fill="#CCD6DD" cx="18" cy="30" r="6"/><circle fill="#DD2E44" cx="18" cy="30" r="4"/><path fill="#272B2B" d="M20.709 12.654C25.163 9.878 32 17 26.952 22.67 23.463 26.591 20 25 20 25s-2.636-10.26.709-12.346zm-5.442.011C10.813 9.888 3.976 17.01 9.023 22.681c3.49 3.92 6.953 2.329 6.953 2.329s2.636-10.26-.709-12.345z"/><path fill="#66757F" d="M11 17s0-2 2-2 2 2 2 2v2s0 2-2 2-2-2-2-2v-2z"/><path fill="#FFF" d="M18 20S7 23.687 7 27s2.687 6 6 6c2.088 0 3.925-1.067 5-2.685C19.074 31.933 20.912 33 23 33c3.313 0 6-2.687 6-6s-11-7-11-7z"/><path fill="#66757F" d="M21 17s0-2 2-2 2 2 2 2v2s0 2-2 2-2-2-2-2v-2z"/><path fill="#272B2B" d="M13.125 25c-1.624 1 3.25 4 4.875 4s6.499-3 4.874-4-8.124-1-9.749 0z"/></svg>

之后

宽度:  |  高度:  |  大小: 1.0 KiB

查看文件

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 36 36"><path fill="#F4ABBA" d="M34.193 13.329c.387-.371.733-.795 1.019-1.28 1.686-2.854.27-10.292-.592-10.8-.695-.411-5.529 1.05-8.246 3.132C23.876 2.884 21.031 2 18 2c-3.021 0-5.856.879-8.349 2.367C6.93 2.293 2.119.839 1.424 1.249c-.861.508-2.276 7.947-.592 10.8.278.471.615.884.989 1.249C.666 15.85 0 18.64 0 21.479 0 31.468 8.011 34 18 34s18-2.532 18-12.521c0-2.828-.66-5.606-1.807-8.15z"/><path fill="#EA596E" d="M7.398 5.965c-2.166-1.267-4.402-2.08-4.8-1.845-.57.337-1.083 4.998-.352 8.265 1.273-2.483 3.04-4.682 5.152-6.42zm26.355 6.419c.733-3.267.219-7.928-.351-8.265-.398-.235-2.635.578-4.801 1.845 2.114 1.739 3.88 3.938 5.152 6.42zM28 23.125c0 4.487-3.097 9.375-10 9.375-6.904 0-10-4.888-10-9.375S11.096 17.5 18 17.5c6.903 0 10 1.138 10 5.625z"/><path fill="#662113" d="M15 24.6c0 1.857-.34 2.4-1.5 2.4s-1.5-.543-1.5-2.4c0-1.856.34-2.399 1.5-2.399s1.5.542 1.5 2.399zm9 0c0 1.857-.34 2.4-1.5 2.4s-1.5-.543-1.5-2.4c0-1.856.34-2.399 1.5-2.399s1.5.542 1.5 2.399z"/><circle fill="#292F33" cx="7" cy="17" r="2"/><circle fill="#292F33" cx="29" cy="17" r="2"/></svg>

之后

宽度:  |  高度:  |  大小: 1.1 KiB

查看文件

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 36 36"><path fill="#99AAB5" d="M33.799.005c-.467-.178-7.998 3.971-9.969 9.131-1.166 3.052-1.686 6.058-1.652 8.112C20.709 16.459 19.257 16 18 16s-2.709.458-4.178 1.249c.033-2.055-.486-5.061-1.652-8.112C10.2 3.977 2.668-.173 2.201.005c-.455.174 4.268 16.044 7.025 20.838C6.805 23.405 5 26.661 5 29.828c0 3.234 1.635 5.14 4 5.94 2.531.857 5-.94 9-.94s6.469 1.798 9 .94c2.365-.801 4-2.706 4-5.94 0-3.166-1.805-6.423-4.225-8.984C29.53 16.049 34.255.179 33.799.005z"/><path fill="#F4ABBA" d="M12.692 17.922c-.178-1.54-.68-3.55-1.457-5.584-1.534-4.016-5.686-7.245-6.049-7.107-.319.122 2.627 10.14 4.783 14.863.866-.824 1.786-1.563 2.723-2.172zm13.338 2.172c2.156-4.723 5.102-14.741 4.784-14.862-.363-.139-4.516 3.091-6.05 7.107-.777 2.034-1.279 4.043-1.457 5.583.937.609 1.857 1.348 2.723 2.172z"/><path fill="#CCD6DD" d="M25 30c0 2.762-3.06 5-6.834 5-3.773 0-6.833-2.238-6.833-5s3.06-5 6.833-5C21.94 25 25 27.238 25 30z"/><path fill="#FFF" d="M21 30.578c0 2.762-.238 3-3 3-2.761 0-3-.238-3-3 0-1 6-1 6 0z"/><circle fill="#292F33" cx="12.5" cy="24.328" r="1.5"/><circle fill="#292F33" cx="23.5" cy="24.328" r="1.5"/><path fill="#F4ABBA" d="M21 25.828c0 1.657-2 3-3 3s-3-1.343-3-3 6-1.657 6 0z"/></svg>

之后

宽度:  |  高度:  |  大小: 1.2 KiB

查看文件

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 36 36"><circle fill="#FFCC4D" cx="7" cy="6" r="6"/><circle fill="#FFCC4D" cx="18" cy="30" r="6"/><circle fill="#DD2E44" cx="18" cy="30" r="4"/><circle fill="#FFCC4D" cx="29" cy="6" r="6"/><circle fill="#E6AAAA" cx="7" cy="6" r="4"/><circle fill="#E6AAAA" cx="29" cy="6" r="4"/><path fill="#FFCC4D" d="M34 22c0 7-4.923 7-4.923 7H6.923S2 29 2 22C2 22 3.231 0 18 0c14.77 0 16 22 16 22z"/><path fill="#272B2B" d="M11 17s0-2 2-2 2 2 2 2v2s0 2-2 2-2-2-2-2v-2zm10 0s0-2 2-2 2 2 2 2v2s0 2-2 2-2-2-2-2v-2z"/><path fill="#FFF" d="M23.678 23c-2.402 0-4.501.953-5.678 2.378C16.823 23.953 14.723 23 12.321 23 2 23 2.043 23.421 2 26.182c-.087 5.61 6.63 6.9 10.321 6.818 2.401-.053 4.502-.989 5.679-2.397 1.177 1.408 3.276 2.345 5.678 2.397 3.691.082 10.409-1.208 10.321-6.818-.043-2.761 0-3.182-10.321-3.182z"/><path fill="#272B2B" d="M33.66 25.242c.204.279.333.588.339.939.03 1.905-.745 3.303-1.915 4.327L26.999 31l6.661-5.758zM15 25c-1 1 2 4 3 4s4-3 3-4-5-1-6 0zM10 3c2.667 2 8 4 8 4s5.333-2 8-4l-8 1-8-1zm8-1s1.652-.62 3.576-1.514C20.48.178 19.295 0 18 0s-2.481.178-3.576.486C16.348 1.38 18 2 18 2zm-7 7c3 2 7 4 7 4s4-2 7-4l-7 1-7-1zm20.645 2.285L27 15l6.006.75c-.334-1.401-.777-2.928-1.361-4.465zm1.911 7.159L28 24h5.835c.102-.595.165-1.251.165-2 0 0-.081-1.43-.444-3.556zm-31.112 0C2.082 20.57 2 22 2 22c0 .748.063 1.405.165 2H8l-5.556-5.556zm-.105 6.798c-.204.279-.333.588-.339.94-.03 1.905.745 3.303 1.916 4.327L9 31l-6.661-5.758zM9 15l-4.644-3.715c-.584 1.537-1.028 3.064-1.361 4.466L9 15z"/></svg>

之后

宽度:  |  高度:  |  大小: 1.5 KiB

查看文件

@@ -90,6 +90,8 @@ describe("live camera avatar helpers", () => {
it("maps prompt keywords into avatar presets", () => {
expect(resolveAvatarKeyFromPrompt("切换成猩猩形象", "gorilla")).toBe("gorilla");
expect(resolveAvatarKeyFromPrompt("dog mascot", "gorilla")).toBe("dog");
expect(resolveAvatarKeyFromPrompt("狐狸风格", "gorilla")).toBe("fox");
expect(resolveAvatarKeyFromPrompt("兔子教练", "gorilla")).toBe("rabbit");
expect(resolveAvatarKeyFromPrompt("", "pig")).toBe("pig");
});

查看文件

@@ -6,7 +6,17 @@ export type PosePoint = {
visibility?: number;
};
export type AvatarKey = "gorilla" | "monkey" | "pig" | "dog";
export type AvatarKey =
| "gorilla"
| "monkey"
| "dog"
| "pig"
| "cat"
| "fox"
| "panda"
| "lion"
| "tiger"
| "rabbit";
export type AvatarRenderState = {
enabled: boolean;
@@ -69,6 +79,13 @@ type AvatarAnchors = {
rightHandY: number;
};
type AvatarVisualSpec = {
src: string;
bodyFill: string;
limbStroke: string;
glow: string;
};
const ACTIONS: LiveActionType[] = ["forehand", "backhand", "serve", "volley", "overhead", "slice", "lob", "unknown"];
export const ACTION_WINDOW_FRAMES = 24;
@@ -82,10 +99,81 @@ const ACTION_SWITCH_DELTA = 0.12;
export const AVATAR_PRESETS: Array<{ key: AvatarKey; label: string; keywords: string[] }> = [
{ key: "gorilla", label: "猩猩", keywords: ["gorilla", "ape", "猩猩", "猩", "大猩猩"] },
{ key: "monkey", label: "猴子", keywords: ["monkey", "ape", "猴", "猴子"] },
{ key: "pig", label: "猪", keywords: ["pig", "猪", "小猪"] },
{ key: "dog", label: "狗", keywords: ["dog", "puppy", "犬", "狗", "小狗"] },
{ key: "pig", label: "猪", keywords: ["pig", "猪", "小猪"] },
{ key: "cat", label: "猫", keywords: ["cat", "kitty", "猫", "小猫"] },
{ key: "fox", label: "狐狸", keywords: ["fox", "狐狸"] },
{ key: "panda", label: "熊猫", keywords: ["panda", "熊猫"] },
{ key: "lion", label: "狮子", keywords: ["lion", "狮子"] },
{ key: "tiger", label: "老虎", keywords: ["tiger", "虎", "老虎"] },
{ key: "rabbit", label: "兔子", keywords: ["rabbit", "bunny", "兔", "兔子"] },
];
const AVATAR_VISUALS: Record<AvatarKey, AvatarVisualSpec> = {
gorilla: {
src: "/avatars/twemoji/gorilla.svg",
bodyFill: "rgba(39,39,42,0.95)",
limbStroke: "rgba(63,63,70,0.92)",
glow: "rgba(161,161,170,0.32)",
},
monkey: {
src: "/avatars/twemoji/monkey.svg",
bodyFill: "rgba(120,53,15,0.95)",
limbStroke: "rgba(146,64,14,0.9)",
glow: "rgba(180,83,9,0.3)",
},
dog: {
src: "/avatars/twemoji/dog.svg",
bodyFill: "rgba(180,83,9,0.93)",
limbStroke: "rgba(180,83,9,0.88)",
glow: "rgba(217,119,6,0.26)",
},
pig: {
src: "/avatars/twemoji/pig.svg",
bodyFill: "rgba(244,114,182,0.92)",
limbStroke: "rgba(244,114,182,0.86)",
glow: "rgba(244,114,182,0.28)",
},
cat: {
src: "/avatars/twemoji/cat.svg",
bodyFill: "rgba(245,158,11,0.92)",
limbStroke: "rgba(217,119,6,0.88)",
glow: "rgba(251,191,36,0.28)",
},
fox: {
src: "/avatars/twemoji/fox.svg",
bodyFill: "rgba(234,88,12,0.93)",
limbStroke: "rgba(194,65,12,0.9)",
glow: "rgba(251,146,60,0.3)",
},
panda: {
src: "/avatars/twemoji/panda.svg",
bodyFill: "rgba(82,82,91,0.92)",
limbStroke: "rgba(39,39,42,0.9)",
glow: "rgba(228,228,231,0.28)",
},
lion: {
src: "/avatars/twemoji/lion.svg",
bodyFill: "rgba(202,138,4,0.92)",
limbStroke: "rgba(161,98,7,0.9)",
glow: "rgba(250,204,21,0.28)",
},
tiger: {
src: "/avatars/twemoji/tiger.svg",
bodyFill: "rgba(249,115,22,0.94)",
limbStroke: "rgba(194,65,12,0.9)",
glow: "rgba(251,146,60,0.3)",
},
rabbit: {
src: "/avatars/twemoji/rabbit.svg",
bodyFill: "rgba(236,72,153,0.9)",
limbStroke: "rgba(219,39,119,0.86)",
glow: "rgba(244,114,182,0.28)",
},
};
const avatarImageCache = new Map<AvatarKey, HTMLImageElement | null>();
function clamp(value: number, min: number, max: number) {
return Math.max(min, Math.min(max, value));
}
@@ -345,105 +433,73 @@ function drawLimbs(ctx: CanvasRenderingContext2D, anchors: AvatarAnchors, stroke
ctx.stroke();
}
function drawGorillaAvatar(ctx: CanvasRenderingContext2D, anchors: AvatarAnchors) {
ctx.fillStyle = "#3f3f46";
ctx.beginPath();
ctx.arc(anchors.headX, anchors.headY, anchors.headRadius, 0, Math.PI * 2);
ctx.fill();
function getAvatarImage(key: AvatarKey) {
if (typeof Image === "undefined") {
return null;
}
ctx.beginPath();
ctx.arc(anchors.headX - anchors.headRadius * 0.78, anchors.headY - anchors.headRadius * 0.1, anchors.headRadius * 0.28, 0, Math.PI * 2);
ctx.arc(anchors.headX + anchors.headRadius * 0.78, anchors.headY - anchors.headRadius * 0.1, anchors.headRadius * 0.28, 0, Math.PI * 2);
ctx.fill();
const cached = avatarImageCache.get(key);
if (cached) {
return cached.complete && cached.naturalWidth > 0 ? cached : null;
}
ctx.fillStyle = "#d6d3d1";
ctx.beginPath();
ctx.ellipse(anchors.headX, anchors.headY + anchors.headRadius * 0.16, anchors.headRadius * 0.54, anchors.headRadius * 0.46, 0, 0, Math.PI * 2);
ctx.fill();
ctx.fillStyle = "#111827";
ctx.beginPath();
ctx.arc(anchors.headX - anchors.headRadius * 0.24, anchors.headY - anchors.headRadius * 0.12, anchors.headRadius * 0.08, 0, Math.PI * 2);
ctx.arc(anchors.headX + anchors.headRadius * 0.24, anchors.headY - anchors.headRadius * 0.12, anchors.headRadius * 0.08, 0, Math.PI * 2);
ctx.fill();
ctx.beginPath();
ctx.arc(anchors.headX, anchors.headY + anchors.headRadius * 0.06, anchors.headRadius * 0.08, 0, Math.PI * 2);
ctx.fill();
drawRoundedBody(ctx, anchors, "rgba(39,39,42,0.95)");
drawLimbs(ctx, anchors, "rgba(63,63,70,0.92)");
const image = new Image();
image.decoding = "async";
image.src = AVATAR_VISUALS[key].src;
avatarImageCache.set(key, image);
return null;
}
function drawMonkeyAvatar(ctx: CanvasRenderingContext2D, anchors: AvatarAnchors) {
ctx.fillStyle = "#8b5a3c";
ctx.beginPath();
ctx.arc(anchors.headX, anchors.headY, anchors.headRadius, 0, Math.PI * 2);
ctx.fill();
ctx.beginPath();
ctx.arc(anchors.headX - anchors.headRadius * 0.82, anchors.headY - anchors.headRadius * 0.16, anchors.headRadius * 0.34, 0, Math.PI * 2);
ctx.arc(anchors.headX + anchors.headRadius * 0.82, anchors.headY - anchors.headRadius * 0.16, anchors.headRadius * 0.34, 0, Math.PI * 2);
ctx.fill();
function drawAvatarBadge(
ctx: CanvasRenderingContext2D,
anchors: AvatarAnchors,
avatarKey: AvatarKey,
sprite: HTMLImageElement | null,
) {
const visual = AVATAR_VISUALS[avatarKey];
const headSize = anchors.headRadius * 2.5;
const torsoBadge = Math.max(anchors.headRadius * 0.95, 40);
ctx.fillStyle = "#f3d7bf";
ctx.beginPath();
ctx.ellipse(anchors.headX, anchors.headY + anchors.headRadius * 0.14, anchors.headRadius * 0.56, anchors.headRadius * 0.5, 0, 0, Math.PI * 2);
ctx.fill();
drawRoundedBody(ctx, anchors, visual.bodyFill);
drawLimbs(ctx, anchors, visual.limbStroke);
drawRoundedBody(ctx, anchors, "rgba(120,53,15,0.95)");
drawLimbs(ctx, anchors, "rgba(146,64,14,0.9)");
}
ctx.save();
ctx.fillStyle = visual.glow;
ctx.beginPath();
ctx.arc(anchors.headX, anchors.headY, anchors.headRadius * 1.16, 0, Math.PI * 2);
ctx.fill();
ctx.restore();
function drawPigAvatar(ctx: CanvasRenderingContext2D, anchors: AvatarAnchors) {
ctx.fillStyle = "#f9a8d4";
ctx.beginPath();
ctx.arc(anchors.headX, anchors.headY, anchors.headRadius, 0, Math.PI * 2);
ctx.fill();
ctx.beginPath();
ctx.moveTo(anchors.headX - anchors.headRadius * 0.62, anchors.headY - anchors.headRadius * 0.42);
ctx.lineTo(anchors.headX - anchors.headRadius * 0.18, anchors.headY - anchors.headRadius * 1.06);
ctx.lineTo(anchors.headX - anchors.headRadius * 0.02, anchors.headY - anchors.headRadius * 0.32);
ctx.closePath();
ctx.moveTo(anchors.headX + anchors.headRadius * 0.62, anchors.headY - anchors.headRadius * 0.42);
ctx.lineTo(anchors.headX + anchors.headRadius * 0.18, anchors.headY - anchors.headRadius * 1.06);
ctx.lineTo(anchors.headX + anchors.headRadius * 0.02, anchors.headY - anchors.headRadius * 0.32);
ctx.closePath();
ctx.fill();
if (sprite) {
ctx.drawImage(
sprite,
anchors.headX - headSize / 2,
anchors.headY - headSize / 2,
headSize,
headSize,
);
ctx.save();
ctx.globalAlpha = 0.94;
ctx.drawImage(
sprite,
anchors.bodyX - torsoBadge / 2,
anchors.bodyY - torsoBadge / 2,
torsoBadge,
torsoBadge,
);
ctx.restore();
return;
}
ctx.fillStyle = "#fbcfe8";
ctx.fillStyle = "rgba(255,255,255,0.92)";
ctx.beginPath();
ctx.ellipse(anchors.headX, anchors.headY + anchors.headRadius * 0.18, anchors.headRadius * 0.44, anchors.headRadius * 0.28, 0, 0, Math.PI * 2);
ctx.arc(anchors.headX, anchors.headY, anchors.headRadius * 0.88, 0, Math.PI * 2);
ctx.fill();
ctx.fillStyle = "#be185d";
ctx.fillStyle = "rgba(17,24,39,0.82)";
ctx.beginPath();
ctx.arc(anchors.headX - anchors.headRadius * 0.14, anchors.headY + anchors.headRadius * 0.18, anchors.headRadius * 0.06, 0, Math.PI * 2);
ctx.arc(anchors.headX + anchors.headRadius * 0.14, anchors.headY + anchors.headRadius * 0.18, anchors.headRadius * 0.06, 0, Math.PI * 2);
ctx.arc(anchors.headX - anchors.headRadius * 0.22, anchors.headY - anchors.headRadius * 0.08, anchors.headRadius * 0.08, 0, Math.PI * 2);
ctx.arc(anchors.headX + anchors.headRadius * 0.22, anchors.headY - anchors.headRadius * 0.08, anchors.headRadius * 0.08, 0, Math.PI * 2);
ctx.fill();
drawRoundedBody(ctx, anchors, "rgba(244,114,182,0.92)");
drawLimbs(ctx, anchors, "rgba(244,114,182,0.86)");
}
function drawDogAvatar(ctx: CanvasRenderingContext2D, anchors: AvatarAnchors) {
ctx.fillStyle = "#d4a373";
ctx.beginPath();
ctx.arc(anchors.headX, anchors.headY, anchors.headRadius, 0, Math.PI * 2);
ctx.fill();
ctx.beginPath();
ctx.ellipse(anchors.headX - anchors.headRadius * 0.72, anchors.headY - anchors.headRadius * 0.28, anchors.headRadius * 0.22, anchors.headRadius * 0.46, Math.PI / 4, 0, Math.PI * 2);
ctx.ellipse(anchors.headX + anchors.headRadius * 0.72, anchors.headY - anchors.headRadius * 0.28, anchors.headRadius * 0.22, anchors.headRadius * 0.46, -Math.PI / 4, 0, Math.PI * 2);
ctx.fill();
ctx.fillStyle = "#f5e6d3";
ctx.beginPath();
ctx.ellipse(anchors.headX, anchors.headY + anchors.headRadius * 0.16, anchors.headRadius * 0.5, anchors.headRadius * 0.38, 0, 0, Math.PI * 2);
ctx.fill();
ctx.fillStyle = "#111827";
ctx.beginPath();
ctx.arc(anchors.headX, anchors.headY + anchors.headRadius * 0.04, anchors.headRadius * 0.09, 0, Math.PI * 2);
ctx.fill();
drawRoundedBody(ctx, anchors, "rgba(180,83,9,0.93)");
drawLimbs(ctx, anchors, "rgba(180,83,9,0.88)");
}
export function drawLiveCameraOverlay(
@@ -459,17 +515,10 @@ export function drawLiveCameraOverlay(
if (avatarState?.enabled) {
const anchors = getAvatarAnchors(landmarks, canvas.width, canvas.height);
if (anchors) {
const sprite = getAvatarImage(avatarState.avatarKey);
ctx.save();
ctx.globalAlpha = 0.95;
if (avatarState.avatarKey === "monkey") {
drawMonkeyAvatar(ctx, anchors);
} else if (avatarState.avatarKey === "pig") {
drawPigAvatar(ctx, anchors);
} else if (avatarState.avatarKey === "dog") {
drawDogAvatar(ctx, anchors);
} else {
drawGorillaAvatar(ctx, anchors);
}
drawAvatarBadge(ctx, anchors, avatarState.avatarKey, sprite);
ctx.restore();
ctx.save();

查看文件

@@ -1320,7 +1320,7 @@ export default function LiveCamera() {
<div>
<h1 className="text-3xl font-semibold tracking-tight"></h1>
<p className="mt-2 max-w-2xl text-sm leading-6 text-white/70">
24
24
</p>
</div>
</div>
@@ -1455,7 +1455,7 @@ export default function LiveCamera() {
<div>
<div className="text-sm font-medium"></div>
<div className="mt-1 text-xs text-muted-foreground">
10
</div>
</div>
<Switch
@@ -1467,7 +1467,7 @@ export default function LiveCamera() {
</div>
<div className="text-xs text-muted-foreground">
{resolvedAvatarLabel}
{avatarPrompt.trim() ? ` · 输入 ${avatarPrompt.trim()}` : " · 可输入别名自动映射到内置形象"}
{avatarPrompt.trim() ? ` · 输入 ${avatarPrompt.trim()}` : " · 可输入猩猩、狐狸、熊猫、兔子等别名自动映射"}
</div>
</div>
<div>
@@ -1488,7 +1488,7 @@ export default function LiveCamera() {
<Input
value={avatarPrompt}
onChange={(event) => setAvatarPrompt(event.target.value)}
placeholder="例如 猴子 / dog mascot"
placeholder="例如 狐狸 / panda coach / dog mascot"
className="h-12 rounded-2xl border-border/60"
/>
</div>