component.tsx 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. import { Dict_Imgs } from "@/dict";
  2. import { useEditor } from "@/modules/editor";
  3. import { defineComponent, watch } from "vue";
  4. import { string, bool } from "vue-types";
  5. import { useCompData } from ".";
  6. import { View } from "../View";
  7. import { css } from "@linaria/core";
  8. export const Component = defineComponent({
  9. props: {
  10. compId: string().isRequired,
  11. editlayer: bool().def(true),
  12. },
  13. setup(props) {
  14. const comp = useCompData(props.compId);
  15. const { actions, helper, store, controls } = useEditor();
  16. function setImageSize(url: string) {
  17. if (!helper.isStreamCardChild(props.compId)) return;
  18. const temImg = new Image();
  19. temImg.src = url;
  20. temImg.onload = function () {
  21. const ratio = temImg.width / temImg.height;
  22. const W = temImg.width > comp.getW() ? comp.getW() : temImg.width;
  23. comp.setW(W);
  24. comp.setH(W / ratio);
  25. actions.onCompLayoutUpdated(comp);
  26. helper.extendStreamCard(store.currStreamCardId);
  27. };
  28. }
  29. async function changeVal() {
  30. try {
  31. const url = await controls.pickCtrl.pickOneImage();
  32. if (!url) return;
  33. comp.value.url = url;
  34. comp.value.x = 0;
  35. comp.value.y = 0;
  36. comp.value.s = 1;
  37. comp.value.matrix = "";
  38. } catch (error) {
  39. console.log(error);
  40. }
  41. }
  42. watch(
  43. () => comp.value.url,
  44. (value, oldValue) => {
  45. if (oldValue !== Dict_Imgs.Default) return;
  46. setImageSize(value);
  47. }
  48. );
  49. return () => {
  50. const value = comp.value;
  51. const scale = value?.s || 1;
  52. const ox = value?.x || 0;
  53. const oy = value?.y || 0;
  54. const objectFit =
  55. scale + "" == "1" && ox + "" == "0" && oy + "" == "0"
  56. ? "cover"
  57. : "contain";
  58. const isCropping = controls.cropCtrl.state.compId == props.compId;
  59. const offsetUnit = value.offsetUnit || "%";
  60. const styleObj = {
  61. transform: `scale(${scale}) translate(${ox}${offsetUnit},${oy}${offsetUnit})`,
  62. objectFit,
  63. transformOrigin: "center",
  64. width: "100%",
  65. height: "100%"
  66. }
  67. if (value.matrix) {
  68. styleObj.transform = value.matrix;
  69. styleObj.transformOrigin = "0 0";
  70. styleObj.width = value.w + "px";
  71. styleObj.height = value.h + "px";
  72. }
  73. return (
  74. <View
  75. compId={props.compId}
  76. onDblclick={store.isEditMode ? changeVal : undefined}
  77. onClick={() => {
  78. if (value.showLink && value.link && !store.isEditMode) {
  79. window.location.href = value.link;
  80. } else {
  81. actions.previewImage(value.url, store.previewImageList);
  82. }
  83. }}
  84. editlayer={props.editlayer}
  85. >
  86. <div class={["w-1/1 h-1/1 object-cover pointer-events-none overflow-hidden", isCropping && cropingBorder]} >
  87. <img
  88. crossorigin="anonymous"
  89. class={"w-1/1 h-1/1 object-cover"}
  90. style={styleObj as any}
  91. src={
  92. value.url.startsWith("data:image/png")
  93. ? value.url
  94. : value.url + "?editMode=" + store.isEditMode
  95. }
  96. />
  97. </div>
  98. </View>
  99. );
  100. };
  101. },
  102. });
  103. const cropingBorder = css`
  104. border: 1px solid orange;
  105. `