vue#ref JavaScript Examples

The following examples show how to use vue#ref. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: useClipboard.js    From ant-simple-pro with MIT License 6 votes vote down vote up
export function useClipboard() {
  const text = ref('')

  async function onCopy() {
    text.value = await navigator.clipboard.readText()
  }

  onMounted(() => {
    window.addEventListener('copy', onCopy)
  })

  onUnmounted(() => {
    window.removeEventListener('copy', onCopy)
  })

  function write(txt) {
    text.value = txt

    return navigator.clipboard.writeText(txt)
  }

  return {
    text,
    write
  }
}
Example #2
Source File: checkbox.js    From Ale with MIT License 6 votes vote down vote up
export function initData() {
  let selfModel = ref(false);
  let focus = ref(false);
  let isLimitExceeded = ref(false);
  return {
    selfModel,
    focus,
    isLimitExceeded
  };
}
Example #3
Source File: pagination.js    From Ale with MIT License 6 votes vote down vote up
function initData() {
  let internalCurrentPage = ref(1);
  let internalPageSize = ref(0);
  let lastEmittedPage = ref(-1);
  let userChangePageSize = ref(false);
  return {
    internalCurrentPage,
    internalPageSize,
    lastEmittedPage,
    userChangePageSize
  };
}
Example #4
Source File: main.js    From Ale with MIT License 6 votes vote down vote up
function initData() {
  let sizeWidth = ref('0');
  let sizeHeight = ref('0');
  let moveX = ref(0);
  let moveY = ref(0);
  return {
    sizeWidth,
    sizeHeight,
    moveX,
    moveY
  };
}
Example #5
Source File: app.js    From fes.js with MIT License 6 votes vote down vote up
layout = layoutConfig => ({
    ...layoutConfig,
    customHeader: <UserCenter />,
    menus: (defaultMenuData) => {
        const menusRef = ref(defaultMenuData);
        // watch(() => initialValue.initialState.userName, () => {
        //     menusRef.value = [{
        //         name: 'store'
        //     }];
        // });
        return menusRef;
    }
})
Example #6
Source File: request.js    From fes.js with MIT License 6 votes vote down vote up
useRequest = (url, data, options = {}) => {
    const loadingRef = ref(true);
    const errorRef = ref(null);
    const dataRef = ref(null);
    let promise;
    if (isPromiseLike(url)) {
        promise = url;
    } else {
        promise = request(url, data, options);
    }
    promise.then((res) => {
        dataRef.value = res;
    }).catch((error) => {
        errorRef.value = error;
    }).finally(() => {
        loadingRef.value = false;
    });
    return {
        loading: loadingRef,
        error: errorRef,
        data: dataRef
    };
}
Example #7
Source File: pluginAccess.js    From fes.js with MIT License 6 votes vote down vote up
hasAccessByMenuItem = (item) => {
    const hasChild = item.children && item.children.length;
    if (item.path && !hasChild) {
        return useAccess(item.path);
    }
    if (hasChild) {
        return computed(() => item.children.some((child) => {
            const rst = hasAccessByMenuItem(child);
            return rst && rst.value;
        }));
    }
    return ref(true);
}
Example #8
Source File: useMobile.js    From ant-simple-pro with MIT License 6 votes vote down vote up
export default function () {
  const mobile = ref(false)
  const onResize = () => {
    const val = isMobile()
    mobile.value = val
    store.commit('app/TOGGLE_SLIDE_BAR', val)
  }
  onResize()
  // onMounted(() => {
  //   window.addEventListener('resize', onResize)
  // })
  // onBeforeUnmount(() => {
  //   window.removeEventListener('resize', onResize)
  // })
  return mobile
}
Example #9
Source File: index.jsx    From ant-simple-pro with MIT License 6 votes vote down vote up
Counter = defineComponent({
  setup(props, { expose }) {
    const count = ref(0)
    expose({ count })

    function onClick() {
      count.value += 1
    }

    return () => {
      return (
        <div>
          <p>some contents...</p>
          <p>{count.value}</p>
          <a-button type="primary" onClick={onClick}>
            增加
          </a-button>
        </div>
      )
    }
  }
})
Example #10
Source File: index.js    From vue-json-schema-form with Apache License 2.0 6 votes vote down vote up
globalOptions = {
    WIDGET_MAP,
    COMPONENT_MAP: {
        form: defineComponent({
            inheritAttrs: false,
            setup(props, { attrs, slots }) {
                const formRef = ref(null);
                if (attrs.setFormRef) {
                    onMounted(() => {
                        attrs.setFormRef(formRef.value);
                    });
                }

                return () => {
                    // eslint-disable-next-line no-unused-vars
                    const { setFormRef, ...otherAttrs } = attrs;

                    return h(vueUtils.resolveComponent('el-form'), {
                        ref: formRef,
                        ...otherAttrs
                    }, slots);
                };
            }
        }),
        formItem: 'el-form-item',
        button: 'el-button',
        popover: 'el-popover'
    },
    HELPERS: {
        // 是否mini显示 description
        isMiniDes(formProps) {
            return formProps && ['left', 'right'].includes(formProps.labelPosition);
        }
    }
}
Example #11
Source File: useHotkeys.js    From ant-simple-pro with MIT License 5 votes vote down vote up
export function useHotkeys(keys, callback, options, deps) {
  if (Array.isArray(options)) {
    deps = options || []
    options = undefined
  }
  const elRef = ref()
  const {
    enableOnTags,
    filter,
    keyup,
    keydown,
    filterPreventDefault = true,
    enabled = true,
    enableOnContentEditable = false
  } = options || {}

  function keyHandler(keyboardEvent, hotkeysEvent) {
    if (filter && !filter(keyboardEvent)) {
      return !filterPreventDefault
    }

    // Check whether the hotkeys was triggered inside an input and that input is enabled or if it was triggered by a content editable tag and it is enabled.
    if (
      (isKeyboardEventTriggeredByInput(keyboardEvent) && !tagFilter(keyboardEvent, enableOnTags)) ||
      (keyboardEvent.target?.isContentEditable && !enableOnContentEditable)
    ) {
      return true
    }

    if (!elRef.value || document.activeElement === elRef.value) {
      callback(keyboardEvent, hotkeysEvent)
      return true
    }

    return false
  }

  function setHotKeys() {
    if (!enabled) {
      return
    }

    // In this case keydown is likely undefined, so we set it to false, since hotkeys needs the `keydown` key to have a value.
    if (keyup && keydown !== true) {
      options.keydown = false
    }

    hotkeys(keys, options || {}, keyHandler)
  }

  onMounted(() => {
    setHotKeys()
  })

  onUnmounted(() => {
    hotkeys.unbind(keys, keyHandler)
  })

  watch(deps ? deps.map(v => () => v) : [], () => { // eslint-disable-line
    setHotKeys()
  })

  watch([() => options, () => keys, () => enabled], () => {
    setHotKeys()
  })

  return elRef
}
Example #12
Source File: useEcharts.js    From ant-simple-pro with MIT License 5 votes vote down vote up
// import store from '@/store'

