| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965 |
- // index.js
- // 获取应用实例
- import {
- VueLikePage
- } from "../../utils/page";
- import {
- CDN_URL,
- API_BASE_URL,
- VIDEO_BASE_URL,
- app
- } from "../../config/index";
- VueLikePage([], {
- data: {
- cdn_url: "",
- baseUrl: API_BASE_URL + "/",
- url_link: "",
- id: "1",
- type: "",
- loadCompele: false,
- filePath: "",
- projectid: '',
- isEditing: false,
- info: {
- resourceImg: {},
- banner: {},
- sceneTitleImg: {},
- recordTitleImg: {},
- rescan: {},
- activeSceneBdImg: {},
- },
- isZoom: false,
- ipsImgList: [],
- selectedIp: null,
- selectedIpIndex: -1,
- ipScaleX: 1,
- ipScaleY: 1,
- ipRotate: 0,
- ipConfirmed: false,
- ipLeft: 0,
- ipTop: 0,
- positionInitialized: false,
- canvasWidth: 375,
- canvasHeight: 600,
- widgetVisible: true,
- zoomScrollLeft: 0,
- scaleOrientation: '',
- baseUniformScale: 1,
- confirmedIps: [],
- // 1:贴纸,2:标题,3:日期
- tabIndex: 1,
- rgb: 'rgba(13, 121, 217, 1)', //初始值
- rgbIndex: 1, //0,1,2,3
- pick: false,
- titleDatas: [],
- title: '',
- //日期
- pickerValue: [0, 0, 0], // 年、月、日的选中索引
- years: [], // 年份数组
- months: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12], // 月份数组
- days: [], // 日期数组(根据年月动态生成)
- selectedDate: '' // 最终选中的日期
- },
- methods: {
- selectConfirm(e){
- this.confirmIp()
- // 拿到item,从confirmedIps去掉当前item
- const selectedItem = e.currentTarget.dataset.item
- console.log(selectedItem)
- this.setData({
- confirmedIps:this.data.confirmedIps.filter(i=>i.id!==selectedItem.id),
- // 再重新还原到选中状态 设置
- selectedIp: selectedItem.selectedIp,
- selectedIpIndex: selectedItem.selectedIpIndex,
- tabIndex: selectedItem.typeIndex, // 判断是贴图还是标题还是日期
- rgb: selectedItem.rgb,
- imgUrl:selectedItem.typeIndex==1? selectedItem?.imgUrl:'',
- title: selectedItem.typeIndex==2?selectedItem?.title:'',
- date: selectedItem.typeIndex==3?selectedItem?.date:'',
- ipScaleX: selectedItem.scaleX,
- ipScaleY: selectedItem.scaleY,
- ipRotate: selectedItem.rotate,
- ipLeft: selectedItem.left,
- ipTop: selectedItem.top,
- positionInitialized:true
- })
- // console.log(this.data)
- },
- loadDate() {
- const now = new Date();
- const currentYear = now.getFullYear();
- const years = [];
- for (let i = currentYear - 10; i <= currentYear + 10; i++) {
- years.push(i);
- }
- this.setData({
- years
- });
- // 2. 初始化当前日期(默认选中今天)
- const currentMonth = now.getMonth() + 1; // 月份从0开始,需+1
- const currentDay = now.getDate();
- // 计算当前年/月/日在数组中的索引
- const yearIndex = years.indexOf(currentYear);
- const monthIndex = currentMonth - 1;
- // 初始化日期数组(根据当前年月)
- this.setDays(currentYear, currentMonth);
- // 设置默认选中值
- this.setData({
- pickerValue: [yearIndex, monthIndex, currentDay - 1],
- selectedDate: `${currentYear}-${this.formatNum(currentMonth)}-${this.formatNum(currentDay)}`
- });
- },
- // 格式化数字(补0,比如1→01)
- formatNum(num) {
- return num < 10 ? `0${num}` : num;
- },
- // 根据年、月动态生成日期数组(处理2月、小月/大月)
- setDays(year, month) {
- // 计算当月最后一天
- const lastDay = new Date(year, month, 0).getDate();
- const days = [];
- for (let i = 1; i <= lastDay; i++) {
- days.push(i);
- }
- this.setData({
- days
- });
- },
- // 日期选择器滚动变化时触发
- onDateChange(e) {
- const [yearIndex, monthIndex, dayIndex] = e.detail.value;
- const {
- years,
- months,
- days
- } = this.data;
- // 获取选中的年、月、日
- const selectedYear = years[yearIndex];
- const selectedMonth = months[monthIndex];
- const selectedDay = days[dayIndex];
- // 重新计算日期数组(防止切换年月后,日期超出当月范围,比如31号切到小月)
- this.setDays(selectedYear, selectedMonth);
- // 更新选中日期和picker值(日期索引可能变化,需重新校准)
- const newDayIndex = Math.min(dayIndex, this.data.days.length - 1);
- this.setData({
- pickerValue: [yearIndex, monthIndex, newDayIndex],
- selectedDate: `${selectedYear}-${this.formatNum(selectedMonth)}-${this.formatNum(this.data.days[newDayIndex])}`
- });
- },
- // 输入时实时更新
- onTitleInput(e) {
- this.setData({
- title: e.detail.value
- })
- console.log(123, this.data.title)
- },
- saveTitle(e) {
- const currentTitle = this.data.title.trim()
- // 防空判断
- if (!currentTitle) {
- wx.showToast({
- title: '请输入标题',
- icon: 'none'
- })
- return
- }
- // 追加
- this.setData({
- titleDatas: [...this.data.titleDatas, currentTitle],
- title: '',
- })
- this.selectIp(e)
- console.log(this.data.titleDatas)
- },
- // 显示取色器
- toPick: function () {
- this.setData({
- pick: !this.data.pick,
- rgbIndex:5
- })
- },
- //取色结果回调
- pickColor(e) {
- let rgb = e.detail.color;
- this.setData({
- rgb: rgb
- })
- },
- //设置颜色
- setColor(e) {
- let rgb = e.currentTarget.dataset.rgb;
- let index = e.currentTarget.dataset.index;
- console.log(rgb)
- this.setData({
- rgb: rgb,
- rgbIndex: index
- })
- },
- // 切换tab
- handleTabTap(e) {
- const index = e.currentTarget.dataset.index;
- console.log(index, '11111')
- this.setData({
- tabIndex: index
- }
- )
- },
- zoom() {
- this.setData({
- isZoom: !this.data.isZoom,
- selectedIp: null,
- selectedIpIndex: -1,
- ipScaleX: 1,
- ipScaleY: 1,
- ipRotate: 0,
- ipConfirmed: false,
- confirmedIps: [],
- zoomScrollLeft: 0
- });
- },
- onLoad: function (options) {
- let {
- rdw,
- id,
- type,
- projectid
- } = options;
- if (!projectid) {
- projectid = 'ZHS2409020-1';
- }
- this.initIpsList(projectid);
- this.getData(projectid);
- let link = "";
- if (type == "0") {
- link = `${VIDEO_BASE_URL}4dvedio/${rdw}.mp4`;
- } else {
- // link = `${VIDEO_BASE_URL}4dpic/${rdw}.jpg`;
- // test
- link = 'https://pic.616pic.com/phototwo/00/06/02/618e27a7290161785.jpg'
- this.loadDate()
- }
- this.setData({
- url_link: link,
- id,
- type,
- projectid,
- cdn_url: CDN_URL + "/" + projectid,
- });
- this.downloadF((data) => {
- this.setData({
- filePath: data,
- });
- });
- },
- initIpsList(projectid) {
- const list = [];
- for (let i = 1; i <= 34; i++) {
- list.push({
- name: String(i),
- imgUrl: `${CDN_URL}/${projectid}/ip/${i}.png`,
- });
- }
- this.setData({
- ipsImgList: list,
- });
- },
- loadcompele() {
- this.setData({
- loadCompele: true,
- });
- },
- cancel() {
- if (this.data.isEditing) {
- this.setData({
- isEditing: false,
- });
- } else {
- // wx.reLaunch({
- // url: "/pages/work/index",
- // });
- wx.navigateBack();
- }
- },
- edit() {
- this.setData({
- isEditing: !this.data.isEditing,
- });
- },
- _wrapText(ctx, text, maxWidth) {
- const chars = text.split('');
- const lines = [];
- let currentLine = '';
- for (let char of chars) {
- const testLine = currentLine + char;
- if (ctx.measureText(testLine).width <= maxWidth || currentLine === '') {
- currentLine = testLine;
- } else {
- lines.push(currentLine);
- currentLine = char;
- }
- }
- if (currentLine) lines.push(currentLine);
- return lines;
- },
- downloadF(cb = () => {}) {
- let link = this.data.url_link,
- m_type = "";
- if (this.data.type == "1") {
- m_type = "jpeg";
- } else {
- m_type = "video";
- }
- wx.downloadFile({
- url: link,
- success: (res) => {
- if (res.statusCode == "404") {
- return app.showAlert("作品暂未生成,请稍后再试", () => {
- wx.navigateBack();
- });
- }
- //判断是否为数组
- let typeType =
- Object.prototype.toString.call(res.header["Content-Type"]) ==
- "[object String]" ?
- res.header["Content-Type"] :
- res.header["Content-Type"][0];
- //判断不是xml文件
- if (typeType.indexOf(m_type) > -1) {
- cb(res.tempFilePath);
- }
- },
- fail: () => {
- app.showAlert("作品暂未生成,请稍后再试");
- },
- });
- this.setData({
- showModal: false,
- });
- },
- drawRoundRect(ctx, x, y, width, height, radius) {
- ctx.beginPath();
- // 左上圆角
- ctx.moveTo(x + radius, y);
- ctx.arcTo(x + width, y, x + width, y + height, radius);
- // 右上圆角
- ctx.arcTo(x + width, y + height, x, y + height, radius);
- // 右下圆角
- ctx.arcTo(x, y + height, x, y, radius);
- // 左下圆角
- ctx.arcTo(x, y, x + width, y, radius);
- ctx.closePath(); // 闭合路径
- },
- async generateImage() {
- wx.showLoading({
- title: '生成中...',
- mask: true
- });
- try {
- const query = wx.createSelectorQuery();
- query.select('.w_video').boundingClientRect();
- if (this.data.selectedIp) {
- query.select('.ip-overlay').boundingClientRect();
- }
- query.selectAll('.confirmed-overlay').boundingClientRect();
- const res = await new Promise(resolve => query.exec(resolve));
- const container = res[0];
- const overlay = this.data.selectedIp ? res[1] : null;
- const confirmedRects = this.data.selectedIp ? (res[2] || []) : (res[1] || []);
- if (!container) throw new Error('Cannot find container');
- let width = container.width;
- let height = container.height;
- if (this.data.isZoom) {
- const imgRes = await new Promise((resolve, reject) => {
- wx.getImageInfo({
- src: this.data.url_link,
- success: resolve,
- fail: reject
- })
- });
- width = imgRes.width;
- height = imgRes.height;
- }
- // Limit canvas size to avoid incomplete rendering on some devices
- const dpr = wx.getSystemInfoSync().pixelRatio;
- const maxCanvasSize = 4096;
- let scale = 1;
- if (width * dpr > maxCanvasSize || height * dpr > maxCanvasSize) {
- scale = Math.min(maxCanvasSize / (width * dpr), maxCanvasSize / (height * dpr));
- }
- const canvasWidth = width * scale;
- const canvasHeight = height * scale;
- await this._resetWidget(canvasWidth, canvasHeight);
- const widget = this.selectComponent('#widget');
- const mainUrl = this.data.url_link;
- let wxml = '';
- if (this.data.isZoom) {
- wxml = `
- <view class="container">
- <image class="main" src="${mainUrl}"></image>
- </view>
- `;
- } else {
- const bgUrl = this.data.info.resourceImg.bg ? (this.data.cdn_url + this.data.info.resourceImg.bg) : '';
- wxml = `
- <view class="container">
- <image class="bg" src="${bgUrl}"></image>
- ${(this.data.type != '0') ? `<image class="main" src="${mainUrl}"></image>` : ''}
- </view>
- `;
- }
- const style = {
- container: {
- width: canvasWidth,
- height: canvasHeight,
- position: 'relative',
- overflow: 'hidden'
- },
- bg: {
- width: canvasWidth,
- height: canvasHeight,
- position: 'absolute',
- left: 0,
- top: 0
- },
- main: {
- width: canvasWidth,
- height: canvasHeight,
- position: 'absolute',
- left: 0,
- top: 0
- }
- };
- const ctx = widget.ctx;
- const use2d = widget.data.use2dCanvas;
- const ratio = canvasWidth / container.width;
- await widget.renderToCanvas({
- wxml,
- style
- });
- // Draw confirmed overlays
- for (let i = 0; i < this.data.confirmedIps.length; i++) {
- const ov = this.data.confirmedIps[i];
- const rect = confirmedRects[i];
- if (!ov || !rect) continue;
- const cx = ((rect.left - container.left + rect.width / 2) + (this.data.isZoom ? this.data.zoomScrollLeft : 0)) * ratio;
- const cy = (rect.top - container.top + rect.height / 2) * ratio;
- const overlayWidth = rect.width * ratio;
- const overlayHeight = rect.height * ratio;
- // 贴纸
- console.log(ov)
- if (ov.typeIndex == 1) {
- const stickerInfo = await new Promise((resolve, reject) => {
- wx.getImageInfo({
- src: ov.imgUrl,
- success: resolve,
- fail: reject
- })
- });
- let imgToDraw = stickerInfo.path;
- if (use2d) {
- const canvas = widget.canvas;
- const img = canvas.createImage();
- await new Promise((resolve, reject) => {
- img.onload = resolve;
- img.onerror = reject;
- img.src = stickerInfo.path;
- });
- imgToDraw = img;
- }
- ctx.save();
- ctx.translate(cx, cy);
- ctx.rotate(ov.rotate * Math.PI / 180);
- ctx.scale(ov.scaleX, ov.scaleY);
- ctx.drawImage(imgToDraw, -overlayWidth / 2, -overlayHeight / 2, overlayWidth, overlayHeight);
- ctx.restore();
- } else if (ov.typeIndex == 2 || ov.typeIndex == 3) {
- const text = ov.typeIndex == 2 ? ov.title.trim() : ov.date.trim();
- if (!text) continue;
- console.log(text)
- ctx.save();
- ctx.translate(cx, cy);
- ctx.rotate((ov.rotate || 0) * Math.PI / 180);
- ctx.scale(ov.scaleX || 1, ov.scaleY || 1);
- // ── 参数定义 ──
- const fontSizeRpx = 40;
- const fontSizePx = fontSizeRpx * ratio * (container.width / 750);
- const maxWidth = canvasWidth;
- const minWidth = 80 * ratio;
- const minHeight = 45 * ratio;
- const lineHeight = 30;
- const paddingRpx = 10;
- const padding = paddingRpx * ratio;
- const borderRadius = 40 * ratio;
- ctx.font = ` ${fontSizePx}px cexwz`;
- ctx.fillStyle = ov.rgb || '#000000';
- ctx.textAlign = 'center';
- ctx.textBaseline = 'middle';
- // 计算换行
- let lines = [text];
- let textWidth = ctx.measureText(text).width;
- if (textWidth > maxWidth) {
- lines = this._wrapText(ctx, text, maxWidth);
- textWidth = Math.max(...lines.map(line => ctx.measureText(line).width));
- }
- // 应用 min-width
- const contentWidth = Math.max(textWidth, minWidth);
- // 计算总内容高度(文字行高总和)
- const contentHeight = lines.length * lineHeight;
- // 最终容器高度(文字高度 + 上下 padding + min-height)
- const finalHeight = Math.max(contentHeight + padding, minHeight);
- console.log(minHeight)
- // 最终容器宽度(文字宽度 + 左右 padding)
- const finalWidth = contentWidth + padding * 2;
- // 绘制圆角矩形背景
- ctx.fillStyle = 'rgba(255, 255, 255, 0.70)';
- ctx.beginPath();
- this.drawRoundRect(
- ctx,
- -finalWidth / 2,
- -finalHeight / 2,
- finalWidth,
- finalHeight,
- 20 // 圆角半径
- );
- ctx.fill();
- // ── 绘制文字(在背景之上) ──
- ctx.fillStyle = ov.rgb || '#000000'; // 恢复文字颜色
- let yOffset = -contentHeight / 2 + lineHeight / 2; // 文字从容器中间开始
- for (const line of lines) {
- ctx.fillText(line, 0, yOffset);
- yOffset += lineHeight;
- }
- ctx.restore();
- }
- if (!use2d) {
- await new Promise(resolve => ctx.draw(true, resolve));
- }
- }
- // Draw active overlay if exists
- if (this.data.selectedIp && overlay) {
- const stickerUrl = this.data.selectedIp.imgUrl;
- const stickerInfo = await new Promise((resolve, reject) => {
- wx.getImageInfo({
- src: stickerUrl,
- success: resolve,
- fail: reject
- })
- });
- let imgToDraw = stickerInfo.path;
- if (use2d) {
- const canvas = widget.canvas;
- const img = canvas.createImage();
- await new Promise((resolve, reject) => {
- img.onload = resolve;
- img.onerror = reject;
- img.src = stickerInfo.path;
- });
- imgToDraw = img;
- }
- const cx = ((overlay.left - container.left + overlay.width / 2) + (this.data.isZoom ? this.data.zoomScrollLeft : 0)) * ratio;
- const cy = (overlay.top - container.top + overlay.height / 2) * ratio;
- const overlayWidth = overlay.width * ratio;
- const overlayHeight = overlay.height * ratio;
- ctx.save();
- ctx.translate(cx, cy);
- ctx.rotate(this.data.ipRotate * Math.PI / 180);
- ctx.scale(this.data.ipScaleX, this.data.ipScaleY);
- ctx.drawImage(imgToDraw, -overlayWidth / 2, -overlayHeight / 2, overlayWidth, overlayHeight);
- ctx.restore();
- if (!use2d) {
- await new Promise(resolve => ctx.draw(true, resolve));
- }
- }
- const {
- tempFilePath
- } = await widget.canvasToTempFilePath();
- // Save
- wx.saveImageToPhotosAlbum({
- filePath: tempFilePath,
- success: () => {
- wx.showModal({
- title: "提示",
- content: "已保存到相册,快去分享吧",
- showCancel: false,
- });
- },
- fail: (e) => {
- if (!(e.errMsg.indexOf("cancel") > -1)) {
- wx.showModal({
- title: "提示",
- content: "保存失败,请检查是否开启相册保存权限",
- showCancel: false,
- });
- }
- }
- });
- } catch (e) {
- console.error(e);
- wx.showToast({
- title: '生成失败',
- icon: 'none'
- });
- } finally {
- wx.hideLoading();
- }
- },
- async _resetWidget(width, height) {
- this.setData({
- widgetVisible: false
- });
- await new Promise(r => setTimeout(r, 50));
- this.setData({
- canvasWidth: width,
- canvasHeight: height,
- widgetVisible: true
- });
- await new Promise(r => setTimeout(r, 120));
- },
- onZoomScroll(e) {
- this.setData({
- zoomScrollLeft: e.detail.scrollLeft || 0
- });
- },
- saveAlbum() {
- let type = this.data.type;
- if (this.data.projectid == 'ZHS2409020-1' && type !== '0') {
- if (this.data.selectedIp && !this.data.ipConfirmed) {
- wx.showToast({
- title: '请先确认标签',
- icon: 'none'
- })
- return;
- }
- this.generateImage();
- return;
- }
- wx.showLoading({
- title: "保存中…",
- mask: true,
- });
- if (this.data.filePath) {
- let api =
- type == "0" ? "saveVideoToPhotosAlbum" : "saveImageToPhotosAlbum";
- wx[api]({
- filePath: this.data.filePath,
- success() {
- wx.showModal({
- title: "提示",
- content: "已保存到相册,快去分享吧",
- showCancel: false,
- });
- },
- fail: (e) => {
- if (!(e.errMsg.indexOf("cancel") > -1)) {
- wx.showModal({
- title: "提示",
- content: "保存失败,请检查是否开启相册保存权限,可在「右上角」 - 「设置」里查看",
- showCancel: false,
- });
- }
- },
- complete: () => {
- wx.hideLoading();
- },
- });
- }
- },
- // 横琴是ZHS2409020-1,替换 ZHS2305758-1
- getData(prjId = "ZHS2305758-1") {
- wx.showLoading({
- title: "资源加载中",
- });
- this.setData({
- cdn_url: CDN_URL + "/" + prjId,
- });
- wx.request({
- url: `${VIDEO_BASE_URL}project/4dage-sxb/${prjId}/config.json`,
- success: ({
- data: {
- title,
- ...rest
- }
- }) => {
- this.setData({
- info: rest,
- },
- () => {
- wx.hideLoading();
- }
- );
- wx.setNavigationBarTitle({
- title: title,
- });
- },
- });
- },
- selectIp(e) {
-
- const index = e.currentTarget.dataset.index ;
- const item = this.data.ipsImgList[index];
- console.log(index,item)
- // 这里日期和标题选择的index都没用,但是也需要传,相当于限制了添加上限为ips数组长度
- if (!item) return;
- if (this.data.selectedIp && !this.data.ipConfirmed) {
- this.setData({
- selectedIpIndex: index,
- selectedIp: item
- });
- } else {
- this.setData({
- selectedIpIndex: index,
- selectedIp: item,
- ipScaleX: 1,
- ipScaleY: 1,
- ipRotate: 0,
- ipConfirmed: false,
- positionInitialized: false,
- }, () => {
- this.getOverlayRect();
- const query = wx.createSelectorQuery();
- query.select('.w_video').boundingClientRect();
- query.select('.ip-overlay').boundingClientRect();
- query.exec((res) => {
- const container = res[0];
- const overlay = res[1];
- console.log(container, overlay, 'index')
- if (container && overlay) {
- this.setData({
- ipLeft: overlay.left - container.left,
- ipTop: overlay.top - container.top,
- positionInitialized: true
- });
- }
- });
- });
- }
- },
- dragStart(e) {
- if (this.data.ipConfirmed) return;
- const touch = e.touches[0];
- this.setData({
- dragStartX: touch.clientX,
- dragStartY: touch.clientY,
- startIpLeft: this.data.ipLeft,
- startIpTop: this.data.ipTop
- });
- },
- dragMove(e) {
- if (this.data.ipConfirmed) return;
- const touch = e.touches[0];
- const dx = touch.clientX - this.data.dragStartX;
- const dy = touch.clientY - this.data.dragStartY;
- this.setData({
- ipLeft: this.data.startIpLeft + dx,
- ipTop: this.data.startIpTop + dy
- });
- },
- getOverlayRect() {
- const query = wx.createSelectorQuery();
- query.select('.ip-overlay').boundingClientRect(rect => {
- if (rect) {
- this.setData({
- centerX: rect.left + rect.width / 2,
- centerY: rect.top + rect.height / 2
- });
- }
- }).exec();
- },
- rotateStart(e) {
- this.getOverlayRect();
- const touch = e.touches[0];
- const dx = touch.clientX - this.data.centerX;
- const dy = touch.clientY - this.data.centerY;
- const startAngle = Math.atan2(dy, dx) * 180 / Math.PI;
- this.setData({
- startRotateAngle: startAngle,
- baseIpRotate: this.data.ipRotate
- });
- },
- rotateMove(e) {
- const touch = e.touches[0];
- const dx = touch.clientX - this.data.centerX;
- const dy = touch.clientY - this.data.centerY;
- const currentAngle = Math.atan2(dy, dx) * 180 / Math.PI;
- const diff = currentAngle - this.data.startRotateAngle;
- let nextRotate = this.data.baseIpRotate + diff;
- this.setData({
- ipRotate: nextRotate
- });
- },
- scaleStart(e) {
- const touch = e.touches[0];
- this.setData({
- startX: touch.clientX,
- startY: touch.clientY,
- baseUniformScale: (this.data.ipScaleX + this.data.ipScaleY) / 2
- });
- },
- scaleMove(e) {
- const touch = e.touches[0];
- const dy = touch.clientY - this.data.startY;
- const factor = 0.005;
- let nextScale = this.data.baseUniformScale + (-dy) * factor;
- if (nextScale < 0.2) nextScale = 0.2;
- if (nextScale > 4) nextScale = 4;
- this.setData({
- ipScaleX: nextScale,
- ipScaleY: nextScale
- });
- },
- rotateIp() {
- // 兼容旧的点击事件,如果不需要可以删除,但保留也不会出错
- if (!this.data.selectedIp) return;
- const nextRotate = (this.data.ipRotate + 15) % 360;
- this.setData({
- ipRotate: nextRotate,
- });
- },
- scaleIp() {
- if (!this.data.selectedIp) return;
- let nextScaleX = this.data.ipScaleX + 0.25;
- let nextScaleY = this.data.ipScaleY + 0.25;
- if (nextScaleX > 2.5 || nextScaleY > 2.5) {
- nextScaleX = 1;
- nextScaleY = 1;
- }
- this.setData({
- ipScaleX: nextScaleX,
- ipScaleY: nextScaleY,
- });
- },
- deleteIp() {
- this.setData({
- selectedIp: null,
- selectedIpIndex: -1,
- ipScaleX: 1,
- ipScaleY: 1,
- ipRotate: 0,
- ipConfirmed: false,
- });
- },
- confirmIp() {
-
- if (!this.data.selectedIp) return;
- const overlayItem = {
- typeIndex: this.data.tabIndex, // 判断是贴图还是标题还是日期
- id: Date.now(),
- rgb: this.data.rgb,
- imgUrl: this.data.selectedIp.imgUrl,
- title: this.data.titleDatas[this.data.titleDatas.length - 1],
- date: this.data.selectedDate,
- scaleX: this.data.ipScaleX,
- scaleY: this.data.ipScaleY,
- rotate: this.data.ipRotate,
- left: this.data.ipLeft,
- top: this.data.ipTop,
- selectedIp:this.data.selectedIp,
- selectedIpIndex:this.data.selectedIpIndex
- };
- this.setData({
- confirmedIps: [...this.data.confirmedIps, overlayItem],
- selectedIp: null,
- selectedIpIndex: -1,
- ipScaleX: 1,
- ipScaleY: 1,
- ipRotate: 0,
- ipConfirmed: false,
- positionInitialized: false
- });
- },
- },
- });
|