描述

内置生成透明背景图逻辑

脚本

  1. // 启发语录列表
  2. const textList = [
  3. '选我所爱,爱我所选。',
  4. '让改变适合你现在的生活和需要,而不是让你的生活和需要围绕着改变去进行。',
  5. '此生理想、近期规划、今日功课。',
  6. '流水不争先,争的是滔滔不绝。',
  7. '既往不恋,当下不杂,未来不迎。',
  8. ];
  9. /*-------上面是配置区域-------*/
  10. const fmLocal = FileManager.local();
  11. const basePath = fmLocal.documentsDirectory();
  12. const bgImgPath = basePath + "bgImg";
  13. const fixedIndexPath = basePath + "fixedIndex";
  14. // 创建小组件
  15. const widget = new ListWidget();
  16. if (config.runsInWidget) {
  17. createWidget();
  18. return;
  19. }
  20. let selectResult = await confirm("???", ["设置", "换一句", "忽略"]);
  21. if (selectResult === 0) {
  22. let selectResult = await confirm("设置什么?", [
  23. "背景图",
  24. "固定文本",
  25. "忽略",
  26. ]);
  27. if (selectResult === 0) {
  28. let selectResult = await confirm("请选择", [
  29. "选择背景图",
  30. "默认背景图",
  31. "透明背景图",
  32. "忽略",
  33. ]);
  34. if (selectResult === 0) {
  35. let img = await Photos.fromLibrary();
  36. fmLocal.writeImage(bgImgPath, img);
  37. widget.backgroundImage = img;
  38. }
  39. if (selectResult === 1) {
  40. const isExistBg = fmLocal.fileExists(bgImgPath);
  41. isExistBg && fmLocal.remove(bgImgPath);
  42. }
  43. if (selectResult === 2) {
  44. let message =
  45. "以下是【透明背景】生成步骤,如果你没有屏幕截图请退出,并返回主屏幕长按进入编辑模式。滑动到最右边的空白页截图。然后重新运行!";
  46. let exitOptions = ["继续(已有截图)", "退出(没有截图)"];
  47. let shouldExit = await confirm(message, exitOptions);
  48. if (shouldExit) return;
  49. let img = await Photos.fromLibrary();
  50. let height = img.size.height;
  51. let phone = phoneSizes()[height];
  52. if (!phone) {
  53. message =
  54. "您似乎选择了非iPhone屏幕截图的图像,或者不支持您的iPhone。请使用其他图像再试一次!";
  55. await confirm(message, ["好的!我现在去截图"]);
  56. return;
  57. }
  58. let crop = { w: phone.中号, h: phone.小号, x: phone.左边, y: phone.顶部 };
  59. // Crop image and finalize the widget.
  60. let imgCrop = cropImage(img, new Rect(crop.x, crop.y, crop.w, crop.h));
  61. message = "您的小部件背景已准备就绪,退出到桌面预览。";
  62. const resultOptions = ["好的"];
  63. await confirm(message, resultOptions);
  64. fmLocal.writeImage(bgImgPath, imgCrop);
  65. }
  66. }
  67. if (selectResult === 1) {
  68. let index = await confirm(
  69. "请选择",
  70. textList.map((item) => item.replace(/\s/gi, ""))
  71. );
  72. fmLocal.writeString(fixedIndexPath, String(index));
  73. }
  74. }
  75. if (selectResult === 1) {
  76. const isExistFixedIndex = fmLocal.fileExists(fixedIndexPath);
  77. isExistFixedIndex && fmLocal.remove(fixedIndexPath);
  78. }
  79. createWidget();
  80. // widget.presentMedium();
  81. // 创建桌面小组件
  82. function createWidget() {
  83. const isExistFixedIndex = fmLocal.fileExists(fixedIndexPath);
  84. let textItem;
  85. if (isExistFixedIndex) {
  86. const index = fmLocal.readString(fixedIndexPath);
  87. textItem = textList[Number(index)];
  88. } else {
  89. const index = Math.floor(Math.random() * textList.length);
  90. textItem = textList[index];
  91. }
  92. const bgImg = fmLocal.readImage(bgImgPath);
  93. if (!bgImg) {
  94. const gradient = new LinearGradient();
  95. gradient.locations = [0, 1];
  96. gradient.colors = [new Color("#333333"), new Color("#111111")];
  97. widget.backgroundGradient = gradient;
  98. } else {
  99. const bgImg = fmLocal.readImage(bgImgPath);
  100. widget.backgroundImage = bgImg;
  101. }
  102. let text;
  103. // 如果文本内容过长,通过给前后加换行实现文本自适应缩小的目的
  104. if (textItem.length >= 30) {
  105. textItem = `\n${textItem}\n`;
  106. }
  107. // 设置语录样式
  108. text = widget.addText(textItem);
  109. text.textColor = new Color("#ffffff");
  110. text.font = new Font("Georgia-BoldItalic", 26);
  111. text.minimumScaleFactor = 0.5;
  112. textItem.length > 12 ? text.leftAlignText() : text.centerAlignText();
  113. Script.setWidget(widget);
  114. }
  115. // 选择框
  116. async function confirm(message, options) {
  117. let alert = new Alert();
  118. alert.message = message;
  119. for (const option of options) {
  120. alert.addAction(option);
  121. }
  122. return await alert.presentAlert();
  123. }
  124. // Pixel sizes and positions for widgets on all supported phones.
  125. function phoneSizes() {
  126. let phones = {
  127. "2340": {
  128. // 12mini
  129. 小号: 436,
  130. 中号: 936,
  131. 大号: 980,
  132. 左边: 72,
  133. 右边: 570,
  134. 顶部: 212,
  135. 中间: 756,
  136. 底部: 1300,
  137. },
  138. "2532": {
  139. // 12/12 Pro
  140. 小号: 472,
  141. 中号: 1012,
  142. 大号: 1058,
  143. 左边: 78,
  144. 右边: 618,
  145. 顶部: 230,
  146. 中间: 818,
  147. 底部: 1408,
  148. },
  149. "2778": {
  150. // 12 Pro Max
  151. 小号: 518,
  152. 中号: 1114,
  153. 大号: 1162,
  154. 左边: 86,
  155. 右边: 678,
  156. 顶部: 252,
  157. 中间: 898,
  158. 底部: 1544,
  159. },
  160. "2688": {
  161. 小号: 507,
  162. 中号: 1080,
  163. 大号: 1137,
  164. 左边: 81,
  165. 右边: 654,
  166. 顶部: 228,
  167. 中间: 858,
  168. 底部: 1488,
  169. },
  170. "1792": {
  171. 小号: 338,
  172. 中号: 720,
  173. 大号: 758,
  174. 左边: 54,
  175. 右边: 436,
  176. 顶部: 160,
  177. 中间: 580,
  178. 底部: 1000,
  179. },
  180. "2436": {
  181. 小号: 465,
  182. 中号: 987,
  183. 大号: 1035,
  184. 左边: 69,
  185. 右边: 591,
  186. 顶部: 213,
  187. 中间: 783,
  188. 底部: 1353,
  189. },
  190. "2208": {
  191. 小号: 471,
  192. 中号: 1044,
  193. 大号: 1071,
  194. 左边: 99,
  195. 右边: 672,
  196. 顶部: 114,
  197. 中间: 696,
  198. 底部: 1278,
  199. },
  200. "1334": {
  201. 小号: 296,
  202. 中号: 642,
  203. 大号: 648,
  204. 左边: 54,
  205. 右边: 400,
  206. 顶部: 60,
  207. 中间: 412,
  208. 底部: 764,
  209. },
  210. "1136": {
  211. 小号: 282,
  212. 中号: 584,
  213. 大号: 622,
  214. 左边: 30,
  215. 右边: 332,
  216. 顶部: 59,
  217. 中间: 399,
  218. 底部: 399,
  219. },
  220. };
  221. return phones;
  222. }
  223. // Crop an image into the specified rect.
  224. function cropImage(img, rect) {
  225. let draw = new DrawContext();
  226. draw.size = new Size(rect.width, rect.height);
  227. draw.drawImageAtPoint(img, new Point(-rect.x, -rect.y));
  228. return draw.getImage();
  229. }

效果图

image.png