export function useEcharts(chartDOM, option) {
  const chartInstance = ref(null)

  watch(chartDOM, () => {
    renderChart() // eslint-disable-line
  })

  watch(option, () => {
    renderChart() // eslint-disable-line
  })

  onBeforeUnmount(() => {
    chartInstance.value && chartInstance.value.dispose()
  })

  function renderChart() {
    if (!chartDOM.value) {
      return
    }
    const renderedInstance = window.echarts.getInstanceByDom(chartDOM.value)
    if (renderedInstance) {
      chartInstance.value = renderedInstance
    } else {
      chartInstance.value = window.echarts.init(chartDOM.value)
    }
    if (!option.value) {
      return
    }
    chartInstance.value.setOption(option.value)
  }

  // let timer: number | null = null

  // watch(() => store.getters.collapsed, () => {
  //   timer = window.setTimeout(() => {
  //     onResize()
  //   }, 500)
  // })

  // onMounted(() => {
  //   window.addEventListener('resize', onResize)
  // })

  // onBeforeUnmount(() => {
  //   window.removeEventListener('resize', onResize)
  //   timer && clearTimeout(timer)
  // })

  // function onResize() {
  //   chartInstance && chartInstance.resize()
  // }

  return {
    chartInstance,
    renderChart
  }
}
Example #13
Source File: useSpeechRecognition.js    From javascript-mini-projects with The Unlicense 5 votes vote down vote up
export default function useSpeechRecognition() {
  const isListening = ref(false);
  const note = ref("");
  const error = ref(null);

  const handleListen = () => {
    if (isListening.value) {
      recognition.start();
    } else {
      recognition.stop();
    }
  };

  const toggleListening = () => {
    isListening.value = !isListening.value;
  };

  recognition.onresult = (event) => {
    const transcript = Array.from(event.results)
      .map((result) => result[0])
      .map((result) => result.transcript)
      .join("");

    note.value = transcript;
  };

  recognition.onerror = (event) => {
    error.value = event.error;
  };

  watch(isListening, () => {
    handleListen();
  });

  return {
    toggleListening,
    note,
    error
  };
}
Example #14
Source File: image-preview.jsx    From ant-simple-pro with MIT License 5 votes vote down vote up
function createInstance() {
  const comp = {
    setup() {
      const show = ref(false)
      let attrs = {}
      const open = opts => {
        show.value = true
        attrs = opts
      }

      const close = () => {
        show.value = false
      }

      const toggle = val => {
        show.value = val
      }

      const render = () => {
        attrs = {
          ...attrs,
          show: show.value,
          'onUpdate:show': toggle
        }

        return <ImageViewer {...attrs} />
      }

      // rewrite render function
      getCurrentInstance().render = render

      return {
        open,
        close
      }
    }
  }
  const { instance } = mountComponent(comp, 'image-preview-wrapper-root')

  return instance
}
Example #15
Source File: request.js    From LoR_Master with MIT License 5 votes vote down vote up
export function useRequest(api) {
  const data = ref(null)
  const loading = ref(false)
  const error = ref(null)
  const controller = ref(null)
  const duration = ref(0)
  const cancel = () => {
    if (controller.value) controller.value.abort()
  }

  const fetch = () => {
    if (loading.value) cancel()
    controller.value = new AbortController()
    loading.value = true
    const reqeustStartTime = Date.now()
    const requestAPi = isRef(api) ? api.value : api
    console.log(requestAPi)
    axios
      .get(requestAPi, { signal: controller.value.signal })
      .then((res) => {
        loading.value = false
        if (res && res.data) {
          error.value = null
          duration.value = Date.now() - reqeustStartTime
          data.value = res.data
        } else {
          error.value = `API ${requestAPi} response invalid`
        }
      })
      .catch((e) => {
        if (axios.isCancel(e)) {
          console.log(`API ${requestAPi} request cancelled`)
        } else {
          loading.value = false
          error.value = e
        }
      })
  }

  // expose managed state as return value
  return { data, loading, duration, error, fetch, cancel }
}
Example #16
Source File: create-context-menu.js    From ant-simple-pro with MIT License 5 votes vote down vote up
function createInstance() {
  const comp = {
    setup() {
      const visible = ref(false)

      let attrs = {}
      const open = opts => {
        visible.value = true
        attrs = opts
      }

      const close = () => {
        visible.value = false
      }

      const toggle = val => {
        visible.value = val
      }

      const render = () => {
        attrs = {
          ...attrs,
          visible: visible.value,
          'onUpdate:visible': toggle
        }

        return h(ContextMenu, attrs)
      }

      // rewrite render function
      getCurrentInstance().render = render

      return {
        open,
        close
      }
    }
  }
  const { instance } = mountComponent(comp, 'context-menu-wrapper-root')

  return instance
}
Example #17
Source File: useChartData.js    From vue3-highcharts with MIT License 5 votes vote down vote up
export default function () {
  const seriesData = ref([25, 39, 30, 15]);
  const categories = ref(['Jun', 'Jul', 'Aug', 'Sept']);

  const chartOptions = computed(() => ({
    chart: {
      type: 'line',
    },
    title: {
      text: 'Number of project stars',
    },
    xAxis: {
      categories: categories.value,
    },
    yAxis: {
      title: {
        text: 'Number of stars',
      },
    },
    series: [{
      name: 'New project stars',
      data: seriesData.value,
    }],
  }));

  const onRender = () => {
    console.log('Chart rendered');
  };

  const onUpdate = () => {
    console.log('Chart updated');
  };

  const onDestroy = () => {
    console.log('Chart destroyed');
  };

  return {
    seriesData,
    categories,
    chartOptions,
    onRender,
    onUpdate,
    onDestroy,
  };
}
Example #18
Source File: radio.js    From Ale with MIT License 5 votes vote down vote up
export function initData() {
  let focus = ref(false);
  return {
    focus
  };
}
Example #19
Source File: vue3-highcharts.js    From vue3-highcharts with MIT License 5 votes vote down vote up
vueHighcharts = defineComponent({
  name: 'VueHighchart',
  props: {
    type: {
      type: String,
      default: 'chart',
    },

    options: {
      type: Object,
      required: true,
    },

    redrawOnUpdate: {
      type: Boolean,
      default: true,
    },

    oneToOneUpdate: {
      type: Boolean,
      default: false,
    },

    animateOnUpdate: {
      type: Boolean,
      default: true,
    },
  },

  setup(props, { emit }) {
    const chartRef = ref(null);
    const chart = ref(null);

    const { options } = toRefs(props);

    if (options.value && Highcharts[props.type]) {
      watch(options, (newValue) => {
        if (chart.value) {
          chart.value.update(newValue, props.redrawOnUpdate, props.oneToOneOnUpdate, props.animateOnUpdate);
          emit('updated');
        }
      }, { deep: true });

      onMounted(() => {
        chart.value = Highcharts[props.type](chartRef.value, options.value, () => {
          emit('rendered');
        });
      });

      onUnmounted(() => {
        if (chart.value) chart.value.destroy();
        emit('destroyed');
      });
    } else if (!props.options) {
      console.warn('The "options" parameter is required.');
    } else {
      console.warn(`${props.type} is not a valid highcharts type or has not been imported`);
    }

    // Rather than returning a render function here. We'll return the chart ref and highcharts
    // instance so there exposed.
    return {
      chartRef,
      chart,
    };
  },

  render() {
    return h('div', {
      class: 'vue-highcharts',
      ref: 'chartRef',
    });
  },
})
Example #20
Source File: useDarkMode.js    From website with MIT License 5 votes vote down vote up
export default function useDarkMode() {
	const isDarkMode = ref(false);

	const updateDarkModeClass = (value = isDarkMode.value) => {
		// set `class="dark"` on `<html>` element
		const htmlEl = window?.document.querySelector('html');
		htmlEl?.classList.toggle('dark', value);

		const systemDarkMode = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches;

		if ((value && systemDarkMode) || (!value && !systemDarkMode)) {
			localStorage.removeItem('guide-color-scheme');
		} else if (value && !systemDarkMode) {
			localStorage.setItem('guide-color-scheme', 'dark');
		} else if (!value && systemDarkMode) {
			localStorage.setItem('guide-color-scheme', 'light');
		}
	}

	const mediaQuery = ref < MediaQueryList | null > (null)
	const onMediaQueryChange = (event) => {
		isDarkMode.value = event.matches;
	};

	onMounted(() => {
		// get stored preference and `prefers-color-scheme` media query and set the initial mode
		const userMode = localStorage.getItem('guide-color-scheme');
		mediaQuery.value = window.matchMedia('(prefers-color-scheme: dark)');
		isDarkMode.value = userMode === 'dark' || (userMode !== 'light' && mediaQuery.value.matches);

		// watch changes
		mediaQuery.value.addEventListener('change', onMediaQueryChange);
		watch(isDarkMode, updateDarkModeClass, { immediate: true });
	});

	onUnmounted(() => {
		mediaQuery.value?.removeEventListener('change', onMediaQueryChange);
	});

	return {
		isDarkMode,
	};
}
Example #21
Source File: use-auto-theme.js    From konsta with MIT License 5 votes vote down vote up
useAutoTheme = (props, autoThemeDetection = true) => {
  const themeState = ref(props.theme);

  /* eslint-disable no-restricted-globals */
  const setTheme = (newTheme) => {
    if (newTheme === 'ios' || newTheme === 'material') {
      if (themeState.value !== newTheme) {
        themeState.value = newTheme;
      }
    } else if (
      autoThemeDetection &&
      themeState.value === 'parent' &&
      typeof window !== 'undefined' &&
      typeof document !== 'undefined'
    ) {
      const htmlEl = document.documentElement;
      if (htmlEl) {
        if (htmlEl.classList.contains('ios')) {
          themeState.value = 'ios';
        } else if (
          htmlEl.classList.contains('md') ||
          htmlEl.classList.contains('material')
        ) {
          themeState.value = 'material';
        }
      }
    }
  };
  /* eslint-enable no-restricted-globals */

  watch(
    () => props.theme,
    (newTheme) => {
      setTheme(newTheme);
    }
  );
  onMounted(() => {
    setTheme(props.theme);
  });

  return themeState;
}
Example #22
Source File: use-touch-ripple.js    From konsta with MIT License 5 votes vote down vote up
useTouchRipple = (elRef, props, addCondition) => {
  const context = inject('KonstaContext');
  const ripple = ref(null);
  let eventsAttached = false;

  const getEl = () => {
    if (!elRef || !elRef.value) return null;
    let el = elRef.value;
    if (el.$el) el = el.$el;
    return el;
  };

  const theme = () => {
    let value = context.value.theme || 'ios';
    if (props.ios) value = 'ios';
    if (props.material) value = 'material';
    return value;
  };
  const needsTouchRipple = () => {
    return (
      theme() === 'material' &&
      props.touchRipple &&
      (addCondition ? addCondition() : true)
    );
  };
  const removeRipple = () => {
    if (ripple.value) ripple.value.remove();
    ripple.value = null;
  };

  const onPointerDown = (e) => {
    ripple.value = new TouchRipple(getEl(), e.pageX, e.pageY);
  };
  const onPointerMove = () => {
    removeRipple();
  };
  const onPointerUp = () => {
    removeRipple();
  };

  const attachEvents = () => {
    if (!context.value.touchRipple || eventsAttached) return;
    eventsAttached = true;
    const el = getEl();
    el.addEventListener('pointerdown', onPointerDown);
    el.addEventListener('pointermove', onPointerMove);
    el.addEventListener('pointerup', onPointerUp);
  };
  const detachEvents = () => {
    eventsAttached = false;
    const el = getEl();
    el.removeEventListener('pointerdown', onPointerDown);
    el.removeEventListener('pointermove', onPointerMove);
    el.removeEventListener('pointerup', onPointerUp);
  };

  watch(
    () => needsTouchRipple(),
    (newV) => {
      if (newV) attachEvents();
      else detachEvents();
    }
  );

  onMounted(() => {
    if (!getEl() || !needsTouchRipple()) return;
    attachEvents();
  });

  onBeforeUnmount(() => {
    if (!getEl() || !needsTouchRipple()) return;
    detachEvents();
  });
}
Example #23
Source File: user.js    From fes.js with MIT License 5 votes vote down vote up
export default function user() {
    const count = ref(1);
    return {
        count
    };
}
Example #24
Source File: profile.js    From vue-iClient3D_for_Cesium with Apache License 2.0 4 votes vote down vote up
function profile(props) {

    // 设置默认值数据
    let state = reactive({
        profile2d: false, //显示剖面分析结果
        polylineColor: "rgb(250, 213, 6)", //贴线颜色
        polylineWidth: 5,   //贴线宽度
        initEchartsOption:null,  //初始化自定义echarts配置对象
        updateEchartsOption:null , //自定义更新echarts配置对象
    });

    // 传入props改变默认值
    if (props) {
        for (let key in props) {
            if (state.hasOwnProperty(key)) {
                state[key] = props[key]
            } else {
                tool.Message.errorMsg(resource.AttributeError + key);
            }
        }
    }

    // 初始化数据
    let myChart, count, //插值点个数
        Entypositions; //当前图标的位置
    let tipFlag = true;  //提示操作提醒一次
    let LatAndLons = []; //所有点的经纬度
    let Cartesians = [];  //所有点的笛卡尔
    let EditPositions= null; //编辑时保存之前位置

    const echarts_box = ref(null);
    onMounted(() => {
        initMyChart();
    });
    if (storeState.isViewer) {
        if (!window.tooltip) {
            window.tooltip = createTooltip(viewer._element);
        }
    }
    //viewer 初始化完成的监听
    watch(() => storeState.isViewer, val => {
        if (val) {
            if (!window.tooltip) {
                window.tooltip = createTooltip(viewer._element);
            }
        }
    });

    //初始化echarts
    function initMyChart() {
        if (window.echarts) {
            if (!myChart) {
                myChart = window.echarts.init(echarts_box.value);  //初始化echarts
                window.onresize = function () {
                    myChart.resize()  //自适应屏幕
                };
            }
        } else {
            tool.Message.warnMsg(resource.EchartsErr);
            return;
        }
        if(state.initEchartsOption){
            myChart.setOption(state.initEchartsOption);
            return;
        }
        myChart.setOption({
            title: {
                text: "剖面分析",
                textStyle: {
                    fontSize: 14
                }
            },
            grid: {
                left: 30,
                right: 0,
                top: 30,
                bottom: 8
            },
            tooltip: {},
            xAxis: {
                data: [],
            },
            yAxis: {
                data: [],
            },
            series: [
                {
                    type: "bar",
                    data: [],
                },
            ],
        });
    };
    /*
     ***分析模块***
    */

    //分析
    function analysis() {
        if (tipFlag) {   //只提示一次
            tooltip.showAt(' <p>点击鼠标左键开始绘制</p> <p>单击右键结束分析</p><p>选中可进行编辑</p>', '250px');
            tipFlag = false
        }
        if (!window.handlerPolyline) {
            initHandler("Polyline");
        }
        handlerDrawing("Polyline").then(
            res => {
                myChart.showLoading();
                EditPositions = res.positions;
                DrawPolylineUpdate(res.positions); //划线效果
                let handlerPolyline = window.handlerPolyline;
                handlerPolyline.polyline.show = false;
                window.polylineTransparent.show = false; //半透线隐藏
                handlerPolyline.deactivate();
                updataProfile3D('', res.result.object); //更新剖面
                Edit(EditPositions, false, updataProfile3D); //编辑功能
                tooltip.setVisible(false);
            },
            (err) => {
                console.log(err);
            }
        );
        window.handlerPolyline.activate();
    };

    // 绘制剖面分析的线
    function DrawPolylineUpdate(position) {
        viewer.entities.removeById('polyline-profile');
        viewer.entities.removeById('location4');
        let fullLineColor = Cesium.Color.fromCssColorString(state.polylineColor);
        viewer.entities.add({
            id: "polyline-profile",
            polyline: {
                positions: Cesium.Cartesian3.fromDegreesArrayHeights(position),
                width: state.polylineWidth,
                material: fullLineColor,
                clampToGround: true, //线贴地
                // classificationType: Cesium.ClassificationType.S3M_TILE, //线面贴对象
            },
        });
        entityUpdate();
    };

    // 更新剖面分析二维图
    function updataProfile3D(position, line) {
        state.profile2d = true; //打开echarts
        myChart.clear()
        myChart.showLoading();
        //position参数不起作用,是为了edit函数不冲突
        LatAndLons.length = 0; //清空之前的点数据
        Cartesians.length = 0; //清空之前的点数据
        let positions = [];
        //折线实现
        for (let i = 1, j = line._positions.length; i < j; i++) {
            let startPoint = line._positions[i - 1];
            let endPoint = line._positions[i];
            let d = Cesium.Cartesian3.distance(startPoint, endPoint)
            getCount(parseInt(d));
            for (let i = 1, j = count; i <= j; i++) {
                positions.push(
                    Cesium.Cartesian3.lerp(
                        startPoint,
                        endPoint,
                        i / count,
                        new Cesium.Cartesian3()
                    )
                );
            }
        }
        viewer.scene
            .clampToHeightMostDetailed(positions)
            .then((clampedCartesians) => {
                Cartesians = clampedCartesians;  //记录所有点的笛卡尔坐标
                LatAndLons = tool.CartesiantoDegreesObjs(Cartesians);  //记录所有点的经纬度坐标
                echartsOption();  //更新echarts
            });
    };

    //精度计算count插值
    function getCount(distance) {
        if (distance / 10000 > 1) {
            count = parseInt(distance / 100)    //  (>10000)  100m
        } else if (distance / 1000 > 5) {
            count = parseInt(distance / 10)    // (5000-10000)  10m
        } else if (distance / 1000 > 2) {
            count = parseInt(distance / 5)     // (2000-5000)  5m
        } else if (distance / 1000 > 1) {
            count = parseInt(distance / 2)     // (1000-2000)  2m
        } else if (distance / 100 > 5) {
            count = parseInt(distance / 1.5)   //  (500-1000) 1.5m
        } else if (distance / 100 > 2) {
            count = distance                  // (200-500) 1m 
        } else {
            count = distance * 2              //   (<200) 0.5m
        }
    }

    // 更新交互图标
    function entityUpdate() {
        if (viewer.entities.getById("location4")) {
            return;
        }
        viewer.entities.add({
            id: "location4",
            position: new Cesium.CallbackProperty(() => {
                return Entypositions;
            }, false),
            billboard: {
                image: "src/style/images/location4.png",
                width: 30,
                height: 40,
                scaleByDistance: new Cesium.NearFarScalar(10, 1.0, 2000, 0.6),
                eyeOffset :new Cesium.Cartesian3(0, 1, -5)
                // heightReference :Cesium.HeightReference.RELATIVE_TO_GROUND
                // disableDepthTestDistance :5000,
                // pixelOffset : new Cesium.Cartesian2(0.0, 1.0),
                // pixelOffsetScaleByDistance : new Cesium.NearFarScalar(1.5e2, 0.0, 8.0e6, 10.0)
            },
        });
    };

    // 更新图表数据
    function echartsOption() {
        myChart.hideLoading();
        myChart.clear();
        if(state.updateEchartsOption){
            myChart.setOption(state.updateEchartsOption);
            return;
        }
        let option = {
            title: {
                text: "剖面信息",
                textStyle: {
                    fontSize: 14
                }
            },
            // 定位
            grid: {
                left: 50,
                right: 8,
                top: 40,
                bottom: 20,
            },
            // backgroundColor: "rgba(73,139,156,0.0)",
            tooltip: {
                trigger: "axis",
                backgroundColor: "#ffffff",
                textStyle: {
                    color: "#000",
                },
                formatter: (param) => {
                    let dataIndex = param[0].dataIndex;
                    Entypositions = Cartesians[dataIndex];
                    return [
                        "当前位置: " + '<hr size=1 style="margin: 3px 0">',
                        "经度: " +
                        LatAndLons[dataIndex].longitude.toFixed(6) +
                        "<br/>",
                        "纬度: " +
                        LatAndLons[dataIndex].latitude.toFixed(6) +
                        "<br/>",
                        "海拔: " +
                        LatAndLons[dataIndex].height.toFixed(2) +
                        "米" +
                        "<br/>",
                    ].join("");
                },
            },
            xAxis: {
                data: LatAndLons.map(function (item, index) {
                    return index;
                }),
                show: false,
            },
            yAxis: {
                min: function (value) {
                    return value.min < 20 ? 0 : Math.floor(value.min);
                },
                axisLabel: {
                    interval: "auto",
                    formatter: function (value, index) {
                        return value > 999
                            ? (value / 1000).toFixed(2) + "km"
                            : value + "m";
                    },
                },
                splitLine: {
                    show: true,
                },
            },
            toolbox: {
                left: "right",
                feature: {
                    dataZoom: {
                        yAxisIndex: "none",
                    },
                    restore: {},
                    saveAsImage: {},
                },
            },
            dataZoom: [
                {
                    type: "inside",
                    xAxisIndex: 0,
                    filterMode: "filter",
                    start: 0,
                    end: 100,
                },
            ],
            series: {
                name: "height",
                type: "line",
                data: LatAndLons.map(function (item) {
                    return item.height;
                }),
                areaStyle: {},
            },
        };
        myChart.setOption(option);
    };

    // 清除
    function clear() {
        state.profile2d = false;
        viewer.entities.removeById('location4');
        viewer.entities.removeById('polyline-profile');
        myChart.clear();
        LatAndLons.length = 0; //清空之前的点数据
        Cartesians.length = 0; //清空之前的点数据
        clearHandlerDrawing("Polyline");
        clearEditHandler();
        initMyChart();
        tooltip.setVisible(false);
    };

    // 监听
    watch(() => state.profile2d, newValue => {
        if (!newValue || !myChart) {
            state.getSkyline2d = false;
            return;
        }
        setTimeout(() => {
            myChart.resize()  //自适应屏幕
        }, 200)
    });

    // 销毁
    onBeforeUnmount(() => {
        clear();
        myChart.clear();
        LatAndLons.length = 0; //清空之前的点数据
        Cartesians.length = 0; //清空之前的点数据
    })

    return {
        ...toRefs(state),
        echarts_box,
        myChart,
        Entypositions,
        LatAndLons,  //所有点的经纬度
        Cartesians,  //所有点的笛卡尔
        analysis,
        clear
    };
}
Example #25
Source File: shadow-query.js    From vue-iClient3D_for_Cesium with Apache License 2.0 4 votes vote down vote up
function shadowquery(props) {

    // 设置默认值数据
    let state = reactive({
        timeValue: [24, 64],  //开始结束时间
        currentDate: new Date(),  //当前日期
        shadowShow: true,   //显示阴影,确定阴影是否由太阳投射形成。
        marks: {    //时间刻度标记
            0: "0:00",
            8: "",
            16: "",
            24: "6:00",
            32: "",
            40: "",
            48: "12:00",
            56: "",
            64: "",
            72: "18:00",
            80: "",
            88: "",
            96: "24:00"
        },
        timeInterval: 60,  //时间间隔
        spacing: 10,     //间距(米)
        bottomHeight: 1,  //底部高程(米)
        extrudeHeight: 30,  //拉伸高度(米)
        shadowQueryRegion: [],  //分析区域
        // shadows: true,   //确定阴影是否由太阳投射形成。
        layerShadowType: Cesium.ShadowType.ALL, // 图层上阴影类型:所有的模型都产生阴影。
        terrainShadows: Cesium.ShadowMode.RECEIVE_ONLY, //确定地形是否投射或接受来自太阳的阴影:(ShadowMode:该对象仅接收阴影)。
        showStartImgForTime: true,  //显示时间轴开始图标
        showStartImgForDate: true,   //显示日期开始图标
        shadowRadio: {  //获取阴影率结果对象
            'shadowRadio': '',
            'longitude': '',
            'latitude': '',
            'height': '',
            'isShow': false
        },
        dockFontShow: true, //停靠图标显示
        legendShow: false,  //图例显示
        shadowBodyShow: false, //阴影率体显示
        shadowBodyFilter: [0, 100]
    });

    // 传入props改变默认值
    if (props) {
        for (let key in props) {
            if (state.hasOwnProperty(key)) {
                state[key] = props[key]
            } else {
                tool.Message.errorMsg(resource.AttributeError + key);
            }
        }
    }

    // 初始化分析区域并执行
    if (props && props.shadowQueryRegion) {
        shadowQueryUpdate(props.shadowQueryRegion)
    }

    // 初始化数据
    let shadowQuery, layers, IntervalForTime,tipFlag = true, IntervalForDate, currentTimeArr = [...state.timeValue];
    const bubble = ref(null);

    let box_s3m = 'public/data/s3m/box.s3m';
    let s3mInstanceCollection, shadowQuery_points = [], setLayersFlag;
    //初始化体显示颜色(根具采光率0-100获取对应颜色值)
    let gradientColors = tool.gradientColors;  // 获取渐变色函数
    let color = ['#0000ff'];
    color = color.concat(gradientColors('#0000ff', '#00ffff', 20))
        .concat(gradientColors('#00ffff', '#00ff00', 20))
        .concat(gradientColors('#00ff00', '#ffff00', 20))
        .concat(gradientColors('#ffff00', '#ff7f00', 20))
        .concat(gradientColors('#ff7f00', '#ff0000', 20));

    if (storeState.isViewer) {
        if (!window.tooltip) {
            window.tooltip = createTooltip(viewer._element);
        }
        init()
    }
    //viewer 初始化完成的监听
    watch(() => storeState.isViewer, val => {
        if (val) {
            if (!window.tooltip) {
                window.tooltip = createTooltip(viewer._element);
            }
            init()
        }
    });
    //监听图层加载完成
    watch(() => storeState.changeLayers, val => {
        setLayerShadowType()
    });

    function init() {   //初始化函数
        let scene = viewer.scene;
        viewer.shadows = state.shadowShow;
        viewer.terrainShadows = state.terrainShadows;
        layers = viewer.scene.layers.layerQueue;
        scene.globe.enableLighting = true;
        scene.skyBox.show = true;
        viewer.clock.multiplier = 1;
        viewer.clock.shouldAnimate = true;
        shadowQuery = new Cesium.ShadowQueryPoints(scene);    //创建阴影查询对象
        s3mInstanceCollection = new Cesium.S3MInstanceCollection(scene._context);
        s3mInstanceCollection.setCullEnabled(box_s3m, true);  //开启单面渲染
        scene.primitives.add(s3mInstanceCollection);
        shadowQuery.queryPointsEvent.addEventListener(function (data) {  //分析完成回调
            shadowQuery_points = data;
            if (state.shadowBodyShow) {
                bodyShow()
            }
        })
        if (storeState.changeLayers) {
            setLayerShadowType()
        }
    }

    function setLayerShadowType() {
        for (let i = 0; i < layers.length; i++) {
            layers[i].shadowType = state.layerShadowType;
            setLayersFlag = true;
        }
    }

    /*
     ***分析模块***
    */

    // 时间轴改变
    function timeChanging(arr) {
        let tm;
        if (currentTimeArr[0] === arr[0]) {
            tm = setCurrentTime(arr[1]);
        } else {
            tm = setCurrentTime(arr[0]);
        }
        viewer.clock.currentTime = Cesium.JulianDate.fromDate(tm);
        currentTimeArr = arr;
    };

    //设置时间轴表示的当前时间
    function setCurrentTime(tm) {
        let h = parseInt(tm / 4);
        let m = parseInt((tm % 4) * 15);
        let d = state.currentDate;
        d.setHours(h);
        d.setMinutes(m);
        return d;
    };

    //时间轴改变后设置shadowQuery(不是实时监听)
    function timeChanged(val) {
        if (state.shadowShow) {
            shadowQuery.startTime = Cesium.JulianDate.fromDate(setCurrentTime(val[0]));
            shadowQuery.endTime = Cesium.JulianDate.fromDate(setCurrentTime(val[1]));
        }
        if(state.showStartImgForTime && state.shadowQueryRegion.length>0){
            shadowQuery.build()
        }
    };

    function filterChanged(val) {
        filterBodyShow(val)
    };

    // 时间轴提示函数
    function formatTooltip(val) {
        if (val === state.timeValue[0]) {
            return (
                "开始时间:" + timeSlice(setCurrentTime(val).toLocaleTimeString())
            );
        } else {
            return (
                "结束时间:" + timeSlice(setCurrentTime(val).toLocaleTimeString())
            );
        };
        function timeSlice(str) {
            let str2 = str.split(':');
            return str2[0] + ':' + str2[1]
        }
    };

    // 播放或暂停时间段内阳光和阴影动画
    function sunLightForTime(flag) {
        if (IntervalForDate) {
            state.showStartImgForDate = true;
            clearInterval(IntervalForDate)
        };
        if (!flag) {
            state.showStartImgForTime = true;
            clearInterval(IntervalForTime);
            return;
        } else {
            state.showStartImgForTime = false;
        }
        let time = [...currentTimeArr];
        let stm = time[0];
        let etm = time[1];
        let ntm = stm;
        IntervalForTime = setInterval(() => {
            if (ntm < etm) {
                ntm += 0.5;
                state.timeValue = [stm, ntm];
            } else {
                state.showStartImgForTime = true;
                clearInterval(IntervalForTime);
            }
        }, 50);
    };

    //播放一年的阳光和阴影动画
    function sunLightForDate(flag) {
        if (IntervalForTime) {
            clearInterval(IntervalForTime);
            state.showStartImgForTime = true;
        };
        if (!flag) {
            state.showStartImgForDate = true;
            clearInterval(IntervalForDate);
            return;
        } else {
            state.showStartImgForDate = false;
        }
        let d = setCurrentTime(currentTimeArr[1]); //时分秒默认按时间轴上结束的时间计算
        let mon = d.getMonth();
        IntervalForDate = setInterval(() => {
            if (mon < 11) {
                mon += 1;
            } else {
                mon = 0;
            }
            d.setMonth(mon);
            // viewer.clock.currentTime = Cesium.JulianDate.fromDate(d);
            state.currentDate = new Date(d)
        }, 1000);
    };

    //   阴影分析
    function analysis() {
        if (!state.shadowShow) {
            // tool.Message.warnMsg(resource.ShadowqueryWarn);
            state.shadowShow = true;
            return;
        }
        tooltip.setVisible(false);
        if (tipFlag) {   //只提示一次
            window.tooltip.showAt(' <p>点击鼠标左键绘制分析区域</p><p>点击鼠标右键结束绘制</p>', '350px');
            tipFlag = false
        }
        if (!setLayersFlag || layers[0].shadowType != state.layerShadowType) {
            setLayerShadowType()
        }
        if (!window.handlerPolygon) {
            initHandler("Polygon");
        }
        handlerDrawing("Polygon").then(
            res => {
                let handlerPolygon = window.handlerPolygon;
                shadowQueryUpdate(res.result.object.positions);
                handlerPolygon.polygon.show = false;
                handlerPolygon.polyline.show = false;
                //   window.polylineTransparent.show = false; //半透线隐藏
                handlerPolygon.deactivate();
                //鼠标左键事件监听
                viewer.eventManager.addEventListener("CLICK", LEFT_CLICK, true);
            },
            err => {
                console.log(err);
            }
        );
        window.handlerPolygon.activate();
        state.legendShow = true
    }

    //更新分析
    function shadowQueryUpdate(p) {
        timeChanged(state.timeValue);
        let position = [];
        shadowQuery.spacing = Number(state.spacing);
        shadowQuery.timeInterval = Number(state.timeInterval);
        let bh = Number(state.bottomHeight);
        let eh = Number(state.extrudeHeight);

        //遍历多边形,取出所有点
        let pos = Cesium.arrayRemoveDuplicates(
            p,
            Cesium.Cartesian3.equalsEpsilon
        );
        for (let i = 0, len = pos.length; i < len; i++) {
            //转化为经纬度,并加入至临时数组
            let cartographic = Cesium.Cartographic.fromCartesian(p[i]);
            let longitude = Cesium.Math.toDegrees(cartographic.longitude);
            let latitude = Cesium.Math.toDegrees(cartographic.latitude);
            position.push(longitude);
            position.push(latitude);
        }
        state.shadowQueryRegion = position;

        shadowQuery.qureyRegion({
            position: position,
            bottom: bh,
            extend: eh
        });
        shadowQuery.build();

    }


    // 鼠标左键事件 点击获取阴影率
    function LEFT_CLICK(e) {
        if (state.shadowBodyShow) {
            let box = scene.pick(e.message.position);
            if (box && box.id) {
                let point = shadowQuery_points[box.id];
                if (!point) return;
                let radio = point.shadowRatio * 100;
                if (radio < state.shadowBodyFilter[0] || radio > state.shadowBodyFilter[1]) state.shadowRadio.isShow = false;
                let position = tool.CartesiantoDegrees(point.position);
                state.shadowRadio = {
                    'shadowRadio': (point.shadowRatio * 100).toFixed(0) + '%',
                    'longitude': position[0].toFixed(8),
                    'latitude': position[1].toFixed(8),
                    'height': position[2].toFixed(8),
                    'isShow': true
                }
                bubble.value.style.top = (e.message.position.y - 160) + 'px';
                bubble.value.style.left = (e.message.position.x) + 'px';
            } else {
                state.shadowRadio.isShow = false
            }

        } else {
            let position1 = scene.pickPosition(e.message.position);
            let cartographic = Cesium.Cartographic.fromCartesian(position1);
            let shadowRadio = shadowQuery.getShadowRadio(cartographic);
            if (shadowRadio != -1) {
                let longitude = Cesium.Math.toDegrees(cartographic.longitude);
                let latitude = Cesium.Math.toDegrees(cartographic.latitude);
                let height = cartographic.height;
                state.shadowRadio = {
                    'shadowRadio': (shadowRadio * 100).toFixed(0) + '%',
                    'longitude': longitude.toFixed(8),
                    'latitude': latitude.toFixed(8),
                    'height': height.toFixed(8),
                    'isShow': true
                }
                bubble.value.style.top = (e.message.position.y - 160) + 'px';
                bubble.value.style.left = (e.message.position.x) + 'px';
            }
            else {
                state.shadowRadio.isShow = false
            }
        }
    }

    //关闭气泡
    function closeBubble() {
        state.shadowRadio.isShow = false
    }
    //悬停气泡
    function dockBubble(val) {
        if (val) {
            bubble.value.classList.add('bubbleDock');
            state.dockFontShow = false
        } else {
            bubble.value.classList.remove('bubbleDock');
            state.dockFontShow = true
        }
    }

    // 清除
    function clear() {
        state.legendShow = false;
        clearHandlerDrawing();
        // viewer.entities.removeAll();
        state.shadowQueryRegion.length = 0;
        tooltip.setVisible(false);
        closeBubble();
        viewer.eventManager.removeEventListener("CLICK", LEFT_CLICK); //移除鼠标点击事件监听
        shadowQuery.clear();
        shadowQuery_points.length = 0;
        s3mInstanceCollection.removeCollection(box_s3m);
        // state.shadowBodyShow = false
        for (let i = 0; i < layers.length; i++) {
            layers[i].shadowType = Cesium.ShadowType.NONE
        }
    };

    //体显示
    function bodyShow() {
        let objs = [];
        if (shadowQuery._bottom < 0 || shadowQuery_points.length == 0) {
            return;
        }
        let width = Number(state.spacing - 0.5);
        for (let i = 0, j = shadowQuery_points.length; i < j; i++) {
            objs.push({
                position: shadowQuery_points[i].position,
                color: getShadowRadioColor(shadowQuery_points[i].shadowRatio),
                scale: new Cesium.Cartesian3(width, width, width)
            })
        };
        if (objs.length > 0) {
            s3mInstanceCollection.add(box_s3m, objs);
        }
        filterBodyShow(state.shadowBodyFilter)
    };

    //体显示获取颜色
    function getShadowRadioColor(shadowRadio) {
        let index = parseInt((shadowRadio * 100));
        let col = color[index];
        return Cesium.Color.fromCssColorString(col);
    };

    //过滤体显示
    function filterBodyShow(arr) {
        if (shadowQuery._bottom <= 0 || shadowQuery_points.length == 0) {
            return;
        }
        for (let i = 0, j = shadowQuery_points.length; i < j; i++) {
            let Ratio = shadowQuery_points[i].shadowRatio * 100;
            if (Ratio < arr[0] || Ratio > arr[1]) {
                s3mInstanceCollection.getInstance(box_s3m, i).visible = false
            } else {
                s3mInstanceCollection.getInstance(box_s3m, i).visible = true
            }
        }
    }


    //   监听
    watch(() => state.timeValue, val => {
        timeChanging(val)
    });
    watch(() => state.currentDate, val => {
        timeChanging(currentTimeArr)
    });
    watch(() => state.timeInterval, val => {
        changeSlider(() => {
            shadowQuery.timeInterval = Number(val);
        })
    });
    watch(() => state.spacing, val => {
        changeSlider(() => {
            shadowQuery.spacing = Number(val);
        })
    });
    watch(() => state.bottomHeight, val => {
        if (state.shadowQueryRegion.length === 0) return;
        changeSlider(() => {
            let bh = Number(val);
            let eh = Number(state.extrudeHeight);
            shadowQuery.qureyRegion({
                position: state.shadowQueryRegion,
                bottom: bh,
                extend: eh
            });
            shadowQuery.build();
        })
    });
    watch(() => state.extrudeHeight, val => {
        if (state.shadowQueryRegion.length === 0) return;
        changeSlider(() => {
            let bh = Number(state.bottomHeight);
            let eh = Number(val);
            shadowQuery.qureyRegion({
                position: state.shadowQueryRegion,
                bottom: bh,
                extend: eh
            });
            shadowQuery.build();
        })
    });
    watch(() => state.shadowShow, val => {
        viewer.shadows = val;
        for (let i = 0, j = layers.length; i < j; i++) {
            if (layers[i].shadowType == state.layerShadowType) break;
            else layers[i].shadowType = state.layerShadowType
        }
    });
    watch(() => state.shadowBodyShow, val => {
        if (val) {
            shadowQuery.isPointsVisible = false;
            bodyShow()
        } else {
            shadowQuery.isPointsVisible = true;
            s3mInstanceCollection.removeCollection(box_s3m);
        }
    });

    let timer;
    // 防止滑块快速滑动的多次执行
    function changeSlider(callback) {
        if (timer) clearTimeout(timer);
        timer = setTimeout(function () {
            callback()
        }, 500);

    }



    // 销毁
    onBeforeUnmount(() => {
        clear();

        shadowQuery.destroy();
        shadowQuery = undefined;
        viewer.shadows = false;
        layers = undefined;
    })

    return {
        ...toRefs(state),
        timeChanged,
        filterChanged,
        formatTooltip,
        sunLightForTime,
        sunLightForDate,
        analysis,
        clear,
        bubble,
        closeBubble,
        dockBubble
    };
}
Example #26
Source File: sky-line.js    From vue-iClient3D_for_Cesium with Apache License 2.0 4 votes vote down vote up
//公共handler.js

