diff --git a/beta.sh b/beta.sh index 48b17a59ce..eba5c59dd9 100644 --- a/beta.sh +++ b/beta.sh @@ -1,11 +1,11 @@ -npm dist-tag add @antv/l7-component@2.5.36 beta -npm dist-tag add @antv/l7-core@2.5.36 beta -npm dist-tag add @antv/l7@2.5.36 beta -npm dist-tag add @antv/l7-layers@2.5.36 beta -npm dist-tag add @antv/l7-map@2.5.36 beta -npm dist-tag add @antv/l7-maps@2.5.36 beta -npm dist-tag add @antv/l7-renderer@2.5.36 beta -npm dist-tag add @antv/l7-scene@2.5.36 beta -npm dist-tag add @antv/l7-source@2.5.36 beta -npm dist-tag add @antv/l7-three@2.5.36 beta -npm dist-tag add @antv/l7-utils@2.5.36 beta +npm dist-tag add @antv/l7-component@2.5.41 beta +npm dist-tag add @antv/l7-core@2.5.41 beta +npm dist-tag add @antv/l7@2.5.41 beta +npm dist-tag add @antv/l7-layers@2.5.41 beta +npm dist-tag add @antv/l7-map@2.5.41 beta +npm dist-tag add @antv/l7-maps@2.5.41 beta +npm dist-tag add @antv/l7-renderer@2.5.41 beta +npm dist-tag add @antv/l7-scene@2.5.41 beta +npm dist-tag add @antv/l7-source@2.5.41 beta +npm dist-tag add @antv/l7-three@2.5.41 beta +npm dist-tag add @antv/l7-utils@2.5.41 beta diff --git a/build/rollup-plugin-miniapp.js b/build/rollup-plugin-miniapp.js new file mode 100644 index 0000000000..26180f910a --- /dev/null +++ b/build/rollup-plugin-miniapp.js @@ -0,0 +1,47 @@ +import inject from '@rollup/plugin-inject'; +import modify from '@rollup/plugin-modify'; + +const module = '@oasis-engine/miniprogram-adapter '; + +function register(name) { + return [module, name]; +} + +function resolveFile(filePath) { + return path.join(__dirname, '..', filePath); +} + +const adapterArray = [ + 'window', + 'atob', + 'devicePixelRatio', + 'document', + 'Element', + 'Event', + 'EventTarget', + 'HTMLCanvasElement', + 'HTMLElement', + 'HTMLMediaElement', + 'HTMLVideoElement', + 'Image', + 'navigator', + 'Node', + 'requestAnimationFrame', + 'cancelAnimationFrame', + 'screen', + 'XMLHttpRequest', + 'performance', +]; +const adapterVars = {}; + +adapterArray.forEach((name) => { + adapterVars[name] = register(name); +}); + +export default [ + inject(adapterVars), + modify({ + find: /^@antv\/l7-(.*)/, + replacement: resolveFile('packages/$1/src'), + }), +]; diff --git a/build/rollup.config.js b/build/rollup.config.js index 905dbe18c6..1085e82eff 100644 --- a/build/rollup.config.js +++ b/build/rollup.config.js @@ -9,6 +9,9 @@ import babel from 'rollup-plugin-babel'; import glsl from './rollup-plugin-glsl'; import postcss from 'rollup-plugin-postcss'; import url from 'postcss-url'; +import miniAdapter from './rollup-plugin-miniapp'; + + const { BUILD, MINIFY } = process.env; const minified = MINIFY === 'true'; const production = BUILD === 'production'; @@ -17,6 +20,8 @@ const outputFile = !production : minified ? 'packages/l7/dist/l7.js' : 'packages/l7/dist/l7-dev.js'; + + function resolveFile(filePath) { return path.join(__dirname, '..', filePath); } @@ -61,6 +66,7 @@ module.exports = [ [ '**/*.glsl' ], true ), + miniAdapter(), json(), postcss({ extract: false, diff --git a/dev-docs/IoC 容器、依赖注入与服务说明.md b/dev-docs/IoC 容器、依赖注入与服务说明.md index c154b448c6..d7c9432817 100644 --- a/dev-docs/IoC 容器、依赖注入与服务说明.md +++ b/dev-docs/IoC 容器、依赖注入与服务说明.md @@ -61,34 +61,6 @@ rootContainer * Shader 模块化服务。提供基本的 GLSL 模块化服务,基于字符串替换实现。 * 配置项校验服务。[详见](./ConfigSchemaValidation.md) -### 日志服务 - -基于 `probe.gl` 实现,默认只输出 debug 级别以上的日志信息。开发模式下通过设置日志等级输出 debug 信息,另外 debug 信息会带上时间戳打点,类似这样: -```bash -L7: 403ms map loaded -L7: 405ms add event listeners on canvas -L7: 676ms regenerate vertex attributes: color finished -``` - -通过 `logger` 引用,可使用 API 如下: - -| 方法名 | 参数 | 返回值 | 说明 | -| -------- | ------------- | --------- | --------- | -| debug | `(message: string)` | 无 | 输出 debug 级别信息,会带上时间戳 | -| info | `(message: string)` | 无 | 输出 info 级别信息 | -| warn | `(message: string)` | 无 | 输出 warn 级别信息 | -| error | `(message: string)` | 无 | 输出 error 级别信息 | - -在自定义图层中使用示例如下: -```typescript -class PolygonLayer extends BaseLayer { - protected renderModels() { - // 输出 debug 级别信息 - this.logger.debug('start to render...'); - } -} -``` - ### Shader 模块化服务 通过 `shaderModuleService` 引用,可使用 API 如下: diff --git a/gatsby-browser.js b/gatsby-browser.js index b13be50271..dcde6c23f3 100644 --- a/gatsby-browser.js +++ b/gatsby-browser.js @@ -5,6 +5,7 @@ require('antd/dist/antd.less'); window.geotiff = require('geotiff'); window.g2 = require('@antv/g2'); window.l7 = require('@antv/l7'); +window.l7Mini = require('@antv/l7-mini'); window.l7Maps = require('@antv/l7-maps'); window.l7React = require('@antv/l7-react'); window.l7Draw = require('@antv/l7-draw'); diff --git a/gatsby-node.js b/gatsby-node.js index fbcc964515..a92bc22a0e 100644 --- a/gatsby-node.js +++ b/gatsby-node.js @@ -11,6 +11,7 @@ exports.onCreateWebpackConfig = ({ getConfig }) => { config.resolve.alias = { ...config.resolve.alias, '@antv/l7': path.resolve(__dirname, 'packages/l7/src'), + '@antv/l7-mini': path.resolve(__dirname, 'packages/mini/src'), '@antv/l7-core': path.resolve(__dirname, 'packages/core/src'), '@antv/l7-component': path.resolve(__dirname, 'packages/component/src'), '@antv/l7-layers': path.resolve(__dirname, 'packages/layers/src'), diff --git a/latest.sh b/latest.sh index d4fdfd9137..7c23f6849a 100644 --- a/latest.sh +++ b/latest.sh @@ -1,11 +1,11 @@ -npm dist-tag add @antv/l7-component@2.5.35 latest -npm dist-tag add @antv/l7-core@2.5.35 latest -npm dist-tag add @antv/l7@2.5.35 latest -npm dist-tag add @antv/l7-layers@2.5.35 latest -npm dist-tag add @antv/l7-map@2.5.35 latest -npm dist-tag add @antv/l7-maps@2.5.35 latest -npm dist-tag add @antv/l7-renderer@2.5.35 latest -npm dist-tag add @antv/l7-scene@2.5.35 latest -npm dist-tag add @antv/l7-source@2.5.35 latest -npm dist-tag add @antv/l7-three@2.5.35 latest -npm dist-tag add @antv/l7-utils@2.5.35 latest +npm dist-tag add @antv/l7-component@2.5.40 latest +npm dist-tag add @antv/l7-core@2.5.40 latest +npm dist-tag add @antv/l7@2.5.40 latest +npm dist-tag add @antv/l7-layers@2.5.40 latest +npm dist-tag add @antv/l7-map@2.5.40 latest +npm dist-tag add @antv/l7-maps@2.5.40 latest +npm dist-tag add @antv/l7-renderer@2.5.40 latest +npm dist-tag add @antv/l7-scene@2.5.40 latest +npm dist-tag add @antv/l7-source@2.5.40 latest +npm dist-tag add @antv/l7-three@2.5.40 latest +npm dist-tag add @antv/l7-utils@2.5.40 latest diff --git a/mini.sh b/mini.sh new file mode 100644 index 0000000000..10d8a89a3a --- /dev/null +++ b/mini.sh @@ -0,0 +1,12 @@ +npm dist-tag add @antv/l7-component@2.5.37-mini20 mini +npm dist-tag add @antv/l7-core@2.5.37-mini20 mini +npm dist-tag add @antv/l7@2.5.37-mini20 mini +npm dist-tag add @antv/l7-mini@2.5.37-mini20 mini +npm dist-tag add @antv/l7-layers@2.5.37-mini20 mini +npm dist-tag add @antv/l7-map@2.5.37-mini20 mini +npm dist-tag add @antv/l7-maps@2.5.37-mini20 mini +npm dist-tag add @antv/l7-renderer@2.5.37-mini20 mini +npm dist-tag add @antv/l7-scene@2.5.37-mini20 mini +npm dist-tag add @antv/l7-source@2.5.37-mini20 mini +npm dist-tag add @antv/l7-three@2.5.37-mini20 mini +npm dist-tag add @antv/l7-utils@2.5.37-mini20 mini diff --git a/package.json b/package.json index 17c4eab9ad..9d76f99e58 100644 --- a/package.json +++ b/package.json @@ -50,7 +50,7 @@ "babel-plugin-inline-import": "^3.0.0", "babel-plugin-inline-webgl-constants": "^1.0.1", "babel-plugin-lodash": "^3.3.4", - "babel-plugin-transform-import-css-l7": "^0.0.4", + "babel-plugin-transform-import-css-l7": "^0.0.5", "babel-plugin-transform-import-styles": "^0.0.11", "babel-plugin-transform-inline-environment-variables": "^0.4.3", "babel-plugin-transform-node-env-inline": "^0.4.3", diff --git a/packages/core/package.json b/packages/core/package.json index 19b0a386dd..087bbf3511 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -26,16 +26,15 @@ "@antv/async-hook": "^2.1.0", "@antv/l7-utils": "^2.5.42", "@babel/runtime": "^7.7.7", - "@mapbox/tiny-sdf": "^1.1.1", + "l7-tiny-sdf": "^0.0.2", "ajv": "^6.10.2", "element-resize-event": "^3.0.3", "eventemitter3": "^4.0.0", "gl-matrix": "^3.1.0", - "hammerjs": "^2.0.8", + "l7hammerjs": "^0.0.5", "inversify": "^5.0.1", "inversify-inject-decorators": "^3.1.0", "lodash": "^4.17.15", - "probe.gl": "^3.1.1", "reflect-metadata": "^0.1.13", "viewport-mercator-project": "^6.2.1" }, diff --git a/packages/core/src/services/asset/FontService.ts b/packages/core/src/services/asset/FontService.ts index 6a71c22e19..84c6139b13 100644 --- a/packages/core/src/services/asset/FontService.ts +++ b/packages/core/src/services/asset/FontService.ts @@ -1,7 +1,6 @@ -import { LRUCache } from '@antv/l7-utils'; -// @ts-ignore -import TinySDF from '@mapbox/tiny-sdf'; +import { $window, LRUCache } from '@antv/l7-utils'; import { inject, injectable } from 'inversify'; +import TinySDF from 'l7-tiny-sdf'; import 'reflect-metadata'; import { buildMapping } from '../../utils/font_util'; import { @@ -182,7 +181,7 @@ export default class FontService implements IFontService { } = this.fontOptions; let canvas = cachedFontAtlas && cachedFontAtlas.data; if (!canvas) { - canvas = document.createElement('canvas'); + canvas = $window.document.createElement('canvas'); canvas.width = MAX_CANVAS_WIDTH; } const ctx = canvas.getContext('2d') as CanvasRenderingContext2D; diff --git a/packages/core/src/services/asset/IIconService.ts b/packages/core/src/services/asset/IIconService.ts index 52e431958d..e39f42e24e 100644 --- a/packages/core/src/services/asset/IIconService.ts +++ b/packages/core/src/services/asset/IIconService.ts @@ -1,5 +1,6 @@ import EventEmitter from 'eventemitter3'; import { ITexture2D } from '../renderer/ITexture2D'; +import { ISceneService } from '../scene/ISceneService'; export type IImage = HTMLImageElement | File | string; export type Listener = (...args: any[]) => void; export interface IIconValue { @@ -25,6 +26,7 @@ export interface IIconService { off(event: string, fn: EventEmitter.ListenerFn, context?: any): this; init(): void; addImage(id: string, image: IImage): void; + addImageMini(id: string, image: IImage, sceneService?: ISceneService): void; hasImage(id: string): boolean; removeImage(id: string): void; getTexture(): ITexture2D; diff --git a/packages/core/src/services/asset/IconService.ts b/packages/core/src/services/asset/IconService.ts index 8234898380..72cd77df1b 100644 --- a/packages/core/src/services/asset/IconService.ts +++ b/packages/core/src/services/asset/IconService.ts @@ -1,11 +1,10 @@ -// @ts-ignore -import TinySDF from '@mapbox/tiny-sdf'; +import { $window } from '@antv/l7-utils'; import { EventEmitter } from 'eventemitter3'; import { inject, injectable } from 'inversify'; import 'reflect-metadata'; -import { TYPES } from '../../types'; import { buildIconMaping } from '../../utils/font_util'; import { ITexture2D } from '../renderer/ITexture2D'; +import { ISceneService } from '../scene/ISceneService'; import { IIcon, IICONMap, @@ -32,7 +31,7 @@ export default class IconService extends EventEmitter implements IIconService { public init() { this.iconData = []; this.iconMap = {}; - this.canvas = document.createElement('canvas'); + this.canvas = $window.document.createElement('canvas'); this.ctx = this.canvas.getContext('2d') as CanvasRenderingContext2D; } @@ -61,6 +60,39 @@ export default class IconService extends EventEmitter implements IIconService { }); } + /** + * 适配小程序 + * @param id + * @param image + * @param sceneService + */ + public addImageMini(id: string, image: IImage, sceneService: ISceneService) { + const canvas = sceneService.getSceneConfig().canvas; + // @ts-ignore + let imagedata = canvas.createImage(); + this.loadingImageCount++; + if (this.hasImage(id)) { + throw new Error('Image Id already exists'); + } + this.iconData.push({ + id, + size: imageSize, + }); + this.updateIconMap(); + this.loadImageMini(image, canvas as HTMLCanvasElement).then((img) => { + imagedata = img as HTMLImageElement; + const iconImage = this.iconData.find((icon: IIcon) => { + return icon.id === id; + }); + if (iconImage) { + iconImage.image = imagedata; + iconImage.width = imagedata.width; + iconImage.height = imagedata.height; + } + this.update(); + }); + } + public getTexture(): ITexture2D { return this.texture; } @@ -153,4 +185,24 @@ export default class IconService extends EventEmitter implements IIconService { image.src = url instanceof File ? URL.createObjectURL(url) : url; }); } + + /** + * 适配小程序 + * @param url + * @returns + */ + private loadImageMini(url: IImage, canvas: HTMLCanvasElement) { + return new Promise((resolve, reject) => { + // @ts-ignore + const image = canvas.createImage(); + image.crossOrigin = 'anonymous'; + image.onload = () => { + resolve(image); + }; + image.onerror = () => { + reject(new Error('Could not load image at ' + url)); + }; + image.src = url as string; + }); + } } diff --git a/packages/core/src/services/config/IConfigService.ts b/packages/core/src/services/config/IConfigService.ts index ea803a0f56..b61b64f75d 100644 --- a/packages/core/src/services/config/IConfigService.ts +++ b/packages/core/src/services/config/IConfigService.ts @@ -5,6 +5,8 @@ import { IMapWrapper } from '../map/IMapService'; import { IRenderConfig } from '../renderer/IRendererService'; export interface ISceneConfig extends IRenderConfig { id: string | HTMLDivElement; + canvas?: HTMLCanvasElement; + hasBaseMap?: boolean; map: IMapWrapper; logoPosition?: PositionName; logoVisible?: boolean; diff --git a/packages/core/src/services/interaction/InteractionService.ts b/packages/core/src/services/interaction/InteractionService.ts index b45175edaf..f255e18895 100644 --- a/packages/core/src/services/interaction/InteractionService.ts +++ b/packages/core/src/services/interaction/InteractionService.ts @@ -1,6 +1,7 @@ +import { $window, isMini } from '@antv/l7-utils'; import EventEmitter from 'eventemitter3'; -import Hammer from 'hammerjs'; import { inject, injectable } from 'inversify'; +import Hammer from 'l7hammerjs'; // l7 - mini import 'reflect-metadata'; // @ts-ignore import { TYPES } from '../../types'; @@ -21,8 +22,9 @@ export default class InteractionService extends EventEmitter implements IInteractionService { @inject(TYPES.IMapService) private readonly mapService: IMapService; - - private hammertime: HammerManager; + // @ts-ignore + // private hammertime: HammerManager; + private hammertime: any; private lastClickTime: number = 0; @@ -57,59 +59,85 @@ export default class InteractionService extends EventEmitter this.emit(InteractionEvent.Active, { featureId: id }); } + public handleMiniEvent(e: any) { + // @ts-ignore + this.onHover({ + clientX: e.touches[0].pageX, + clientY: e.touches[0].pageY, + type: 'touch', + }); + } + private addEventListenerOnMap() { const $containter = this.mapService.getMapContainer(); if ($containter) { - const hammertime = new Hammer.Manager($containter); - hammertime.add( - new Hammer.Tap({ - event: 'dblclick', - taps: 2, - }), - ); - hammertime.add( - new Hammer.Tap({ - event: 'click', - }), - ); - hammertime.add(new Hammer.Pan({ threshold: 0, pointers: 0 })); - hammertime.add(new Hammer.Press({})); - // hammertime.get('pan').set({ direction: Hammer.DIRECTION_ALL }); - // hammertime.get('pinch').set({ enable: true }); - hammertime.on('dblclick click', this.onHammer); - hammertime.on('panstart panmove panend pancancel', this.onDrag); - // $containter.addEventListener('touchstart', this.onTouch); - $containter.addEventListener('mousemove', this.onHover); - // $containter.addEventListener('click', this.onHover); - $containter.addEventListener('mousedown', this.onHover, true); - $containter.addEventListener('mouseup', this.onHover); - $containter.addEventListener('contextmenu', this.onHover); + if (isMini) { + $window.document.addEventListener( + 'touchstart', + this.handleMiniEvent.bind(this), + ); + } else { + const hammertime = new Hammer.Manager($containter); + // $containter.addEventListener('mousemove', this.onHover); + // $containter.addEventListener('click', this.onHover); + hammertime.add( + new Hammer.Tap({ + event: 'dblclick', + taps: 2, + }), + ); + hammertime.add( + new Hammer.Tap({ + event: 'click', + }), + ); + hammertime.add(new Hammer.Pan({ threshold: 0, pointers: 0 })); + hammertime.add(new Hammer.Press({})); + // hammertime.get('pan').set({ direction: Hammer.DIRECTION_ALL }); + // hammertime.get('pinch').set({ enable: true }); + hammertime.on('dblclick click', this.onHammer); + hammertime.on('panstart panmove panend pancancel', this.onDrag); + // $containter.addEventListener('touchstart', this.onTouch); + $containter.addEventListener('mousemove', this.onHover); + // $containter.addEventListener('click', this.onHover); + $containter.addEventListener('mousedown', this.onHover, true); + $containter.addEventListener('mouseup', this.onHover); + $containter.addEventListener('contextmenu', this.onHover); + this.hammertime = hammertime; + } - this.hammertime = hammertime; - - // TODO: 根据场景注册事件到 L7 canvas 上 + // // TODO: 根据场景注册事件到 L7 canvas 上 } } private removeEventListenerOnMap() { - const $containter = this.mapService.getMapContainer(); - if ($containter) { - $containter.removeEventListener('mousemove', this.onHover); - // this.hammertime.off('dblclick click', this.onHammer); - this.hammertime.off('panstart panmove panend pancancel', this.onDrag); - // $containter.removeEventListener('touchstart', this.onTouch); - // $containter.removeEventListener('click', this.onHover); - $containter.removeEventListener('mousedown', this.onHover); - $containter.removeEventListener('mouseup', this.onHover); - // $containter.removeEventListener('dblclick', this.onHover); - $containter.removeEventListener('contextmenu', this.onHover); + if (isMini) { + $window.document.removeEventListener( + 'touchstart', + this.handleMiniEvent.bind(this), + ); + } else { + const $containter = this.mapService.getMapContainer(); + if ($containter) { + $containter.removeEventListener('mousemove', this.onHover); + // this.hammertime.off('dblclick click', this.onHammer); + this.hammertime.off('panstart panmove panend pancancel', this.onDrag); + // $containter.removeEventListener('touchstart', this.onTouch); + // $containter.removeEventListener('click', this.onHover); + $containter.removeEventListener('mousedown', this.onHover); + $containter.removeEventListener('mouseup', this.onHover); + // $containter.removeEventListener('dblclick', this.onHover); + $containter.removeEventListener('contextmenu', this.onHover); + } } } - private onDrag = (target: HammerInput) => { + + private onDrag = (target: any) => { const interactionTarget = this.interactionEvent(target); interactionTarget.type = DragEventMap[interactionTarget.type]; this.emit(InteractionEvent.Drag, interactionTarget); }; - private onHammer = (target: HammerInput) => { + + private onHammer = (target: any) => { target.srcEvent.stopPropagation(); const interactionTarget = this.interactionEvent(target); this.emit(InteractionEvent.Hover, interactionTarget); @@ -124,7 +152,7 @@ export default class InteractionService extends EventEmitter }); }; - private interactionEvent(target: HammerInput) { + private interactionEvent(target: any) { const { type, pointerType } = target; let clientX; let clientY; @@ -152,15 +180,26 @@ export default class InteractionService extends EventEmitter const type = event.type; const $containter = this.mapService.getMapContainer(); if ($containter) { - const { top, left } = $containter.getBoundingClientRect(); - x = x - left - $containter.clientLeft; - y = y - top - $containter.clientTop; + if (isMini) { + // l7 - mini + // @ts-ignore + x = x - $containter.left - 0; + // @ts-ignore + y = y - $containter.top - 0; + } else { + const { top, left } = $containter.getBoundingClientRect(); + x = x - left - $containter.clientLeft; + y = y - top - $containter.clientTop; + } } const lngLat = this.mapService.containerToLngLat([x, y]); if (type === 'click') { - if ('ontouchstart' in document.documentElement === true) { - return; + if (!isMini) { + // l7 - mini + if ('ontouchstart' in document.documentElement === true) { + return; + } } this.isDoubleTap(x, y, lngLat); return; diff --git a/packages/core/src/services/interaction/PickingService.ts b/packages/core/src/services/interaction/PickingService.ts index 2660ee67b7..e385275fb5 100644 --- a/packages/core/src/services/interaction/PickingService.ts +++ b/packages/core/src/services/interaction/PickingService.ts @@ -15,7 +15,6 @@ import { gl } from '../renderer/gl'; import { IFramebuffer } from '../renderer/IFramebuffer'; import { IRendererService } from '../renderer/IRendererService'; import { IPickingService } from './IPickingService'; - @injectable() export default class PickingService implements IPickingService { @inject(TYPES.IRendererService) @@ -46,10 +45,10 @@ export default class PickingService implements IPickingService { getViewportSize, getContainer, } = this.rendererService; - let { - width, - height, - } = (getContainer() as HTMLElement).getBoundingClientRect(); + + let { width, height } = this.getContainerSize( + getContainer() as HTMLCanvasElement | HTMLElement, + ); width *= DOM.DPR; height *= DOM.DPR; this.pickBufferScale = @@ -99,10 +98,9 @@ export default class PickingService implements IPickingService { return Math.floor((tmpV * DOM.DPR) / this.pickBufferScale); }); const { getViewportSize, readPixels, getContainer } = this.rendererService; - let { - width, - height, - } = (getContainer() as HTMLElement).getBoundingClientRect(); + let { width, height } = this.getContainerSize( + getContainer() as HTMLCanvasElement | HTMLElement, + ); width *= DOM.DPR; height *= DOM.DPR; if ( @@ -139,6 +137,18 @@ export default class PickingService implements IPickingService { } return features; } + + // 获取容器的大小 - 兼容小程序环境 + private getContainerSize(container: HTMLCanvasElement | HTMLElement) { + if (!!(container as HTMLCanvasElement).getContext) { + return { + width: (container as HTMLCanvasElement).width, + height: (container as HTMLCanvasElement).height, + }; + } else { + return container.getBoundingClientRect(); + } + } private async pickingAllLayer(target: IInteractionTarget) { if ( // TODO: this.alreadyInPicking 避免多次重复拾取 @@ -159,10 +169,9 @@ export default class PickingService implements IPickingService { private resizePickingFBO() { const { getContainer } = this.rendererService; - let { - width, - height, - } = (getContainer() as HTMLElement).getBoundingClientRect(); + let { width, height } = this.getContainerSize( + getContainer() as HTMLCanvasElement | HTMLElement, + ); width *= DOM.DPR; height *= DOM.DPR; if (this.width !== width || this.height !== height) { @@ -211,10 +220,9 @@ export default class PickingService implements IPickingService { ) => { let isPicked = false; const { getViewportSize, readPixels, getContainer } = this.rendererService; - let { - width, - height, - } = (getContainer() as HTMLElement).getBoundingClientRect(); + let { width, height } = this.getContainerSize( + getContainer() as HTMLCanvasElement | HTMLElement, + ); width *= DOM.DPR; height *= DOM.DPR; const { enableHighlight, enableSelect } = layer.getLayerConfig(); diff --git a/packages/core/src/services/layer/ILayerService.ts b/packages/core/src/services/layer/ILayerService.ts index fb39a7180f..c266eaba61 100644 --- a/packages/core/src/services/layer/ILayerService.ts +++ b/packages/core/src/services/layer/ILayerService.ts @@ -372,6 +372,7 @@ export interface ILayerConfig { export interface ILayerService { clock: Clock; alreadyInRendering: boolean; + sceneService?: any; add(layer: ILayer): void; initLayers(): void; startAnimate(): void; diff --git a/packages/core/src/services/layer/LayerService.ts b/packages/core/src/services/layer/LayerService.ts index c36ab2876f..2bbc5ca7ee 100644 --- a/packages/core/src/services/layer/LayerService.ts +++ b/packages/core/src/services/layer/LayerService.ts @@ -1,4 +1,4 @@ -import { rgb2arr } from '@antv/l7-utils'; +import { $window, rgb2arr } from '@antv/l7-utils'; import { inject, injectable } from 'inversify'; import 'reflect-metadata'; import { ILayer } from '../..'; @@ -238,6 +238,6 @@ export default class LayerService implements ILayerService { } private stopRender() { - cancelAnimationFrame(this.layerRenderID); + $window.cancelAnimationFrame(this.layerRenderID); } } diff --git a/packages/core/src/services/map/IMapService.ts b/packages/core/src/services/map/IMapService.ts index 592e90baa3..282f746b30 100644 --- a/packages/core/src/services/map/IMapService.ts +++ b/packages/core/src/services/map/IMapService.ts @@ -26,7 +26,12 @@ export interface IStatusOptions { } export type MapStyle = string | { [key: string]: any }; export interface IMapWrapper { - setContainer(container: Container, id: string | HTMLDivElement): void; + setContainer( + container: Container, + id: string | HTMLDivElement, + canvas?: HTMLCanvasElement, + hasBaseMap?: boolean, + ): void; } export interface IMapService { @@ -36,6 +41,7 @@ export interface IMapService { bgColor: string; setBgColor(color: string): void; init(): void; + initMiniMap?(): void; initViewPort?(): void; destroy(): void; onCameraChanged(callback: (viewport: IViewport) => void): void; diff --git a/packages/core/src/services/renderer/passes/TAAPass.ts b/packages/core/src/services/renderer/passes/TAAPass.ts index c07f61fa7a..da21e15f50 100644 --- a/packages/core/src/services/renderer/passes/TAAPass.ts +++ b/packages/core/src/services/renderer/passes/TAAPass.ts @@ -1,3 +1,4 @@ +import { $window } from '@antv/l7-utils'; import { inject, injectable } from 'inversify'; import 'reflect-metadata'; import blendFS from '../../../shaders/post-processing/blend.glsl'; @@ -176,14 +177,15 @@ export default class TAAPass extends BaseNormalPass< if (!this.isFinished()) { this.doRender(layer); - requestAnimationFrame(() => { + $window.requestAnimationFrame(() => { accumulate(id); }); } }; this.accumulatingId = accumulatingId++; - this.timer = window.setTimeout(() => { + // @ts-ignore + this.timer = $window.setTimeout(() => { accumulate(this.accumulatingId); }, 50); } @@ -290,7 +292,7 @@ export default class TAAPass extends BaseNormalPass< private stopAccumulating() { this.accumulatingId = 0; - window.clearTimeout(this.timer); + $window.clearTimeout(this.timer); } private createTriangleModel( diff --git a/packages/core/src/services/scene/ISceneService.ts b/packages/core/src/services/scene/ISceneService.ts index 7305c07a6f..b35551e25e 100644 --- a/packages/core/src/services/scene/ISceneService.ts +++ b/packages/core/src/services/scene/ISceneService.ts @@ -12,6 +12,7 @@ export interface ISceneService { off(type: string, handle: (...args: any[]) => void): void; removeAllListeners(event?: string): this; init(config: IMapConfig & IRenderConfig): void; + initMiniScene(config: IMapConfig & IRenderConfig): void; addLayer(layer: ILayer): void; getSceneConfig(): Partial; render(type?: string): void; diff --git a/packages/core/src/services/scene/SceneService.ts b/packages/core/src/services/scene/SceneService.ts index 94bb7121fc..bc145fdadf 100644 --- a/packages/core/src/services/scene/SceneService.ts +++ b/packages/core/src/services/scene/SceneService.ts @@ -1,6 +1,6 @@ // @ts-ignore import { AsyncParallelHook } from '@antv/async-hook'; -import { DOM } from '@antv/l7-utils'; +import { DOM, isMini } from '@antv/l7-utils'; import elementResizeEvent, { unbind } from 'element-resize-event'; import { EventEmitter } from 'eventemitter3'; import { inject, injectable } from 'inversify'; @@ -99,7 +99,7 @@ export default class Scene extends EventEmitter implements ISceneService { /** * canvas 容器 */ - private $container: HTMLDivElement | null; + private $container: HTMLDivElement | null | HTMLCanvasElement; private canvas: HTMLCanvasElement; @@ -164,7 +164,6 @@ export default class Scene extends EventEmitter implements ISceneService { await this.map.init(); this.map.initViewPort(); } - // this.controlService.addControls(); // 重新绑定非首次相机更新事件 this.map.onCameraChanged(this.handleMapCameraChanged); @@ -194,8 +193,6 @@ export default class Scene extends EventEmitter implements ISceneService { // 添加marker container; this.$container = $container; - // this.addMarkerContainer(); - if ($container) { this.canvas = DOM.create('canvas', '', $container) as HTMLCanvasElement; this.setCanvas(); @@ -205,8 +202,6 @@ export default class Scene extends EventEmitter implements ISceneService { this.configService.getSceneConfig(this.id) as IRenderConfig, ); - // this.initContainer(); - // window.addEventListener('resize', this.handleWindowResized); elementResizeEvent( this.$container as HTMLDivElement, this.handleWindowResized, @@ -227,7 +222,78 @@ export default class Scene extends EventEmitter implements ISceneService { this.render(); } + /** + * 小程序环境下初始化 Scene + * @param sceneConfig + */ + public initMiniScene(sceneConfig: ISceneConfig) { + // 设置场景配置项 + this.configService.setSceneConfig(this.id, sceneConfig); + + // 初始化 ShaderModule + this.shaderModuleService.registerBuiltinModules(); + + // 初始化资源管理 图片 + this.iconService.init(); + // 字体资源 + this.fontService.init(); + + /** + * 初始化底图 + */ + this.hooks.init.tapPromise('initMap', async () => { + // 等待首次相机同步 + await new Promise((resolve) => { + this.map.onCameraChanged((viewport: IViewport) => { + this.cameraService.init(); + this.cameraService.update(viewport); + if (this.map.version !== 'GAODE2.x') { + // not amap2 + resolve(); + } + }); + // @ts-ignore + this.map.initMiniMap(); + }); + + // 重新绑定非首次相机更新事件 + this.map.onCameraChanged(this.handleMapCameraChanged); + + // 地图初始化之后 才能初始化 container 上的交互 + this.interactionService.init(); + this.interactionService.on( + InteractionEvent.Drag, + this.addSceneEvent.bind(this), + ); + }); + + /** + * 初始化渲染引擎 + */ + this.hooks.init.tapPromise('initRenderer', async () => { + // 创建底图之上的 container + const $container = sceneConfig.canvas; + + // 添加marker container; + this.$container = $container ? $container : null; + await this.rendererService.init( + // @ts-ignore + sceneConfig.canvas, + this.configService.getSceneConfig(this.id) as IRenderConfig, + ); + + this.pickingService.init(this.id); + }); + // TODO:init worker, fontAtlas... + + // 执行异步并行初始化任务 + // @ts-ignore + this.initPromise = this.hooks.init.promise(); + this.render(); + } + public addLayer(layer: ILayer) { + this.layerService.sceneService = this; this.layerService.add(layer); this.render(); } @@ -365,8 +431,8 @@ export default class Scene extends EventEmitter implements ISceneService { if (canvas) { canvas.width = w * pixelRatio; canvas.height = h * pixelRatio; - canvas.style.width = `${w}px`; - canvas.style.height = `${h}px`; + // canvas.style.width = `${w}px`; + // canvas.style.height = `${h}px`; } this.rendererService.viewport({ x: 0, @@ -383,8 +449,10 @@ export default class Scene extends EventEmitter implements ISceneService { const canvas = this.canvas; canvas.width = w * pixelRatio; canvas.height = h * pixelRatio; - canvas.style.width = `${w}px`; - canvas.style.height = `${h}px`; + // canvas.style.width = `${w}px`; + // canvas.style.height = `${h}px`; + canvas.style.width = '100%'; + canvas.style.height = '100%'; } private handleMapCameraChanged = (viewport: IViewport) => { diff --git a/packages/core/src/shaders/picking.frag.glsl b/packages/core/src/shaders/picking.frag.glsl index cdfc354fb2..879e266994 100644 --- a/packages/core/src/shaders/picking.frag.glsl +++ b/packages/core/src/shaders/picking.frag.glsl @@ -44,6 +44,6 @@ vec4 filterPickingColor(vec4 color) { */ vec4 filterColor(vec4 color) { // TODO: 过滤多余的 shader 计算 - if(u_Dragging > 0.0) return color; + // if(u_Dragging > 0.0) return color; // 暂时去除 直接取消计算在选中时拖拽地图会有问题 return filterPickingColor(filterHighlightColor(color)); } diff --git a/packages/core/src/utils/dom.ts b/packages/core/src/utils/dom.ts index bfbdcd0194..573ea09622 100644 --- a/packages/core/src/utils/dom.ts +++ b/packages/core/src/utils/dom.ts @@ -1,9 +1,12 @@ -const docStyle = window.document.documentElement.style; -type ELType = HTMLElement | SVGElement; +import { isMini } from '@antv/l7-utils'; let containerCounter = 0; export function createRendererContainer( domId: string | HTMLDivElement, ): HTMLDivElement | null { + if (isMini) { + return null; + } + let $wrapper = domId as HTMLDivElement; if (typeof domId === 'string') { $wrapper = document.getElementById(domId) as HTMLDivElement; diff --git a/packages/core/typings/l7-tiny-sdf.d.ts b/packages/core/typings/l7-tiny-sdf.d.ts new file mode 100644 index 0000000000..0edfa828fe --- /dev/null +++ b/packages/core/typings/l7-tiny-sdf.d.ts @@ -0,0 +1,2 @@ +declare module 'l7hammerjs'; +declare module 'l7-tiny-sdf'; \ No newline at end of file diff --git a/packages/core/typings/probe.gl.d.ts b/packages/core/typings/probe.gl.d.ts deleted file mode 100644 index f05d0e34b9..0000000000 --- a/packages/core/typings/probe.gl.d.ts +++ /dev/null @@ -1,14 +0,0 @@ -declare module 'probe.gl' { - class Log { - constructor(options: { id: string }); - - priority: number; - enable(enabled?: boolean): Log; - - debug(priority: number, message: string): () => any; - info(priority: number, message: string): () => any; - warn(message: string): () => any; - error(message: string): () => any; - probe(priority: number, message: string): () => any; - } -} diff --git a/packages/layers/src/core/BaseModel.ts b/packages/layers/src/core/BaseModel.ts index 59768a242a..34fab0dd74 100644 --- a/packages/layers/src/core/BaseModel.ts +++ b/packages/layers/src/core/BaseModel.ts @@ -162,7 +162,7 @@ export default class BaseModel // 只有在不支持数据纹理的情况下进行赋值 if (!this.dataTextureTest) { this.dataTexture = this.createTexture2D({ - data: new ImageData(1, 1).data, + data: new Uint8ClampedArray(4), mag: gl.NEAREST, min: gl.NEAREST, width: 1, diff --git a/packages/layers/src/heatmap/models/heatmap.ts b/packages/layers/src/heatmap/models/heatmap.ts index 3c77e048fb..902809264c 100644 --- a/packages/layers/src/heatmap/models/heatmap.ts +++ b/packages/layers/src/heatmap/models/heatmap.ts @@ -78,10 +78,6 @@ export default class HeatMapModel extends BaseModel { ? this.buildHeatmapColor() // 2D : this.build3dHeatMap(); // 3D - const { - rampColors, - } = this.layer.getLayerConfig() as IHeatMapLayerStyleOptions; - const imageData = generateColorRamp(rampColors as IColorRamp); const { width, height } = getViewportSize(); // 初始化密度图纹理 diff --git a/packages/layers/src/image/models/image.ts b/packages/layers/src/image/models/image.ts index 5b4f589b64..6cd02e7f11 100644 --- a/packages/layers/src/image/models/image.ts +++ b/packages/layers/src/image/models/image.ts @@ -12,7 +12,7 @@ import { lazyInject, TYPES, } from '@antv/l7-core'; -import { generateColorRamp, IColorRamp } from '@antv/l7-utils'; +import { isMini } from '@antv/l7-utils'; import BaseModel from '../../core/BaseModel'; import { RasterImageTriangulation } from '../../core/triangulation'; import ImageFrag from '../shaders/image_frag.glsl'; @@ -37,14 +37,34 @@ export default class ImageModel extends BaseModel { height: 0, width: 0, }); - source.data.images.then((imageData: HTMLImageElement[]) => { - this.texture = createTexture2D({ - data: imageData[0], - width: imageData[0].width, - height: imageData[0].height, + + if (isMini) { + // @ts-ignore + const canvas = this.layerService.sceneService.getSceneConfig().canvas; + const img = canvas.createImage(); + // let img = new Image() + img.crossOrigin = 'anonymous'; + img.src = source.data.originData; + + img.onload = () => { + this.texture = createTexture2D({ + data: img, + width: img.width, + height: img.height, + }); + this.layerService.renderLayers(); + }; + } else { + source.data.images.then((imageData: HTMLImageElement[]) => { + this.texture = createTexture2D({ + data: imageData[0], + width: imageData[0].width, + height: imageData[0].height, + }); + this.layerService.renderLayers(); }); - this.layerService.renderLayers(); - }); + } + return [ this.layer.buildLayerModel({ moduleName: 'RasterImage', diff --git a/packages/layers/src/plugins/ShaderUniformPlugin.ts b/packages/layers/src/plugins/ShaderUniformPlugin.ts index e0f03a0e66..017d41bc61 100644 --- a/packages/layers/src/plugins/ShaderUniformPlugin.ts +++ b/packages/layers/src/plugins/ShaderUniformPlugin.ts @@ -9,7 +9,7 @@ import { IRendererService, TYPES, } from '@antv/l7-core'; -import { DOM } from '@antv/l7-utils'; +import { $window } from '@antv/l7-utils'; import { inject, injectable } from 'inversify'; import 'reflect-metadata'; @@ -74,9 +74,9 @@ export default class ShaderUniformPlugin implements ILayerPlugin { u_SceneCenterMKT: sceneCenterMKT, // 其他参数,例如视口大小、DPR 等 u_ViewportSize: [width, height], - u_DevicePixelRatio: window.devicePixelRatio, - // u_ModelMatrix: [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], u_ModelMatrix: this.cameraService.getModelMatrix(), + u_DevicePixelRatio: $window.devicePixelRatio, + // u_ModelMatrix: [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], u_PickingBuffer: layer.getLayerConfig().pickingBuffer || 0, // TODO: 当前地图是否在拖动 u_Dragging: Number(this.mapService.dragging), diff --git a/packages/layers/src/point/models/image.ts b/packages/layers/src/point/models/image.ts index 0a3aa6f02f..073d296599 100644 --- a/packages/layers/src/point/models/image.ts +++ b/packages/layers/src/point/models/image.ts @@ -2,6 +2,7 @@ import { AttributeType, gl, IEncodeFeature, + ILayer, IModel, IModelUniform, ITexture2D, diff --git a/packages/map/src/camera.ts b/packages/map/src/camera.ts index 9e900c9260..c709e99649 100644 --- a/packages/map/src/camera.ts +++ b/packages/map/src/camera.ts @@ -618,7 +618,9 @@ export default class Camera extends EventEmitter { public stop(allowGestures?: boolean, easeId?: string) { if (this.easeFrameId) { this.cancelRenderFrame(this.easeFrameId); + // @ts-ignore delete this.easeFrameId; + // @ts-ignore delete this.onEaseFrame; } @@ -627,6 +629,7 @@ export default class Camera extends EventEmitter { // animation, which sets a new _onEaseEnd. Ensure we don't delete // it unintentionally. const onEaseEnd = this.onEaseEnd; + // @ts-ignore delete this.onEaseEnd; onEaseEnd.call(this, easeId); } diff --git a/packages/map/src/earthmap.ts b/packages/map/src/earthmap.ts index 59bc1e9e0b..7d4c320cb9 100644 --- a/packages/map/src/earthmap.ts +++ b/packages/map/src/earthmap.ts @@ -16,7 +16,6 @@ import DragPanHandler from './handler/shim/drag_pan'; import DragRotateHandler from './handler/shim/drag_rotate'; import TouchZoomRotateHandler from './handler/shim/touch_zoom_rotate'; import { TouchPitchHandler } from './handler/touch'; -import Hash from './hash'; import { IMapOptions } from './interface'; import { renderframe } from './util'; import { PerformanceUtils } from './utils/performance'; @@ -71,7 +70,7 @@ export class EarthMap extends Camera { private renderTaskQueue: TaskQueue = new TaskQueue(); private frame: { cancel: () => void } | null; private trackResize: boolean = true; - private hash: Hash | undefined; + constructor(options: Partial) { super(merge({}, DefaultOptions, options)); this.initContainer(); @@ -83,30 +82,6 @@ export class EarthMap extends Camera { window.addEventListener('resize', this.onWindowResize, false); window.addEventListener('orientationchange', this.onWindowResize, false); } - - const hashName = - (typeof options.hash === 'string' && options.hash) || undefined; - if (options.hash) { - this.hash = new Hash(hashName).addTo(this) as Hash; - } - - // don't set position from options if set through hash - if (!this.hash || !this.hash.onHashChange()) { - this.jumpTo({ - center: options.center, - zoom: options.zoom, - bearing: options.bearing, - pitch: options.pitch, - }); - - if (options.bounds) { - this.resize(); - this.fitBounds( - options.bounds, - merge({}, options.fitBoundsOptions, { duration: 0 }), - ); - } - } } public resize(eventData?: any) { diff --git a/packages/map/src/handler/handler_manager.ts b/packages/map/src/handler/handler_manager.ts index 203a28abc4..fa8ddcecec 100644 --- a/packages/map/src/handler/handler_manager.ts +++ b/packages/map/src/handler/handler_manager.ts @@ -1,6 +1,7 @@ // @ts-ignore // tslint:disable-next-line: no-submodule-imports -import merge from 'lodash/merge'; +import { $window, isMini } from '@antv/l7-utils'; +import { merge } from 'lodash'; import { EarthMap } from '../earthmap'; import Point from '../geo/point'; import { Map } from '../map'; @@ -100,53 +101,87 @@ class HandlerManager { this.addDefaultHandlers(options); const el = this.el; + this.listeners = []; + if (!isMini) { + // l7 - mini + this.listeners = [ + // Bind touchstart and touchmove with passive: false because, even though + // they only fire a map events and therefore could theoretically be + // passive, binding with passive: true causes iOS not to respect + // e.preventDefault() in _other_ handlers, even if they are non-passive + // (see https://bugs.webkit.org/show_bug.cgi?id=184251) + [el, 'touchstart', { passive: false }], + [el, 'touchmove', { passive: false }], + [el, 'touchend', undefined], + [el, 'touchcancel', undefined], - this.listeners = [ - // Bind touchstart and touchmove with passive: false because, even though - // they only fire a map events and therefore could theoretically be - // passive, binding with passive: true causes iOS not to respect - // e.preventDefault() in _other_ handlers, even if they are non-passive - // (see https://bugs.webkit.org/show_bug.cgi?id=184251) - [el, 'touchstart', { passive: false }], - [el, 'touchmove', { passive: false }], - [el, 'touchend', undefined], - [el, 'touchcancel', undefined], + [el, 'mousedown', undefined], + [el, 'mousemove', undefined], + [el, 'mouseup', undefined], - [el, 'mousedown', undefined], - [el, 'mousemove', undefined], - [el, 'mouseup', undefined], - - // Bind window-level event listeners for move and up/end events. In the absence of - // the pointer capture API, which is not supported by all necessary platforms, - // window-level event listeners give us the best shot at capturing events that - // fall outside the map canvas element. Use `{capture: true}` for the move event - // to prevent map move events from being fired during a drag. - // @ts-ignore - [window.document, 'mousemove', { capture: true }], - // @ts-ignore - [window.document, 'mouseup', undefined], - - [el, 'mouseover', undefined], - [el, 'mouseout', undefined], - [el, 'dblclick', undefined], - [el, 'click', undefined], - - [el, 'keydown', { capture: false }], - [el, 'keyup', undefined], - - [el, 'wheel', { passive: false }], - [el, 'contextmenu', undefined], - // @ts-ignore - [window, 'blur', undefined], - ]; - for (const [target, type, listenerOptions] of this.listeners) { - // @ts-ignore - DOM.addEventListener( - target, - type, + // Bind window-level event listeners for move and up/end events. In the absence of + // the pointer capture API, which is not supported by all necessary platforms, + // window-level event listeners give us the best shot at capturing events that + // fall outside the map canvas element. Use `{capture: true}` for the move event + // to prevent map move events from being fired during a drag. // @ts-ignore - target === window.document ? this.handleWindowEvent : this.handleEvent, - listenerOptions, + [window.document, 'mousemove', { capture: true }], + // @ts-ignore + [window.document, 'mouseup', undefined], + + [el, 'mouseover', undefined], + [el, 'mouseout', undefined], + [el, 'dblclick', undefined], + [el, 'click', undefined], + + [el, 'keydown', { capture: false }], + [el, 'keyup', undefined], + + [el, 'wheel', { passive: false }], + [el, 'contextmenu', undefined], + // @ts-ignore + [window, 'blur', undefined], + ]; + for (const [target, type, listenerOptions] of this.listeners) { + // @ts-ignore + DOM.addEventListener( + target, + type, + // @ts-ignore + target === window.document + ? this.handleWindowEvent + : this.handleEvent, + listenerOptions, + ); + } + } else { + $window.document.addEventListener( + 'touchstart', + (e: any) => { + this.handleEvent(e); + }, + {}, + ); + $window.document.addEventListener( + 'touchmove', + (e: any) => { + this.handleEvent(e); + }, + {}, + ); + $window.document.addEventListener( + 'touchend', + (e: any) => { + this.handleEvent(e); + }, + {}, + ); + $window.document.addEventListener( + 'touchcancel', + (e: any) => { + this.handleEvent(e); + }, + {}, ); } } @@ -433,7 +468,7 @@ class HandlerManager { const mapTouches = []; for (const t of touches) { const target = t.target as Node; - if (this.el.contains(target)) { + if (isMini || this.el.contains(target)) { mapTouches.push(t); } } diff --git a/packages/map/src/handler/shim/drag_pan.ts b/packages/map/src/handler/shim/drag_pan.ts index 1580c234ae..9594f14da9 100644 --- a/packages/map/src/handler/shim/drag_pan.ts +++ b/packages/map/src/handler/shim/drag_pan.ts @@ -1,3 +1,4 @@ +import { isMini } from '@antv/l7-utils'; import { MousePanHandler } from '../mouse/'; import { TouchPanHandler } from '../touch/'; @@ -53,7 +54,9 @@ export default class DragPanHandler { this.inertiaOptions = options || {}; this.mousePan.enable(); this.touchPan.enable(); - this.el.classList.add('l7-touch-drag-pan'); + if (!isMini) { + this.el.classList.add('l7-touch-drag-pan'); + } } /** @@ -65,7 +68,9 @@ export default class DragPanHandler { public disable() { this.mousePan.disable(); this.touchPan.disable(); - this.el.classList.remove('l7-touch-drag-pan'); + if (!isMini) { + this.el.classList.remove('l7-touch-drag-pan'); + } } /** diff --git a/packages/map/src/handler/shim/touch_zoom_rotate.ts b/packages/map/src/handler/shim/touch_zoom_rotate.ts index 67c57f8247..7007e8d480 100644 --- a/packages/map/src/handler/shim/touch_zoom_rotate.ts +++ b/packages/map/src/handler/shim/touch_zoom_rotate.ts @@ -1,3 +1,4 @@ +import { isMini } from '@antv/l7-utils'; import TapDragZoomHandler from '../tap/tap_drag_zoom'; import { TouchRotateHandler, TouchZoomHandler } from '../touch'; @@ -50,7 +51,9 @@ export default class TouchZoomRotateHandler { this.touchRotate.enable(options); } this.tapDragZoom.enable(); - this.el.classList.add('l7-touch-zoom-rotate'); + if (!isMini) { + this.el.classList.add('l7-touch-zoom-rotate'); + } } /** @@ -63,7 +66,9 @@ export default class TouchZoomRotateHandler { this.touchZoom.disable(); this.touchRotate.disable(); this.tapDragZoom.disable(); - this.el.classList.remove('l7-touch-zoom-rotate'); + if (!isMini) { + this.el.classList.remove('l7-touch-zoom-rotate'); + } } /** diff --git a/packages/map/src/hash.ts b/packages/map/src/hash.ts index e8581cb52a..8dd89fb2ea 100644 --- a/packages/map/src/hash.ts +++ b/packages/map/src/hash.ts @@ -1,7 +1,7 @@ // @ts-ignore // tslint:disable-next-line:no-submodule-imports -import throttle from 'lodash/throttle'; -import { EarthMap } from './earthmap'; +import { $window } from '@antv/l7-utils'; +import { throttle } from 'lodash'; import { Map } from './map'; /* @@ -11,7 +11,7 @@ import { Map } from './map'; * @returns {Hash} `this` */ class Hash { - private map: Map | EarthMap; + private map: Map; private updateHash: () => number | void; private hashName?: string; @@ -21,18 +21,17 @@ class Hash { // Mobile Safari doesn't allow updating the hash more than 100 times per 30 seconds. this.updateHash = throttle(this.updateHashUnthrottled, (30 * 1000) / 100); } - public addTo(map: Map | EarthMap) { + public addTo(map: Map) { this.map = map; - window.addEventListener('hashchange', this.onHashChange, false); - // @ts-ignore + $window.addEventListener('hashchange', this.onHashChange, false); this.map.on('moveend', this.updateHash); return this; } public remove() { - window.removeEventListener('hashchange', this.onHashChange, false); - // @ts-ignore + $window.removeEventListener('hashchange', this.onHashChange, false); this.map.off('moveend', this.updateHash); // clearTimeout(this.updateHash()); + // @ts-ignore delete this.map; return this; diff --git a/packages/map/src/interface.ts b/packages/map/src/interface.ts index 99f94d7c67..3c1f3e4c2f 100644 --- a/packages/map/src/interface.ts +++ b/packages/map/src/interface.ts @@ -4,6 +4,7 @@ export interface IMapOptions { hash: boolean; style?: any; container?: HTMLElement | string; + canvas?: HTMLCanvasElement; center: [number, number]; zoom: number; bearing: number; diff --git a/packages/map/src/map.ts b/packages/map/src/map.ts index ad6afc572b..560d45d087 100644 --- a/packages/map/src/map.ts +++ b/packages/map/src/map.ts @@ -1,4 +1,4 @@ -import { DOM } from '@antv/l7-utils'; +import { $window, DOM, isMini } from '@antv/l7-utils'; import { merge } from 'lodash'; import Camera from './camera'; import './css/l7.css'; @@ -74,14 +74,14 @@ export class Map extends Camera { private hash: Hash | undefined; constructor(options: Partial) { super(merge({}, DefaultOptions, options)); - this.initContainer(); + if (isMini) { + this.initMiniContainer(); + } else { + this.initContainer(); + } + this.resize(); this.handlers = new HandlerManager(this, this.options); - // this.on('move', () => this.update()); - // this.on('moveend', () => this.update()); - // this.on('zoom', () => { - // console.log('zoom'); - // }); if (typeof window !== 'undefined') { window.addEventListener('online', this.onWindowOnline, false); @@ -89,10 +89,12 @@ export class Map extends Camera { window.addEventListener('orientationchange', this.onWindowResize, false); } - const hashName = - (typeof options.hash === 'string' && options.hash) || undefined; - if (options.hash) { - this.hash = new Hash(hashName).addTo(this) as Hash; + if (!isMini) { + const hashName = + (typeof options.hash === 'string' && options.hash) || undefined; + if (options.hash) { + this.hash = new Hash(hashName).addTo(this) as Hash; + } } // don't set position from options if set through hash @@ -119,19 +121,21 @@ export class Map extends Camera { const width = dimensions[0]; const height = dimensions[1]; - // this.resizeCanvas(width, height); this.transform.resize(width, height); + if (!isMini) { + return this; + } const fireMoving = !this.moving; if (fireMoving) { this.stop(); - this.emit('movestart', new Event('movestart', eventData)); - this.emit('move', new Event('move', eventData)); + this.emit('movestart', new $window.Event('movestart', eventData)); + this.emit('move', new $window.Event('move', eventData)); } - this.emit('resize', new Event('resize', eventData)); + this.emit('resize', new $window.Event('resize', eventData)); if (fireMoving) { - this.emit('moveend', new Event('moveend', eventData)); + this.emit('moveend', new $window.Event('moveend', eventData)); } return this; @@ -338,36 +342,31 @@ export class Map extends Camera { if (this.options.interactive) { canvasContainer.classList.add('l7-interactive'); } + } - // this.canvas = DOM.create( - // 'canvas', - // 'l7-canvas', - // canvasContainer, - // ) as HTMLCanvasElement; - // this.canvas.setAttribute('tabindex', '-'); - // this.canvas.setAttribute('aria-label', 'Map'); + /** + * 小程序环境构建容器 + */ + private initMiniContainer() { + this.container = this.options.canvas as HTMLCanvasElement; + this.canvasContainer = this.container; } private containerDimensions(): [number, number] { let width = 0; let height = 0; if (this.container) { - width = this.container.clientWidth || 400; - height = this.container.clientHeight || 300; + if (isMini) { + width = (this.container as HTMLCanvasElement).width; + height = (this.container as HTMLCanvasElement).height; + } else { + width = this.container.clientWidth; + height = this.container.clientHeight; + } } return [width, height]; } - private resizeCanvas(width: number, height: number) { - const pixelRatio = DOM.DPR || 1; - this.canvas.width = pixelRatio * width; - this.canvas.height = pixelRatio * height; - - // Maintain the same canvas size, potentially downscaling it for HiDPI displays - this.canvas.style.width = `${width}px`; - this.canvas.style.height = `${height}px`; - } - private onWindowOnline = () => { this.update(); }; diff --git a/packages/map/src/util.ts b/packages/map/src/util.ts index 88d7b1e5d0..74833806a2 100644 --- a/packages/map/src/util.ts +++ b/packages/map/src/util.ts @@ -1,3 +1,4 @@ +import { $window, isMini } from '@antv/l7-utils'; // @ts-ignore import UnitBezier from '@mapbox/unitbezier'; let reducedMotionQuery: MediaQueryList; @@ -32,12 +33,14 @@ export function bezier( export const ease = bezier(0.25, 0.1, 0.25, 1); export function prefersReducedMotion(): boolean { - if (!window.matchMedia) { + // @ts-ignore + if (isMini || !$window.matchMedia) { return false; } // Lazily initialize media query if (reducedMotionQuery == null) { - reducedMotionQuery = window.matchMedia('(prefers-reduced-motion: reduce)'); + // @ts-ignore + reducedMotionQuery = $window.matchMedia('(prefers-reduced-motion: reduce)'); } return reducedMotionQuery.matches; } @@ -55,28 +58,29 @@ export function pick( return result; } -export const now = - window.performance && window.performance.now - ? window.performance.now.bind(window.performance) - : Date.now.bind(Date); +export const now = isMini + ? Date.now.bind(Date) + : $window.performance && $window.performance.now + ? $window.performance.now.bind($window.performance) + : Date.now.bind(Date); export const raf = - window.requestAnimationFrame || + $window.requestAnimationFrame || // @ts-ignore - window.mozRequestAnimationFrame || + $window.mozRequestAnimationFrame || // @ts-ignore - window.webkitRequestAnimationFrame || + $window.webkitRequestAnimationFrame || // @ts-ignore - window.msRequestAnimationFrame; + $window.msRequestAnimationFrame; export const cancel = - window.cancelAnimationFrame || + $window.cancelAnimationFrame || // @ts-ignore - window.mozCancelAnimationFrame || + $window.mozCancelAnimationFrame || // @ts-ignore - window.webkitCancelAnimationFrame || + $window.webkitCancelAnimationFrame || // @ts-ignore - window.msCancelAnimationFrame; + $window.msCancelAnimationFrame; export function renderframe( fn: (paintStartTimestamp: number) => void, diff --git a/packages/map/src/utils/dom.ts b/packages/map/src/utils/dom.ts index 39c5adc188..0eaa38e518 100644 --- a/packages/map/src/utils/dom.ts +++ b/packages/map/src/utils/dom.ts @@ -1,3 +1,4 @@ +import { $window, isMini } from '@antv/l7-utils'; // @ts-ignore import Point from '../geo/point'; @@ -7,7 +8,7 @@ const DOM: { export default DOM; DOM.create = (tagName: string, className?: string, container?: HTMLElement) => { - const el = window.document.createElement(tagName); + const el = $window.document.createElement(tagName) as HTMLElement; if (className !== undefined) { el.className = className; } @@ -18,11 +19,14 @@ DOM.create = (tagName: string, className?: string, container?: HTMLElement) => { }; DOM.createNS = (namespaceURI: string, tagName: string) => { - const el = window.document.createElementNS(namespaceURI, tagName); + const el = $window.document.createElementNS( + namespaceURI, + tagName, + ) as HTMLElement; return el; }; -const docStyle = window.document && window.document.documentElement.style; +const docStyle = $window.document && $window.document.documentElement.style; function testProp(props: any) { if (!docStyle) { @@ -78,9 +82,9 @@ try { }, }); // @ts-ignore - window.addEventListener('test', options, options); + $window.addEventListener('test', options, options); // @ts-ignore - window.removeEventListener('test', options, options); + $window.removeEventListener('test', options, options); } catch (err) { passiveSupported = false; } @@ -115,45 +119,77 @@ DOM.removeEventListener = ( const suppressClick = (e: MouseEvent) => { e.preventDefault(); e.stopPropagation(); - window.removeEventListener('click', suppressClick, true); + $window.removeEventListener('click', suppressClick, true); }; DOM.suppressClick = () => { - window.addEventListener('click', suppressClick, true); - window.setTimeout(() => { - window.removeEventListener('click', suppressClick, true); + if (isMini) { + return; + } + $window.addEventListener('click', suppressClick, true); + setTimeout(() => { + $window.removeEventListener('click', suppressClick, true); }, 0); }; DOM.mousePos = (el: HTMLElement, e: MouseEvent | Touch) => { - const rect = el.getBoundingClientRect(); - return new Point( - e.clientX - rect.left - el.clientLeft, - e.clientY - rect.top - el.clientTop, - ); + // 暂时从 el 上获取 top/left, 后面需要动态获取 + if (!isMini) { + const rect = el.getBoundingClientRect(); + return new Point( + e.clientX - rect.left - el.clientLeft, + e.clientY - rect.top - el.clientTop, + ); + } else { + return new Point( + // @ts-ignore + e.clientX - el.left - 0, + // @ts-ignore + e.clientY - el.top - 0, + ); + } }; DOM.touchPos = (el: HTMLElement, touches: Touch[]) => { - const rect = el.getBoundingClientRect(); - const points = []; - for (const touche of touches) { - points.push( - new Point( - touche.clientX - rect.left - el.clientLeft, - touche.clientY - rect.top - el.clientTop, - ), - ); + // 暂时从 el 上获取 top/left, 后面需要动态获取 + if (!isMini) { + const rect = el.getBoundingClientRect(); + const points = []; + for (const touche of touches) { + points.push( + new Point( + touche.clientX - rect.left - el.clientLeft, + touche.clientY - rect.top - el.clientTop, + ), + ); + } + return points; + } else { + const points = []; + for (const touche of touches) { + points.push( + new Point( + // @ts-ignore + touche.clientX - el.left, + // @ts-ignore + touche.clientY - el.top, + ), + ); + } + return points; } - return points; }; DOM.mouseButton = (e: MouseEvent) => { + if (!isMini) { + return e.button; + } if ( // @ts-ignore - typeof window.InstallTrigger !== 'undefined' && + typeof $window.InstallTrigger !== 'undefined' && e.button === 2 && e.ctrlKey && - window.navigator.platform.toUpperCase().indexOf('MAC') >= 0 + $window.navigator.platform.toUpperCase().indexOf('MAC') >= 0 ) { // Fix for https://github.com/mapbox/mapbox-gl-js/issues/3131: // Firefox (detected by InstallTrigger) on Mac determines e.button = 2 when diff --git a/packages/map/src/utils/performance.ts b/packages/map/src/utils/performance.ts index 8b079d5903..cd4242807d 100644 --- a/packages/map/src/utils/performance.ts +++ b/packages/map/src/utils/performance.ts @@ -1,9 +1,10 @@ +import { $window } from '@antv/l7-utils'; let lastFrameTime: number | null = null; let frameTimes: number[] = []; const minFramerateTarget = 30; const frameTimeTarget = 1000 / minFramerateTarget; -const performance = window.performance; +const performance = $window.performance; export interface IPerformanceMetrics { loadTime: number; diff --git a/packages/maps/src/BaseMapWrapper.ts b/packages/maps/src/BaseMapWrapper.ts index 5d90c3a401..71aca9ce99 100644 --- a/packages/maps/src/BaseMapWrapper.ts +++ b/packages/maps/src/BaseMapWrapper.ts @@ -17,7 +17,12 @@ export default class BaseMapWrapper implements IMapWrapper { this.config = config; } - public setContainer(sceneContainer: Container, id: string | HTMLDivElement) { + public setContainer( + sceneContainer: Container, + id: string | HTMLDivElement, + canvas?: HTMLCanvasElement, + hasBaseMap?: boolean, + ) { // // 首先使用全局配置服务校验地图参数 // const { valid, errorText } = this.configService.validateMapConfig( // this.config, @@ -31,6 +36,8 @@ export default class BaseMapWrapper implements IMapWrapper { sceneContainer.bind>(TYPES.MapConfig).toConstantValue({ ...this.config, id, + canvas, + hasBaseMap, }); sceneContainer .bind>(TYPES.IMapService) diff --git a/packages/maps/src/index.ts b/packages/maps/src/index.ts index bc4d542e0c..c88b7cae20 100644 --- a/packages/maps/src/index.ts +++ b/packages/maps/src/index.ts @@ -1,9 +1,11 @@ -// import GaodeMap from './amap/'; import GaodeMap from './amap/'; // import GaodeMapV1 from './amap/'; import GaodeMapV2 from './amap2/'; import Earth from './earth/'; +// import GaodeMapV2 from './amap2/'; import Map from './map/'; import Mapbox from './mapbox/'; export { GaodeMap, GaodeMapV2, Mapbox, Map, Earth }; +// export { GaodeMap, GaodeMapV2, Mapbox, Map }; +// export { Map }; diff --git a/packages/maps/src/map/Viewport.ts b/packages/maps/src/map/Viewport.ts index 27f80593d1..6bbada973a 100644 --- a/packages/maps/src/map/Viewport.ts +++ b/packages/maps/src/map/Viewport.ts @@ -70,6 +70,10 @@ export default class Viewport implements IViewport { return 1; } + /** + * P20 坐标系,固定 scale + */ + public projectFlat( lngLat: [number, number], scale?: number | undefined, diff --git a/packages/maps/src/map/map.ts b/packages/maps/src/map/map.ts index 4fe4b4c824..8eb319348f 100644 --- a/packages/maps/src/map/map.ts +++ b/packages/maps/src/map/map.ts @@ -18,8 +18,7 @@ import { TYPES, } from '@antv/l7-core'; import { Map } from '@antv/l7-map'; -import { DOM } from '@antv/l7-utils'; -import { mat4, vec2, vec3 } from 'gl-matrix'; +import { $window, DOM } from '@antv/l7-utils'; import { inject, injectable } from 'inversify'; import 'reflect-metadata'; import { Version } from '../version'; @@ -297,6 +296,65 @@ export default class L7MapService implements IMapService { this.handleCameraChanged(); } + // 初始化小程序地图 + public async initMiniMap(): Promise { + const { + id = 'map', + attributionControl = false, + style = 'light', + rotation = 0, + mapInstance, + canvas = null, + hasBaseMap = false, + ...rest + } = this.config; + + this.viewport = new Viewport(); + + this.$mapContainer = canvas; + + this.map = new Map({ + container: this.$mapContainer as HTMLElement, + style: this.getMapStyle(style), + bearing: rotation, + // @ts-ignore + canvas, + ...rest, + }); + + if (!hasBaseMap) { + // 没有地图底图的模式 + this.map.on('load', this.handleCameraChanged); + this.map.on('move', this.handleCameraChanged); + + // 不同于高德地图,需要手动触发首次渲染 + this.handleCameraChanged(); + } else { + // 存在地图底图的模式( L7Mini ) + const center = this.map.getCenter(); + // 不同于高德地图,需要手动触发首次渲染 + this.handleMiniCameraChanged( + center.lng, + center.lat, + this.map.getZoom(), + this.map.getBearing(), + this.map.getPitch(), + ); + $window.document.addEventListener('mapCameaParams', (event: any) => { + const { + e: { longitude, latitude, scale, bearing, pitch }, + } = event; + this.handleMiniCameraChanged( + longitude, + latitude, + scale - 1.25, + bearing, + pitch, + ); + }); + } + } + public destroy() { // TODO: 销毁地图可视化层的容器 this.$mapContainer?.parentNode?.removeChild(this.$mapContainer); @@ -330,6 +388,44 @@ export default class L7MapService implements IMapService { this.cameraChangedCallback = callback; } + // TODO: 处理小程序中有底图模式下的相机跟新 + private handleMiniCameraChanged = ( + lng: number, + lat: number, + zoom: number, + bearing: number, + pitch: number, + ) => { + const { offsetCoordinate = true } = this.config; + + // resync + this.viewport.syncWithMapCamera({ + // bearing: this.map.getBearing(), + bearing, + center: [lng, lat], + viewportHeight: this.map.transform.height, + // pitch: this.map.getPitch(), + pitch, + viewportWidth: this.map.transform.width, + zoom, + // mapbox 中固定相机高度为 viewport 高度的 1.5 倍 + cameraHeight: 0, + }); + // set coordinate system + if ( + this.viewport.getZoom() > LNGLAT_OFFSET_ZOOM_THRESHOLD && + offsetCoordinate + ) { + this.coordinateSystemService.setCoordinateSystem( + CoordinateSystem.LNGLAT_OFFSET, + ); + } else { + this.coordinateSystemService.setCoordinateSystem(CoordinateSystem.LNGLAT); + } + + this.cameraChangedCallback(this.viewport); + }; + private handleCameraChanged = () => { const { lat, lng } = this.map.getCenter(); const { offsetCoordinate = true } = this.config; diff --git a/packages/maps/typing.d.ts b/packages/maps/typing.d.ts new file mode 100644 index 0000000000..1d3eba232e --- /dev/null +++ b/packages/maps/typing.d.ts @@ -0,0 +1 @@ +declare module '@antv/l7-maps/lib/map/'; \ No newline at end of file diff --git a/packages/mini/.gitignore b/packages/mini/.gitignore new file mode 100644 index 0000000000..d7b96564ba --- /dev/null +++ b/packages/mini/.gitignore @@ -0,0 +1,4 @@ +lib +es +dist +package_bak.json diff --git a/packages/mini/CHANGELOG.md b/packages/mini/CHANGELOG.md new file mode 100644 index 0000000000..61e0272c01 --- /dev/null +++ b/packages/mini/CHANGELOG.md @@ -0,0 +1,289 @@ +# Change Log + +All notable changes to this project will be documented in this file. +See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. + +## [2.1.12](https://github.com/antvis/L7/compare/v2.1.11...v2.1.12) (2020-04-10) + + +### Bug Fixes + +* **heatmap:** 修复热力图某些设备上黑色 fix [#278](https://github.com/antvis/L7/issues/278) ([b8f5899](https://github.com/antvis/L7/commit/b8f58992d1fce38fdaac9d82ebfbec14e35298bd)) + + + + + +## [2.1.11](https://github.com/antvis/L7/compare/v2.1.10...v2.1.11) (2020-04-07) + +**Note:** Version bump only for package @antv/l7 + + + + + +## [2.1.8](https://github.com/antvis/L7/compare/v2.1.7...v2.1.8) (2020-03-26) + +**Note:** Version bump only for package @antv/l7 + + + + + +## [2.1.7](https://github.com/antvis/L7/compare/v2.1.6...v2.1.7) (2020-03-26) + +**Note:** Version bump only for package @antv/l7 + + + + + +## [2.1.5](https://github.com/antvis/L7/compare/v2.1.4...v2.1.5) (2020-03-20) + + +### Bug Fixes + +* observerable打包问题 ([412e2a8](https://github.com/antvis/L7/commit/412e2a83f78a9a448f0a5b65ccaf2ea97f78b47a)) + + + + + +## [2.1.3](https://github.com/antvis/L7/compare/v2.0.36...v2.1.3) (2020-03-17) + + +### Bug Fixes + +* ios 12 点击事件问题 & regl 版本锁定 ([ad52e8e](https://github.com/antvis/L7/commit/ad52e8e8fde4a7b4b3e16d86a6035bd7c07fb80c)) +* merge conflict ([89c8cb2](https://github.com/antvis/L7/commit/89c8cb2c0250eb5a28d96d82c87b804bf3db4c30)) + + + + + +## [2.1.2](https://github.com/antvis/L7/compare/v2.0.36...v2.1.2) (2020-03-15) + + +### Bug Fixes + +* ios 12 点击事件问题 & regl 版本锁定 ([ad52e8e](https://github.com/antvis/L7/commit/ad52e8e8fde4a7b4b3e16d86a6035bd7c07fb80c)) +* merge conflict ([89c8cb2](https://github.com/antvis/L7/commit/89c8cb2c0250eb5a28d96d82c87b804bf3db4c30)) + + + + + +## [2.1.1](https://github.com/antvis/L7/compare/v2.0.36...v2.1.1) (2020-03-15) + + +### Bug Fixes + +* ios 12 点击事件问题 & regl 版本锁定 ([ad52e8e](https://github.com/antvis/L7/commit/ad52e8e8fde4a7b4b3e16d86a6035bd7c07fb80c)) + + + + + +## [2.0.34](https://github.com/antvis/L7/compare/v2.0.32...v2.0.34) (2020-03-02) + +**Note:** Version bump only for package @antv/l7 + + + + + +# [2.0.0-beta.28](https://github.com/antvis/L7/compare/v2.0.0-beta.16...v2.0.0-beta.28) (2020-01-02) + + +### Features + +* **source:** add join transfroms ([ec3cae2](https://github.com/antvis/L7/commit/ec3cae2f5fd0491a895cf4ba3953da94b5af2c84)) + + + + + +# [2.0.0-beta.27](https://github.com/antvis/L7/compare/v2.0.0-beta.16...v2.0.0-beta.27) (2020-01-01) + + +### Features + +* **source:** add join transfroms ([ec3cae2](https://github.com/antvis/L7/commit/ec3cae2f5fd0491a895cf4ba3953da94b5af2c84)) + + + + + +# [2.0.0-alpha.28](https://github.com/antvis/L7/compare/v2.0.0-beta.16...v2.0.0-alpha.28) (2020-01-01) + + +### Features + +* **source:** add join transfroms ([ec3cae2](https://github.com/antvis/L7/commit/ec3cae2f5fd0491a895cf4ba3953da94b5af2c84)) + + + + + +# [2.0.0-alpha.27](https://github.com/antvis/L7/compare/v2.0.0-beta.16...v2.0.0-alpha.27) (2019-12-31) + + +### Features + +* **source:** add join transfroms ([ec3cae2](https://github.com/antvis/L7/commit/ec3cae2f5fd0491a895cf4ba3953da94b5af2c84)) + + + + + +# [2.0.0-beta.26](https://github.com/antvis/L7/compare/v2.0.0-beta.16...v2.0.0-beta.26) (2019-12-30) + + +### Features + +* **source:** add join transfroms ([ec3cae2](https://github.com/antvis/L7/commit/ec3cae2f5fd0491a895cf4ba3953da94b5af2c84)) + + + + + +# [2.0.0-beta.25](https://github.com/antvis/L7/compare/v2.0.0-beta.16...v2.0.0-beta.25) (2019-12-27) + + +### Features + +* **source:** add join transfroms ([ec3cae2](https://github.com/antvis/L7/commit/ec3cae2f5fd0491a895cf4ba3953da94b5af2c84)) + + + + + +# [2.0.0-beta.24](https://github.com/antvis/L7/compare/v2.0.0-beta.16...v2.0.0-beta.24) (2019-12-23) + + +### Features + +* **source:** add join transfroms ([ec3cae2](https://github.com/antvis/L7/commit/ec3cae2f5fd0491a895cf4ba3953da94b5af2c84)) + + + + + +# [2.0.0-beta.23](https://github.com/antvis/L7/compare/v2.0.0-beta.16...v2.0.0-beta.23) (2019-12-23) + + +### Features + +* **source:** add join transfroms ([ec3cae2](https://github.com/antvis/L7/commit/ec3cae2f5fd0491a895cf4ba3953da94b5af2c84)) + + + + + +# [2.0.0-beta.21](https://github.com/antvis/L7/compare/v2.0.0-beta.16...v2.0.0-beta.21) (2019-12-18) + + +### Features + +* **source:** add join transfroms ([ec3cae2](https://github.com/antvis/L7/commit/ec3cae2f5fd0491a895cf4ba3953da94b5af2c84)) + + + + + +# [2.0.0-beta.20](https://github.com/antvis/L7/compare/v2.0.0-beta.16...v2.0.0-beta.20) (2019-12-12) + + +### Features + +* **source:** add join transfroms ([ec3cae2](https://github.com/antvis/L7/commit/ec3cae2f5fd0491a895cf4ba3953da94b5af2c84)) + + + + + +# [2.0.0-beta.19](https://github.com/antvis/L7/compare/v2.0.0-beta.16...v2.0.0-beta.19) (2019-12-08) + +**Note:** Version bump only for package @antv/l7 + + + + + +# [2.0.0-beta.18](https://github.com/antvis/L7/compare/v2.0.0-beta.16...v2.0.0-beta.18) (2019-12-08) + +**Note:** Version bump only for package @antv/l7 + + + + + +# [2.0.0-beta.17](https://github.com/antvis/L7/compare/v2.0.0-beta.16...v2.0.0-beta.17) (2019-12-08) + +**Note:** Version bump only for package @antv/l7 + + + + + +# [2.0.0-beta.16](https://github.com/antvis/L7/compare/v2.0.0-beta.15...v2.0.0-beta.16) (2019-11-29) + +**Note:** Version bump only for package @antv/l7 + + + + + +# [2.0.0-beta.15](https://github.com/antvis/L7/compare/v2.0.0-beta.14...v2.0.0-beta.15) (2019-11-29) + +**Note:** Version bump only for package @antv/l7 + + + + + +# [2.0.0-beta.14](https://github.com/antvis/L7/compare/v2.0.0-beta.13...v2.0.0-beta.14) (2019-11-28) + +**Note:** Version bump only for package @antv/l7 + + + + + +# [2.0.0-beta.13](https://github.com/antvis/L7/compare/v2.0.0-beta.12...v2.0.0-beta.13) (2019-11-28) + +**Note:** Version bump only for package @antv/l7 + + + + + +# [2.0.0-beta.12](https://github.com/antvis/L7/compare/v2.0.0-beta.11...v2.0.0-beta.12) (2019-11-28) + + +### Bug Fixes + +* **component:** fix marker ([14d4818](https://github.com/antvis/L7/commit/14d48184a1579241b077110ed51a8358de25e010)) + + + + + +# 2.0.0-beta.11 (2019-11-28) + + +### Bug Fixes + +* **babel:** gatsby env ([a0f249e](https://github.com/antvis/L7/commit/a0f249e40f18f712c522b2ccf3adf4434b9c2837)) +* **docs:** merge master remove manual ([0cf4a94](https://github.com/antvis/L7/commit/0cf4a949f983a08d492075596c7a44c400a51228)) +* **l7:** modules import ([7106b4f](https://github.com/antvis/L7/commit/7106b4f7ad494541ee2f8f56018d18a19c940ada)) +* **layerservice:** fix init bugs in layer service ([8cbbf7b](https://github.com/antvis/L7/commit/8cbbf7b28d63f4df16f061a4ae21726f243e7108)) +* **layerservice:** fix init bugs in layer service ([8844243](https://github.com/antvis/L7/commit/8844243050f619b28043c4e9ed1942fe172f561e)) +* **maker:** marker demo ([34d4d68](https://github.com/antvis/L7/commit/34d4d68151fe09992ec26bcec83a9862f6591920)) +* **maker:** marker demo ([685e17b](https://github.com/antvis/L7/commit/685e17bf44033ad86d7fd7793605018bbdc71206)) +* **map:** amap contanier creat new amap div ([bf43136](https://github.com/antvis/L7/commit/bf4313678501ec9c96da43de87b3b8dbf7be4c18)) +* **map:** export l7-maps in CDN bundle ([9d08549](https://github.com/antvis/L7/commit/9d085491f697ac2c17b80c55df8cc97e3e2c2298)) +* **master:** merge master branch fix conflict ([2ea903e](https://github.com/antvis/L7/commit/2ea903ee3f17bfdb670abfb1d252de8b6222b19f)) +* **packages:** remove sub modules node_modules ([132b99e](https://github.com/antvis/L7/commit/132b99e4d2bef7ec5565a0b18c5659e8b246944b)) +* **site:** 首页头图位置,以及英文大小写 ([1c1f5b1](https://github.com/antvis/L7/commit/1c1f5b1f1efe150cbbc572fb6408141fbc97dc81)) +* **site:** megre conflict ([1b5619b](https://github.com/antvis/L7/commit/1b5619b3945e97919e0c616a48ba2265a2a95c22)) diff --git a/packages/mini/README.md b/packages/mini/README.md new file mode 100644 index 0000000000..9f5011e38e --- /dev/null +++ b/packages/mini/README.md @@ -0,0 +1,72 @@ +# L7 + +![最近提交](https://badgen.net/github/last-commit/antvis/L7) + +L7 Large-scale WebGL-powered Geospatial data visualization analysis framework + +## l7 visualization demos + +![l7 demo](https://gw.alipayobjects.com/mdn/antv_site/afts/img/A*zOFwTJ9wHXQAAAAAAAAAAABkARQnAQ) + +### Installation + +```bash + npm install @antv/l7 +``` + +### Features + + +### Links + + +## Development + +使用 Yarn Workspace 完成依赖安装以及各包之间的 link 工作: +```bash +yarn install +``` + +开发模式: +```bash +yarn watch +``` + +运行 Demo +```bash +yarn storybook +``` + +代替 `git commit` 提交: +```bash +yarn commit +``` + +## view doc example + +```bash + npm start +``` +visit http://localhost:8000/ + +## Add Package + +add new package: +```bash +lerna create my-pack -y +``` + +将 ui-lib 作为 my-pack 的依赖: +```bash +yarn workspace my-pack add ui-lib/1.0.0 +``` + +将 lodash 添加为所有 package 的依赖(不包含root) +```bash +yarn workspaces run add lodash +``` + +将 typescript 设置为 root 的开发依赖 +```bash +yarn add -W -D typescript jest +``` diff --git a/packages/mini/package.json b/packages/mini/package.json new file mode 100644 index 0000000000..c918bbf0b8 --- /dev/null +++ b/packages/mini/package.json @@ -0,0 +1,39 @@ +{ + "name": "@antv/l7-mini", + "version": "2.5.37-mini20", + "description": "A Large-scale WebGL-powered Geospatial Data Visualization", + "main": "lib/index.js", + "module": "es/index.js", + "types": "es/index.d.ts", + "unpkg": "dist/l7.js", + "sideEffects": true, + "files": [ + "dist", + "lib", + "es", + "README.md" + ], + "scripts": { + "tsc": "tsc --project tsconfig.build.json", + "clean": "rimraf dist; rimraf es; rimraf lib;", + "build": "run-p build:*", + "build:cjs": "BABEL_ENV=cjs babel src --root-mode upward --out-dir lib --source-maps --extensions .ts,.tsx --delete-dir-on-start --no-comments", + "build:esm": "BABEL_ENV=esm babel src --root-mode upward --out-dir es --source-maps --extensions .ts,.tsx --delete-dir-on-start --no-comments", + "watch": "BABEL_ENV=cjs babel src --watch --root-mode upward --out-dir lib --source-maps --extensions .ts,.tsx --delete-dir-on-start --no-comments", + "sync": "tnpm sync" + }, + "author": "antv", + "license": "MIT", + "dependencies": { + "@antv/l7-core": "^2.5.37-mini20", + "@antv/l7-layers": "^2.5.37-mini20", + "@antv/l7-maps": "^2.5.37-mini20", + "@antv/l7-scene": "^2.5.37-mini20", + "@antv/l7-utils": "^2.5.37-mini20", + "@babel/runtime": "^7.7.7" + }, + "gitHead": "684ba4eb806a798713496d3fc0b4d1e17517dc31", + "publishConfig": { + "access": "public" + } +} diff --git a/packages/mini/src/index.ts b/packages/mini/src/index.ts new file mode 100644 index 0000000000..644dc4dbb1 --- /dev/null +++ b/packages/mini/src/index.ts @@ -0,0 +1,8 @@ +// @ts-ignore +// tslint:disable-next-line:no-submodule-imports +import Map from '@antv/l7-maps/lib/map/'; +export * from '@antv/l7-core'; +export * from '@antv/l7-scene'; +export * from '@antv/l7-layers'; +export * from '@antv/l7-utils'; +export { Map }; diff --git a/packages/mini/tsconfig.build.json b/packages/mini/tsconfig.build.json new file mode 100644 index 0000000000..17f6c4525a --- /dev/null +++ b/packages/mini/tsconfig.build.json @@ -0,0 +1,9 @@ +{ + "extends": "../../tsconfig.build.json", + "compilerOptions": { + "declarationDir": "./es", + "rootDir": "./src", + "baseUrl": "./" + }, + "include": ["./src"] +} \ No newline at end of file diff --git a/packages/renderer/package.json b/packages/renderer/package.json index 1ee7b0322d..6c82247067 100644 --- a/packages/renderer/package.json +++ b/packages/renderer/package.json @@ -29,7 +29,7 @@ "@antv/l7-core": "^2.5.42", "@babel/runtime": "^7.7.7", "inversify": "^5.0.1", - "l7regl": "^0.0.14", + "l7regl": "^0.0.15", "lodash": "^4.17.15", "reflect-metadata": "^0.1.13" }, diff --git a/packages/renderer/src/regl/index.ts b/packages/renderer/src/regl/index.ts index 69fda86c42..1fc66fe636 100644 --- a/packages/renderer/src/regl/index.ts +++ b/packages/renderer/src/regl/index.ts @@ -21,6 +21,7 @@ import { ITexture2D, ITexture2DInitializationOptions, } from '@antv/l7-core'; +import { isMini } from '@antv/l7-utils'; import { injectable } from 'inversify'; import regl from 'l7regl'; import 'reflect-metadata'; @@ -66,7 +67,7 @@ export default class ReglRendererService implements IRendererService { extensions: [ 'OES_element_index_uint', 'OES_standard_derivatives', // wireframe - 'angle_instanced_arrays', // VSM shadow map + 'ANGLE_instanced_arrays', // VSM shadow map ], optionalExtensions: [ 'oes_texture_float_linear', @@ -184,7 +185,11 @@ export default class ReglRendererService implements IRendererService { }; public getContainer = () => { - return this.canvas?.parentElement; + if (isMini) { + return this.canvas; + } else { + return this.canvas?.parentElement; + } }; public getCanvas = () => { diff --git a/packages/scene/src/index.ts b/packages/scene/src/index.ts index 51f6361c38..0b7f9df94b 100644 --- a/packages/scene/src/index.ts +++ b/packages/scene/src/index.ts @@ -31,7 +31,7 @@ import { TYPES, } from '@antv/l7-core'; import { ReglRendererService } from '@antv/l7-renderer'; -import { DOM } from '@antv/l7-utils'; +import { DOM, isMini } from '@antv/l7-utils'; import { Container } from 'inversify'; import ILayerManager from './ILayerManager'; import IMapController from './IMapController'; @@ -63,12 +63,12 @@ class Scene private container: Container; public constructor(config: ISceneConfig) { - const { id, map } = config; + const { id, map, canvas, hasBaseMap } = config; // 创建场景容器 const sceneContainer = createSceneContainer(); this.container = sceneContainer; // 绑定地图服务 - map.setContainer(sceneContainer, id); + map.setContainer(sceneContainer, id, canvas, hasBaseMap); // 绑定渲染引擎服务 sceneContainer @@ -96,13 +96,17 @@ class Scene ); this.popupService = sceneContainer.get(TYPES.IPopupService); - this.initComponent(id); + if (isMini) { + this.sceneService.initMiniScene(config); + } else { + this.initComponent(id); - // 初始化 scene - this.sceneService.init(config); - // TODO: 初始化组件 + // 初始化 scene + this.sceneService.init(config); + // TODO: 初始化组件 - this.initControl(); + this.initControl(); + } } public getServiceContainer(): Container { return this.container; @@ -215,7 +219,12 @@ class Scene } public addImage(id: string, img: IImage) { - this.iconService.addImage(id, img); + if (!isMini) { + this.iconService.addImage(id, img); + } else { + this.iconService.addImageMini(id, img, this.sceneService); + } + // this.iconService.addImage(id, img); } public hasImage(id: string) { diff --git a/packages/source/src/parser/image.ts b/packages/source/src/parser/image.ts index af81482e64..741284026d 100644 --- a/packages/source/src/parser/image.ts +++ b/packages/source/src/parser/image.ts @@ -15,6 +15,7 @@ export default function image( }); }); const resultData: IParserData = { + originData: data, images, _id: 1, dataArray: [ diff --git a/packages/utils/src/color.ts b/packages/utils/src/color.ts index cf31e6964b..08799d8b4a 100644 --- a/packages/utils/src/color.ts +++ b/packages/utils/src/color.ts @@ -1,4 +1,5 @@ import * as d3 from 'd3-color'; +import { $window, isMini } from './mini-adapter'; export interface IColorRamp { positions: number[]; colors: string[]; @@ -34,8 +35,16 @@ export function encodePickingColor( ]; } -export function generateColorRamp(colorRamp: IColorRamp): ImageData { - const canvas = document.createElement('canvas'); +export interface IImagedata { + data: Uint8ClampedArray; + width: number; + height: number; +} + +export function generateColorRamp( + colorRamp: IColorRamp, +): ImageData | IImagedata { + const canvas = $window.document.createElement('canvas'); const ctx = canvas.getContext('2d') as CanvasRenderingContext2D; canvas.width = 256; canvas.height = 1; @@ -51,5 +60,7 @@ export function generateColorRamp(colorRamp: IColorRamp): ImageData { ctx.fillRect(0, 0, 256, 1); data = new Uint8ClampedArray(ctx.getImageData(0, 0, 256, 1).data); - return new ImageData(data, 256, 1); + return !isMini + ? new ImageData(data, 256, 1) + : { data, width: 256, height: 1 }; } diff --git a/packages/utils/src/dom.ts b/packages/utils/src/dom.ts index 0dea9263ee..dd0690d9df 100644 --- a/packages/utils/src/dom.ts +++ b/packages/utils/src/dom.ts @@ -1,9 +1,9 @@ -const docStyle = window.document.documentElement.style; +import { $window, isMini } from './mini-adapter'; type ELType = HTMLElement | SVGElement; export function getContainer(domId: string | HTMLDivElement) { let $dom = domId as HTMLDivElement; if (typeof domId === 'string') { - $dom = document.getElementById(domId) as HTMLDivElement; + $dom = $window.document.getElementById(domId) as HTMLDivElement; } return $dom; } @@ -19,6 +19,7 @@ export function splitWords(str: string) { } function testProp(props: string[]): string { + const docStyle = $window?.document?.documentElement?.style; if (!docStyle) { return props[0]; } @@ -35,7 +36,7 @@ export function create( className?: string, container?: HTMLElement, ) { - const el = document.createElement(tagName); + const el = $window.document.createElement(tagName); el.className = className || ''; if (container) { @@ -133,14 +134,14 @@ export function setTransform(el: ELType, value: string) { export function triggerResize() { if (typeof Event === 'function') { // modern browsers - window.dispatchEvent(new Event('resize')); + $window.dispatchEvent(new Event('resize')); } else { // for IE and other old browsers // causes deprecation warning on modern browsers - const evt = window.document.createEvent('UIEvents'); + const evt = $window.document.createEvent('UIEvents'); // @ts-ignore - evt.initUIEvent('resize', true, false, window, 0); - window.dispatchEvent(evt); + evt.initUIEvent('resize', true, false, $window, 0); + $window.dispatchEvent(evt); } } @@ -155,7 +156,7 @@ export function printCanvas(canvas: HTMLCanvasElement) { } export function getViewPortScale() { - const meta = document.querySelector('meta[name="viewport"]'); + const meta = $window.document.querySelector('meta[name="viewport"]'); if (!meta) { return 1; } @@ -167,4 +168,4 @@ export function getViewPortScale() { return scale ? scale.split('=')[1] * 1 : 1; } -export const DPR = getViewPortScale() < 1 ? 1 : window.devicePixelRatio; +export const DPR = getViewPortScale() < 1 ? 1 : $window.devicePixelRatio; diff --git a/packages/utils/src/fetchData.ts b/packages/utils/src/fetchData.ts index a4e874fee6..340de06127 100644 --- a/packages/utils/src/fetchData.ts +++ b/packages/utils/src/fetchData.ts @@ -1,3 +1,4 @@ +import { $window, $XMLHttpRequest } from './mini-adapter'; class AJAXError extends Error { private status: number; private url: string; @@ -18,7 +19,7 @@ class AJAXError extends Error { } function makeRequest(requestParameters: any) { - const xhr = new XMLHttpRequest(); + const xhr = new $XMLHttpRequest(); xhr.open('GET', requestParameters.url, true); for (const k in requestParameters.headers) { @@ -89,11 +90,11 @@ export const getArrayBuffer = (requestParameters: any, callback: any) => { }; function sameOrigin(url: string) { - const a = window.document.createElement('a'); + const a = $window.document.createElement('a'); a.href = url; return ( - a.protocol === window.document.location.protocol && - a.host === window.document.location.host + a.protocol === $window.document.location.protocol && + a.host === $window.document.location.host ); } @@ -107,14 +108,15 @@ export const getImage = (requestParameters: any, callback: any) => { if (err) { callback(err); } else if (imgData) { - const img = new window.Image(); + const img = new $window.Image(); img.crossOrigin = 'anonymous'; - const URL = window.URL || window.webkitURL; + const URL = $window.URL || $window.webkitURL; + // @ts-ignore img.onload = () => { callback(null, img); URL.revokeObjectURL(img.src); }; - const blob = new window.Blob([new Uint8Array(imgData.data)], { + const blob = new $window.Blob([new Uint8Array(imgData.data)], { type: 'image/png', }); img.src = imgData.data.byteLength diff --git a/packages/utils/src/index.ts b/packages/utils/src/index.ts index 2ddcc58da4..42de82fe48 100644 --- a/packages/utils/src/index.ts +++ b/packages/utils/src/index.ts @@ -1,6 +1,7 @@ // @ts-ignore export { djb2hash, BKDRHash } from './hash'; import * as DOM from './dom'; +export * from './mini-adapter/index'; export * from './fetchData'; export * from './geo'; export * from './lru_cache'; diff --git a/packages/utils/src/mini-adapter/Element.ts b/packages/utils/src/mini-adapter/Element.ts new file mode 100644 index 0000000000..d39504a72c --- /dev/null +++ b/packages/utils/src/mini-adapter/Element.ts @@ -0,0 +1,31 @@ +// @ts-nocheck +// tslint:disable +import { Node } from './Node'; + +export class Element extends Node { + public className: string; + public children: any[]; + + constructor() { + super(); + + this.className = ''; + this.children = []; + } + + public setAttribute(name, value) { + this[name] = value; + } + + public getAttribute(name) { + return this[name]; + } + + public setAttributeNS(name, value) { + this[name] = value; + } + + public getAttributeNS(name) { + return this[name]; + } +} diff --git a/packages/utils/src/mini-adapter/Event.ts b/packages/utils/src/mini-adapter/Event.ts new file mode 100644 index 0000000000..e6cf7d2d1a --- /dev/null +++ b/packages/utils/src/mini-adapter/Event.ts @@ -0,0 +1,28 @@ +// @ts-nocheck +// tslint:disable +export class Event { + public cancelBubble: boolean; + public cancelable: boolean; + public target: any; + public currentTarget: any; + public preventDefault: any; + public stopPropagation: any; + public type: any; + public timeStamp: number; + + constructor(type: any,data) { + this.cancelBubble = false; + this.cancelable = false; + this.target = null; + this.currentTarget = null; + this.preventDefault = () => { + // TODO + }; + this.stopPropagation = () => { + // TODO + }; + + this.type = type; + this.timeStamp = Date.now(); + } +} diff --git a/packages/utils/src/mini-adapter/EventIniter/MouseEvent.ts b/packages/utils/src/mini-adapter/EventIniter/MouseEvent.ts new file mode 100644 index 0000000000..ed5983dc3f --- /dev/null +++ b/packages/utils/src/mini-adapter/EventIniter/MouseEvent.ts @@ -0,0 +1,22 @@ +// @ts-nocheck +// tslint:disable +import { document } from '../document'; +import { Event } from '../Event'; + +class MouseEvent extends Event { + constructor(type) { + super(type); + } +} + +function eventHandlerFactory(type) { + return (rawEvent) => { + rawEvent.type = type; + document.dispatchEvent(rawEvent); + }; +} + +const dispatchMouseDown = eventHandlerFactory('mousedown'); +const dispatchMouseMove = eventHandlerFactory('mousemove'); +const dispatchMouseUp = eventHandlerFactory('mouseup'); +export { dispatchMouseDown, dispatchMouseMove, dispatchMouseUp }; diff --git a/packages/utils/src/mini-adapter/EventIniter/PointerEvent.ts b/packages/utils/src/mini-adapter/EventIniter/PointerEvent.ts new file mode 100644 index 0000000000..7c8895d6c1 --- /dev/null +++ b/packages/utils/src/mini-adapter/EventIniter/PointerEvent.ts @@ -0,0 +1,199 @@ +// @ts-nocheck +// tslint:disable +import { document } from '../document'; +import { Event } from '../Event'; +import { getCanvas } from '../register'; + +class PointerEvent extends Event { + public buttons: number; + public which: number; + + public pointerId: number; + public bubbles: boolean; + public button: number; + public width: number; + public height: number; + public pressure: number; + public isPrimary: boolean; + public pointerType: string; + public altKey: boolean; + public ctrlKey: boolean; + public metaKey: boolean; + public shiftKey: boolean; + + constructor(type) { + super(type); + + this.target = getCanvas(); + this.currentTarget = getCanvas(); + } +} + +const CLONE_PROPS = [ + // MouseEvent + 'bubbles', + 'cancelable', + 'view', + 'detail', + 'screenX', + 'screenY', + 'clientX', + 'clientY', + 'ctrlKey', + 'altKey', + 'shiftKey', + 'metaKey', + 'button', + 'relatedTarget', + + // PointerEvent + 'pointerId', + 'width', + 'height', + 'pressure', + 'tiltX', + 'tiltY', + 'pointerType', + 'hwTimestamp', + 'isPrimary', + + // event instance + 'pageX', + 'pageY', + 'timeStamp', +]; + +const CLONE_DEFAULTS = [ + // MouseEvent + false, + false, + null, + null, + 0, + 0, + 0, + 0, + false, + false, + false, + false, + 0, + null, + + // DOM Level 3 + 0, + + // PointerEvent + 0, + 0, + 0, + 0, + 0, + 0, + '', + 0, + false, + + // event instance + 0, + 0, + 0, +]; + +const POINTER_TYPE = 'touch'; + +function touchToPointer(type, touch, rawEvent) { + const e = new PointerEvent(type); + + for (let i = 0; i < CLONE_PROPS.length; i++) { + const p = CLONE_PROPS[i]; + e[p] = touch[p] || CLONE_DEFAULTS[i]; + } + + e.type = type; + e.target = getCanvas(); + e.currentTarget = getCanvas(); + e.buttons = typeToButtons(type); + e.which = e.buttons; + + e.pointerId = (touch.identifier || 0) + 2; + e.bubbles = true; + e.cancelable = true; + // e.detail = this.clickCount; + e.button = 0; + + e.width = (touch.radiusX || 0.5) * 2; + e.height = (touch.radiusY || 0.5) * 2; + e.pressure = touch.force || 0.5; + e.isPrimary = isPrimaryPointer(touch); + e.pointerType = POINTER_TYPE; + + // forward modifier keys + e.altKey = rawEvent.altKey; + e.ctrlKey = rawEvent.ctrlKey; + e.metaKey = rawEvent.metaKey; + e.shiftKey = rawEvent.shiftKey; + + if (rawEvent.preventDefault) { + e.preventDefault = () => { + rawEvent.preventDefault(); + }; + } + + return e; +} + +function typeToButtons(type) { + let ret = 0; + if ( + type === 'touchstart' || + type === 'touchmove' || + type === 'pointerdown' || + type === 'pointermove' + ) { + ret = 1; + } + return ret; +} + +let firstPointer = null; + +function isPrimaryPointer(touch) { + return firstPointer === touch.identifier; +} + +function setPrimaryPointer(touch) { + if (firstPointer === null) { + firstPointer = touch.identifier; + } +} + +function removePrimaryPointer(touch) { + if (firstPointer === touch.identifier) { + firstPointer = null; + } +} + +function eventHandlerFactory(type) { + return (rawEvent) => { + const changedTouches = rawEvent.changedTouches; + + for (let i = 0; i < changedTouches.length; i++) { + const touch = changedTouches[i]; + + if (i === 0 && type === 'pointerdown') { + setPrimaryPointer(touch); + } else if (type === 'pointerup' || type === 'pointercancel') { + removePrimaryPointer(touch); + } + + const event = touchToPointer(type, touch, rawEvent); + document.dispatchEvent(event); + } + }; +} + +const dispatchPointerDown = eventHandlerFactory('pointerdown'); +const dispatchPointerMove = eventHandlerFactory('pointermove'); +const dispatchPointerUp = eventHandlerFactory('pointerup'); +export { dispatchPointerDown, dispatchPointerMove, dispatchPointerUp }; diff --git a/packages/utils/src/mini-adapter/EventIniter/TouchEvent.ts b/packages/utils/src/mini-adapter/EventIniter/TouchEvent.ts new file mode 100755 index 0000000000..d9567236b1 --- /dev/null +++ b/packages/utils/src/mini-adapter/EventIniter/TouchEvent.ts @@ -0,0 +1,65 @@ +// @ts-nocheck +// tslint:disable +import { document } from '../document'; +import { Event } from '../Event'; +import { getCanvas } from '../register'; + +class TouchEvent extends Event { + public touches: any[]; + public targetTouches: any[]; + public changedTouches: any[]; + + constructor(type) { + super(type); + + this.touches = []; + this.targetTouches = []; + this.changedTouches = []; + + this.target = getCanvas(); + this.currentTarget = getCanvas(); + } +} + +function mapEvent(event) { + const { x = 0, y = 0, clientX = 0, clientY = 0 } = event || {}; + // 小程序不支持Object.hasOwnProperty + // (抹平不同的view事件)[https://docs.alipay.com/mini/framework/event-object] + if (Object.keys(event).indexOf('x') !== -1) { + event.pageX = event.clientX = x; + event.pageY = event.clientY = y; + } else { + event.x = clientX; + event.y = clientY; + } +} + +function eventHandlerFactory(type) { + return (rawEvent) => { + const event = new TouchEvent(type); + + event.changedTouches = rawEvent.changedTouches; + event.touches = rawEvent.touches; + event.targetTouches = Array.prototype.slice.call(rawEvent.touches); + event.timeStamp = rawEvent.timeStamp; + + event.changedTouches.forEach((e) => mapEvent(e)); + event.touches.forEach((e) => mapEvent(e)); + event.targetTouches.forEach((e) => mapEvent(e)); + + document.dispatchEvent(event); + }; +} + +function eventMapHandlerFactory(type) { + return function (rawEvent) { + rawEvent.type = type; + document.dispatchEvent(rawEvent); + }; +} + +const dispatchTouchStart = eventHandlerFactory('touchstart'); +const dispatchTouchMove = eventHandlerFactory('touchmove'); +const dispatchTouchEnd = eventHandlerFactory('touchend'); +const dispatchMapCameraParams = eventMapHandlerFactory('mapCameaParams'); +export { dispatchTouchStart, dispatchTouchMove, dispatchTouchEnd, dispatchMapCameraParams }; diff --git a/packages/utils/src/mini-adapter/EventIniter/index.ts b/packages/utils/src/mini-adapter/EventIniter/index.ts new file mode 100755 index 0000000000..f4ad67c2ef --- /dev/null +++ b/packages/utils/src/mini-adapter/EventIniter/index.ts @@ -0,0 +1,3 @@ +export * from './TouchEvent'; +export * from './PointerEvent'; +export * from './MouseEvent'; diff --git a/packages/utils/src/mini-adapter/EventTarget.ts b/packages/utils/src/mini-adapter/EventTarget.ts new file mode 100644 index 0000000000..b03abe99fb --- /dev/null +++ b/packages/utils/src/mini-adapter/EventTarget.ts @@ -0,0 +1,61 @@ +// @ts-nocheck +// tslint:disable +import { Event } from './Event'; + +const _events = new WeakMap(); + +export default class EventTarget { + constructor() { + _events.set(this, {}); + } + + public addEventListener(type, listener, options: any = {}) { + let events = _events.get(this); + + if (!events) { + events = {}; + } + if (!events[type]) { + events[type] = []; + } + events[type].push(listener); + _events.set(this, events); + + if (options.capture) { + // console.warn('EventTarget.addEventListener: options.capture is not implemented.') + } + if (options.once) { + // console.warn('EventTarget.addEventListener: options.once is not implemented.') + } + if (options.passive) { + // console.warn('EventTarget.addEventListener: options.passive is not implemented.') + } + } + + public removeEventListener(type, listener, options = {}) { + const events = _events.get(this); + + if (events) { + const listeners = events[type]; + + if (listeners && listeners.length > 0) { + for (let i = listeners.length; i--; i > 0) { + if (listeners[i] === listener) { + listeners.splice(i, 1); + break; + } + } + } + } + } + + public dispatchEvent(event: Event) { + const listeners = _events.get(this)[event.type]; + + if (listeners) { + for (const listener of listeners) { + listener(event); + } + } + } +} diff --git a/packages/utils/src/mini-adapter/HTMLCanvasElement.ts b/packages/utils/src/mini-adapter/HTMLCanvasElement.ts new file mode 100644 index 0000000000..cf51698d34 --- /dev/null +++ b/packages/utils/src/mini-adapter/HTMLCanvasElement.ts @@ -0,0 +1,3 @@ +// @ts-nocheck +// tslint:disable +export const HTMLCanvasElement = Object; diff --git a/packages/utils/src/mini-adapter/HTMLElement.ts b/packages/utils/src/mini-adapter/HTMLElement.ts new file mode 100644 index 0000000000..d6d5c18c26 --- /dev/null +++ b/packages/utils/src/mini-adapter/HTMLElement.ts @@ -0,0 +1,45 @@ +// @ts-nocheck +// tslint:disable +import { Element } from './Element'; +import * as Mixin from './util/mixin'; + +function noop() {} + +export class HTMLElement extends Element { + public className: string; + public children: any[]; + public focus: any; + public blur: any; + public insertBefore: any; + public appendChild: any; + public removeChild: any; + public remove: any; + public innerHTML: string; + public tagName: string; + + constructor(tagName = '', level?: number) { + super(); + + this.className = ''; + this.children = []; + + this.focus = noop; + this.blur = noop; + + this.insertBefore = noop; + this.appendChild = noop; + this.removeChild = noop; + this.remove = noop; + + this.innerHTML = ''; + + this.tagName = tagName.toUpperCase(); + + Mixin.parentNode(this, level); + Mixin.style(this); + Mixin.classList(this); + Mixin.clientRegion(this); + Mixin.offsetRegion(this); + Mixin.scrollRegion(this); + } +} diff --git a/packages/utils/src/mini-adapter/HTMLMediaElement.ts b/packages/utils/src/mini-adapter/HTMLMediaElement.ts new file mode 100644 index 0000000000..b62173a963 --- /dev/null +++ b/packages/utils/src/mini-adapter/HTMLMediaElement.ts @@ -0,0 +1,21 @@ +// @ts-nocheck +// tslint:disable +import { HTMLElement } from './HTMLElement'; + +export class HTMLMediaElement extends HTMLElement { + constructor(tagName: string) { + super(tagName); + } + + public addTextTrack() {} + + public captureStream() {} + + public fastSeek() {} + + public load() {} + + public pause() {} + + public play() {} +} diff --git a/packages/utils/src/mini-adapter/HTMLVideoElement.ts b/packages/utils/src/mini-adapter/HTMLVideoElement.ts new file mode 100644 index 0000000000..412bd65a37 --- /dev/null +++ b/packages/utils/src/mini-adapter/HTMLVideoElement.ts @@ -0,0 +1,9 @@ +// @ts-nocheck +// tslint:disable +import { HTMLMediaElement } from './HTMLMediaElement'; + +export class HTMLVideoElement extends HTMLMediaElement { + constructor() { + super('video'); + } +} diff --git a/packages/utils/src/mini-adapter/Image.ts b/packages/utils/src/mini-adapter/Image.ts new file mode 100644 index 0000000000..b531b1eb3c --- /dev/null +++ b/packages/utils/src/mini-adapter/Image.ts @@ -0,0 +1,31 @@ +// @ts-nocheck +// tslint:disable +import { getCanvas } from './register'; +import * as Mixin from './util/mixin'; + +export class Image { + constructor() { + const canvas = getCanvas(); + + const image = (canvas.createImage && canvas.createImage()) || {}; + + if (!('tagName' in image)) { + image.tagName = 'IMG'; + image.__proto__ = Image.prototype; + } + + Mixin.parentNode(image); + Mixin.classList(image); + + Object.assign(image, { + addEventListener(name, cb) { + image[`on${name}`] = cb.bind(image); + }, + removeEventListener(name) { + image[`on${name}`] = null; + }, + }); + + return image; + } +} diff --git a/packages/utils/src/mini-adapter/ImageData.ts b/packages/utils/src/mini-adapter/ImageData.ts new file mode 100644 index 0000000000..9e8769f9e1 --- /dev/null +++ b/packages/utils/src/mini-adapter/ImageData.ts @@ -0,0 +1,45 @@ +// @ts-nocheck +// tslint:disable +export class ImageData { + private _w: number; + private _h: number; + private _data: Uint8ClampedArray; + + constructor() { + const len = arguments.length; + if (len === 2) { + if ( + typeof arguments[0] === 'number' && + typeof arguments[1] === 'number' + ) { + this._w = arguments[0]; + this._h = arguments[1]; + this._data = new Uint8ClampedArray(this._w * this._h * 4); + return; + } + } else if (len === 3) { + if ( + typeof arguments[0] === 'object' && + typeof arguments[1] === 'number' && + typeof arguments[2] === 'number' + ) { + this._data = arguments[0]; + this._w = arguments[1]; + this._h = arguments[2]; + } + } + throw new Error('ImageData: params error'); + } + + get width(): number { + return this._w; + } + + get height(): number { + return this._h; + } + + get data(): Uint8ClampedArray { + return this._data; + } +} diff --git a/packages/utils/src/mini-adapter/Node.ts b/packages/utils/src/mini-adapter/Node.ts new file mode 100755 index 0000000000..e61d7d38db --- /dev/null +++ b/packages/utils/src/mini-adapter/Node.ts @@ -0,0 +1,37 @@ +// @ts-nocheck +// tslint:disable +import EventTarget from './EventTarget'; + +export class Node extends EventTarget { + public childNodes: any[]; + + constructor() { + super(); + this.childNodes = []; + } + + public appendChild(node) { + this.childNodes.push(node); + // if (node instanceof Node) { + // this.childNodes.push(node) + // } else { + // throw new TypeError('Failed to executed \'appendChild\' on \'Node\': parameter 1 is not of type \'Node\'.') + // } + } + + public cloneNode() { + const copyNode = Object.create(this); + + Object.assign(copyNode, this); + return copyNode; + } + + public removeChild(node) { + const index = this.childNodes.findIndex((child) => child === node); + + if (index > -1) { + return this.childNodes.splice(index, 1); + } + return null; + } +} diff --git a/packages/utils/src/mini-adapter/WebGL.ts b/packages/utils/src/mini-adapter/WebGL.ts new file mode 100644 index 0000000000..be6749d41c --- /dev/null +++ b/packages/utils/src/mini-adapter/WebGL.ts @@ -0,0 +1,837 @@ +// @ts-nocheck +// tslint:disable +export const WebGLRenderingContext = { + GCCSO_SHADER_BINARY_FJ: 0x9260, + _3DC_XY_AMD: 0x87fa, + _3DC_X_AMD: 0x87f9, + ACTIVE_ATTRIBUTES: 0x8b89, + ACTIVE_ATTRIBUTE_MAX_LENGTH: 0x8b8a, + ACTIVE_PROGRAM_EXT: 0x8259, + ACTIVE_TEXTURE: 0x84e0, + ACTIVE_UNIFORMS: 0x8b86, + ACTIVE_UNIFORM_MAX_LENGTH: 0x8b87, + ALIASED_LINE_WIDTH_RANGE: 0x846e, + ALIASED_POINT_SIZE_RANGE: 0x846d, + ALL_COMPLETED_NV: 0x84f2, + ALL_SHADER_BITS_EXT: 0xffffffff, + ALPHA: 0x1906, + ALPHA16F_EXT: 0x881c, + ALPHA32F_EXT: 0x8816, + ALPHA8_EXT: 0x803c, + ALPHA8_OES: 0x803c, + ALPHA_BITS: 0xd55, + ALPHA_TEST_FUNC_QCOM: 0xbc1, + ALPHA_TEST_QCOM: 0xbc0, + ALPHA_TEST_REF_QCOM: 0xbc2, + ALREADY_SIGNALED_APPLE: 0x911a, + ALWAYS: 0x207, + AMD_compressed_3DC_texture: 0x1, + AMD_compressed_ATC_texture: 0x1, + AMD_performance_monitor: 0x1, + AMD_program_binary_Z400: 0x1, + ANGLE_depth_texture: 0x1, + ANGLE_framebuffer_blit: 0x1, + ANGLE_framebuffer_multisample: 0x1, + ANGLE_instanced_arrays: 0x1, + ANGLE_pack_reverse_row_order: 0x1, + ANGLE_program_binary: 0x1, + ANGLE_texture_compression_dxt3: 0x1, + ANGLE_texture_compression_dxt5: 0x1, + ANGLE_texture_usage: 0x1, + ANGLE_translated_shader_source: 0x1, + ANY_SAMPLES_PASSED_CONSERVATIVE_EXT: 0x8d6a, + ANY_SAMPLES_PASSED_EXT: 0x8c2f, + APPLE_copy_texture_levels: 0x1, + APPLE_framebuffer_multisample: 0x1, + APPLE_rgb_422: 0x1, + APPLE_sync: 0x1, + APPLE_texture_format_BGRA8888: 0x1, + APPLE_texture_max_level: 0x1, + ARM_mali_program_binary: 0x1, + ARM_mali_shader_binary: 0x1, + ARM_rgba8: 0x1, + ARRAY_BUFFER: 0x8892, + ARRAY_BUFFER_BINDING: 0x8894, + ATC_RGBA_EXPLICIT_ALPHA_AMD: 0x8c93, + ATC_RGBA_INTERPOLATED_ALPHA_AMD: 0x87ee, + ATC_RGB_AMD: 0x8c92, + ATTACHED_SHADERS: 0x8b85, + BACK: 0x405, + BGRA8_EXT: 0x93a1, + BGRA_EXT: 0x80e1, + BGRA_IMG: 0x80e1, + BINNING_CONTROL_HINT_QCOM: 0x8fb0, + BLEND: 0xbe2, + BLEND_COLOR: 0x8005, + BLEND_DST_ALPHA: 0x80ca, + BLEND_DST_RGB: 0x80c8, + BLEND_EQUATION: 0x8009, + BLEND_EQUATION_ALPHA: 0x883d, + BLEND_EQUATION_RGB: 0x8009, + BLEND_SRC_ALPHA: 0x80cb, + BLEND_SRC_RGB: 0x80c9, + BLUE_BITS: 0xd54, + BOOL: 0x8b56, + BOOL_VEC2: 0x8b57, + BOOL_VEC3: 0x8b58, + BOOL_VEC4: 0x8b59, + BUFFER: 0x82e0, + BUFFER_ACCESS_OES: 0x88bb, + BUFFER_MAPPED_OES: 0x88bc, + BUFFER_MAP_POINTER_OES: 0x88bd, + BUFFER_OBJECT_EXT: 0x9151, + BUFFER_SIZE: 0x8764, + BUFFER_USAGE: 0x8765, + BYTE: 0x1400, + CCW: 0x901, + CLAMP_TO_BORDER_NV: 0x812d, + CLAMP_TO_EDGE: 0x812f, + COLOR_ATTACHMENT0: 0x8ce0, + COLOR_ATTACHMENT0_NV: 0x8ce0, + COLOR_ATTACHMENT10_NV: 0x8cea, + COLOR_ATTACHMENT11_NV: 0x8ceb, + COLOR_ATTACHMENT12_NV: 0x8cec, + COLOR_ATTACHMENT13_NV: 0x8ced, + COLOR_ATTACHMENT14_NV: 0x8cee, + COLOR_ATTACHMENT15_NV: 0x8cef, + COLOR_ATTACHMENT1_NV: 0x8ce1, + COLOR_ATTACHMENT2_NV: 0x8ce2, + COLOR_ATTACHMENT3_NV: 0x8ce3, + COLOR_ATTACHMENT4_NV: 0x8ce4, + COLOR_ATTACHMENT5_NV: 0x8ce5, + COLOR_ATTACHMENT6_NV: 0x8ce6, + COLOR_ATTACHMENT7_NV: 0x8ce7, + COLOR_ATTACHMENT8_NV: 0x8ce8, + COLOR_ATTACHMENT9_NV: 0x8ce9, + COLOR_ATTACHMENT_EXT: 0x90f0, + COLOR_BUFFER_BIT: 0x4000, + COLOR_BUFFER_BIT0_QCOM: 0x1, + COLOR_BUFFER_BIT1_QCOM: 0x2, + COLOR_BUFFER_BIT2_QCOM: 0x4, + COLOR_BUFFER_BIT3_QCOM: 0x8, + COLOR_BUFFER_BIT4_QCOM: 0x10, + COLOR_BUFFER_BIT5_QCOM: 0x20, + COLOR_BUFFER_BIT6_QCOM: 0x40, + COLOR_BUFFER_BIT7_QCOM: 0x80, + COLOR_CLEAR_VALUE: 0xc22, + COLOR_EXT: 0x1800, + COLOR_WRITEMASK: 0xc23, + COMPARE_REF_TO_TEXTURE_EXT: 0x884e, + COMPILE_STATUS: 0x8b81, + COMPRESSED_RGBA_ASTC_10x10_KHR: 0x93bb, + COMPRESSED_RGBA_ASTC_10x5_KHR: 0x93b8, + COMPRESSED_RGBA_ASTC_10x6_KHR: 0x93b9, + COMPRESSED_RGBA_ASTC_10x8_KHR: 0x93ba, + COMPRESSED_RGBA_ASTC_12x10_KHR: 0x93bc, + COMPRESSED_RGBA_ASTC_12x12_KHR: 0x93bd, + COMPRESSED_RGBA_ASTC_4x4_KHR: 0x93b0, + COMPRESSED_RGBA_ASTC_5x4_KHR: 0x93b1, + COMPRESSED_RGBA_ASTC_5x5_KHR: 0x93b2, + COMPRESSED_RGBA_ASTC_6x5_KHR: 0x93b3, + COMPRESSED_RGBA_ASTC_6x6_KHR: 0x93b4, + COMPRESSED_RGBA_ASTC_8x5_KHR: 0x93b5, + COMPRESSED_RGBA_ASTC_8x6_KHR: 0x93b6, + COMPRESSED_RGBA_ASTC_8x8_KHR: 0x93b7, + COMPRESSED_RGBA_PVRTC_2BPPV1_IMG: 0x8c03, + COMPRESSED_RGBA_PVRTC_2BPPV2_IMG: 0x9137, + COMPRESSED_RGBA_PVRTC_4BPPV1_IMG: 0x8c02, + COMPRESSED_RGBA_PVRTC_4BPPV2_IMG: 0x9138, + COMPRESSED_RGBA_S3TC_DXT1_EXT: 0x83f1, + COMPRESSED_RGBA_S3TC_DXT3_ANGLE: 0x83f2, + COMPRESSED_RGBA_S3TC_DXT5_ANGLE: 0x83f3, + COMPRESSED_RGB_PVRTC_2BPPV1_IMG: 0x8c01, + COMPRESSED_RGB_PVRTC_4BPPV1_IMG: 0x8c00, + COMPRESSED_RGB_S3TC_DXT1_EXT: 0x83f0, + COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR: 0x93db, + COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR: 0x93d8, + COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR: 0x93d9, + COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR: 0x93da, + COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR: 0x93dc, + COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR: 0x93dd, + COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR: 0x93d0, + COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR: 0x93d1, + COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR: 0x93d2, + COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR: 0x93d3, + COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR: 0x93d4, + COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR: 0x93d5, + COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR: 0x93d6, + COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR: 0x93d7, + COMPRESSED_SRGB_ALPHA_S3TC_DXT1_NV: 0x8c4d, + COMPRESSED_SRGB_ALPHA_S3TC_DXT3_NV: 0x8c4e, + COMPRESSED_SRGB_ALPHA_S3TC_DXT5_NV: 0x8c4f, + COMPRESSED_SRGB_S3TC_DXT1_NV: 0x8c4c, + COMPRESSED_TEXTURE_FORMATS: 0x86a3, + CONDITION_SATISFIED_APPLE: 0x911c, + CONSTANT_ALPHA: 0x8003, + CONSTANT_COLOR: 0x8001, + CONTEXT_FLAG_DEBUG_BIT: 0x2, + CONTEXT_ROBUST_ACCESS_EXT: 0x90f3, + COUNTER_RANGE_AMD: 0x8bc1, + COUNTER_TYPE_AMD: 0x8bc0, + COVERAGE_ALL_FRAGMENTS_NV: 0x8ed5, + COVERAGE_ATTACHMENT_NV: 0x8ed2, + COVERAGE_AUTOMATIC_NV: 0x8ed7, + COVERAGE_BUFFERS_NV: 0x8ed3, + COVERAGE_BUFFER_BIT_NV: 0x8000, + COVERAGE_COMPONENT4_NV: 0x8ed1, + COVERAGE_COMPONENT_NV: 0x8ed0, + COVERAGE_EDGE_FRAGMENTS_NV: 0x8ed6, + COVERAGE_SAMPLES_NV: 0x8ed4, + CPU_OPTIMIZED_QCOM: 0x8fb1, + CULL_FACE: 0xb44, + CULL_FACE_MODE: 0xb45, + CURRENT_PROGRAM: 0x8b8d, + CURRENT_QUERY_EXT: 0x8865, + CURRENT_VERTEX_ATTRIB: 0x8626, + CW: 0x900, + DEBUG_CALLBACK_FUNCTION: 0x8244, + DEBUG_CALLBACK_USER_PARAM: 0x8245, + DEBUG_GROUP_STACK_DEPTH: 0x826d, + DEBUG_LOGGED_MESSAGES: 0x9145, + DEBUG_NEXT_LOGGED_MESSAGE_LENGTH: 0x8243, + DEBUG_OUTPUT: 0x92e0, + DEBUG_OUTPUT_SYNCHRONOUS: 0x8242, + DEBUG_SEVERITY_HIGH: 0x9146, + DEBUG_SEVERITY_LOW: 0x9148, + DEBUG_SEVERITY_MEDIUM: 0x9147, + DEBUG_SEVERITY_NOTIFICATION: 0x826b, + DEBUG_SOURCE_API: 0x8246, + DEBUG_SOURCE_APPLICATION: 0x824a, + DEBUG_SOURCE_OTHER: 0x824b, + DEBUG_SOURCE_SHADER_COMPILER: 0x8248, + DEBUG_SOURCE_THIRD_PARTY: 0x8249, + DEBUG_SOURCE_WINDOW_SYSTEM: 0x8247, + DEBUG_TYPE_DEPRECATED_BEHAVIOR: 0x824d, + DEBUG_TYPE_ERROR: 0x824c, + DEBUG_TYPE_MARKER: 0x8268, + DEBUG_TYPE_OTHER: 0x8251, + DEBUG_TYPE_PERFORMANCE: 0x8250, + DEBUG_TYPE_POP_GROUP: 0x826a, + DEBUG_TYPE_PORTABILITY: 0x824f, + DEBUG_TYPE_PUSH_GROUP: 0x8269, + DEBUG_TYPE_UNDEFINED_BEHAVIOR: 0x824e, + DECR: 0x1e03, + DECR_WRAP: 0x8508, + DELETE_STATUS: 0x8b80, + DEPTH24_STENCIL8_OES: 0x88f0, + DEPTH_ATTACHMENT: 0x8d00, + DEPTH_STENCIL_ATTACHMENT: 0x821a, + DEPTH_BITS: 0xd56, + DEPTH_BUFFER_BIT: 0x100, + DEPTH_BUFFER_BIT0_QCOM: 0x100, + DEPTH_BUFFER_BIT1_QCOM: 0x200, + DEPTH_BUFFER_BIT2_QCOM: 0x400, + DEPTH_BUFFER_BIT3_QCOM: 0x800, + DEPTH_BUFFER_BIT4_QCOM: 0x1000, + DEPTH_BUFFER_BIT5_QCOM: 0x2000, + DEPTH_BUFFER_BIT6_QCOM: 0x4000, + DEPTH_BUFFER_BIT7_QCOM: 0x8000, + DEPTH_CLEAR_VALUE: 0xb73, + DEPTH_COMPONENT: 0x1902, + DEPTH_COMPONENT16: 0x81a5, + DEPTH_COMPONENT16_NONLINEAR_NV: 0x8e2c, + DEPTH_COMPONENT16_OES: 0x81a5, + DEPTH_COMPONENT24_OES: 0x81a6, + DEPTH_COMPONENT32_OES: 0x81a7, + DEPTH_EXT: 0x1801, + DEPTH_FUNC: 0xb74, + DEPTH_RANGE: 0xb70, + DEPTH_STENCIL: 0x84f9, + DEPTH_STENCIL_OES: 0x84f9, + DEPTH_TEST: 0xb71, + DEPTH_WRITEMASK: 0xb72, + DITHER: 0xbd0, + DMP_shader_binary: 0x1, + DONT_CARE: 0x1100, + DRAW_BUFFER0_NV: 0x8825, + DRAW_BUFFER10_NV: 0x882f, + DRAW_BUFFER11_NV: 0x8830, + DRAW_BUFFER12_NV: 0x8831, + DRAW_BUFFER13_NV: 0x8832, + DRAW_BUFFER14_NV: 0x8833, + DRAW_BUFFER15_NV: 0x8834, + DRAW_BUFFER1_NV: 0x8826, + DRAW_BUFFER2_NV: 0x8827, + DRAW_BUFFER3_NV: 0x8828, + DRAW_BUFFER4_NV: 0x8829, + DRAW_BUFFER5_NV: 0x882a, + DRAW_BUFFER6_NV: 0x882b, + DRAW_BUFFER7_NV: 0x882c, + DRAW_BUFFER8_NV: 0x882d, + DRAW_BUFFER9_NV: 0x882e, + DRAW_BUFFER_EXT: 0xc01, + DRAW_FRAMEBUFFER_ANGLE: 0x8ca9, + DRAW_FRAMEBUFFER_APPLE: 0x8ca9, + DRAW_FRAMEBUFFER_BINDING_ANGLE: 0x8ca6, + DRAW_FRAMEBUFFER_BINDING_APPLE: 0x8ca6, + DRAW_FRAMEBUFFER_BINDING_NV: 0x8ca6, + DRAW_FRAMEBUFFER_NV: 0x8ca9, + DST_ALPHA: 0x304, + DST_COLOR: 0x306, + DYNAMIC_DRAW: 0x88e8, + ELEMENT_ARRAY_BUFFER: 0x8893, + ELEMENT_ARRAY_BUFFER_BINDING: 0x8895, + EQUAL: 0x202, + ES_VERSION_2_0: 0x1, + ETC1_RGB8_OES: 0x8d64, + ETC1_SRGB8_NV: 0x88ee, + EXTENSIONS: 0x1f03, + EXT_blend_minmax: 0x1, + EXT_color_buffer_half_float: 0x1, + EXT_debug_label: 0x1, + EXT_debug_marker: 0x1, + EXT_discard_framebuffer: 0x1, + EXT_map_buffer_range: 0x1, + EXT_multi_draw_arrays: 0x1, + EXT_multisampled_render_to_texture: 0x1, + EXT_multiview_draw_buffers: 0x1, + EXT_occlusion_query_boolean: 0x1, + EXT_read_format_bgra: 0x1, + EXT_robustness: 0x1, + EXT_sRGB: 0x1, + EXT_separate_shader_objects: 0x1, + EXT_shader_framebuffer_fetch: 0x1, + EXT_shader_texture_lod: 0x1, + EXT_shadow_samplers: 0x1, + EXT_texture_compression_dxt1: 0x1, + EXT_texture_filter_anisotropic: 0x1, + EXT_texture_format_BGRA8888: 0x1, + EXT_texture_rg: 0x1, + EXT_texture_storage: 0x1, + EXT_texture_type_2_10_10_10_REV: 0x1, + EXT_unpack_subimage: 0x1, + FALSE: 0x0, + FASTEST: 0x1101, + FENCE_CONDITION_NV: 0x84f4, + FENCE_STATUS_NV: 0x84f3, + FIXED: 0x140c, + FJ_shader_binary_GCCSO: 0x1, + FLOAT: 0x1406, + FLOAT_MAT2: 0x8b5a, + FLOAT_MAT3: 0x8b5b, + FLOAT_MAT4: 0x8b5c, + FLOAT_VEC2: 0x8b50, + FLOAT_VEC3: 0x8b51, + FLOAT_VEC4: 0x8b52, + FRAGMENT_SHADER: 0x8b30, + FRAGMENT_SHADER_BIT_EXT: 0x2, + FRAGMENT_SHADER_DERIVATIVE_HINT_OES: 0x8b8b, + FRAGMENT_SHADER_DISCARDS_SAMPLES_EXT: 0x8a52, + FRAMEBUFFER: 0x8d40, + FRAMEBUFFER_ATTACHMENT_ANGLE: 0x93a3, + FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING_EXT: 0x8210, + FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE_EXT: 0x8211, + FRAMEBUFFER_ATTACHMENT_OBJECT_NAME: 0x8cd1, + FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE: 0x8cd0, + FRAMEBUFFER_ATTACHMENT_TEXTURE_3D_ZOFFSET_OES: 0x8cd4, + FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE: 0x8cd3, + FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL: 0x8cd2, + FRAMEBUFFER_ATTACHMENT_TEXTURE_SAMPLES_EXT: 0x8d6c, + FRAMEBUFFER_BINDING: 0x8ca6, + FRAMEBUFFER_COMPLETE: 0x8cd5, + FRAMEBUFFER_INCOMPLETE_ATTACHMENT: 0x8cd6, + FRAMEBUFFER_INCOMPLETE_DIMENSIONS: 0x8cd9, + FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT: 0x8cd7, + FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_ANGLE: 0x8d56, + FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_APPLE: 0x8d56, + FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_EXT: 0x8d56, + FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_IMG: 0x9134, + FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_NV: 0x8d56, + FRAMEBUFFER_UNDEFINED_OES: 0x8219, + FRAMEBUFFER_UNSUPPORTED: 0x8cdd, + FRONT: 0x404, + FRONT_AND_BACK: 0x408, + FRONT_FACE: 0xb46, + FUNC_ADD: 0x8006, + FUNC_REVERSE_SUBTRACT: 0x800b, + FUNC_SUBTRACT: 0x800a, + GENERATE_MIPMAP_HINT: 0x8192, + GEQUAL: 0x206, + GPU_OPTIMIZED_QCOM: 0x8fb2, + GREATER: 0x204, + GREEN_BITS: 0xd53, + GUILTY_CONTEXT_RESET_EXT: 0x8253, + HALF_FLOAT_OES: 0x8d61, + HIGH_FLOAT: 0x8df2, + HIGH_INT: 0x8df5, + IMG_multisampled_render_to_texture: 0x1, + IMG_program_binary: 0x1, + IMG_read_format: 0x1, + IMG_shader_binary: 0x1, + IMG_texture_compression_pvrtc: 0x1, + IMG_texture_compression_pvrtc2: 0x1, + IMPLEMENTATION_COLOR_READ_FORMAT: 0x8b9b, + IMPLEMENTATION_COLOR_READ_TYPE: 0x8b9a, + INCR: 0x1e02, + INCR_WRAP: 0x8507, + INFO_LOG_LENGTH: 0x8b84, + INNOCENT_CONTEXT_RESET_EXT: 0x8254, + INT: 0x1404, + INT_10_10_10_2_OES: 0x8df7, + INT_VEC2: 0x8b53, + INT_VEC3: 0x8b54, + INT_VEC4: 0x8b55, + INVALID_ENUM: 0x500, + INVALID_FRAMEBUFFER_OPERATION: 0x506, + INVALID_OPERATION: 0x502, + INVALID_VALUE: 0x501, + INVERT: 0x150a, + KEEP: 0x1e00, + KHR_debug: 0x1, + KHR_texture_compression_astc_ldr: 0x1, + LEFT: 0x0406, + LEQUAL: 0x203, + LESS: 0x201, + LINEAR: 0x2601, + LINEAR_MIPMAP_LINEAR: 0x2703, + LINEAR_MIPMAP_NEAREST: 0x2701, + LINES: 0x1, + LINE_LOOP: 0x2, + LINE_STRIP: 0x3, + LINE_WIDTH: 0xb21, + LINK_STATUS: 0x8b82, + LOSE_CONTEXT_ON_RESET_EXT: 0x8252, + LOW_FLOAT: 0x8df0, + LOW_INT: 0x8df3, + LUMINANCE: 0x1909, + LUMINANCE16F_EXT: 0x881e, + LUMINANCE32F_EXT: 0x8818, + LUMINANCE4_ALPHA4_OES: 0x8043, + LUMINANCE8_ALPHA8_EXT: 0x8045, + LUMINANCE8_ALPHA8_OES: 0x8045, + LUMINANCE8_EXT: 0x8040, + LUMINANCE8_OES: 0x8040, + LUMINANCE_ALPHA: 0x190a, + LUMINANCE_ALPHA16F_EXT: 0x881f, + LUMINANCE_ALPHA32F_EXT: 0x8819, + MALI_PROGRAM_BINARY_ARM: 0x8f61, + MALI_SHADER_BINARY_ARM: 0x8f60, + MAP_FLUSH_EXPLICIT_BIT_EXT: 0x10, + MAP_INVALIDATE_BUFFER_BIT_EXT: 0x8, + MAP_INVALIDATE_RANGE_BIT_EXT: 0x4, + MAP_READ_BIT_EXT: 0x1, + MAP_UNSYNCHRONIZED_BIT_EXT: 0x20, + MAP_WRITE_BIT_EXT: 0x2, + MAX_3D_TEXTURE_SIZE_OES: 0x8073, + MAX_COLOR_ATTACHMENTS_NV: 0x8cdf, + MAX_COMBINED_TEXTURE_IMAGE_UNITS: 0x8b4d, + MAX_CUBE_MAP_TEXTURE_SIZE: 0x851c, + MAX_DEBUG_GROUP_STACK_DEPTH: 0x826c, + MAX_DEBUG_LOGGED_MESSAGES: 0x9144, + MAX_DEBUG_MESSAGE_LENGTH: 0x9143, + MAX_DRAW_BUFFERS_NV: 0x8824, + MAX_EXT: 0x8008, + MAX_FRAGMENT_UNIFORM_VECTORS: 0x8dfd, + MAX_LABEL_LENGTH: 0x82e8, + MAX_MULTIVIEW_BUFFERS_EXT: 0x90f2, + MAX_RENDERBUFFER_SIZE: 0x84e8, + MAX_SAMPLES_ANGLE: 0x8d57, + MAX_SAMPLES_APPLE: 0x8d57, + MAX_SAMPLES_EXT: 0x8d57, + MAX_SAMPLES_IMG: 0x9135, + MAX_SAMPLES_NV: 0x8d57, + MAX_SERVER_WAIT_TIMEOUT_APPLE: 0x9111, + MAX_TEXTURE_IMAGE_UNITS: 0x8872, + MAX_TEXTURE_MAX_ANISOTROPY_EXT: 0x84ff, + MAX_TEXTURE_SIZE: 0xd33, + MAX_VARYING_VECTORS: 0x8dfc, + MAX_VERTEX_ATTRIBS: 0x8869, + MAX_VERTEX_TEXTURE_IMAGE_UNITS: 0x8b4c, + MAX_VERTEX_UNIFORM_VECTORS: 0x8dfb, + MAX_VIEWPORT_DIMS: 0xd3a, + MEDIUM_FLOAT: 0x8df1, + MEDIUM_INT: 0x8df4, + MIN_EXT: 0x8007, + MIRRORED_REPEAT: 0x8370, + MULTISAMPLE_BUFFER_BIT0_QCOM: 0x1000000, + MULTISAMPLE_BUFFER_BIT1_QCOM: 0x2000000, + MULTISAMPLE_BUFFER_BIT2_QCOM: 0x4000000, + MULTISAMPLE_BUFFER_BIT3_QCOM: 0x8000000, + MULTISAMPLE_BUFFER_BIT4_QCOM: 0x10000000, + MULTISAMPLE_BUFFER_BIT5_QCOM: 0x20000000, + MULTISAMPLE_BUFFER_BIT6_QCOM: 0x40000000, + MULTISAMPLE_BUFFER_BIT7_QCOM: 0x80000000, + MULTIVIEW_EXT: 0x90f1, + NEAREST: 0x2600, + NEAREST_MIPMAP_LINEAR: 0x2702, + NEAREST_MIPMAP_NEAREST: 0x2700, + NEVER: 0x200, + NICEST: 0x1102, + NONE: 0x0, + NOTEQUAL: 0x205, + NO_ERROR: 0x0, + NO_RESET_NOTIFICATION_EXT: 0x8261, + NUM_COMPRESSED_TEXTURE_FORMATS: 0x86a2, + NUM_PROGRAM_BINARY_FORMATS_OES: 0x87fe, + NUM_SHADER_BINARY_FORMATS: 0x8df9, + NV_coverage_sample: 0x1, + NV_depth_nonlinear: 0x1, + NV_draw_buffers: 0x1, + NV_draw_instanced: 0x1, + NV_fbo_color_attachments: 0x1, + NV_fence: 0x1, + NV_framebuffer_blit: 0x1, + NV_framebuffer_multisample: 0x1, + NV_generate_mipmap_sRGB: 0x1, + NV_instanced_arrays: 0x1, + NV_read_buffer: 0x1, + NV_read_buffer_front: 0x1, + NV_read_depth: 0x1, + NV_read_depth_stencil: 0x1, + NV_read_stencil: 0x1, + NV_sRGB_formats: 0x1, + NV_shadow_samplers_array: 0x1, + NV_shadow_samplers_cube: 0x1, + NV_texture_border_clamp: 0x1, + NV_texture_compression_s3tc_update: 0x1, + NV_texture_npot_2D_mipmap: 0x1, + OBJECT_TYPE_APPLE: 0x9112, + OES_EGL_image: 0x1, + OES_EGL_image_external: 0x1, + OES_compressed_ETC1_RGB8_texture: 0x1, + OES_compressed_paletted_texture: 0x1, + OES_depth24: 0x1, + OES_depth32: 0x1, + OES_depth_texture: 0x1, + OES_element_index_uint: 0x1, + OES_fbo_render_mipmap: 0x1, + OES_fragment_precision_high: 0x1, + OES_get_program_binary: 0x1, + OES_mapbuffer: 0x1, + OES_packed_depth_stencil: 0x1, + OES_required_internalformat: 0x1, + OES_rgb8_rgba8: 0x1, + OES_standard_derivatives: 0x1, + OES_stencil1: 0x1, + OES_stencil4: 0x1, + OES_surfaceless_context: 0x1, + OES_texture_3D: 0x1, + OES_texture_float: 0x1, + OES_texture_float_linear: 0x1, + OES_texture_half_float: 0x1, + OES_texture_half_float_linear: 0x1, + OES_texture_npot: 0x1, + OES_vertex_array_object: 0x1, + OES_vertex_half_float: 0x1, + OES_vertex_type_10_10_10_2: 0x1, + ONE: 0x1, + ONE_MINUS_CONSTANT_ALPHA: 0x8004, + ONE_MINUS_CONSTANT_COLOR: 0x8002, + ONE_MINUS_DST_ALPHA: 0x305, + ONE_MINUS_DST_COLOR: 0x307, + ONE_MINUS_SRC_ALPHA: 0x303, + ONE_MINUS_SRC_COLOR: 0x301, + OUT_OF_MEMORY: 0x505, + PACK_ALIGNMENT: 0xd05, + PACK_REVERSE_ROW_ORDER_ANGLE: 0x93a4, + PALETTE4_R5_G6_B5_OES: 0x8b92, + PALETTE4_RGB5_A1_OES: 0x8b94, + PALETTE4_RGB8_OES: 0x8b90, + PALETTE4_RGBA4_OES: 0x8b93, + PALETTE4_RGBA8_OES: 0x8b91, + PALETTE8_R5_G6_B5_OES: 0x8b97, + PALETTE8_RGB5_A1_OES: 0x8b99, + PALETTE8_RGB8_OES: 0x8b95, + PALETTE8_RGBA4_OES: 0x8b98, + PALETTE8_RGBA8_OES: 0x8b96, + PERCENTAGE_AMD: 0x8bc3, + PERFMON_GLOBAL_MODE_QCOM: 0x8fa0, + PERFMON_RESULT_AMD: 0x8bc6, + PERFMON_RESULT_AVAILABLE_AMD: 0x8bc4, + PERFMON_RESULT_SIZE_AMD: 0x8bc5, + POINTS: 0x0, + POLYGON_OFFSET_FACTOR: 0x8038, + POLYGON_OFFSET_FILL: 0x8037, + POLYGON_OFFSET_UNITS: 0x2a00, + PROGRAM: 0x82e2, + PROGRAM_BINARY_ANGLE: 0x93a6, + PROGRAM_BINARY_FORMATS_OES: 0x87ff, + PROGRAM_BINARY_LENGTH_OES: 0x8741, + PROGRAM_OBJECT_EXT: 0x8b40, + PROGRAM_PIPELINE_BINDING_EXT: 0x825a, + PROGRAM_PIPELINE_OBJECT_EXT: 0x8a4f, + PROGRAM_SEPARABLE_EXT: 0x8258, + QCOM_alpha_test: 0x1, + QCOM_binning_control: 0x1, + QCOM_driver_control: 0x1, + QCOM_extended_get: 0x1, + QCOM_extended_get2: 0x1, + QCOM_perfmon_global_mode: 0x1, + QCOM_tiled_rendering: 0x1, + QCOM_writeonly_rendering: 0x1, + QUERY: 0x82e3, + QUERY_OBJECT_EXT: 0x9153, + QUERY_RESULT_AVAILABLE_EXT: 0x8867, + QUERY_RESULT_EXT: 0x8866, + R16F_EXT: 0x822d, + R32F_EXT: 0x822e, + R8_EXT: 0x8229, + READ_BUFFER_EXT: 0xc02, + READ_BUFFER_NV: 0xc02, + READ_FRAMEBUFFER_ANGLE: 0x8ca8, + READ_FRAMEBUFFER_APPLE: 0x8ca8, + READ_FRAMEBUFFER_BINDING_ANGLE: 0x8caa, + READ_FRAMEBUFFER_BINDING_APPLE: 0x8caa, + READ_FRAMEBUFFER_BINDING_NV: 0x8caa, + READ_FRAMEBUFFER_NV: 0x8ca8, + RED_BITS: 0xd52, + RED_EXT: 0x1903, + RENDERBUFFER: 0x8d41, + RENDERBUFFER_ALPHA_SIZE: 0x8d53, + RENDERBUFFER_BINDING: 0x8ca7, + RENDERBUFFER_BLUE_SIZE: 0x8d52, + RENDERBUFFER_DEPTH_SIZE: 0x8d54, + RENDERBUFFER_GREEN_SIZE: 0x8d51, + RENDERBUFFER_HEIGHT: 0x8d43, + RENDERBUFFER_INTERNAL_FORMAT: 0x8d44, + RENDERBUFFER_RED_SIZE: 0x8d50, + RENDERBUFFER_SAMPLES_ANGLE: 0x8cab, + RENDERBUFFER_SAMPLES_APPLE: 0x8cab, + RENDERBUFFER_SAMPLES_EXT: 0x8cab, + RENDERBUFFER_SAMPLES_IMG: 0x9133, + RENDERBUFFER_SAMPLES_NV: 0x8cab, + RENDERBUFFER_STENCIL_SIZE: 0x8d55, + RENDERBUFFER_WIDTH: 0x8d42, + RENDERER: 0x1f01, + RENDER_DIRECT_TO_FRAMEBUFFER_QCOM: 0x8fb3, + REPEAT: 0x2901, + REPLACE: 0x1e01, + REQUIRED_TEXTURE_IMAGE_UNITS_OES: 0x8d68, + RESET_NOTIFICATION_STRATEGY_EXT: 0x8256, + RG16F_EXT: 0x822f, + RG32F_EXT: 0x8230, + RG8_EXT: 0x822b, + RGB: 0x1907, + RGB10_A2_EXT: 0x8059, + RGB10_EXT: 0x8052, + RGB16F_EXT: 0x881b, + RGB32F_EXT: 0x8815, + RGB565: 0x8d62, + RGB565_OES: 0x8d62, + RGB5_A1: 0x8057, + RGB5_A1_OES: 0x8057, + RGB8_OES: 0x8051, + RGBA: 0x1908, + RGBA16F_EXT: 0x881a, + RGBA32F_EXT: 0x8814, + RGBA4: 0x8056, + RGBA4_OES: 0x8056, + RGBA8_OES: 0x8058, + RGB_422_APPLE: 0x8a1f, + RG_EXT: 0x8227, + RIGHT: 0x0407, + SAMPLER: 0x82e6, + SAMPLER_2D: 0x8b5e, + SAMPLER_2D_ARRAY_SHADOW_NV: 0x8dc4, + SAMPLER_2D_SHADOW_EXT: 0x8b62, + SAMPLER_3D_OES: 0x8b5f, + SAMPLER_CUBE: 0x8b60, + SAMPLER_CUBE_SHADOW_NV: 0x8dc5, + SAMPLER_EXTERNAL_OES: 0x8d66, + SAMPLES: 0x80a9, + SAMPLE_ALPHA_TO_COVERAGE: 0x809e, + SAMPLE_BUFFERS: 0x80a8, + SAMPLE_COVERAGE: 0x80a0, + SAMPLE_COVERAGE_INVERT: 0x80ab, + SAMPLE_COVERAGE_VALUE: 0x80aa, + SCISSOR_BOX: 0xc10, + SCISSOR_TEST: 0xc11, + SGX_BINARY_IMG: 0x8c0a, + SGX_PROGRAM_BINARY_IMG: 0x9130, + SHADER: 0x82e1, + SHADER_BINARY_DMP: 0x9250, + SHADER_BINARY_FORMATS: 0x8df8, + SHADER_BINARY_VIV: 0x8fc4, + SHADER_COMPILER: 0x8dfa, + SHADER_OBJECT_EXT: 0x8b48, + SHADER_SOURCE_LENGTH: 0x8b88, + SHADER_TYPE: 0x8b4f, + SHADING_LANGUAGE_VERSION: 0x8b8c, + SHORT: 0x1402, + SIGNALED_APPLE: 0x9119, + SLUMINANCE8_ALPHA8_NV: 0x8c45, + SLUMINANCE8_NV: 0x8c47, + SLUMINANCE_ALPHA_NV: 0x8c44, + SLUMINANCE_NV: 0x8c46, + SRC_ALPHA: 0x302, + SRC_ALPHA_SATURATE: 0x308, + SRC_COLOR: 0x300, + SRGB8_ALPHA8_EXT: 0x8c43, + SRGB8_NV: 0x8c41, + SRGB_ALPHA_EXT: 0x8c42, + SRGB_EXT: 0x8c40, + STACK_OVERFLOW: 0x503, + STACK_UNDERFLOW: 0x504, + STATE_RESTORE: 0x8bdc, + STATIC_DRAW: 0x88e4, + STENCIL_ATTACHMENT: 0x8d20, + STENCIL_BACK_FAIL: 0x8801, + STENCIL_BACK_FUNC: 0x8800, + STENCIL_BACK_PASS_DEPTH_FAIL: 0x8802, + STENCIL_BACK_PASS_DEPTH_PASS: 0x8803, + STENCIL_BACK_REF: 0x8ca3, + STENCIL_BACK_VALUE_MASK: 0x8ca4, + STENCIL_BACK_WRITEMASK: 0x8ca5, + STENCIL_BITS: 0xd57, + STENCIL_BUFFER_BIT: 0x400, + STENCIL_BUFFER_BIT0_QCOM: 0x10000, + STENCIL_BUFFER_BIT1_QCOM: 0x20000, + STENCIL_BUFFER_BIT2_QCOM: 0x40000, + STENCIL_BUFFER_BIT3_QCOM: 0x80000, + STENCIL_BUFFER_BIT4_QCOM: 0x100000, + STENCIL_BUFFER_BIT5_QCOM: 0x200000, + STENCIL_BUFFER_BIT6_QCOM: 0x400000, + STENCIL_BUFFER_BIT7_QCOM: 0x800000, + STENCIL_CLEAR_VALUE: 0xb91, + STENCIL_EXT: 0x1802, + STENCIL_FAIL: 0xb94, + STENCIL_FUNC: 0xb92, + STENCIL_INDEX1_OES: 0x8d46, + STENCIL_INDEX4_OES: 0x8d47, + STENCIL_INDEX: 0x1901, + STENCIL_INDEX8: 0x8d48, + STENCIL_PASS_DEPTH_FAIL: 0xb95, + STENCIL_PASS_DEPTH_PASS: 0xb96, + STENCIL_REF: 0xb97, + STENCIL_TEST: 0xb90, + STENCIL_VALUE_MASK: 0xb93, + STENCIL_WRITEMASK: 0xb98, + STREAM_DRAW: 0x88e0, + SUBPIXEL_BITS: 0xd50, + SYNC_CONDITION_APPLE: 0x9113, + SYNC_FENCE_APPLE: 0x9116, + SYNC_FLAGS_APPLE: 0x9115, + SYNC_FLUSH_COMMANDS_BIT_APPLE: 0x1, + SYNC_GPU_COMMANDS_COMPLETE_APPLE: 0x9117, + SYNC_OBJECT_APPLE: 0x8a53, + SYNC_STATUS_APPLE: 0x9114, + TEXTURE: 0x1702, + TEXTURE0: 0x84c0, + TEXTURE1: 0x84c1, + TEXTURE10: 0x84ca, + TEXTURE11: 0x84cb, + TEXTURE12: 0x84cc, + TEXTURE13: 0x84cd, + TEXTURE14: 0x84ce, + TEXTURE15: 0x84cf, + TEXTURE16: 0x84d0, + TEXTURE17: 0x84d1, + TEXTURE18: 0x84d2, + TEXTURE19: 0x84d3, + TEXTURE2: 0x84c2, + TEXTURE20: 0x84d4, + TEXTURE21: 0x84d5, + TEXTURE22: 0x84d6, + TEXTURE23: 0x84d7, + TEXTURE24: 0x84d8, + TEXTURE25: 0x84d9, + TEXTURE26: 0x84da, + TEXTURE27: 0x84db, + TEXTURE28: 0x84dc, + TEXTURE29: 0x84dd, + TEXTURE3: 0x84c3, + TEXTURE30: 0x84de, + TEXTURE31: 0x84df, + TEXTURE4: 0x84c4, + TEXTURE5: 0x84c5, + TEXTURE6: 0x84c6, + TEXTURE7: 0x84c7, + TEXTURE8: 0x84c8, + TEXTURE9: 0x84c9, + TEXTURE_2D: 0xde1, + TEXTURE_3D_OES: 0x806f, + TEXTURE_BINDING_2D: 0x8069, + TEXTURE_BINDING_3D_OES: 0x806a, + TEXTURE_BINDING_CUBE_MAP: 0x8514, + TEXTURE_BINDING_EXTERNAL_OES: 0x8d67, + TEXTURE_BORDER_COLOR_NV: 0x1004, + TEXTURE_COMPARE_FUNC_EXT: 0x884d, + TEXTURE_COMPARE_MODE_EXT: 0x884c, + TEXTURE_CUBE_MAP: 0x8513, + TEXTURE_CUBE_MAP_NEGATIVE_X: 0x8516, + TEXTURE_CUBE_MAP_NEGATIVE_Y: 0x8518, + TEXTURE_CUBE_MAP_NEGATIVE_Z: 0x851a, + TEXTURE_CUBE_MAP_POSITIVE_X: 0x8515, + TEXTURE_CUBE_MAP_POSITIVE_Y: 0x8517, + TEXTURE_CUBE_MAP_POSITIVE_Z: 0x8519, + TEXTURE_DEPTH_QCOM: 0x8bd4, + TEXTURE_EXTERNAL_OES: 0x8d65, + TEXTURE_FORMAT_QCOM: 0x8bd6, + TEXTURE_HEIGHT_QCOM: 0x8bd3, + TEXTURE_IMAGE_VALID_QCOM: 0x8bd8, + TEXTURE_IMMUTABLE_FORMAT_EXT: 0x912f, + TEXTURE_INTERNAL_FORMAT_QCOM: 0x8bd5, + TEXTURE_MAG_FILTER: 0x2800, + TEXTURE_MAX_ANISOTROPY_EXT: 0x84fe, + TEXTURE_MAX_LEVEL_APPLE: 0x813d, + TEXTURE_MIN_FILTER: 0x2801, + TEXTURE_NUM_LEVELS_QCOM: 0x8bd9, + TEXTURE_OBJECT_VALID_QCOM: 0x8bdb, + TEXTURE_SAMPLES_IMG: 0x9136, + TEXTURE_TARGET_QCOM: 0x8bda, + TEXTURE_TYPE_QCOM: 0x8bd7, + TEXTURE_USAGE_ANGLE: 0x93a2, + TEXTURE_WIDTH_QCOM: 0x8bd2, + TEXTURE_WRAP_R_OES: 0x8072, + TEXTURE_WRAP_S: 0x2802, + TEXTURE_WRAP_T: 0x2803, + TIMEOUT_EXPIRED_APPLE: 0x911b, + TIMEOUT_IGNORED_APPLE: 0xffffffffffffffff, + TRANSLATED_SHADER_SOURCE_LENGTH_ANGLE: 0x93a0, + TRIANGLES: 0x4, + TRIANGLE_FAN: 0x6, + TRIANGLE_STRIP: 0x5, + TRUE: 0x1, + UNKNOWN_CONTEXT_RESET_EXT: 0x8255, + UNPACK_ALIGNMENT: 0xcf5, + UNPACK_ROW_LENGTH: 0xcf2, + UNPACK_SKIP_PIXELS: 0xcf4, + UNPACK_SKIP_ROWS: 0xcf3, + UNSIGNALED_APPLE: 0x9118, + UNSIGNED_BYTE: 0x1401, + UNSIGNED_INT: 0x1405, + UNSIGNED_INT64_AMD: 0x8bc2, + UNSIGNED_INT_10_10_10_2_OES: 0x8df6, + UNSIGNED_INT_24_8_OES: 0x84fa, + UNSIGNED_INT_2_10_10_10_REV_EXT: 0x8368, + UNSIGNED_NORMALIZED_EXT: 0x8c17, + UNSIGNED_SHORT: 0x1403, + UNSIGNED_SHORT_1_5_5_5_REV_EXT: 0x8366, + UNSIGNED_SHORT_4_4_4_4: 0x8033, + UNSIGNED_SHORT_4_4_4_4_REV_EXT: 0x8365, + UNSIGNED_SHORT_4_4_4_4_REV_IMG: 0x8365, + UNSIGNED_SHORT_5_5_5_1: 0x8034, + UNSIGNED_SHORT_5_6_5: 0x8363, + UNSIGNED_SHORT_8_8_APPLE: 0x85ba, + UNSIGNED_SHORT_8_8_REV_APPLE: 0x85bb, + VALIDATE_STATUS: 0x8b83, + VENDOR: 0x1f00, + VERSION: 0x1f02, + VERTEX_ARRAY_BINDING_OES: 0x85b5, + VERTEX_ARRAY_OBJECT_EXT: 0x9154, + VERTEX_ATTRIB_ARRAY_BUFFER_BINDING: 0x889f, + VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE: 0x88fe, + VERTEX_ATTRIB_ARRAY_DIVISOR_NV: 0x88fe, + VERTEX_ATTRIB_ARRAY_ENABLED: 0x8622, + VERTEX_ATTRIB_ARRAY_NORMALIZED: 0x886a, + VERTEX_ATTRIB_ARRAY_POINTER: 0x8645, + VERTEX_ATTRIB_ARRAY_SIZE: 0x8623, + VERTEX_ATTRIB_ARRAY_STRIDE: 0x8624, + VERTEX_ATTRIB_ARRAY_TYPE: 0x8625, + VERTEX_SHADER: 0x8b31, + VERTEX_SHADER_BIT_EXT: 0x1, + VIEWPORT: 0xba2, + VIV_shader_binary: 0x1, + WAIT_FAILED_APPLE: 0x911d, + WRITEONLY_RENDERING_QCOM: 0x8823, + WRITE_ONLY_OES: 0x88b9, + Z400_BINARY_AMD: 0x8740, + ZERO: 0x0, + + RASTERIZER_DISCARD: 0x8c89, + UNPACK_FLIP_Y_WEBGL: 0x9240, + UNPACK_PREMULTIPLY_ALPHA_WEBGL: 0x9241, + CONTEXT_LOST_WEBGL: 0x9242, + UNPACK_COLORSPACE_CONVERSION_WEBGL: 0x9243, + BROWSER_DEFAULT_WEBGL: 0x9244, +}; diff --git a/packages/utils/src/mini-adapter/WebGL2.ts b/packages/utils/src/mini-adapter/WebGL2.ts new file mode 100644 index 0000000000..39c765f67a --- /dev/null +++ b/packages/utils/src/mini-adapter/WebGL2.ts @@ -0,0 +1,3 @@ +// @ts-nocheck +// tslint:disable +export const WebGL2RenderingContext = {}; diff --git a/packages/utils/src/mini-adapter/XMLHttpRequest.ts b/packages/utils/src/mini-adapter/XMLHttpRequest.ts new file mode 100755 index 0000000000..ed0ac3973d --- /dev/null +++ b/packages/utils/src/mini-adapter/XMLHttpRequest.ts @@ -0,0 +1,236 @@ +// @ts-nocheck +// tslint:disable +import EventTarget from './EventTarget'; + +declare let my: any; +const _requestHeader = new Map(); +const _responseHeader = new Map(); +const _requestTask = new Map(); +const contentTypes = { + json: 'application/json', + text: 'application/text', + arraybuffer: 'application/octet-stream', +}; + +function _triggerEvent(type, event = { target: this }) { + if (typeof this[`on${type}`] === 'function') { + this[`on${type}`].call(this, event); + } +} + +function _changeReadyState(readyState, event = { readyState }) { + this.readyState = readyState; + _triggerEvent.call(this, 'readystatechange', event); +} + +export class XMLHttpRequest extends EventTarget { + public static UNSEND: number; + public static OPENED: number; + public static HEADERS_RECEIVED: number; + public static LOADING: number; + public static DONE: number; + public onabort: any; + public onerror: any; + public onload: any; + public onloadstart: any; + public onprogress: any; + public ontimeout: any; + public onloadend: any; + public onreadystatechange: any; + public readyState: number; + public response: any; + public responseText: any; + public _responseType: string; + public responseXML: any; + public status: number; + public statusText: string; + public upload: any; + public withCredentials: boolean; + public timeout: number; + + public _url: string; + public _method: string; + + constructor() { + super(); + + this.onabort = null; + this.onerror = null; + this.onload = null; + this.onloadstart = null; + this.onprogress = null; + this.ontimeout = null; + this.onloadend = null; + + this.onreadystatechange = null; + this.readyState = 0; + this.response = null; + this.responseText = null; + this._responseType = 'text'; + this.responseXML = null; + this.status = 0; + this.statusText = ''; + this.upload = {}; + this.withCredentials = false; + + _requestHeader.set('requestHeader', { + 'content-type': 'application/x-www-form-urlencoded', + }); + } + + set responseType(type: string) { + this._responseType = type; + } + + public abort() { + const myRequestTask = _requestTask.get('requestTask'); + + if (myRequestTask) { + myRequestTask.abort(); + } + } + + public getAllResponseHeaders() { + const responseHeader = _responseHeader.get('responseHeader'); + + return Object.keys(responseHeader) + .map((header) => { + return `${header}: ${responseHeader[header]}`; + }) + .join('\n'); + } + + public getResponseHeader(header) { + return _responseHeader.get('responseHeader')[header]; + } + + public open(method, url /* GET/POST*/, flag) { + this._method = method; + this._url = url; + _changeReadyState.call(this, XMLHttpRequest.OPENED); + } + + public overrideMimeType() {} + + public send($data = '') { + if (this.readyState !== XMLHttpRequest.OPENED) { + throw new Error( + "Failed to execute 'send' on 'XMLHttpRequest': The object's state must be OPENED.", + ); + } else { + const url = this._url; + const header = _requestHeader.get('requestHeader'); + const responseType = this._responseType; + + if (contentTypes[responseType]) { + header['content-type'] = contentTypes[responseType]; + } + + delete this.response; + this.response = null; + + const onSuccess = ({ data, status, headers }) => { + status = status === undefined ? 200 : status; + + try { + if ( + data == null || + (data instanceof ArrayBuffer && data.byteLength == 0) + ) { + status = 404; + } + } catch (e) {} + + this.status = status; + if (headers) { + _responseHeader.set('responseHeader', headers); + } + _triggerEvent.call(this, 'loadstart'); + _changeReadyState.call(this, XMLHttpRequest.HEADERS_RECEIVED); + _changeReadyState.call(this, XMLHttpRequest.LOADING); + + this.response = data; + + if (data instanceof ArrayBuffer) { + // TODO temporary solution, fix native gc error. + this.response = data.slice(0); + Object.defineProperty(this, 'responseText', { + enumerable: true, + configurable: true, + get() { + throw new Error( + 'InvalidStateError : responseType is ' + this._responseType, + ); + }, + }); + } else { + this.responseText = data; + } + _changeReadyState.call(this, XMLHttpRequest.DONE); + _triggerEvent.call(this, 'load'); + _triggerEvent.call(this, 'loadend'); + }; + + const onFail = (e) => { + const errMsg = e.message || e.errorMessage; + // TODO 规范错误 + if (!errMsg) { + return; + } + if (errMsg.indexOf('abort') !== -1) { + _triggerEvent.call(this, 'abort', { + message: errMsg + this._url, + }); + } else { + _triggerEvent.call(this, 'error', { + message: errMsg + this._url, + }); + } + _triggerEvent.call(this, 'loadend'); + }; + + const requestTask = my.request({ + $data, + url, + method: this._method, + timeout: this.timeout ? this.timeout : 30000, + headers: header, + dataType: responseType, + success: onSuccess, + fail: onFail, + }); + _requestTask.set('requestTask', requestTask); + } + } + + public setRequestHeader(header, value) { + const myHeader = _requestHeader.get('requestHeader'); + + myHeader[header] = value; + _requestHeader.set('requestHeader', myHeader); + } + + public addEventListener(type, listener) { + if (typeof listener !== 'function') { + return; + } + + this['on' + type] = (event: any = {}) => { + event.target = event.target || this; + listener.call(this, event); + }; + } + + public removeEventListener(type, listener) { + if (this['on' + type] === listener) { + this['on' + type] = null; + } + } +} + +// TODO 没法模拟 HEADERS_RECEIVED 和 LOADING 两个状态 +XMLHttpRequest.UNSEND = 0; +XMLHttpRequest.OPENED = 1; +XMLHttpRequest.HEADERS_RECEIVED = 2; +XMLHttpRequest.LOADING = 3; +XMLHttpRequest.DONE = 4; diff --git a/packages/utils/src/mini-adapter/atob.ts b/packages/utils/src/mini-adapter/atob.ts new file mode 100644 index 0000000000..9a7692e884 --- /dev/null +++ b/packages/utils/src/mini-adapter/atob.ts @@ -0,0 +1,72 @@ +// @ts-nocheck +// tslint:disable +const chars = + 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/='; + +function InvalidCharacterError(message) { + this.message = message; +} + +InvalidCharacterError.prototype = new Error(); +InvalidCharacterError.prototype.name = 'InvalidCharacterError'; + +export function atob(input: string) { + const str = String(input).replace(/=+$/, ''); + if (str.length % 4 === 1) { + throw new InvalidCharacterError( + "'atob' failed: The string to be decoded is not correctly encoded.", + ); + } + let output = ''; + for ( + // initialize result and counters + let bc = 0, bs, buffer, idx = 0; + // get next character + (buffer = str.charAt(idx++)); + // character found in table? initialize bit storage and add its ascii value; + ~buffer && + ((bs = bc % 4 ? bs * 64 + buffer : buffer), + // and if not first of each 4 characters, + // convert the first 8 bits to one ascii character + bc++ % 4) + ? (output += String.fromCharCode(255 & (bs >> ((-2 * bc) & 6)))) + : 0 + ) { + // try to find character in table (0-63, not found => -1) + buffer = chars.indexOf(buffer); + } + return output; +} + +export function btoa(string: string) { + string = String(string); + let bitmap, + a, + b, + c, + result = '', + i = 0, + rest = string.length % 3; // To determine the final padding + + for (; i < string.length; ) { + if ( + (a = string.charCodeAt(i++)) > 255 || + (b = string.charCodeAt(i++)) > 255 || + (c = string.charCodeAt(i++)) > 255 + ) { + throw new TypeError( + "Failed to execute 'btoa' on 'Window': The string to be encoded contains characters outside of the Latin1 range.", + ); + } + + bitmap = (a << 16) | (b << 8) | c; + result += + chars.charAt((bitmap >> 18) & 63) + + chars.charAt((bitmap >> 12) & 63) + + chars.charAt((bitmap >> 6) & 63) + + chars.charAt(bitmap & 63); + } + + // If there's need of padding, replace the last 'A's with equal signs + return rest ? result.slice(0, rest - 3) + '==='.substring(rest) : result; +} diff --git a/packages/utils/src/mini-adapter/blob.ts b/packages/utils/src/mini-adapter/blob.ts new file mode 100644 index 0000000000..a9aefd6e5a --- /dev/null +++ b/packages/utils/src/mini-adapter/blob.ts @@ -0,0 +1,29 @@ +// @ts-nocheck +// tslint:disable +export class Blob { + /** + * + * @param buffers only support zero index + * @param type mimetype image/png image/webp... + */ + constructor( + public readonly buffers: ArrayBuffer[], + public readonly type: string | { type: string }, + ) {} + + public arraybuffer(): Promise { + return Promise.resolve(this.buffers[0]); + } + + public stream() { + throw new Error('not implemented'); + } + + public text() { + throw new Error('not implemented'); + } + + public slice(start?: number, end?: number, contentType?: string) { + throw new Error('not implemented'); + } +} diff --git a/packages/utils/src/mini-adapter/devicePixelRatio.ts b/packages/utils/src/mini-adapter/devicePixelRatio.ts new file mode 100644 index 0000000000..5f7687cc46 --- /dev/null +++ b/packages/utils/src/mini-adapter/devicePixelRatio.ts @@ -0,0 +1,7 @@ +// @ts-nocheck +export const isMiniAli = + // @ts-ignore + typeof my !== 'undefined' && !!my && typeof my.showToast === 'function'; +export default !isMiniAli + ? devicePixelRatio + : (my.getSystemInfoSync().pixelRatio as number); diff --git a/packages/utils/src/mini-adapter/document.ts b/packages/utils/src/mini-adapter/document.ts new file mode 100644 index 0000000000..cc74c4ab82 --- /dev/null +++ b/packages/utils/src/mini-adapter/document.ts @@ -0,0 +1,206 @@ +// @ts-nocheck +// tslint:disable +import { Event } from './Event'; +import { HTMLElement } from './HTMLElement'; +import { HTMLVideoElement } from './HTMLVideoElement'; +import { Image } from './Image'; +import { getCanvas, getCanvas2D } from './register'; +import { location } from './location'; + +class Body extends HTMLElement { + constructor() { + // 为了性能, 此处不按照标准的DOM层级关系设计 + // 将 body 设置为 0级, parent元素为null + super('body', 0); + } + + public addEventListener(type, listener, options = {}) { + document.addEventListener(type, listener, options); + } + + public removeEventListener(type, listener, options) { + document.removeEventListener(type, listener); + } + + public dispatchEvent(event: Event) { + document.dispatchEvent(event); + } +} + +class DocumentElement extends HTMLElement { + constructor() { + super('html', 0); + } + + public addEventListener(type, listener, options = {}) { + document.addEventListener(type, listener, options); + } + + public removeEventListener(type, listener) { + document.removeEventListener(type, listener); + } + + public dispatchEvent(event: Event) { + document.dispatchEvent(event); + } +} + +const events = {}; + +export const document = { + readyState: 'complete', + visibilityState: 'visible', // 'visible' , 'hidden' + hidden: false, + fullscreen: true, + + scripts: [], + style: {}, + + location: location, + + ontouchstart: null, + ontouchmove: null, + ontouchend: null, + onvisibilitychange: null, + + parentNode: null, + parentElement: null, + head: null, + body: null, + documentElement: { + style: [] as any[] , + }, + createElement(tagName) { + tagName = tagName.toLowerCase(); + if (tagName === 'canvas') { + // return getCanvas(); + // @ts-ignore + return my.createOffscreenCanvas(1024, 128, '2d') + } else if (tagName === 'img') { + return new Image(); + } else if (tagName === 'video') { + return new HTMLVideoElement(); + } + + return new HTMLElement(tagName); + }, + + createElementNS(nameSpace, tagName) { + return this.createElement(tagName); + }, + + createTextNode(text) { + // TODO: Do we need the TextNode Class ??? + return text; + }, + + getElementById(id) { + const canvas = getCanvas(); + const canvas2D = getCanvas2D(); + if (id === canvas.id) { + return canvas; + } else if (id === canvas2D.id) { + return canvas2D; + } + return null; + }, + + getElementsByTagName(tagName) { + tagName = tagName.toLowerCase(); + if (tagName === 'head') { + return [document.head]; + } else if (tagName === 'body') { + return [document.body]; + } else if (tagName === 'canvas') { + return [getCanvas(), getCanvas2D()]; + } + return []; + }, + + getElementsByTagNameNS(nameSpace, tagName) { + return this.getElementsByTagName(tagName); + }, + + getElementsByName(tagName) { + if (tagName === 'head') { + return [document.head]; + } else if (tagName === 'body') { + return [document.body]; + } else if (tagName === 'canvas') { + return [getCanvas(), getCanvas2D()]; + } + return []; + }, + + querySelector(query) { + const canvas = getCanvas(); + const canvas2D = getCanvas2D(); + if (query === 'head') { + return document.head; + } else if (query === 'meta[name="viewport"]') { + return undefined; + } else if (query === 'body') { + return document.body; + } else if (query === 'canvas') { + return canvas; + } else if (query === `#${canvas.id}`) { + return canvas; + } else if (query === `#${canvas2D.id}`) { + return canvas2D; + } + return null; + }, + + querySelectorAll(query) { + if (query === 'head') { + return [document.head]; + } else if (query === 'body') { + return [document.body]; + } else if (query === 'canvas') { + return [getCanvas(), getCanvas2D()]; + } + return []; + }, + + addEventListener(type, listener, options) { + if (!events[type]) { + events[type] = []; + } + events[type].push(listener); + }, + + removeEventListener(type, listener) { + const listeners = events[type]; + + if (listeners && listeners.length > 0) { + for (let i = listeners.length; i--; i > 0) { + if (listeners[i] === listener) { + listeners.splice(i, 1); + break; + } + } + } + }, + + dispatchEvent(event: Event) { + const type = event.type; + const listeners = events[type]; + + if (listeners) { + for (let i = 0; i < listeners.length; i++) { + listeners[i](event); + } + } + + if (event.target && typeof event.target['on' + type] === 'function') { + event.target['on' + type](event); + } + }, + createEvent(type: string) { + return new Event(type); + }, +}; + +document.documentElement = new DocumentElement(); +document.head = new HTMLElement('head'); +document.body = new Body(); diff --git a/packages/utils/src/mini-adapter/index.ts b/packages/utils/src/mini-adapter/index.ts new file mode 100644 index 0000000000..24bacfe84e --- /dev/null +++ b/packages/utils/src/mini-adapter/index.ts @@ -0,0 +1,122 @@ +// @ts-nocheck +// tslint:disable +import { atob, btoa } from './atob'; +import { Blob } from './blob'; +import devicePixelRatio from './devicePixelRatio'; +import { document } from './document'; +import { Element } from './Element'; +import { Event } from './Event'; +import EventTarget from './EventTarget'; +import { HTMLCanvasElement } from './HTMLCanvasElement'; +import { HTMLElement } from './HTMLElement'; +import { HTMLMediaElement } from './HTMLMediaElement'; +import { HTMLVideoElement } from './HTMLVideoElement'; +import { Image } from './Image'; +import { ImageData } from './ImageData'; +import { location } from './location'; +import { navigator } from './navigator'; +import { Node } from './Node'; +import { performance } from './performance'; +import { + cancelAnimationFrame, + requestAnimationFrame, +} from './requestAnimationFrame'; +import { screen } from './screen'; +import { URL } from './url'; +import { WebGLRenderingContext } from './WebGL'; +import { WebGL2RenderingContext } from './WebGL2'; +import { XMLHttpRequest } from './XMLHttpRequest'; + +// 判断时候是支付宝小程序环境 +export const isMiniAli = + // @ts-ignore + typeof my !== 'undefined' && !!my && typeof my.showToast === 'function'; + +export const isWeChatMiniProgram = typeof wx !== 'undefined' && wx !== null && (typeof wx.request !== 'undefined' || typeof wx.miniProgram !== 'undefined'); + +export const isMini = isMiniAli || isWeChatMiniProgram; + +export const miniWindow = { + atob, + btoa, + devicePixelRatio, + Blob, + document, + Element, + Event, + EventTarget, + HTMLCanvasElement, + HTMLElement, + HTMLMediaElement, + HTMLVideoElement, + Image, + ImageData, + navigator, + Node, + requestAnimationFrame, + cancelAnimationFrame, + screen, + XMLHttpRequest, + performance, + URL, + WebGLRenderingContext, + WebGL2RenderingContext, + addEventListener(type, listener, options = {}) { + document.addEventListener(type, listener, options); + }, + removeEventListener(type, listener,options) { + document.removeEventListener(type, listener); + }, + dispatchEvent(event: Event) { + document.dispatchEvent(event); + }, + innerWidth: screen.availWidth, + innerHeight: screen.availHeight, + setTimeout: setTimeout, + clearTimeout: clearTimeout, + setInterval: setInterval, + clearInterval: clearInterval +} as Window & typeof globalThis; + +// export { +// btoa, +// URL, +// Blob, +// window, +// atob, +// devicePixelRatio, +// document, +// Element, +// Event, +// EventTarget, +// HTMLCanvasElement, +// HTMLElement, +// HTMLMediaElement, +// HTMLVideoElement, +// Image, +// navigator, +// Node, +// requestAnimationFrame, +// cancelAnimationFrame, +// screen, +// XMLHttpRequest, +// performance, +// WebGLRenderingContext, +// WebGL2RenderingContext, +// ImageData, +// location +// }; +// export { +// window as $window, +// document as $document, +// XMLHttpRequest as $XMLHttpRequest, +// location as $location, +// }; + +export const $window = isMini ? miniWindow : window; +export const $XMLHttpRequest = isMini ? XMLHttpRequest: window.XMLHttpRequest; +export const $location = isMini ? location : window.location; + +export { registerCanvas, registerCanvas2D } from './register'; + +export * from './EventIniter/index'; diff --git a/packages/utils/src/mini-adapter/location.ts b/packages/utils/src/mini-adapter/location.ts new file mode 100644 index 0000000000..11532dfefc --- /dev/null +++ b/packages/utils/src/mini-adapter/location.ts @@ -0,0 +1,7 @@ +// @ts-nocheck +// tslint:disable +export let location = { + href: '', + protocol: '', + host:'' +}; diff --git a/packages/utils/src/mini-adapter/navigator.ts b/packages/utils/src/mini-adapter/navigator.ts new file mode 100755 index 0000000000..646c3ca6c5 --- /dev/null +++ b/packages/utils/src/mini-adapter/navigator.ts @@ -0,0 +1,77 @@ +// @ts-nocheck +export const isMiniAli = + // @ts-ignore + typeof my !== 'undefined' && !!my && typeof my.showToast === 'function'; +let system; +let platform; +let language; +if (isMiniAli) { + const myOptions = my.getSystemInfoSync(); + system = myOptions.system; + platform = myOptions.platform; + language = myOptions.language; +} else { + const browser = { + versions: (() => { + const u = window.navigator.userAgent; + return { + trident: u.indexOf('Trident') > -1, // IE内核 + presto: u.indexOf('Presto') > -1, // opera内核 + webKit: u.indexOf('AppleWebKit') > -1, // 苹果、谷歌内核 + gecko: u.indexOf('Gecko') > -1 && u.indexOf('KHTML') === -1, // 火狐内核 + mobile: !!u.match(/AppleWebKit.*Mobile.*/), // 是否为移动终端 + ios: !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/), // ios终端 + android: u.indexOf('Android') > -1 || u.indexOf('Linux') > -1, // android终端或者uc浏览器 + iPhone: u.indexOf('iPhone') > -1, // 是否为iPhone或者QQHD浏览器 + iPad: u.indexOf('iPad') > -1, // 是否iPad + webApp: u.indexOf('Safari') === -1, // 是否web应该程序,没有头部与底部 + weixin: u.indexOf('MicroMessenger') > -1, // 是否微信 (2015-01-22新增) + qq: u.match(/\sQQ/i) === ' qq', // 是否QQ + }; + })(), + language: ( + window.navigator.browserLanguage || window.navigator.language + ).toLowerCase(), + }; + if (browser.versions.android) { + platform = 'android'; + } else if (browser.versions.trident) { + platform = 'IE'; + } else if (browser.versions.presto) { + platform = 'Opera'; + } else if (browser.versions.webKit) { + platform = 'webKit'; + } else if (browser.versions.gecko) { + platform = 'Firefox'; + } else if (browser.versions.mobile) { + platform = 'mobile'; + } else if (browser.versions.ios) { + platform = 'ios'; + } else if (browser.versions.iPhone) { + platform = 'iPhone'; + } else if (browser.versions.iPad) { + platform = 'ipad'; + } else if (browser.versions.webApp) { + platform = 'webApp'; + } else if (browser.versions.weixin) { + platform = 'weixin'; + } else if (browser.versions.qq) { + platform = 'qq'; + } + system = window.navigator.userAgent; + language = browser.language; +} + +const android = system.toLowerCase().indexOf('android') !== -1; + +const uaDesc = android + ? 'Android; CPU Android 6.0' + : 'iPhone; CPU iPhone OS 10_3_1 like Mac OS X'; +const ua = `Mozilla/5.0 (${uaDesc}) AppleWebKit/603.1.30 (KHTML, like Gecko) Mobile/14E8301 MicroMessenger/6.6.0 MiniGame NetType/WIFI Language/${language}`; + +export const navigator = { + platform, + language, + appVersion: `5.0 (${uaDesc}) AppleWebKit/601.1.46 (KHTML, like Gecko) Version/9.0 Mobile/13B143 Safari/601.1`, + userAgent: ua, +}; diff --git a/packages/utils/src/mini-adapter/performance.ts b/packages/utils/src/mini-adapter/performance.ts new file mode 100644 index 0000000000..a9467f06bf --- /dev/null +++ b/packages/utils/src/mini-adapter/performance.ts @@ -0,0 +1,14 @@ +// @ts-nocheck +// tslint:disable +// 暂不支持 +export const performance = { + mark: (mark: string) => null, + clearMeasures: (measure: string) => null, + clearMarks: (mark: string) => null, + measure: (mark: string, create: string, load: string) => { + return { + duration: 0, + }; + }, + now: () => { } +};; diff --git a/packages/utils/src/mini-adapter/register.ts b/packages/utils/src/mini-adapter/register.ts new file mode 100644 index 0000000000..9a794cd3ba --- /dev/null +++ b/packages/utils/src/mini-adapter/register.ts @@ -0,0 +1,100 @@ +// @ts-nocheck +// tslint:disable +import devicePixelRatio from './devicePixelRatio'; +import { document } from './document'; +import * as Mixin from './util/mixin'; + +declare let my: any; + +// 同步和异步都需要的数据 +let canvas: any = {}; +let canvas2D: any = {}; + +// 异步注册3Dcanvas +function registerCanvas(c, id: string) { + canvas = c; + canvas.id = id; + + if (!('tagName' in canvas)) { + canvas.tagName = 'CANVAS'; + } + + canvas.type = 'canvas'; + + Mixin.parentNode(canvas); + Mixin.style(canvas); + Mixin.classList(canvas); + Mixin.clientRegion(canvas); + Mixin.offsetRegion(canvas); + + canvas.focus = function() {}; + canvas.blur = function() {}; + + canvas.addEventListener = function(type, listener, options = {}) { + document.addEventListener(type, listener, options); + }; + + canvas.removeEventListener = function(type, listener) { + document.removeEventListener(type, listener); + }; + + canvas.dispatchEvent = function(event: any) { + document.dispatchEvent(event); + }; +} + +// 异步注册2Dcanvas +function registerCanvas2D(ctx, id: string) { + const width = 1024; + const height = 1024; + canvas2D = { + width, + height, + clientWidth: width / devicePixelRatio, + clientHeight: height / devicePixelRatio, + id, + type: 'canvas', + }; + + if (!('tagName' in canvas2D)) { + canvas2D.tagName = 'CANVAS'; + } + + Mixin.parentNode(canvas2D); + Mixin.style(canvas2D); + Mixin.classList(canvas2D); + Mixin.clientRegion(canvas2D); + Mixin.offsetRegion(canvas2D); + + canvas2D.getContext = function(type) { + if (type === '2d') { + return ctx; + } + }; + canvas2D.focus = function() {}; + canvas2D.blur = function() {}; + + canvas2D.addEventListener = function(type, listener, options = {}) { + document.addEventListener(type, listener, options); + }; + + canvas2D.removeEventListener = function(type, listener) { + document.removeEventListener(type, listener); + }; + + canvas2D.dispatchEvent = function(event: any) { + document.dispatchEvent(event); + }; +} + +// 异步获取3Dcanvas +function getCanvas() { + return canvas; +} + +// 异步获取2Dcanvas +function getCanvas2D() { + return canvas2D; +} + +export { registerCanvas, registerCanvas2D, getCanvas, getCanvas2D }; diff --git a/packages/utils/src/mini-adapter/requestAnimationFrame.ts b/packages/utils/src/mini-adapter/requestAnimationFrame.ts new file mode 100644 index 0000000000..57d2e63835 --- /dev/null +++ b/packages/utils/src/mini-adapter/requestAnimationFrame.ts @@ -0,0 +1,38 @@ +// @ts-nocheck +// tslint:disable +import { getCanvas } from './register'; + +let lastTime: any = 0; +let id: any = 0; + +function hack(cb) { + const now = Date.now(); + + const nextTime = Math.max(lastTime + 23, now); + + id = setTimeout(() => { + cb((lastTime = nextTime)); + }, nextTime - now); + + return id; +} + +function requestAnimationFrame(cb) { + const canvas = getCanvas(); + if (canvas.requestAnimationFrame) { + return canvas.requestAnimationFrame(cb); + } else { + return hack(cb); + } +} + +function cancelAnimationFrame(id) { + const canvas = getCanvas(); + if (canvas.cancelAnimationFrame) { + return canvas.cancelAnimationFrame(id); + } else { + return clearTimeout(id); + } +} + +export { requestAnimationFrame, cancelAnimationFrame }; diff --git a/packages/utils/src/mini-adapter/screen.ts b/packages/utils/src/mini-adapter/screen.ts new file mode 100644 index 0000000000..e1c0cce181 --- /dev/null +++ b/packages/utils/src/mini-adapter/screen.ts @@ -0,0 +1,31 @@ +// @ts-nocheck +// 判断时候是支付宝小程序环境 +export const isMiniAli = + // @ts-ignore + typeof my !== 'undefined' && !!my && typeof my.showToast === 'function'; +let screenWidth; +let screenHeight; +let windowWidth; +let windowHeight; +if (isMiniAli) { + const myOptions = my.getSystemInfoSync(); + screenWidth = myOptions.screenWidth; + screenHeight = myOptions.screenHeight; + windowWidth = myOptions.windowWidth; + windowHeight = myOptions.windowHeight; +} else { + const { innerWidth, innerHeight } = window; + screenWidth = innerWidth; + screenHeight = innerHeight; + windowWidth = innerWidth; + windowHeight = innerHeight; +} + +export const screen = { + width: screenWidth, + height: screenHeight, + availWidth: windowWidth, + availHeight: windowHeight, + availLeft: 0, + availTop: 0, +}; diff --git a/packages/utils/src/mini-adapter/url.ts b/packages/utils/src/mini-adapter/url.ts new file mode 100644 index 0000000000..a18c9e978f --- /dev/null +++ b/packages/utils/src/mini-adapter/url.ts @@ -0,0 +1,39 @@ +// @ts-nocheck +// tslint:disable +import { btoa } from './atob'; +import { Blob } from './blob'; + +export class URL { + /** + * fake createObject, use base64 instead + * @param blob + */ + public static createObjectURL(blob: Blob) { + const buffer = blob.buffers[0]; + const type = blob.type; + const base64 = _arrayBufferToBase64(buffer); + const prefix = `data:${type};base64, `; + return prefix + base64; + } + + public href: string; + + // todo: 完善URL对象 + constructor(url, host = '') { + if (url.indexOf('http://') == 0 || url.indexOf('https://') == 0) { + this.href = url; + return; + } + this.href = host + url; + } +} + +function _arrayBufferToBase64(buffer) { + let binary = ''; + const bytes = new Uint8Array(buffer); + const len = bytes.byteLength; + for (let i = 0; i < len; i++) { + binary += String.fromCharCode(bytes[i]); + } + return btoa(binary); +} diff --git a/packages/utils/src/mini-adapter/util/mixin.ts b/packages/utils/src/mini-adapter/util/mixin.ts new file mode 100644 index 0000000000..30dfdd76f0 --- /dev/null +++ b/packages/utils/src/mini-adapter/util/mixin.ts @@ -0,0 +1,127 @@ +// @ts-nocheck +// tslint:disable +import { screen } from '../screen'; + +const { availWidth: innerWidth, availHeight: innerHeight } = screen; +import { document } from '../document'; + +export function parentNode(obj, level?: number) { + if (!('parentNode' in obj)) { + let _parent; + + if (level === 0) { + _parent = function() { + // return document + return null; + }; + } else if (level === 1) { + _parent = function() { + return document.documentElement; + }; + } else { + _parent = function() { + return document.body; + }; + } + + Object.defineProperty(obj, 'parentNode', { + enumerable: true, + get: _parent, + }); + } + + if (!('parentElement' in obj)) { + let _parent; + + if (level === 0) { + _parent = function() { + return null; + }; + } else if (level === 1) { + _parent = function() { + return document.documentElement; + }; + } else { + _parent = function() { + return document.body; + }; + } + + Object.defineProperty(obj, 'parentElement', { + enumerable: true, + get: _parent, + }); + } +} + +export function style(obj) { + obj.style = obj.style || {}; + + Object.assign(obj.style, { + top: '0px', + left: '0px', + width: innerWidth + 'px', + height: innerHeight + 'px', + margin: '0px', + padding: '0px', + }); +} + +export function clientRegion(obj) { + if (!('clientLeft' in obj)) { + obj.clientLeft = 0; + obj.clientTop = 0; + } + if (!('clientWidth' in obj)) { + obj.clientWidth = innerWidth; + obj.clientHeight = innerHeight; + } + + if (!('getBoundingClientRect' in obj)) { + obj.getBoundingClientRect = function() { + const ret = { + x: 0, + y: 0, + top: 0, + left: 0, + width: this.clientWidth, + height: this.clientHeight, + right: this.clientWidth, + bottom: this.clientHeight, + }; + + return ret; + }; + } +} + +export function offsetRegion(obj) { + if (!('offsetLeft' in obj)) { + obj.offsetLeft = 0; + obj.offsetTop = 0; + } + if (!('offsetWidth' in obj)) { + obj.offsetWidth = innerWidth; + obj.offsetHeight = innerHeight; + } +} + +export function scrollRegion(obj) { + if (!('scrollLeft' in obj)) { + obj.scrollLeft = 0; + obj.scrollTop = 0; + } + if (!('scrollWidth' in obj)) { + obj.scrollWidth = innerWidth; + obj.scrollHeight = innerHeight; + } +} + +export function classList(obj) { + const noop = function() {}; + obj.classList = []; + obj.classList.add = noop; + obj.classList.remove = noop; + obj.classList.contains = noop; + obj.classList.toggle = noop; +} diff --git a/publish.sh b/publish.sh index ef101e1d66..09a1f83d5a 100644 --- a/publish.sh +++ b/publish.sh @@ -12,6 +12,10 @@ cd ./l7/ npm publish cd .. +cd ./mini/ +npm publish +cd .. + cd ./layers/ npm publish cd .. diff --git a/stories/Draw/Components/Circle.tsx b/stories/Draw/Components/Circle.tsx index 9fd4f9b724..b14fed588d 100644 --- a/stories/Draw/Components/Circle.tsx +++ b/stories/Draw/Components/Circle.tsx @@ -1,5 +1,6 @@ +// @ts-ignore import { LineLayer, PointLayer, PolygonLayer, Popup, Scene } from '@antv/l7'; -import { DrawPolygon } from '@antv/l7-draw'; +import { DrawPolygon, DrawCircle } from '@antv/l7-draw'; import { GaodeMap, Mapbox } from '@antv/l7-maps'; import * as React from 'react'; @@ -23,7 +24,7 @@ export default class Circle extends React.Component { this.scene = scene; scene.on('loaded', () => { - const drawCircle = new DrawPolygon(scene); + const drawCircle = new DrawCircle(scene); drawCircle.enable(); drawCircle.on('draw.create', (e: any) => { console.log(e); diff --git a/stories/Draw/Components/DrawCircle.tsx b/stories/Draw/Components/DrawCircle.tsx index 10c2f5b5e2..0ddc18d600 100644 --- a/stories/Draw/Components/DrawCircle.tsx +++ b/stories/Draw/Components/DrawCircle.tsx @@ -55,7 +55,7 @@ export default class MultiPolygon extends React.Component { scene.addLayer(circleLayer); scene.on('dragstart', (e: any) => { // @ts-ignore - scene.map.drag.disable(); + scene.getMapService().setMapStatus({ dragEnable: false }); startPoint = e.lngLat; const layer = new PointLayer() .source([startPoint], { @@ -74,7 +74,9 @@ export default class MultiPolygon extends React.Component { }); scene.addLayer(layer); }); - scene.on('drag', (e: any) => { + scene.on('dragging', (e: any) => { + //dragging - drag + // console.log('drag', startPoint, e.lngLat) // @ts-ignore const start = [startPoint.lng, startPoint.lat]; const dis = lnglatDistance( @@ -82,17 +84,20 @@ export default class MultiPolygon extends React.Component { start, [e.lngLat.lng, e.lngLat.lat], ); + // console.log('dis', dis) const circleData = createGeoJSONCircle( start as [number, number], dis / 1000, ); circleLayer.setData(circleData.data); + // console.log('circleData.data', circleData.data) const popup = new Popup().setText(`${dis}`).setLnglat(e.lngLat); scene.addPopup(popup); }); scene.on('dragend', (e: any) => { + console.log('dragend'); // @ts-ignore - scene.map.dragdrag.enable(); + scene.getMapService().setMapStatus({ dragEnable: true }); }); }); } diff --git a/stories/Layers/components/data_update.tsx b/stories/Layers/components/data_update.tsx index 753f808c77..e39d8ac869 100644 --- a/stories/Layers/components/data_update.tsx +++ b/stories/Layers/components/data_update.tsx @@ -1,5 +1,6 @@ import { PointLayer, Scene } from '@antv/l7'; import { GaodeMap, Mapbox } from '@antv/l7-maps'; +import { $window } from '@antv/l7-utils'; import * as React from 'react'; // @ts-ignore export default class DataUpdate extends React.Component { @@ -58,7 +59,7 @@ export default class DataUpdate extends React.Component { function animateMarker(timestamp: number) { layer.setData(pointOnCircle(timestamp / 1000)); scene.render(); - requestAnimationFrame(animateMarker); + $window.requestAnimationFrame(animateMarker); } animateMarker(0); } diff --git a/stories/customMap/components/Map.tsx b/stories/customMap/components/Map.tsx index 433d262dfc..b0118af4a9 100644 --- a/stories/customMap/components/Map.tsx +++ b/stories/customMap/components/Map.tsx @@ -1,7 +1,7 @@ -// @ts-ignore -import { Scene } from '@antv/l7'; -import { PolygonLayer, PointLayer } from '@antv/l7-layers'; -import { Map } from '@antv/l7-maps'; +import { Scene, PolygonLayer, PointLayer, Map } from '@antv/l7-mini'; +// import { Scene } from '@antv/l7'; +// import { PolygonLayer, PointLayer } from '@antv/l7-layers'; +// import { Map } from '@antv/l7-maps'; import * as React from 'react'; export default class ScaleComponent extends React.Component { @@ -101,14 +101,13 @@ export default class ScaleComponent extends React.Component { padding: [1, 1], // 文本包围盒 padding [水平,垂直],影响碰撞检测结果,避免相邻文本靠的太近 fontFamily: 'Times New Roman', textAllowOverlap: true, - }); + }) + .active(true); scene.addLayer(textLayer); const layer = new PolygonLayer({ name: '01', - }); - - layer + }) .source(data) .size('name', [0, 10000, 50000, 30000, 100000]) .color('name', [