| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002 |
- <template>
- <view class="box">
-
- <view class="zdyNavBox">
- <view class="status_bar" :style="{height: iStatusBarHeight + 'px'}"></view>
- <view class="zdyNav">
- <!-- <view class="zdyNavLeft">
- <div @click="goback" class="uni-page-head-btn"><i class="uni-btn-icon"
- style="color: rgb(0, 0, 0); font-size: 27px;"></i></div>
- </view>
- <view class="xx" style="position: absolute;left:100rpx;color: black;font-size: 23px;" @click="goToSelectCarModel">X</view> -->
- <view class="zdyNavLeft">
- <div @click="goback" class="uni-page-head-btn"><i class="uni-btn-icon"
- style="color: #333333; font-size: 27px;" ></i></div>
-
- </view>
- <view class="xx" style="margin-left: -70rpx;" @click="goToSelectCarModel">
- <image src="/static/img/group2.png" style="width: 27rpx;height: 27rpx;"></image>
- </view>
- <view class="tab-box" @click="changeIsShow()">
- <view class="title">{{chlildObj.title}}</view>
- <view class="sanjiao" v-if="isShowAll == 1">▲</view>
- <view class="sanjiao" :class="{shangjian:isShowAll == 0}" v-if="isShowAll == 0">▼</view>
- </view>
- <!-- <view class="zdyNavTitle" @click="changeIsShow()">
- <view class="title">{{chlildObj.title}}</view>
- <view class="sanjiao" v-if="isShowAll == 1">▲</view>
- <view class="sanjiao" v-if="isShowAll == 0">▼</view>
- </view> -->
- <view style="width: 120rpx;"></view>
-
- </view>
- <view class="title-box" v-if="isShowAll == 1" style="z-index: 999;">
- <view class="item" v-for="(item,index) in allChildrenObj" :key="index" @click="clickTitle(item)">
- <view class="item-image">
- <image :src="item.image" mode="aspectFit" style="width: 100%;height: 180rpx;"></image>
- </view>
- <view class="item-title" >
- {{item.title}}
- </view>
- </view>
- <view v-if="isShowAll == 1" style="height: 100vh;;z-index: 998;" @click="closeTitleTab()"></view>
- <view v-if="isShowAll == 1" style="height: 100vh;;z-index: 998;" @click="closeTitleTab()"></view>
- <view v-if="isShowAll == 1" style="height: 100vh;;z-index: 998;" @click="closeTitleTab()"></view>
- </view>
-
- </view>
-
- <view class="box-image-big" v-if="showType == 0">
- <view class="image-big">
- <image :src="chlildObj.image" mode="aspectFit" style="width: 100%;height: 80vh"></image>
- <canvas canvas-id="big-this-image" class="drawing-canvas" id="big-this-image" type="2d"
- @touchstart="handleTouchStartBig"
- @touchmove="handleTouchMoveBig"
- @touchend="handleTouchEndBig"></canvas>
- </view>
- <view class="box-btn">
- <view class="leftBtn" @click="getOther(-1)"><</view>
- <view class="rightBtn"@click="getOther(1)">></view>
- </view>
-
-
- </view>
- <view class="box-image-small" v-if="showType == 1" @tap="handleImageClick">
- <view class="small-image" >
- <image class="small-this-image" :src="chlildObj.image" mode="aspectFill" ></image>
- <!-- Canvas遮罩层 -->
- <canvas
- canvas-id="mask-canvas"
- class="mask-canvas"
- :style="{
- position: 'absolute',
- top: 0,
- left: 0,
- width: '100%',
- height: '100%',
- zIndex: 1,
- pointerEvents: 'none'
- }"
- ></canvas>
- </view>
- </view>
- <view class="box-jiantou">
- <view class="jian-span " :class="{'jian-down':isRotated}" @click="changeIsRotated()">》</view>
- </view>
- <view class="box-lab">
- <scroll-view scroll-x=true enable-flex=true show-scrollbar=false class="box-lab-scr" style="white-space: nowrap;height: 90rpx;" :scroll-into-view="scrollIntoId">
- <view class="lab-titles" :class="{'clickLab':labtitile==index}" :id="'item-' + index" @click="labTitile(item,index)" v-for="(item,index) in chlildObj.children" :key="index">
- {{item.title}}
- </view>
- </scroll-view>
-
- </view>
- <view class="lab-grid" v-if="showType == 1">
- <view class="lab-child" v-for="(item,index) in labChildObj" :key="index" @click="labChildClick(item)">
- <view class="lab-child-image">
- <image :src="item.image" mode="aspectFit" style="width: 160rpx;height: 150rpx;"></image>
- </view>
- <view class="lab-child-title">
- {{item.title}}
- </view>
- </view>
- </view>
-
-
- </view>
- </template>
- <script>
- export default {
- data() {
- return {
- toke:"",
- param:"",
- access_time:"",
- epc_id:"",
- brand_id:"",
- iStatusBarHeight: '',
- chlildObj:null,
- allChildrenObj:null,
- isShowAll:0,
- isRotated: false,
- labtitile: 0,
- labChildObj:null,
- showType:0, //0大图1小图
- ctxBig: null, //大画布
- pointsBig: [], // 存储所有点的坐标数组
- isDrawingBig: false, // 是否正在绘制的标志
- currentPathBig: [], // 当前路径的点数组
- ctxMask: null, //小画布
- pointsSmall: [], // 存储所有点的坐标数组
- isDrawingSmall: false, // 是否正在绘制的标志
- currentPathSmall: [], // 当前路径的点数组
- hitChild:[],//圈选中对象
- thisWidth: 0,//当前屏幕宽度
- scrollIntoId: '', //工东严肃定位
-
- specifiedAreas: [], //预定义位置
- unmaskAreas: [], // 已取消遮罩的区域
- unmaskSize: 80,
-
- brand_name:'',
- caption:'',
- vin:'',
- imageicon:'',
- modelname:'',
- isReturningFromChild: false,
- }
- },
- onLoad(opt) {
- this.iStatusBarHeight = uni.getSystemInfoSync().statusBarHeight;
- //当前对象
- this.chlildObj = uni.getStorageSync('epcChildren');
- //全部对象
- this.allChildrenObj = uni.getStorageSync('epcAllChildren');
- //当前详细
- this.labChildObj = this.chlildObj.children[this.labtitile].children;
- this.token = opt.token;
- this.param = opt.param;
- this.access_time = opt.access_time;
- this.epc_id = opt.epc_id;
- this.brand_id = opt.brand_id;
- this.brand_name = opt.brand_name;
- this.caption = opt.caption;
- this.vin = opt.vin;
- this.imageicon = opt.imageicon;
- this.modelname = opt.modelname;
- this.getSmileDate();
- this.initCanvas();
- },
- // onReady(){
- // this.initCanvas();
-
- // },
- // onShow() {
-
- // },
- methods: {
- goback() {
- uni.navigateBack({})
- },
- //返回选品牌
- goToSelectCarModel(){
- let vin = this.vin;
- if(vin ==undefined || vin =='' ||vin == 'undefined' ){
- uni.navigateTo({url:'SelectCarModel'});
- }else{
- uni.navigateTo({url:'index'});
- }
- },
- //标题title点击事件
- changeIsShow(){
- this.isShowAll = this.isShowAll == 0 ? 1 : 0;
- },
- //上下箭头点击事件
- changeIsRotated(){
- this.isRotated = !this.isRotated;
- this.showType = this.isRotated ? 1:0;
-
- if (this.showType == 1) {
- this.$nextTick(() => {
- this.initSpecifiedAreasPush();
- });
- }else{
- this.clearUnmaskAreas()
- }
- },
- //左右按钮点击
- getOther(typeNum){
- //获取顺序
- let index = 0;
- for (var i = 0; i < this.allChildrenObj.length; i++) {
- let item = this.allChildrenObj[i]
- if (item.id == this.chlildObj.id){
- index = i;
- }
- }
- if(typeNum ==-1){
- index = index-1 < 0 ? this.allChildrenObj.length-1 : index-1 ;
- }else{
- index = index+1 > this.allChildrenObj.length-1 ? 0 : index+1 ;
- }
- this.chlildObj = this.allChildrenObj[index];
- this.labChildObj = this.chlildObj.children[index].children;
-
- },
- //标题下拉图片点击
- clickTitle(item){
- this.chlildObj = item;
- this.isShowAll = 0;
- this.showType = 0;
- this.initCanvas();
- this.getSmileDate();
- this.initSpecifiedAreasPush();
- },
- //labtitiel的点击事件
- labTitile(item,index){
- this.showType = 1;
- this.isRotated = true;
- this.labtitile = index;
- this.labChildObj = this.chlildObj.children[this.labtitile].children;
- this.scrollIntoId = 'item-' + index;
- //set 小图坐标
- //this.specifiedAreasPush(item);
- //延时等待渲染效果
- setTimeout(()=>{
- this.initSpecifiedAreasPush();
- },100)
-
- },
- //下布局grid点击图片事件
- labChildClick(item){
-
- var that = this;
- console.log(item);
- let url = "/simpleEpc/getCustomDetail";
- let data = {
- brand_id : this.brand_id,
- epc_id : this.epc_id,
- custom_id : item.id,
- token : this.token,
- access_time : this.access_time,
- param : this.param,
- vin:''
-
- };
- // let data = {
- // brand_id : this.brand_id,
- // epc_id : this.epc_id,
- // pid:item.id
-
- // };
- let res = this.textJieKou(url,data);
- res.then(response =>{
- let number = response.data.number;
- if(number != 200 ){
- uni.navigateTo({
- url: 'SimpleOemSearch?brand=' + undefined + '&token=' + this.token + '¶m=' +
- this.param + '&access_time=' + this.access_time + '&title=' + item.title+'&epc_id='+this.epc_id+"&brand_name="+this.brand_name
- +"&caption="+this.caption
- })
- return;
- }
-
- let data = response.data.result.data.list;
- if(data.length > 1){//跳子组页
- uni.navigateTo({
- url: 'modelTwoSimple?brand=' + undefined + '&token=' + this.token + '¶m=' +
- this.param + '&zzTime=' + this.access_time + '&title=' + item.title+'&epc_id='+this.epc_id+"&brand_name="+this.brand_name
- +"&caption="+this.caption
- })
- }else if(data.length == 1){//跳配件展示页
- uni.navigateTo({
- url: 'vinDetail?brand=' + undefined + '&token=' + data[0].token + '¶m=' +
- data[0].param + '&access_time=' + response.data.result.data.access_time + '&title=' + item.title+'&epc_id='+this.epc_id+"&brand_name="+this.brand_name
- +"&tabIndex=0"
- })
- }
- })
-
-
- },
- //关闭title 下拉
- closeTitleTab(){
- this.isShowAll = 0;
- },
- //初始化画布
- initCanvas(){
- console.log("画布初始化");
- this.ctxBig = uni.createCanvasContext('big-this-image',this);
- //this.ctxSmall = uni.createCanvasContext('small-this-image',this);
-
- this.ctxMask = uni.createCanvasContext('mask-canvas', this);
-
- // 设置线条颜色
- this.ctxBig.setStrokeStyle("red");
- // 设置线宽
- this.ctxBig.setLineWidth(5);
- // 设置线条末端为圆形
- this.ctxBig.setLineCap("round");
- // 设置线条连接处为圆形
- this.ctxBig.setLineJoin("round");
- this.ctxBig.setLineDash([]); // 确保不是虚线
- // 设置更高的绘制质量
- this.ctxBig.setGlobalAlpha(1);
- this.ctxBig.setShadow(0, 0, 0, 'transparent'); // 清除阴影避免性能问题
-
-
- this.drawFullMask();
- },
- //小图遮罩初始化显示 正前
- initSpecifiedAreasPush(){
- let id = 0;
- //获取这是第几个labtitle
- const element = document.querySelector('.clickLab');
- if (element) {
- id = element.id.split("-")[1];
- }
-
- let tetxx = this.chlildObj.children[id].title;
- let isAreas = {"title":tetxx};
- this.specifiedAreasPush(isAreas);
- },
- // 处理触摸开始事件
- handleTouchStartBig(e) {
- // 获取触摸点的x,y坐标
- const x = e.touches[0].x;
- const y = e.touches[0].y;
-
- // 设置正在绘制标志
- this.isDrawingBig = true;
- // 初始化当前路径数组,并添加第一个点
- this.currentPathBig = [{x, y}];
-
- // 开始新路径
- this.ctxBig.beginPath();
- // 移动画笔到起始点
- this.ctxBig.moveTo(x, y);
- },
- // 处理触摸移动事件
- handleTouchMoveBig(e) {
- // 如果不是绘制状态则返回
- if (!this.isDrawingBig) return;
-
- // 获取当前触摸点的坐标
- const x = e.touches[0].x;
- const y = e.touches[0].y;
-
- // 将当前点添加到当前路径数组
- this.currentPathBig.push({x, y});
-
- // 当有足够点数时使用贝塞尔曲线
- if (this.currentPathBig.length >= 3) {
- this.drawSmoothLine();
- } else {
- this.drawStraightLine();
- }
- },
- // 绘制平滑曲线
- drawSmoothLine() {
- const points = this.currentPathBig;
- const len = points.length;
-
- if (len < 3) return;
-
- this.ctxBig.beginPath();
- this.ctxBig.moveTo(points[0].x, points[0].y);
-
- // 使用二次贝塞尔曲线平滑连接
- for (let i = 1; i < len - 2; i++) {
- const controlX = (points[i].x + points[i + 1].x) / 2;
- const controlY = (points[i].y + points[i + 1].y) / 2;
- this.ctxBig.quadraticCurveTo(points[i].x, points[i].y, controlX, controlY);
- }
-
- // 处理最后两个点
- if (len >= 3) {
- this.ctxBig.quadraticCurveTo(
- points[len - 2].x,
- points[len - 2].y,
- points[len - 1].x,
- points[len - 1].y
- );
- }
-
- this.ctxBig.stroke();
- this.ctxBig.draw(true);
- },
-
- // 绘制直线(点数不足时)
- drawStraightLine() {
- if (this.currentPathBig.length < 2) return;
-
- this.ctxBig.beginPath();
- this.ctxBig.moveTo(this.currentPathBig[0].x, this.currentPathBig[0].y);
- this.ctxBig.lineTo(this.currentPathBig[1].x, this.currentPathBig[1].y);
- this.ctxBig.stroke();
- this.ctxBig.draw(true);
- },
- // 处理触摸结束事件
- handleTouchEndBig() {
- // 如果不是绘制状态则返回
- if (!this.isDrawingBig) return;
-
- // 将当前路径的所有点合并到总点数组中
- this.pointsBig = [...this.pointsBig, ...this.currentPathBig];
- // 清空当前路径
- //this.currentPathBig = [];
- // 重置绘制状态
- this.isDrawingBig = false;
- //清空圈选对象
- this.hitChild = [];
- setTimeout(()=>{
- const width = this.ctxBig.width || 1024; // 如果没有设置width属性,使用默认值
- const height = this.ctxBig.height || 1024;
- this.ctxBig.clearRect(0,0,width,height);
- this.ctxBig.draw(true);
- this.isDrawingBig = true;
- this.toDetailByCanvas();
- },400)
- },
- //筛选圈选的位置
- toDetailByCanvas(){
- //坐标集合
- let zuobiao = this.currentPathBig,
- //当前对象
- chlildObj = this.labChildObj;
- //击中对象
- const oneSet = new Set();
- let isgo =false;
- zuobiao.forEach(x =>{
- //判断当前坐标是否在当前位置
- this.ifClickObj(x.x,x.y);
- //判断是否跳转
- if(this.isGoTwo()){
- //跳转
- uni.removeStorageSync('epcChildrenTwo');
- uni.setStorageSync('epcChildrenTwo', this.hitChild);
- isgo =true;
- }
- })
- if(isgo){
- uni.navigateTo({
- url: 'epcSimpleDetailTwo?token='+this.token+'¶m='+this.param+'&access_time='+this.access_time+'&epc_id='+this.epc_id+"&title="+this.chlildObj.title
- +'&brand_id='+this.brand_id+"&brand_name="+this.brand_name+"&caption="+this.caption+"&vin="+this.vin
- })
- }
- },
- isGoTwo(){
- if (this.hitChild.length === 0) {
- return false;
- } else {
- return this.hitChild.some(x => x.children.length > 0);
- }
- },
- /**
- * @param {Object} x
- * @param {Object} y
- * 要遍历多次,第一次为外面的大类确定
- * 第二次为大类里面的包含的小件
- */
- //根据坐标判断是否击中集合
- ifClickObj(x,y){
-
- let isDelete = 0;
- let chlildObj = this.chlildObj; //顶级对象
- this.thisWidth = uni.getSystemInfoSync().screenWidth;
- chlildObj.children.forEach(item => {
- let item_width = item.width,
- item_top = item.top,
- item_left = item.left,
- item_height = item.height,
- image_width = chlildObj.width,
- image_height = chlildObj.height;
-
- //计算实际坐标
- let x1 = 0,//x头
- x2 = 0,//x尾
- y1 = 0,//y头
- y2 = 0;//y尾
- x1 = this.pxToX(item_left,image_width);
- x2 = x1+this.pxToX(item_width,image_width);
- y1 =this.pxToY(item_top,image_width,image_height);
- y2 = y1+this.pxToY(item_height,image_width,image_height);
- //命中父级组件
- if(x>x1 && x<x2 && y>y1 && y<y2){
- let childrenParent = this.hitChild.find(x1 => x1.title === item.title);
- if(childrenParent==undefined || childrenParent.length == "" ){
- childrenParent = {
- "id":item.id,
- "children":[],
- "image":item.image,
- "pid":item.pid,
- "title":item.title,
- "is_visible":item.is_visible,
- "height":item.height,
- "top":item.top,
- "left":item.left,
- "width":item.width
- };
- this.hitChild.push(childrenParent);
- }
-
- //判断命中小组建
- item.children.forEach(childItem =>{
- let child_width = childItem.width,
- child_top = childItem.top,
- child_left = childItem.left,
- child_height = childItem.height,
- child_x = 0,
- child_x2 = 0,
- child_y = 0,
- child_y2 = 0;
- child_x = this.pxToX(child_width,image_width);
- child_x2 = child_x+this.pxToX(child_width,image_width);
- child_y = this.pxToY(child_top,image_width,image_height);
- child_y2 = child_y+this.pxToY(child_height,image_width,image_height);
- //命中小组件
- if(x>child_x && x<child_x2 && y>child_y && y<child_y2){
- //判断是否存在
- let hitchilditem = childrenParent.children.find(mm => mm.title === childItem.title);
- if(hitchilditem == undefined || hitchilditem == ""){
- childrenParent.children.push(childItem);
- }
-
- }
- })
-
- }
- })
- },
- /**
- * 像素等比例转换X轴
- * @param {Object} px 标记像素
- * @param {Object} widch 图片宽度
- */
- pxToX(px,width){
- let pxx = Math.floor((px / width) * this.thisWidth);
- return pxx;
- },
- /**
- * 像素等比例转换Y轴
- * @param {Object} px 标记像素
- * @param {Object} height 图片高度
- */
- pxToY(px,width,height){
- //计算等比例高度
- const scaledHeight = (this.thisWidth / width) * height;
- let pxx = Math.floor(( px/ height) * scaledHeight);
- return pxx;
-
- },
-
- // 清除所有取消遮罩的区域
- getSmileDate(){
- this.chlildObj.children.forEach(item => {
- let chlildObj = this.chlildObj;
- let item_width = item.width,
- item_top = item.top,
- item_left = item.left,
- item_height = item.height,
- image_width = chlildObj.width,
- image_height = chlildObj.height;
- let x1 = 0,
- x2 = 0,
- y1 = 0,
- y2 = 0;
-
- let oldx = item_left,
- oldy = item_top,
- oldx2 = item_width*1,
- oldy2 = item_height*1;
-
- x1 = oldy*1;
- x2 = oldy*1 + oldy2*1;
- y1 = image_width*1 - oldx*1;
- y2 = image_width*1 - oldx*1 - oldx2*1;
-
- // y1 = item_left;
- // x1 = item_top;
- // y2 = item_left*1 + item_width*1;
- // x2 = item_top*1 + item_height*1;
-
- let zb1 = this.shuToHeng(image_width,image_height,x1,y1);
- let zb2 = this.shuToHeng(image_width,image_height,x2,y2);
- this.specifiedAreas.push({
- "x1":zb1.x,"y1":zb1.y,"x2":zb2.x,"y2":zb2.y,id:'area'+item.title
- })
- })
-
- },
- //push 取消遮罩
- specifiedAreasPush(item){
- let allAreas = this.specifiedAreas;
- //获取tab坐标
- let isAreas = allAreas.find(x => x.id == "area"+item.title);
- this.unmaskAreas = [];
- this.unmaskAreas.push({
- id: isAreas.id,
- x1: isAreas.x1,
- y1: isAreas.y1,
- x2: isAreas.x2,
- y2: isAreas.y2,
- radius: this.unmaskSize/2
- });
- // 重绘Canvas遮罩
- this.updateMaskCanvas();
- },
- //计算横置小图的坐标,竖坐标转化成横坐标,宽高也改变了
- /**
- * @param {Object} width 图片宽度
- * @param {Object} height 图片高度
- * @param {Object} x 坐标
- * @param {Object} y 坐标
- * @param {Object} thisWidth 当前屏幕宽度
- */
- shuToHeng(width,height,x,y){
- //转换后的宽度
- let thisWidth = uni.getSystemInfoSync().screenWidth;
- //选装的高度
- let thisHeight = (thisWidth / height) * width;
- //旋转后的y轴
- let pxy = Math.floor(( y/ width) * thisHeight);
- //旋转后的X轴
- let pxx = Math.floor((x / height) * thisWidth);
- return {"x":pxx,"y":pxy};
- },
- //start
- handleImageClick(event) {
- const query = uni.createSelectorQuery().in(this);
- query.select('.small-image').boundingClientRect(data => {
- if (data) {
- const clickX = event.touches[0].clientX - data.left;
- const clickY = event.touches[0].clientY - data.top;
- // 检查是否点击在指定区域内
- const hitArea = this.checkClickInSpecifiedArea(clickX, clickY);
- if (hitArea) {
- // 如果点击在指定区域内,取消该区域遮罩
- this.addUnmaskArea(hitArea, clickX, clickY);
- }
- }
- }).exec();
-
- },
-
- // 检查点击是否在指定区域内
- checkClickInSpecifiedArea(clickX, clickY) {
-
- for (let area of this.specifiedAreas) {
- // 检查点击坐标是否在区域内
- if (clickX >= area.x1 &&
- clickX <= area.x2 &&
- clickY >= area.y2 &&
- clickY <= area.y1) {
- return area;
- }
- }
- return null;
- },
- // 添加取消遮罩区域
- addUnmaskArea(area, x, y) {
- const exists = this.unmaskAreas.some(item => item.id === area.id);
- if (!exists) {
- this.unmaskAreas = [];
- this.unmaskAreas.push({
- id: area.id,
- x1: area.x1,
- y1: area.y1,
- x2: area.x2,
- y2: area.y2,
- radius: this.unmaskSize/2
- });
- //lab标题获取焦点
- let childrenFor = this.chlildObj.children;
- let index = 0;
- for (var i = 0; i < childrenFor.length; i++) {
- let item = childrenFor[i];
- if(item.title == area.id.split("area")[1]){
- index = i;
- this.labTitile(item,i);
- }
- }
- }
- },
-
- // 更新Canvas遮罩
- updateMaskCanvas() {
-
- const ctx = this.ctxMask;
- // 1. 清除画布(动态获取尺寸)
- const { windowWidth, windowHeight } = uni.getSystemInfoSync();
- ctx.clearRect(0, 0, windowWidth, windowHeight);
-
- // 2. 绘制全屏半透明遮罩
- ctx.setFillStyle('rgba(255, 255, 255, 0.5)');
- ctx.fillRect(0, 0, windowWidth, windowHeight);
-
- // 3. 关键!设置合成模式为“擦除”
- ctx.globalCompositeOperation = 'destination-out';
- ctx.setFillStyle('rgba(0, 0, 0, 1)'); // 颜色不重要,alpha通道生效
-
- // 4. 绘制取消遮罩的区域(矩形示例)
- this.unmaskAreas.forEach(area => {
- ctx.beginPath();
- ctx.moveTo(area.x1, area.y1);
- ctx.lineTo(area.x2, area.y1);
- ctx.lineTo(area.x2, area.y2);
- ctx.lineTo(area.x1, area.y2);
- ctx.closePath();
- ctx.fill();
- });
-
- // 5. 恢复默认合成模式
- ctx.globalCompositeOperation = 'source-over';
-
- // 6. 提交绘制(微信小程序需调用 draw)
- ctx.draw(true); // 注意:微信小程序中需传 true 表示异步绘制
- },
- // 清除所有取消遮罩的区域
- clearUnmaskAreas() {
- this.unmaskAreas = [];
- const ctx = this.ctxMask;
- const { windowWidth, windowHeight } = uni.getSystemInfoSync();
- // 1. 清除画布(使用实际尺寸)
- ctx.clearRect(0, 0, windowWidth * 2, windowHeight * 2); // 考虑retina屏幕
- ctx.draw(false, () => {
- uni.hideLoading(); // 如果之前有loading可以隐藏
- });
- },
- // 绘制全屏遮罩
- drawFullMask() {
- const ctx = this.ctxMask;
-
- // 获取实际屏幕尺寸(更精确的方式)
- const { windowWidth, windowHeight } = uni.getSystemInfoSync();
- // 1. 清除画布(使用实际尺寸)
- ctx.clearRect(0, 0, windowWidth * 2, windowHeight * 2); // 考虑retina屏幕
- // 2. 绘制全屏遮罩
- ctx.setFillStyle('rgba(255, 255, 255, 0.5)');
- ctx.fillRect(0, 0, windowWidth * 2, windowHeight * 2);
- ctx.draw(false, () => {
- uni.hideLoading(); // 如果之前有loading可以隐藏
- });
- },
- //测试接口
- async textJieKou(url,data){
- let returnRes ;
- await this.$http(url,data, 'GET').then(res => {
- returnRes = res;
- console.log("方法内部返回:",res);
- });
-
- return returnRes;
- },
- }
- }
- </script>
- <style scoped>
-
- .zdyNavBox {
- width: 100vw;
- background: #FFFFFF;
- position: fixed;
- top: 0;
- left: 0;
- z-index: 9999999;
- }
- .zdyNav {
- display: flex;
- justify-content: space-between;
- align-items: center;
- padding: 14rpx 6rpx;
- }
-
- .zdyNavLeft {
- width: 120rpx;
- }
-
- .tab-box{
- width: 360rpx;
- display: flex;
- height: 65rpx;
- align-items: center;
- justify-content: center;
-
- }
-
- .zdyNavRight {
- background: #FFFFFF;
- text-align: center;
- font-size: 28rpx;
- color: #3F90F7;
- width: 120rpx;
- }
- .box{
-
- }
- .title{
- background: #FFFFFF;
- text-align: center;
- font-size: 32rpx;
- color: #1777FF;
- }
- .sanjiao{
- font-size: 14rpx;
- color: #1777FF;
- padding: 10rpx 0 0 8rpx;
- /* right: 42%;
- top: 40%; */
- }
- .shangjian{
- padding: 0rpx 0 0 8rpx;
- }
- .title-box{
- display: grid;
- grid-template-columns: repeat(3,1fr);
- gap: 5rpx;
- padding-bottom: 20rpx;
- .item{
-
- margin: 30rpx 10rpx;
- height: 220rpx;
- .item-image{
- border: solid 1rpx #999999;
- border-radius: 10rpx;
- padding-bottom: 10rpx;
- }
- .item-title{
- text-align: center;
- }
- }
-
- }
- .box-image-big{
- background: #ffffff;
- height: 80vh;
- .image-big{
- position: relative;
- width: 100%;
- height: 80vh;
- }
- .drawing-canvas {
- position: absolute;
- top: 0;
- left: 0;
- width: 100%;
- height: 100%;
- z-index: 10;
- }
- .box-btn{
- display: flex;
- justify-content: space-between;
- position: relative;
- top: -50%;
- z-index: 99999;
- .leftBtn{
- width: 40rpx;
- height: 100rpx;
- background: #999999;
- color: #ffffff;
- font-size: 35rpx;
- line-height: 100rpx;
- text-align: center;
- border-radius: 0 15rpx 15rpx 0;
- }
- .rightBtn{
- width: 40rpx;
- height: 100rpx;
- background: #999999;
- color: #ffffff;
- font-size: 35rpx;
- line-height: 100rpx;
- text-align: center;
- border-radius: 15rpx 0 0 15rpx;
- }
- }
- }
- .box-image-small{
- z-index: 999;
- .small-image{
- width: 100%;
- height: 420rpx;
- background: #ffffff;
- position: relative; /* 关键:为遮罩层提供定位基准 */
- .small-this-image{
- transform: rotate(-90deg);
- height: 750rpx;
- width: 420rpx;
- margin: -150rpx 165rpx;
- }
-
- }
- }
-
-
- .image-mask {
- position: absolute;
- top: 0;
- left: 0;
- width: 100%;
- height: 100%;
- background: rgba(255, 255, 255, 0.5);
- pointer-events: none;
- z-index: 1; /* 确保在取消区域之下 */
- }
- /* 双箭头核心实现 */
- .box-jiantou {
- background: #ffffff;
- text-align: center;
- margin-top: -5rpx;
- .jian-span{
- width: 20rpx;
- height: 40rpx;
- line-height: 40rpx;
- transform: rotate(-90deg);
- transform-origin: center;
- margin: 0 auto;
- color: #999;
-
- }
- .jian-down{
- transform: rotate(90deg);
- transform-origin: center;
- }
- }
- .box-lab{
- background: #ffffff;
- z-index: 999;
- }
- .box-lab-scr{
- .uni-scroll-view-content{
- display: flex;
- flex-direction: row;
- flex-wrap: nowrap;
- white-space: nowrap;
-
- }
- }
-
- .lab-titles{
- /* width: 130rpx !important; */
- /* min-width: 130rpx !important; */
- height: 60rpx;
- font-size: 35rpx;
- color: #999999;
- padding-left: 10rpx;
- margin: 10rpx;
- padding-right: 8rpx;
- text-align: center;
- }
- .clickLab{
- color: #1777FF;
- border-bottom: 4rpx solid #1777FF;
- }
- .lab-grid{
- display: grid;
- grid-template-columns: repeat(4,1fr);
- background: #ffffff;
- gap: 1rpx;
- .lab-child{
- margin: 10rpx;
- .lab-child-image{
- border: 1rpx solid #E2E2E2;
- border-radius: 14rpx;
- }
- .lab-child-title{
- text-align: center;
- font-size: 24rpx;
- }
- }
- }
-
-
-
- </style>
|