function skyLine(props) {

    // 设置默认值数据
    let state = reactive({
        skylineRadius: 10000,  //分析半径
        lineWidth: 3,   //天际线宽度
        skylineColor: "rgb(200, 0, 0)",   //天际线颜色
        skyBodyColor: "rgba(44,149,197,0.6)",   //天际体颜色
        barrierColor: "rgba(255, 186, 1, 1)",   //障碍物颜色
        skylineMode: 0,   //分析模式
        highlightBarrier: false,   //是否显示高亮障碍物
        getSkyline2d: true,    //是否显示二维分析结果
        skylineSpatialAnalysisUrl: null,   //分析服务地址 'http://www.supermapol.com/realspace/services/spatialAnalysis-data_all/restjsr/spatialanalyst/geometry/3d/skylinesectorbody.json'
        observerInformation: null,  //观察者信息
        ignoreGlobe: true,  // 地球表面不参与分析
    });

    // 传入props改变默认值
    if (props) {
        for (let key in props) {
            if (state.hasOwnProperty(key)) {
                state[key] = props[key]
            } else {
                tool.Message.errorMsg(resource.AttributeError + key);
            }
        }
    }

    // 初始化数据
    let myChart, s3mInstance, skyline, scene, tipFlag = true;
    const echarts_box = ref(null);
    onMounted(() => {
        initMyChart();
    });

    if (storeState.isViewer) {
        scene = viewer.scene;
        skyline = new Cesium.Skyline(scene);
        skyline.ignoreGlobe = state.ignoreGlobe;  //地球表面不参与分析
        skyline.build();
        s3mInstance = new Cesium.S3MInstanceCollection(scene._context);
        scene.primitives.add(s3mInstance);
        //初始化观察者信息(后面有需要可以添加监听)
        if (state.observerInformation) {
            skyLineUpdate(state.observerInformation);
        }
        if (!window.tooltip) {
            window.tooltip = createTooltip(viewer._element);
        }
    }
    //viewer 初始化完成的监听
    watch(() => storeState.isViewer, val => {
        if (val) {
            scene = viewer.scene;
            skyline = new Cesium.Skyline(viewer.scene);
            skyline.ignoreGlobe = state.ignoreGlobe;
            skyline.build();
            s3mInstance = new Cesium.S3MInstanceCollection(viewer.scene._context);
            viewer.scene.primitives.add(s3mInstance);
            if (state.observerInformation) {
                skyLineUpdate(state.observerInformation);
            }
            if (!window.tooltip) {
                window.tooltip = createTooltip(viewer._element);
            }
        }
    });

    //初始化echarts
    function initMyChart() {
        if (window.echarts) {
            if (!myChart) {
                myChart = window.echarts.init(echarts_box.value);  //初始化echarts
                window.onresize = function () {
                    myChart.resize()  //自适应屏幕
                };
            }
        } else {
            tool.Message.warnMsg(resource.EchartsErr);
            return;
        }
        myChart.setOption({
            title: {
                text: "二维天际线",
                textStyle: {
                    fontSize: 14
                }
            },
            grid: {
                left: 30,
                right: 0,
                top: 30,
                bottom: 8
            },
            tooltip: {},
            xAxis: {
                show: false
            },
            yAxis: {
                show: false
            },
            series: [
                {
                    type: "bar",
                    data: [],
                },
            ],
        });
    };

    /*
     ***分析模块***
    */

    //分析
    function skyLineAnalysis() {
        clear(); // 清除上一次分析结果
        // 天际线分析的视口位置设置成当前相机位置
        let cartographic = viewer.scene.camera.positionCartographic;
        let observerObj = {
            longitude: Cesium.Math.toDegrees(cartographic.longitude),
            latitude: Cesium.Math.toDegrees(cartographic.latitude),
            height: cartographic.height,
            pitch: Cesium.Math.toDegrees(scene.camera.pitch),
            direction: Cesium.Math.toDegrees(scene.camera.heading)
        };
        skyLineUpdate(observerObj);
    };

    // 设置限高体
    function setLimitBody() {
        if (!window.handlerPolygon) {
            initHandler("Polygon");
        }
        tooltip.setVisible(false);
        if (tipFlag) {   //只提示一次
            window.tooltip.showAt(' <p>点击鼠标左键绘制区域</p><p>点击鼠标右键结束绘制</p>', '450px');
            tipFlag = false
        }
        handlerDrawing("Polygon").then(
            res => {
                skyline.removeLimitbody("limitBody");
                let handlerPolygon = window.handlerPolygon;
                let pos = res.result.object.positions;
                let positions = [];
                // 遍历多边形,取出所有点
                for (let i = 0, len = pos.length; i < len; i++) {
                    //转化为经纬度,并加入至临时数组
                    let cartographic = Cesium.Cartographic.fromCartesian(pos[i]);
                    let longitude = Cesium.Math.toDegrees(cartographic.longitude);
                    let latitude = Cesium.Math.toDegrees(cartographic.latitude);
                    positions.push([longitude, latitude]);
                }
                //去除重复点
                let p = tool.unique(positions);
                let posArr = [];
                //再次遍历转化为接口所需的数组格式
                for (let i = 0, len = p.length; i < len; i++) {
                    posArr.push(positions[i][0]);
                    posArr.push(positions[i][1]);
                }
                //添加限高体对象
                skyline.addLimitbody({
                    position: posArr,
                    name: "limitBody"
                });
                handlerPolygon.polygon.show = false;
                handlerPolygon.polyline.show = false;
                //   window.polylineTransparent.show = false; //半透线隐藏
                handlerPolygon.deactivate();
            },
            err => {
                console.log(err);
            }
        );
        window.handlerPolygon.activate();
    };

    // 更新天际线
    function skyLineUpdate(observerObj) {
        skyline.viewPosition = [observerObj.longitude, observerObj.latitude, observerObj.height];
        //设置俯仰和方向
        skyline.pitch = observerObj.pitch
        skyline.direction = observerObj.direction
        skyline.radius = Number(state.skylineRadius);
        skyline.lineWidth = Number(state.lineWidth);
        skyline.color = Cesium.Color.fromCssColorString(state.skylineColor);
        skyline.displayStyle = Number(state.skylineMode > 1 ? 0 : state.skylineMode);

        setTimeout(() => {
            if (state.highlightBarrier) { // 显示障碍物
                let BarrierColor = Cesium.Color.fromCssColorString(
                    state.barrierColor
                );
                changeBarrierColor(BarrierColor);
            }
            if (state.skylineMode == 2) {   // 是否切换天际体
                if (state.skylineSpatialAnalysisUrl) {
                    setSkyLineBody(observerObj)
                } else {
                    setSkyLineBody2(observerObj)
                    // setSkyLineBody(observerObj)
                }
            }
            let object = skyline.getSkyline2D();
            setOptions(object)  // 设置二维天际线
        }, 300);
        state.observerInformation = observerObj
    }

    // 改变障碍物颜色
    function changeBarrierColor(BarrierColor) {
        let ObjectIds = skyline.getObjectIds();
        console.log(ObjectIds)

        let layers = viewer.scene.layers._layerQueue;
        for (let index in ObjectIds) {
            layers.forEach(layer => {
                if (layer._id === Number(index)) {
                    layer.setObjsColor(ObjectIds[index], BarrierColor);
                }
            });
        }
    };

    // 设置二维天际线
    function setOptions(object) {
        if (state.observerInformation && myChart) {
            let option = {
                tooltip: {
                    trigger: 'axis',
                    // formatter: 'X: {b}<br/>Y : {c}'
                    formatter: (param) => {
                        let datax = Number(param[0].axisValue);
                        let datay = param[0].data;
                        return [
                            "X: " +
                            datax.toFixed(6) +
                            "<br/>",
                            "Y: " +
                            datay.toFixed(6)
                        ].join("");
                    },
                },
                grid: {
                    left: 40,
                    right: 0,
                    top: 35,
                    bottom: 8,
                    borderColor: '#333333'
                },
                // backgroundColor: "rgba(73,139,156,0.0)",
                color: 'red',
                xAxis: [
                    {
                        type: "category",
                        boundaryGap: false,
                        data: object.x,
                        show: false
                    }
                ],
                yAxis: {
                    min: function (value) {
                        return (value.min - 0.05).toFixed(2);
                    },
                    show: true,
                    axisLine: {
                        show: true,

                    }
                },
                dataZoom: [
                    {
                        type: "inside",
                        xAxisIndex: 0,
                        filterMode: "filter",
                        start: 0,
                        end: 100,
                    },
                ],
                series: [
                    {
                        symbolSize: 8,
                        symbol: 'circle',
                        smooth: true,
                        // name: "天际线分析",
                        // symbol: "none",
                        type: "line",
                        data: object.y,
                        lineStyle: {
                            width: 2,
                            shadowColor: 'rgba(145, 146, 148,0.7)',
                            shadowBlur: 10,
                            shadowOffsetY: 8
                        },
                    }
                ]
            };
            myChart.setOption(option);
        }
    };

    // 天际线体走数据服务
    function setSkyLineBody() {
        let param = skyline.getSkylineSectorParameter();
        let geometrySkylineSectorBodyPostParameter = {
            viewerPoint: param.viewPos,
            line3D: param.geoLine3D,
            height: 0,
            lonlat: true
        };

        let url = state.skylineSpatialAnalysisUrl;
        let queryData = JSON.stringify(geometrySkylineSectorBodyPostParameter);
        axios
            .post(url, queryData)
            .then(response => {
                //再发送一次GET请求  获取到运算结果
                axios
                    .get(response.data.newResourceLocation + ".json")
                    .then(response => {
                        let data = response.data;
                        if (data.geometry === null) {
                            return;
                        }
                        let uint8Array = new Uint8Array(data.geometry.model);
                        let buffer = uint8Array.buffer;
                        s3mInstance.add(
                            "SkyLineBody",
                            {
                                id: 1,
                                position: Cesium.Cartesian3.fromDegrees(
                                    data.geometry.position.x,
                                    data.geometry.position.y,
                                    data.geometry.position.z
                                ),
                                hpr: new Cesium.HeadingPitchRoll(0, 0, 0),
                                color: Cesium.Color.fromCssColorString(state.skyBodyColor)
                            },
                            buffer, false
                        );
                        data.geometry.model = [4, 0, 0, 0].concat(data.geometry.model);
                        // // 传到store可以做gpu查询
                        data.geometry["name"] = resource.SkyLineBody;
                        storeDate.geometrys["SkyLineBody"] = data.geometry;
                        actions.setGeometrys();
                    })
                    .catch(function (error) {
                        console.log(error);
                        tool.Message.errorMsg("获取天际线体数据失败", error);
                    });
            })
            .catch(function (error) {
                console.log(error);
                tool.Message.errorMsg("获取天际线体数据失败", error);
            });
    };

    // 天际线体走entity
    function setSkyLineBody2(observerObj) {
        let points = skyline.getSkyline3D();
        let pointArr = new Array();
        let cameraPoint = Cesium.Cartesian3.fromDegrees(observerObj.longitude, observerObj.latitude, observerObj.height);
        pointArr.push(cameraPoint);
        for (let i = 0; i < points.x.length; i++) {
            let point = Cesium.Cartesian3.fromDegrees(points.x[i], points.y[i], points.z[i]);
            pointArr.push(point);
        }
        viewer.entities.add({
            id: 'SkyLineBody',
            polygon: {
                extrudedHeight: 10,
                hierarchy: pointArr,
                perPositionHeight: true,
                material: Cesium.Color.fromCssColorString(state.skyBodyColor)
            }
        })
    }

    // 清除
    function clear() {
        clearHandlerDrawing();
        tooltip.setVisible(false);
        if (!state.observerInformation) return;
        // viewer.entities.removeAll();
        viewer.entities.removeById('SkyLineBody')
        if (skyline) {
            skyline.clear();
        }
        for (let i = 0; i < scene.layers._layerQueue.length; i++) {
            let layer = scene.layers.findByIndex(i);
            layer.removeAllObjsColor();
        }
        state.observerInformation = null;
        myChart.clear();
        initMyChart()
        s3mInstance.removeCollection("SkyLineBody");
        if (storeDate.geometrys.SkyLineBody) {
            delete storeDate.geometrys.SkyLineBody;
            actions.setGeometrys();
        }

    };

    // 监听

    watch(() => state.skylineRadius, val => {
        if (state.observerInformation) {
            skyline.radius = parseFloat(val);
            skyline.pitch = parseFloat(state.observerInformation.pitch);
        }
    });
    watch(() => state.lineWidth, val => {
        skyline.lineWidth = Number(val);
        if (state.observerInformation) {
            skyline.pitch = parseFloat(state.observerInformation.pitch); //加上才能实时改变线宽,可能是缺陷
        }
    });
    watch(() => state.skylineColor, newValue => {
        if (state.observerInformation && newValue != "") {
            let color = Cesium.Color.fromCssColorString(newValue);
            skyline.color = color;
            skyline.pitch = parseFloat(state.observerInformation.pitch);
        }
    });
    watch(() => state.barrierColor, newValue => {
        if (state.observerInformation || !state.highlightBarrier) {
            let BarrierColor = Cesium.Color.fromCssColorString(newValue);
            changeBarrierColor(BarrierColor);
        }
    });
    watch(() => state.ignoreGlobe, newValue => {
        if (skyline) skyline.ignoreGlobe = newValue;
    });


    watch(() => state.highlightBarrier, newValue => {
        if (newValue && state.observerInformation) {
            let BarrierColor = Cesium.Color.fromCssColorString(
                state.barrierColor
            );
            changeBarrierColor(BarrierColor);
        } else {
            for (let i = 0; i < scene.layers._layerQueue.length; i++) {
                let layer = scene.layers.findByIndex(i);
                layer.removeAllObjsColor();
            }
        }
    });
    watch(() => state.skyBodyColor, newValue => {
        if (state.observerInformation && newValue != "") {
            let color = Cesium.Color.fromCssColorString(newValue);
            if (state.skylineSpatialAnalysisUrl) {
                s3mInstance.getInstance("SkyLineBody", 1).updateColor(color);
            } else {
                viewer.entities.getById('SkyLineBody').polygon.material = color //不走服务用这个
            }
        }
    });
    watch(() => state.getSkyline2d, newValue => {
        if (!newValue || !myChart) {
            state.getSkyline2d = false;
            return;
        }
        setTimeout(() => {
            myChart.resize()  //自适应屏幕
        }, 200)

    });
    watch(() => state.skylineMode, newValue => {
        if (newValue == 0) {
            skyline.displayStyle = 0;
            viewer.entities.removeById('SkyLineBody')
            s3mInstance.removeCollection("SkyLineBody");
            if (storeDate.geometrys.SkyLineBody) {
                delete storeDate.geometrys.SkyLineBody;
                actions.setGeometrys();
            }
        } else if (newValue == 1) {
            skyline.displayStyle = 1;
            viewer.entities.removeById('SkyLineBody')
            s3mInstance.removeCollection("SkyLineBody");
            if (storeDate.geometrys.SkyLineBody) {
                delete storeDate.geometrys.SkyLineBody;
                actions.setGeometrys();
            }
        } else if (newValue == 2) {
            // 需要iServer910支持=
            skyline.displayStyle = 0;
            if (state.observerInformation) {
                if (state.skylineSpatialAnalysisUrl) {
                    setSkyLineBody(state.observerInformation)
                } else {
                    setSkyLineBody2(state.observerInformation)
                    // setSkyLineBody(state.observerInformation)
                }
            }
        }
    });

    // 销毁
    onBeforeUnmount(() => {
        clear();
        if (s3mInstance) {
            // s3mInstance.destroy();
        }
        skyline = undefined;
        myChart = undefined;
        s3mInstance = undefined;
    })

    return {
        ...toRefs(state),
        skyLineAnalysis,
        setLimitBody,
        echarts_box,
        clear
    };
}
Example #27
Source File: fly-route.js    From vue-iClient3D_for_Cesium with Apache License 2.0 4 votes vote down vote up
function compass(props) {

    // 设置默认值数据
    let state = reactive({
        routeType: "designatedRoute",  //自定义还得指定路线类型
        fileSrc: "",  //文件地址,不能同时使用fpfUrl
        fpfUrl: null, //指定fpf路径
        selectedStopIndex: 0,  //选中当前站点
        showRoute: false,  //显示路线
        showStop: false,   //显示站点
        currentStopNames: [],   //当前路线的站点名称集合
        //自定义
        customRouteNames: [],  //保存自定义路线名称
        customRouteSelectedIndex: null,  //自定义选中路线索引
        routeStops: [],  //自定义当前路线的站点集合
        selectedAddedStopIndex: null,    //自定义已加站点选中索引
        //站点
        setStopName: 'Stop-1',  //设置当前站点名称
        setStopSpeed: 0,   // 设置当前站点速度
        stopPlayMode: 'StopPause',  //设置站点模式:默认停留
        waitTime: 0,  //停留时间
        surroundDuration: 1,  //环绕模式时间
        //飞行路线设置
        isAlongline: false,  //获取或者设置该飞行路线是否是沿线飞行。
        routeSpeed: 200,  //飞行路线速度
    });


    // 传入props改变默认值
    if (props) {
        for (let key in props) {
            if (state.hasOwnProperty(key)) {
                state[key] = props[key]
            } else {
                tool.Message.errorMsg(resource.AttributeError + key);
            }
        }
    }

    // 初始化数据
    let flyManager, routeCollection; //创建飞行路线集合对象类
    let flyFile_dom = ref(null);
    let currentStops //当前路线所有站点集合
    let reader = new FileReader();
    let createXml, flyLineXmls = []; //创建和保存xml飞行路线文件

    if (storeState.isViewer) {
        if (!window.tooltip) {
            window.tooltip = createTooltip(viewer._element);
        }
        initFlyManager()
    }
    //viewer 初始化完成的监听
    watch(() => storeState.isViewer, val => {
        if (val) {
            if (!window.tooltip) {
                window.tooltip = createTooltip(viewer._element);
            }
            initFlyManager()
        }
    });

    onMounted(() => {
        fileChange();
    })


    /**
    * 指定路线分析
    */
    //初始化飞行管理
    function initFlyManager() {
        routeCollection = new Cesium.RouteCollection(viewer.entities);
        flyManager = new Cesium.FlyManager({
            scene: viewer.scene,
            routes: routeCollection
        });
        createXml = new createFlyLine_xml();
        if (state.fpfUrl) {
            fpfUrlChange()
        }
    }
    // 点击选择文件函数
    function chooseFile() {
        flyFile_dom.value.click();
    }

    // 改变默认fpf文件路径触发
    function fpfUrlChange() {
        flyManager.stop();
        routeCollection.fromFile(state.fpfUrl);
        flyManager.readyPromise.then(function () {
            let route = flyManager.currentRoute;
            route.isLineVisible = state.showRoute;
            route.isStopVisible = state.showStop;
            updateCurrentStops();
        })
    }
    //文件夹改变文件触发
    function fileChange() {
        flyFile_dom.value.addEventListener("change", evt => {
            flyManager.stop();
            let route = flyManager.currentRoute;
            if (route) route.clear(); //清除之前的
            routeCollection = new Cesium.RouteCollection(viewer.entities);  //飞行路线底层默认第一条路线,所以重新new
            let file = evt.target.files[0];
            if (!file) return;
            state.fileSrc = flyFile_dom.value.value;
            reader.onload = function (e) {
                // 读取操作完成时出发
                let XMLContent = e.target.result;
                routeCollection.fromXML(XMLContent);
            };
            reader.readAsBinaryString(file);
            readyPromise();
        });
    }
    // 异步飞行管理准备就绪函数
    function readyPromise() {
        routeCollection.readyPromise.then(() => {
            flyManager.routes = routeCollection;
            let route = flyManager.currentRoute;
            route.isLineVisible = state.showRoute;
            route.isStopVisible = state.showStop;
            updateCurrentStops();
        })
    }

    // 更新当前路线站点
    function updateCurrentStops() {
        state.currentStopNames.length = 0;
        currentStops = flyManager.getAllRouteStops();
        for (let i = 0, j = currentStops.length; i < j; i++) {
            let stopName = currentStops[i].stopName || 'Stop' + (i + 1);
            state.currentStopNames.push(stopName)
        }
    }
    // 更新当前飞行管理的所有路线(暂不支持路线选择,所有未开放)
    function updateAllRoutes() {
        state.allRoutes.length = 0;
        let allRoutes = routeCollection.routes;
        for (let i = 0, j = allRoutes.length; i < j; i++) {
            let route = '飞行路线' + (i + 1);
            state.allRoutes.push(route)
        }
    }

    function flyStart() {
        flyManager.readyPromise.then(() => {
            flyManager.play();
        })
    };
    function flyPause() {
        flyManager && flyManager.pause();
    };
    function flyStop() {
        flyManager && flyManager.stop();
    };

    /**
   * 自定义路线分析
   */
    // 添加站点
    function addStop() {
        flyManager.stop();
        let point = viewer.camera.position;
        let position = tool.CartesiantoDegrees(point);
        let stop = {
            stopName: state.setStopName,
            point: position,
            heading: viewer.camera.heading,
            tilt: viewer.camera.pitch,
            speed: state.setStopSpeed,
            stopPlayMode: state.stopPlayMode,
            surroundDuration: state.surroundDuration,
            waitTime: state.waitTime
        }
        state.routeStops.push(stop);
        if (state.routeStops.length > 0) {
            let len = state.routeStops.length;
            let lastStopName = state.routeStops[len - 1].stopName;
            let index = lastStopName.split('-')[1] || 1;
            let name = 'Stop-' + (Number(index) + 1);
            state.setStopName = name;
        }
        state.selectedAddedStopIndex = state.routeStops.length - 1;
    }

    // 保存站点
    function saveStop() {
        if (state.routeStops.length < 2) {
            tool.Message.warnMsg('节点小于2')
            return;
        }

        // 飞行路线配置
        let index = flyLineXmls.length + 1;
        let route = {
            routeName: '飞行路线_' + index,
            speed: state.routeSpeed,
            isAlongLine: "False",
            routeStops: state.routeStops
        }
        let xml = createXml.createXMLflyLine(route);
        flyLineXmls.push(xml);
        state.customRouteNames.push(route.routeName);
        // restStops();
        if (state.customRouteSelectedIndex === null)
            state.customRouteSelectedIndex = 0;
    }

    // 重置当前路线
    function restStops() {
        state.routeStops.length = 0;
        state.setStopName = 'Stop-1';
        state.setStopSpeed = 0;
        state.stopPlayMode = 'StopPause';
        state.waitTime = 0;
        state.surroundDuration = 1;
    }

    // 下载选择的飞行路线fpf文件
    function downLoad() {
        let data = flyLineXmls[state.customRouteSelectedIndex];
        if (!data) return;
        let blob = new Blob([data]);//将返回的数据包装成blob(方法的具体使用参考mdn)
        let alink = document.createElement("a");
        alink.download = 'fly-route.fpf';//文件名,大部分浏览器兼容,IE10及以下不兼容
        alink.href = URL.createObjectURL(blob);//根据blob 创建 url
        alink.click(); //自动点击
    }
    // 清除选中飞行路线
    function clearRoute() {
        flyManager.stop();
        if (flyLineXmls.length < 1) return;
        flyLineXmls.splice(state.customRouteSelectedIndex, 1);
        state.customRouteNames.splice(state.customRouteSelectedIndex, 1);
        if (flyLineXmls.length > 0) {
            state.customRouteSelectedIndex = 0;
            return;
        }
        state.customRouteSelectedIndex = null;
        state.currentStopNames.length = 0;
        let route = flyManager.currentRoute;
        if (route) route.clear(); //清除之前的

    }

    // 清除选中站点
    function clearStop() {
        state.routeStops.splice(state.selectedAddedStopIndex, 1);
        if (state.routeStops.length > 0) {
            state.selectedAddedStopIndex = state.routeStops.length - 1;
            return;
        }
        state.selectedAddedStopIndex = null;
        state.setStopName = 'Stop-1';
    }


    // 监听
    watch(() => state.selectedStopIndex, val => {
        flyManager && flyManager.stop();
        let index = Number(val);
        let stop = currentStops[index];
        flyManager.viewToStop(stop);
    });
    watch(() => state.showRoute, val => {
        let route = flyManager.currentRoute;
        if (route) route.isLineVisible = val
    });
    watch(() => state.showStop, val => {
        let route = flyManager.currentRoute;
        if (route) route.isStopVisible = val
    });
    watch(() => state.fpfUrl, val => {
        fpfUrlChange()
    });

    watch(() => state.customRouteSelectedIndex, val => {
        if (val === null) return;
        flyManager && flyManager.stop();
        let route = flyManager.currentRoute;
        if (route) route.clear(); //清除之前的
        routeCollection = new Cesium.RouteCollection(viewer.entities);  //飞行路线底层默认第一条路线,所以重新new
        routeCollection.fromXML(flyLineXmls[val]);
        readyPromise()
    });

    watch(() => state.selectedAddedStopIndex, val => {
        let stop = state.routeStops[val];
        if (!stop) return;
        viewer.camera.setView({
            destination: Cesium.Cartesian3.fromDegrees(stop.point[0], stop.point[1], stop.point[2]),
            orientation: {
                heading: stop.heading,
                pitch: stop.tilt,
                roll: 0
            }
        });
    });

    watch(() => state.routeType, val => {
        if(val === 'customRoute'){
            window.tooltip.showAt(' <p>调整当前相机位置和视角</p><p>以当前相机位置和视角设置站点</p><p>点击添加保存此站点</p>', '50%');
            setTimeout(()=>{
                window.tooltip.setVisible(false);
            },5000)
        }else{
            window.tooltip.setVisible(false);
        }
    });


    // 销毁
    onBeforeUnmount(() => {
        state = null;
        flyManager = routeCollection = null;
        currentStops = null;
        createXml = flyLineXmls = null;
    });


    return {
        ...toRefs(state),
        flyFile_dom,
        chooseFile,
        flyStart,
        flyPause,
        flyStop,
        addStop,
        saveStop,
        restStops,
        downLoad,
        clearRoute,
        clearStop
    };
}
Example #28
Source File: atropos-vue.js    From atropos with MIT License 4 votes vote down vote up
Atropos = {
  props: {
    component: { type: String, default: 'div' },
    innerClass: String,
    scaleClass: String,
    rotateClass: String,

    eventsEl: { type: [String, Object], default: undefined },
    alwaysActive: { type: Boolean, default: false },
    activeOffset: { type: Number, default: undefined },
    shadowOffset: { type: Number, default: undefined },
    shadowScale: { type: Number, default: undefined },
    duration: { type: Number, default: undefined },
    rotate: { type: Boolean, default: undefined },
    rotateTouch: { type: Boolean, default: undefined },
    rotateXMax: { type: Number, default: undefined },
    rotateYMax: { type: Number, default: undefined },
    rotateXInvert: { type: Boolean, default: undefined },
    rotateYInvert: { type: Boolean, default: undefined },
    stretchX: { type: Number, default: undefined },
    stretchY: { type: Number, default: undefined },
    stretchZ: { type: Number, default: undefined },
    commonOrigin: { type: Boolean, default: true },
    shadow: { type: Boolean, default: true },
    highlight: { type: Boolean, default: true },
  },
  emits: ['enter', 'leave', 'rotate'],
  setup(props, ctx) {
    const elRef = ref(null);
    const atroposRef = ref(null);
    const { slots, emit } = ctx;

    const init = () => {
      atroposRef.value = AtroposCore({
        el: elRef.value,
        ...props,
        onEnter() {
          emit('enter');
        },
        onLeave() {
          emit('leave');
        },
        onRotate(...args) {
          emit('rotate', ...args);
        },
      });
    };

    const destroy = () => {
      if (atroposRef.value) {
        atroposRef.value.destroy();
        atroposRef.value = null;
      }
    };

    onMounted(() => {
      init();
    });
    onBeforeUnmount(() => {
      destroy();
    });

    const cls = (...args) => {
      return args.filter((c) => !!c).join(' ');
    };

    return () =>
      h(
        props.component,
        {
          class: 'atropos',
          ref: elRef,
        },
        [
          h('span', { class: cls('atropos-scale', props.scaleClass) }, [
            h('span', { class: cls('atropos-rotate', props.rotateClass) }, [
              h('span', { class: cls('atropos-inner', props.innerClass) }, [
                slots.default && slots.default(),
                props.highlight && h('span', { class: 'atropos-highlight' }),
              ]),
              slots.rotate && slots.rotate(),
              props.shadow && h('span', { class: 'atropos-shadow' }),
            ]),
            slots.scale && slots.scale(),
          ]),
          slots.root && slots.root(),
        ],
      );
  },
}
Example #29
Source File: index.js    From vue-json-schema-form with Apache License 2.0 4 votes vote down vote up
globalOptions = {
    WIDGET_MAP,
    COMPONENT_MAP: {
        form: defineComponent({
            inheritAttrs: false,
            setup(props, { attrs, slots }) {
                // 处理 labelPosition 参数和 label-placement 之间的关系
                const labelPositionMap = {
                    top: {
                        labelAlign: 'left',
                        labelPlacement: 'top',
                    },
                    left: {
                        labelAlign: 'left',
                        labelPlacement: 'left',
                    },
                    right: {
                        labelAlign: 'right',
                        labelPlacement: 'left',
                    }
                };

                const formRef = ref(null);
                if (attrs.setFormRef) {
                    onMounted(() => {
                        // form组件实例上重置一个 validate 方法
                        formRef.value.$$validate = (callBack) => {
                            formRef.value.validate((errors) => {
                                if (errors) {
                                    return callBack(false, errors);
                                }

                                return callBack(true);
                            });
                        };

                        attrs.setFormRef(formRef.value);
                    });
                }

                return () => {
                    const {
                        // eslint-disable-next-line no-unused-vars
                        setFormRef, labelPosition, model, ...otherAttrs
                    } = attrs;

                    return h(vueUtils.resolveComponent('n-form'), {
                        ref: formRef,
                        model: model.value, // 不会自动解包
                        ...labelPositionMap[labelPosition || 'top'],
                        ...otherAttrs
                    }, slots);
                };
            }
        }),
        formItem: defineComponent({
            inheritAttrs: false,
            setup(props, { attrs, slots }) {
                return () => {
                    const { prop, rules, ...originAttrs } = attrs;
                    const childAttrs = {
                        ...originAttrs,
                        path: prop,
                        rule: (rules || []).map(validateRule => ({
                            trigger: validateRule.trigger,
                            asyncValidator(rule, value, callback) {
                                return validateRule.validator(rule, value, callback);
                            }
                        })),
                    };
                    return h(vueUtils.resolveComponent('n-form-item'), childAttrs, slots);
                };
            }
        }),
        button: 'n-button',
        // popover: ,
        popover: defineComponent({
            setup(props, { attrs, slots }) {
                return () => h(vueUtils.resolveComponent('n-popover'), attrs, {
                    trigger: slots.reference,
                    default: slots.default,
                });
            }
        }),
    },
    HELPERS: {
        // 是否mini显示 description
        isMiniDes(formProps) {
            return formProps && ['left', 'right'].includes(formProps.labelPosition);
        }
    }
}