diff --git a/demo/index.ts b/demo/index.ts index 6db198f..8262da0 100644 --- a/demo/index.ts +++ b/demo/index.ts @@ -27,6 +27,9 @@ async function start() { color: '#FFF3F3', }, groundCoveringColor: 'rgba(0, 0, 0, 0.8)', + minZoom: 15, + maxZoom: 20, + modelsNearCameraFade: 0, }); (window as any).gltfPlugin = plugin; diff --git a/demo/models/palm.glb b/demo/models/palm.glb new file mode 100644 index 0000000..9f502f6 Binary files /dev/null and b/demo/models/palm.glb differ diff --git a/demo/models/pine.glb b/demo/models/pine.glb new file mode 100644 index 0000000..49c4006 Binary files /dev/null and b/demo/models/pine.glb differ diff --git a/package-lock.json b/package-lock.json index 41e74d3..703c1a2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,12 +9,13 @@ "version": "2.0.2", "license": "BSD-2-Clause", "devDependencies": { - "@2gis/mapgl": "^1.47.0", + "@2gis/mapgl": "^1.52.0", "@documentalist/compiler": "^2.8.1", "@types/geojson": "^7946.0.10", "@types/jest": "^27.4.0", "@types/jest-image-snapshot": "^4.3.1", "@types/puppeteer": "^5.4.4", + "@types/sinon": "^17.0.3", "clean-webpack-plugin": "^4.0.0", "copy-webpack-plugin": "^11.0.0", "css-loader": "^3.6.0", @@ -26,6 +27,7 @@ "prettier": "^2.8.7", "puppeteer": "^13.3.2", "raw-loader": "^4.0.2", + "sinon": "^19.0.2", "style-loader": "^1.3.0", "ts-jest": "^27.1.3", "ts-loader": "^9.4.2", @@ -36,9 +38,9 @@ } }, "node_modules/@2gis/mapgl": { - "version": "1.47.0", - "resolved": "https://registry.npmjs.org/@2gis/mapgl/-/mapgl-1.47.0.tgz", - "integrity": "sha512-aAMXb/+AveKZeusP/ZU/wCtI20F3nyH4pX99E6OpVJjRIL8jhGptyxpP45oPaGozG+3fZypoQVFp8lb7tMYKGQ==", + "version": "1.53.0", + "resolved": "https://registry.npmjs.org/@2gis/mapgl/-/mapgl-1.53.0.tgz", + "integrity": "sha512-lT+XX1grV/Qg7rVtBfAPkXl+0c5JIzBr9j/+LcEURLKacfPOwAhlEh2lEY+O+YFA2IPi91FXYHs031IF3d/omA==", "dev": true, "dependencies": { "@types/geojson": "^7946.0.7" @@ -1466,6 +1468,50 @@ "@sinonjs/commons": "^1.7.0" } }, + "node_modules/@sinonjs/samsam": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-8.0.2.tgz", + "integrity": "sha512-v46t/fwnhejRSFTGqbpn9u+LQ9xJDse10gNnPgAcxgdoCDMXj/G2asWAC/8Qs+BAZDicX+MNZouXT1A7c83kVw==", + "dev": true, + "dependencies": { + "@sinonjs/commons": "^3.0.1", + "lodash.get": "^4.4.2", + "type-detect": "^4.1.0" + } + }, + "node_modules/@sinonjs/samsam/node_modules/@sinonjs/commons": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.1.tgz", + "integrity": "sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==", + "dev": true, + "dependencies": { + "type-detect": "4.0.8" + } + }, + "node_modules/@sinonjs/samsam/node_modules/@sinonjs/commons/node_modules/type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/@sinonjs/samsam/node_modules/type-detect": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.1.0.tgz", + "integrity": "sha512-Acylog8/luQ8L7il+geoSxhEkazvkslg7PSNKOX59mbB9cOveP5aq9h74Y7YU8yDpJwetzQQrfIwtf4Wp4LKcw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/@sinonjs/text-encoding": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/@sinonjs/text-encoding/-/text-encoding-0.7.3.tgz", + "integrity": "sha512-DE427ROAphMQzU4ENbliGYrBSYPXF+TtLg9S8vzeA+OF4ZKzoDdzfL8sxuMUGS/lgRhM6j1URSk9ghf7Xo1tyA==", + "dev": true + }, "node_modules/@tootallnate/once": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", @@ -1756,6 +1802,21 @@ "@types/node": "*" } }, + "node_modules/@types/sinon": { + "version": "17.0.3", + "resolved": "https://registry.npmjs.org/@types/sinon/-/sinon-17.0.3.tgz", + "integrity": "sha512-j3uovdn8ewky9kRBG19bOwaZbexJu/XjtkHyjvUgt4xfPFz18dcORIMqnYh66Fx3Powhcr85NT5+er3+oViapw==", + "dev": true, + "dependencies": { + "@types/sinonjs__fake-timers": "*" + } + }, + "node_modules/@types/sinonjs__fake-timers": { + "version": "8.1.5", + "resolved": "https://registry.npmjs.org/@types/sinonjs__fake-timers/-/sinonjs__fake-timers-8.1.5.tgz", + "integrity": "sha512-mQkU2jY8jJEF7YHjHvsQO8+3ughTL1mcnn96igfhONmR+fUPSKIkefQYpSe8bsly2Ep7oQbn/6VG5/9/0qcArQ==", + "dev": true + }, "node_modules/@types/sockjs": { "version": "0.3.33", "dev": true, @@ -3334,6 +3395,15 @@ "integrity": "sha512-0cuGS8+jhR67Fy7qG3i3Pc7Aw494sb9yG9QgpG97SFVWwolgYjlhJg7n+UaHxOQT30d1TYu/EYe9k01ivLErIg==", "dev": true }, + "node_modules/diff": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-7.0.0.tgz", + "integrity": "sha512-PJWHUb1RFevKCwaFA9RlG5tCd+FO5iRh9A8HEtkmBH2Li03iJriB6m6JIN4rGz3K3JLawI7/veA1xzRKP6ISBw==", + "dev": true, + "engines": { + "node": ">=0.3.1" + } + }, "node_modules/diff-sequences": { "version": "27.5.1", "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-27.5.1.tgz", @@ -6689,6 +6759,12 @@ "graceful-fs": "^4.1.6" } }, + "node_modules/just-extend": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/just-extend/-/just-extend-6.2.0.tgz", + "integrity": "sha512-cYofQu2Xpom82S6qD778jBDpwvvy39s1l/hrYij2u9AMdQcGRpaBu6kY4mVhuno5kJVi1DAz4aiphA2WI1/OAw==", + "dev": true + }, "node_modules/kind-of": { "version": "6.0.3", "dev": true, @@ -6933,6 +7009,12 @@ "dev": true, "license": "MIT" }, + "node_modules/lodash.get": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", + "integrity": "sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==", + "dev": true + }, "node_modules/lodash.memoize": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", @@ -7248,6 +7330,46 @@ "dev": true, "license": "MIT" }, + "node_modules/nise": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/nise/-/nise-6.1.1.tgz", + "integrity": "sha512-aMSAzLVY7LyeM60gvBS423nBmIPP+Wy7St7hsb+8/fc1HmeoHJfLO8CKse4u3BtOZvQLJghYPI2i/1WZrEj5/g==", + "dev": true, + "dependencies": { + "@sinonjs/commons": "^3.0.1", + "@sinonjs/fake-timers": "^13.0.1", + "@sinonjs/text-encoding": "^0.7.3", + "just-extend": "^6.2.0", + "path-to-regexp": "^8.1.0" + } + }, + "node_modules/nise/node_modules/@sinonjs/commons": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.1.tgz", + "integrity": "sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==", + "dev": true, + "dependencies": { + "type-detect": "4.0.8" + } + }, + "node_modules/nise/node_modules/@sinonjs/fake-timers": { + "version": "13.0.5", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-13.0.5.tgz", + "integrity": "sha512-36/hTbH2uaWuGVERyC6da9YwGWnzUZXuPro/F2LfsdOsLnCojz/iSH8MxUt/FD2S5XBSVPhmArFUXcpCQ2Hkiw==", + "dev": true, + "dependencies": { + "@sinonjs/commons": "^3.0.1" + } + }, + "node_modules/nise/node_modules/path-to-regexp": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.2.0.tgz", + "integrity": "sha512-TdrF7fW9Rphjq4RjrW0Kp2AW0Ahwu9sRGTkS6bvDi0SCwZlEZYmcfDbEsTz8RVk0EHIS/Vd1bv3JhG+1xZuAyQ==", + "dev": true, + "engines": { + "node": ">=16" + } + }, "node_modules/no-case": { "version": "3.0.4", "dev": true, @@ -8899,6 +9021,42 @@ "dev": true, "license": "ISC" }, + "node_modules/sinon": { + "version": "19.0.2", + "resolved": "https://registry.npmjs.org/sinon/-/sinon-19.0.2.tgz", + "integrity": "sha512-euuToqM+PjO4UgXeLETsfQiuoyPXlqFezr6YZDFwHR3t4qaX0fZUe1MfPMznTL5f8BWrVS89KduLdMUsxFCO6g==", + "dev": true, + "dependencies": { + "@sinonjs/commons": "^3.0.1", + "@sinonjs/fake-timers": "^13.0.2", + "@sinonjs/samsam": "^8.0.1", + "diff": "^7.0.0", + "nise": "^6.1.1", + "supports-color": "^7.2.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/sinon" + } + }, + "node_modules/sinon/node_modules/@sinonjs/commons": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.1.tgz", + "integrity": "sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==", + "dev": true, + "dependencies": { + "type-detect": "4.0.8" + } + }, + "node_modules/sinon/node_modules/@sinonjs/fake-timers": { + "version": "13.0.5", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-13.0.5.tgz", + "integrity": "sha512-36/hTbH2uaWuGVERyC6da9YwGWnzUZXuPro/F2LfsdOsLnCojz/iSH8MxUt/FD2S5XBSVPhmArFUXcpCQ2Hkiw==", + "dev": true, + "dependencies": { + "@sinonjs/commons": "^3.0.1" + } + }, "node_modules/sisteransi": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", @@ -10553,9 +10711,9 @@ }, "dependencies": { "@2gis/mapgl": { - "version": "1.47.0", - "resolved": "https://registry.npmjs.org/@2gis/mapgl/-/mapgl-1.47.0.tgz", - "integrity": "sha512-aAMXb/+AveKZeusP/ZU/wCtI20F3nyH4pX99E6OpVJjRIL8jhGptyxpP45oPaGozG+3fZypoQVFp8lb7tMYKGQ==", + "version": "1.53.0", + "resolved": "https://registry.npmjs.org/@2gis/mapgl/-/mapgl-1.53.0.tgz", + "integrity": "sha512-lT+XX1grV/Qg7rVtBfAPkXl+0c5JIzBr9j/+LcEURLKacfPOwAhlEh2lEY+O+YFA2IPi91FXYHs031IF3d/omA==", "dev": true, "requires": { "@types/geojson": "^7946.0.7" @@ -11675,6 +11833,48 @@ "@sinonjs/commons": "^1.7.0" } }, + "@sinonjs/samsam": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-8.0.2.tgz", + "integrity": "sha512-v46t/fwnhejRSFTGqbpn9u+LQ9xJDse10gNnPgAcxgdoCDMXj/G2asWAC/8Qs+BAZDicX+MNZouXT1A7c83kVw==", + "dev": true, + "requires": { + "@sinonjs/commons": "^3.0.1", + "lodash.get": "^4.4.2", + "type-detect": "^4.1.0" + }, + "dependencies": { + "@sinonjs/commons": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.1.tgz", + "integrity": "sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==", + "dev": true, + "requires": { + "type-detect": "4.0.8" + }, + "dependencies": { + "type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "dev": true + } + } + }, + "type-detect": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.1.0.tgz", + "integrity": "sha512-Acylog8/luQ8L7il+geoSxhEkazvkslg7PSNKOX59mbB9cOveP5aq9h74Y7YU8yDpJwetzQQrfIwtf4Wp4LKcw==", + "dev": true + } + } + }, + "@sinonjs/text-encoding": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/@sinonjs/text-encoding/-/text-encoding-0.7.3.tgz", + "integrity": "sha512-DE427ROAphMQzU4ENbliGYrBSYPXF+TtLg9S8vzeA+OF4ZKzoDdzfL8sxuMUGS/lgRhM6j1URSk9ghf7Xo1tyA==", + "dev": true + }, "@tootallnate/once": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", @@ -11939,6 +12139,21 @@ "@types/node": "*" } }, + "@types/sinon": { + "version": "17.0.3", + "resolved": "https://registry.npmjs.org/@types/sinon/-/sinon-17.0.3.tgz", + "integrity": "sha512-j3uovdn8ewky9kRBG19bOwaZbexJu/XjtkHyjvUgt4xfPFz18dcORIMqnYh66Fx3Powhcr85NT5+er3+oViapw==", + "dev": true, + "requires": { + "@types/sinonjs__fake-timers": "*" + } + }, + "@types/sinonjs__fake-timers": { + "version": "8.1.5", + "resolved": "https://registry.npmjs.org/@types/sinonjs__fake-timers/-/sinonjs__fake-timers-8.1.5.tgz", + "integrity": "sha512-mQkU2jY8jJEF7YHjHvsQO8+3ughTL1mcnn96igfhONmR+fUPSKIkefQYpSe8bsly2Ep7oQbn/6VG5/9/0qcArQ==", + "dev": true + }, "@types/sockjs": { "version": "0.3.33", "dev": true, @@ -13047,6 +13262,12 @@ "integrity": "sha512-0cuGS8+jhR67Fy7qG3i3Pc7Aw494sb9yG9QgpG97SFVWwolgYjlhJg7n+UaHxOQT30d1TYu/EYe9k01ivLErIg==", "dev": true }, + "diff": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-7.0.0.tgz", + "integrity": "sha512-PJWHUb1RFevKCwaFA9RlG5tCd+FO5iRh9A8HEtkmBH2Li03iJriB6m6JIN4rGz3K3JLawI7/veA1xzRKP6ISBw==", + "dev": true + }, "diff-sequences": { "version": "27.5.1", "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-27.5.1.tgz", @@ -15502,6 +15723,12 @@ "universalify": "^2.0.0" } }, + "just-extend": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/just-extend/-/just-extend-6.2.0.tgz", + "integrity": "sha512-cYofQu2Xpom82S6qD778jBDpwvvy39s1l/hrYij2u9AMdQcGRpaBu6kY4mVhuno5kJVi1DAz4aiphA2WI1/OAw==", + "dev": true + }, "kind-of": { "version": "6.0.3", "dev": true @@ -15672,6 +15899,12 @@ "version": "4.17.21", "dev": true }, + "lodash.get": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", + "integrity": "sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==", + "dev": true + }, "lodash.memoize": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", @@ -15887,6 +16120,45 @@ "version": "1.0.5", "dev": true }, + "nise": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/nise/-/nise-6.1.1.tgz", + "integrity": "sha512-aMSAzLVY7LyeM60gvBS423nBmIPP+Wy7St7hsb+8/fc1HmeoHJfLO8CKse4u3BtOZvQLJghYPI2i/1WZrEj5/g==", + "dev": true, + "requires": { + "@sinonjs/commons": "^3.0.1", + "@sinonjs/fake-timers": "^13.0.1", + "@sinonjs/text-encoding": "^0.7.3", + "just-extend": "^6.2.0", + "path-to-regexp": "^8.1.0" + }, + "dependencies": { + "@sinonjs/commons": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.1.tgz", + "integrity": "sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==", + "dev": true, + "requires": { + "type-detect": "4.0.8" + } + }, + "@sinonjs/fake-timers": { + "version": "13.0.5", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-13.0.5.tgz", + "integrity": "sha512-36/hTbH2uaWuGVERyC6da9YwGWnzUZXuPro/F2LfsdOsLnCojz/iSH8MxUt/FD2S5XBSVPhmArFUXcpCQ2Hkiw==", + "dev": true, + "requires": { + "@sinonjs/commons": "^3.0.1" + } + }, + "path-to-regexp": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.2.0.tgz", + "integrity": "sha512-TdrF7fW9Rphjq4RjrW0Kp2AW0Ahwu9sRGTkS6bvDi0SCwZlEZYmcfDbEsTz8RVk0EHIS/Vd1bv3JhG+1xZuAyQ==", + "dev": true + } + } + }, "no-case": { "version": "3.0.4", "dev": true, @@ -16977,6 +17249,40 @@ "version": "3.0.7", "dev": true }, + "sinon": { + "version": "19.0.2", + "resolved": "https://registry.npmjs.org/sinon/-/sinon-19.0.2.tgz", + "integrity": "sha512-euuToqM+PjO4UgXeLETsfQiuoyPXlqFezr6YZDFwHR3t4qaX0fZUe1MfPMznTL5f8BWrVS89KduLdMUsxFCO6g==", + "dev": true, + "requires": { + "@sinonjs/commons": "^3.0.1", + "@sinonjs/fake-timers": "^13.0.2", + "@sinonjs/samsam": "^8.0.1", + "diff": "^7.0.0", + "nise": "^6.1.1", + "supports-color": "^7.2.0" + }, + "dependencies": { + "@sinonjs/commons": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.1.tgz", + "integrity": "sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==", + "dev": true, + "requires": { + "type-detect": "4.0.8" + } + }, + "@sinonjs/fake-timers": { + "version": "13.0.5", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-13.0.5.tgz", + "integrity": "sha512-36/hTbH2uaWuGVERyC6da9YwGWnzUZXuPro/F2LfsdOsLnCojz/iSH8MxUt/FD2S5XBSVPhmArFUXcpCQ2Hkiw==", + "dev": true, + "requires": { + "@sinonjs/commons": "^3.0.1" + } + } + } + }, "sisteransi": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", diff --git a/package.json b/package.json index e45235b..3c984c6 100644 --- a/package.json +++ b/package.json @@ -36,12 +36,13 @@ "author": "2GIS WebMaps Team", "license": "BSD-2-Clause", "devDependencies": { - "@2gis/mapgl": "^1.47.0", + "@2gis/mapgl": "^1.52.0", "@documentalist/compiler": "^2.8.1", "@types/geojson": "^7946.0.10", "@types/jest": "^27.4.0", "@types/jest-image-snapshot": "^4.3.1", "@types/puppeteer": "^5.4.4", + "@types/sinon": "^17.0.3", "clean-webpack-plugin": "^4.0.0", "copy-webpack-plugin": "^11.0.0", "css-loader": "^3.6.0", @@ -53,6 +54,7 @@ "prettier": "^2.8.7", "puppeteer": "^13.3.2", "raw-loader": "^4.0.2", + "sinon": "^19.0.2", "style-loader": "^1.3.0", "ts-jest": "^27.1.3", "ts-loader": "^9.4.2", diff --git a/src/defaultOptions.ts b/src/defaultOptions.ts index d83dcbd..a17dbcc 100644 --- a/src/defaultOptions.ts +++ b/src/defaultOptions.ts @@ -7,6 +7,7 @@ export const defaultOptions: Required = { }, modelsBaseUrl: '', modelsLoadStrategy: 'waitAll', + modelsNearCameraFade: 2500, labelGroupDefaults: { fontSize: DEFAULT_FONT_SIZE, fontColor: DEFAULT_FONT_COLOR, @@ -17,4 +18,6 @@ export const defaultOptions: Required = { }, groundCoveringColor: '#F8F8EBCC', zIndex: 0, + minZoom: -Infinity, + maxZoom: Infinity, }; diff --git a/src/labelGroups.ts b/src/labelGroups.ts index 293f974..caac6a1 100644 --- a/src/labelGroups.ts +++ b/src/labelGroups.ts @@ -55,8 +55,8 @@ export class LabelGroups { text, userData, image: image === 'default' ? labelGroupDefaults.image ?? DEFAULT_IMAGE : image, - minZoom, - maxZoom, + minZoom: minZoom ?? this.options.minZoom, + maxZoom: maxZoom ?? this.options.maxZoom, color: fontColor ?? labelGroupDefaults.fontColor ?? DEFAULT_FONT_COLOR, fontSize: fontSize ?? labelGroupDefaults.fontSize ?? DEFAULT_FONT_SIZE, relativeAnchor: [0.5, 1], diff --git a/src/plugin.ts b/src/plugin.ts index 0fff720..6e75bdc 100644 --- a/src/plugin.ts +++ b/src/plugin.ts @@ -156,6 +156,9 @@ export class GltfPlugin extends Evented { }, disableAnimation: true, zIndex: this.options.zIndex, + minZoom: options.minZoom ?? this.options.minZoom, + maxZoom: options.maxZoom ?? this.options.maxZoom, + nearCameraFade: this.options.modelsNearCameraFade, }); const model: Model = { @@ -215,11 +218,12 @@ export class GltfPlugin extends Evented { * Removes a model from the map. * * @param id A model id. + * @param keepModel Specifies whether model data should be cached for future use. */ - public removeModel(id: string) { + public removeModel(id: string, keepModel?: boolean) { const model = this.models.get(id); if (model) { - model.instance.destroy(); + model.instance.destroy(keepModel); this.models.delete(id); } } @@ -228,9 +232,10 @@ export class GltfPlugin extends Evented { * Removes models from the map. * * @param id Model ids. + * @param keepModels Specifies whether model data should be cached for future use. */ - public removeModels(ids: string[]) { - ids.forEach((id) => this.removeModel(id)); + public removeModels(ids: string[], keepModels?: boolean) { + ids.forEach((id) => this.removeModel(id, keepModels)); } /** @@ -316,9 +321,11 @@ export class GltfPlugin extends Evented { /** * Removes an interactive realty scene from the map. + * + * @param keepModels Specifies whether model data should be cached for future use. */ - public removeRealtyScene() { - this.realtyScene?.destroy(); + public removeRealtyScene(keepModels?: boolean) { + this.realtyScene?.destroy(keepModels); this.realtyScene = undefined; } } diff --git a/src/realtyScene/realtyScene.ts b/src/realtyScene/realtyScene.ts index f1b8477..213ecb0 100644 --- a/src/realtyScene/realtyScene.ts +++ b/src/realtyScene/realtyScene.ts @@ -256,6 +256,29 @@ export class RealtyScene { } } + if (prevState.activeModelId !== newState.activeModelId) { + let buildingModelId: string | undefined; + let floorModelId: string | undefined; + + if (newState.activeModelId !== undefined) { + const building = this.buildings.get(newState.activeModelId); + if (building) { + buildingModelId = building.modelId; + } else { + const floor = this.floors.get(newState.activeModelId); + if (floor) { + buildingModelId = floor.buildingOptions.modelId; + floorModelId = floor.id; + } + } + } + + this.plugin.emit('activemodelchange', { + buildingModelId, + floorModelId, + }); + } + this.state = { buildingVisibility, activeModelId: newState.activeModelId, @@ -395,7 +418,7 @@ export class RealtyScene { }); } - public destroy() { + public destroy(keepModels?: boolean) { if (this.state.status === 'destroyed') { return; } @@ -412,7 +435,7 @@ export class RealtyScene { this.plugin.removeLabelGroup(id); }); }); - this.plugin.removeModels([...this.buildings.keys(), ...this.floors.keys()]); + this.plugin.removeModels([...this.buildings.keys(), ...this.floors.keys()], keepModels); this.map.removeLayer(GROUND_COVERING_LAYER_ID); this.groundCoveringSource.destroy(); @@ -439,16 +462,16 @@ export class RealtyScene { duration: 500, }; - if (options.center) { + if (options.center !== undefined) { this.map.setCenter(options.center, animationOptions); } - if (options.pitch) { + if (options.pitch !== undefined) { this.map.setPitch(options.pitch, animationOptions); } - if (options.rotation) { + if (options.rotation !== undefined) { this.map.setRotation(options.rotation, animationOptions); } - if (options.zoom) { + if (options.zoom !== undefined) { this.map.setZoom(options.zoom, animationOptions); } } diff --git a/src/types/events.ts b/src/types/events.ts index 4c3aa71..f2b4c00 100644 --- a/src/types/events.ts +++ b/src/types/events.ts @@ -99,4 +99,13 @@ export interface GltfPluginEventTable { * Emitted when user moves mouse away from a model or a label. */ mouseout: GltfPluginLabelEvent | GltfPluginModelEvent; + /** + * Emitted when an active model has changed on the realty scene. + * @hidden + * @internal + */ + activemodelchange: { + buildingModelId?: string; + floorModelId?: string; + }; } diff --git a/src/types/plugin.ts b/src/types/plugin.ts index 4f6493c..c1332b1 100644 --- a/src/types/plugin.ts +++ b/src/types/plugin.ts @@ -86,6 +86,19 @@ export interface PluginOptions { * on the map so that user could manage draw order of the plugin and these objects. */ zIndex?: number; + /** + * Minimum display styleZoom for all models. + */ + minZoom?: number; + /** + * Maximum display styleZoom for all models. + */ + maxZoom?: number; + /** + * A distance to the camera the models get transparent from. + * It's set in units along Z axis of the WebGL space. + */ + modelsNearCameraFade?: number; } /** @@ -159,6 +172,14 @@ export interface ModelOptions { * Interactivity of a model. The model isn't interactive by default. */ interactive?: boolean; + /** + * Minimum display styleZoom of the model. + */ + minZoom?: number; + /** + * Maximum display styleZoom of the model. + */ + maxZoom?: number; } /** diff --git a/src/utils/realtyScene.ts b/src/utils/realtyScene.ts index 94f8c28..907ecb4 100644 --- a/src/utils/realtyScene.ts +++ b/src/utils/realtyScene.ts @@ -14,6 +14,8 @@ export function getBuildingModelOptions(building: BuildingOptionsInternal): Mode scale: building.scale, linkedIds: building.linkedIds, interactive: building.interactive, + minZoom: building.minZoom, + maxZoom: building.maxZoom, }; } @@ -35,6 +37,8 @@ export function getFloorModelOptions({ scale: buildingOptions.scale, linkedIds: buildingOptions.linkedIds, interactive: buildingOptions.interactive, + minZoom: buildingOptions.minZoom, + maxZoom: buildingOptions.maxZoom, }; } diff --git a/test/index.ts b/test/index.ts index ead18dd..8451462 100644 --- a/test/index.ts +++ b/test/index.ts @@ -1,5 +1,7 @@ +import * as sinon from 'sinon'; import { GltfPlugin } from '../src'; import { MOCKS } from './mocks'; window.GltfPlugin = GltfPlugin; window.MOCKS = MOCKS; // storage for any data for tests +window.sinon = sinon; diff --git a/test/integration/events.ts b/test/integration/events.ts new file mode 100644 index 0000000..93679c0 --- /dev/null +++ b/test/integration/events.ts @@ -0,0 +1,48 @@ +import { Page, pageSetUp } from '../puppeteer'; +import { initBlankMap, waitForReadiness } from '../puppeteer/utils'; + +describe('Events', () => { + let page: Page; + + beforeEach(async () => { + page = await pageSetUp(); + await initBlankMap(page, { + center: [47.245286302641034, 56.134743473834099], + styleZoom: 18, + }); + await page.evaluate(() => { + window.gltfPlugin = new window.GltfPlugin(window.map, { + modelsBaseUrl: + 'https://disk.2gis.com/digital-twin/models_s3/realty_ads/zgktechnology/', + }); + }); + }); + + afterEach(async () => { + await page.close(); + }); + + describe('activemodelchange', () => { + it('activemodelchange is emitted on adding realty scene with a state', async () => { + const buildingId = '03a234cb'; + const floorId = '235034'; + await page.evaluate( + (buildingId, floorId) => { + window.spy = window.sinon.spy(); + window.gltfPlugin.on('activemodelchange', window.spy); + return window.gltfPlugin.addRealtyScene(window.MOCKS.realtyScene, { + buildingId, + floorId, + }); + }, + buildingId, + floorId, + ); + await waitForReadiness(page); + expect(await page.evaluate(() => window.spy.firstCall.args[0])).toEqual({ + buildingModelId: buildingId, + floorModelId: floorId, + }); + }); + }); +}); diff --git a/test/integration/stub.ts b/test/integration/stub.ts deleted file mode 100644 index 57b60c4..0000000 --- a/test/integration/stub.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { Page, pageSetUp } from '../puppeteer'; -import { initBlankMap } from '../puppeteer/utils'; - -describe('stub integration test', () => { - let page: Page; - - beforeEach(async () => { - page = await pageSetUp(); - await initBlankMap(page); - }); - - afterEach(async () => { - await page.close(); - }); - - it('stub test is ok', async () => { - const isOk = await page.evaluate(() => { - return window.map !== undefined && window.GltfPlugin !== undefined; - }); - - expect(isOk).toBe(true); - }); - - it('pure stub test is ok', async () => { - expect(true).toBe(true); - }); -}); diff --git a/test/mocks/index.ts b/test/mocks/index.ts index 3f48cbc..2e9ce64 100644 --- a/test/mocks/index.ts +++ b/test/mocks/index.ts @@ -1,11 +1,14 @@ -import { MODEL_CUBE_BIG, MODEL_CUBE_SMALL } from './models'; +import { MODEL_CUBE_BIG, MODEL_CUBE_MID, MODEL_CUBE_SMALL, MODEL_PALM, MODEL_PINE } from './models'; import { LABEL_ASCII_LETTERS, LABEL_ENG_RUS_LETTERS } from './labels'; import { REALTY_SCENE } from './realtyScene'; export const MOCKS = { models: { cubeBig: MODEL_CUBE_BIG, + cubeMid: MODEL_CUBE_MID, cubeSmall: MODEL_CUBE_SMALL, + palm: MODEL_PALM, + pine: MODEL_PINE, }, labels: { asciiLetters: LABEL_ASCII_LETTERS, diff --git a/test/mocks/models.ts b/test/mocks/models.ts index ec75a5c..a7083fd 100644 --- a/test/mocks/models.ts +++ b/test/mocks/models.ts @@ -1,6 +1,6 @@ import { BuildingOptions } from '../../src/types/realtyScene'; -export const MODEL_CUBE_BIG: BuildingOptions = { +export const MODEL_CUBE_MID: BuildingOptions = { modelId: '1', coordinates: [82.886554, 54.98085], modelUrl: `${location.origin}/models/cube_draco.glb`, @@ -14,3 +14,24 @@ export const MODEL_CUBE_SMALL: BuildingOptions = { rotateZ: 31, scale: 1, }; + +export const MODEL_CUBE_BIG: BuildingOptions = { + modelId: '3', + coordinates: [82.886554, 54.98085], + modelUrl: `${location.origin}/models/cube_draco.glb`, + scale: 10, +}; + +export const MODEL_PALM: BuildingOptions = { + modelId: '4', + coordinates: [82.88378289287995, 54.90501866207913], + modelUrl: `${location.origin}/models/palm.glb`, + scale: 3, +}; + +export const MODEL_PINE: BuildingOptions = { + modelId: '5', + coordinates: [82.88520478969967, 54.90440124749836], + modelUrl: `${location.origin}/models/pine.glb`, + scale: 3, +}; diff --git a/test/screenshots/__screenshots__/plugin/add_label_group-snap.png b/test/screenshots/__screenshots__/plugin/add_label_group-snap.png index 91ab0e4..bca3df6 100644 Binary files a/test/screenshots/__screenshots__/plugin/add_label_group-snap.png and b/test/screenshots/__screenshots__/plugin/add_label_group-snap.png differ diff --git a/test/screenshots/__screenshots__/plugin/add_model-snap.png b/test/screenshots/__screenshots__/plugin/add_model-snap.png index e91f312..cc1446c 100644 Binary files a/test/screenshots/__screenshots__/plugin/add_model-snap.png and b/test/screenshots/__screenshots__/plugin/add_model-snap.png differ diff --git a/test/screenshots/__screenshots__/plugin/add_models-snap.png b/test/screenshots/__screenshots__/plugin/add_models-snap.png index 1d28e33..e3eefd8 100644 Binary files a/test/screenshots/__screenshots__/plugin/add_models-snap.png and b/test/screenshots/__screenshots__/plugin/add_models-snap.png differ diff --git a/test/screenshots/__screenshots__/plugin/add_models_partially-snap.png b/test/screenshots/__screenshots__/plugin/add_models_partially-snap.png index e91f312..cc1446c 100644 Binary files a/test/screenshots/__screenshots__/plugin/add_models_partially-snap.png and b/test/screenshots/__screenshots__/plugin/add_models_partially-snap.png differ diff --git a/test/screenshots/__screenshots__/plugin/add_realty_scene-snap.png b/test/screenshots/__screenshots__/plugin/add_realty_scene-snap.png index 38aeabb..c47b2d4 100644 Binary files a/test/screenshots/__screenshots__/plugin/add_realty_scene-snap.png and b/test/screenshots/__screenshots__/plugin/add_realty_scene-snap.png differ diff --git a/test/screenshots/__screenshots__/plugin/change_style-snap.png b/test/screenshots/__screenshots__/plugin/change_style-snap.png index 80494b2..1bc964b 100644 Binary files a/test/screenshots/__screenshots__/plugin/change_style-snap.png and b/test/screenshots/__screenshots__/plugin/change_style-snap.png differ diff --git a/test/screenshots/__screenshots__/plugin/plugin_options_default_modelsNearCameraFade-snap.png b/test/screenshots/__screenshots__/plugin/plugin_options_default_modelsNearCameraFade-snap.png new file mode 100644 index 0000000..85fd522 Binary files /dev/null and b/test/screenshots/__screenshots__/plugin/plugin_options_default_modelsNearCameraFade-snap.png differ diff --git a/test/screenshots/__screenshots__/plugin/plugin_options_great_modelsNearCameraFade-snap.png b/test/screenshots/__screenshots__/plugin/plugin_options_great_modelsNearCameraFade-snap.png new file mode 100644 index 0000000..596049b Binary files /dev/null and b/test/screenshots/__screenshots__/plugin/plugin_options_great_modelsNearCameraFade-snap.png differ diff --git a/test/screenshots/__screenshots__/plugin/plugin_options_minZoom_maxZoom_invisible_all_models-snap.png b/test/screenshots/__screenshots__/plugin/plugin_options_minZoom_maxZoom_invisible_all_models-snap.png new file mode 100644 index 0000000..115367a Binary files /dev/null and b/test/screenshots/__screenshots__/plugin/plugin_options_minZoom_maxZoom_invisible_all_models-snap.png differ diff --git a/test/screenshots/__screenshots__/plugin/plugin_options_minZoom_maxZoom_no_visible_models-snap.png b/test/screenshots/__screenshots__/plugin/plugin_options_minZoom_maxZoom_no_visible_models-snap.png new file mode 100644 index 0000000..115367a Binary files /dev/null and b/test/screenshots/__screenshots__/plugin/plugin_options_minZoom_maxZoom_no_visible_models-snap.png differ diff --git a/test/screenshots/__screenshots__/plugin/plugin_options_minZoom_maxZoom_visible_all_models-snap.png b/test/screenshots/__screenshots__/plugin/plugin_options_minZoom_maxZoom_visible_all_models-snap.png new file mode 100644 index 0000000..6c8b6f0 Binary files /dev/null and b/test/screenshots/__screenshots__/plugin/plugin_options_minZoom_maxZoom_visible_all_models-snap.png differ diff --git a/test/screenshots/__screenshots__/plugin/plugin_options_minZoom_maxZoom_visible_cube-snap.png b/test/screenshots/__screenshots__/plugin/plugin_options_minZoom_maxZoom_visible_cube-snap.png new file mode 100644 index 0000000..8d5ccf9 Binary files /dev/null and b/test/screenshots/__screenshots__/plugin/plugin_options_minZoom_maxZoom_visible_cube-snap.png differ diff --git a/test/screenshots/__screenshots__/plugin/plugin_options_minZoom_maxZoom_visible_cube_again-snap.png b/test/screenshots/__screenshots__/plugin/plugin_options_minZoom_maxZoom_visible_cube_again-snap.png new file mode 100644 index 0000000..f38d588 Binary files /dev/null and b/test/screenshots/__screenshots__/plugin/plugin_options_minZoom_maxZoom_visible_cube_again-snap.png differ diff --git a/test/screenshots/__screenshots__/plugin/plugin_options_minZoom_maxZoom_visible_cube_and_palm-snap.png b/test/screenshots/__screenshots__/plugin/plugin_options_minZoom_maxZoom_visible_cube_and_palm-snap.png new file mode 100644 index 0000000..8dcf542 Binary files /dev/null and b/test/screenshots/__screenshots__/plugin/plugin_options_minZoom_maxZoom_visible_cube_and_palm-snap.png differ diff --git a/test/screenshots/__screenshots__/plugin/plugin_options_minZoom_maxZoom_visible_cube_and_pine-snap.png b/test/screenshots/__screenshots__/plugin/plugin_options_minZoom_maxZoom_visible_cube_and_pine-snap.png new file mode 100644 index 0000000..2e12dfa Binary files /dev/null and b/test/screenshots/__screenshots__/plugin/plugin_options_minZoom_maxZoom_visible_cube_and_pine-snap.png differ diff --git a/test/screenshots/__screenshots__/plugin/plugin_options_no_modelsNearCameraFade-snap.png b/test/screenshots/__screenshots__/plugin/plugin_options_no_modelsNearCameraFade-snap.png new file mode 100644 index 0000000..fabb021 Binary files /dev/null and b/test/screenshots/__screenshots__/plugin/plugin_options_no_modelsNearCameraFade-snap.png differ diff --git a/test/screenshots/__screenshots__/plugin/show_realty_scene-snap.png b/test/screenshots/__screenshots__/plugin/show_realty_scene-snap.png index 38aeabb..c47b2d4 100644 Binary files a/test/screenshots/__screenshots__/plugin/show_realty_scene-snap.png and b/test/screenshots/__screenshots__/plugin/show_realty_scene-snap.png differ diff --git a/test/screenshots/plugin.screen.ts b/test/screenshots/plugin.screen.ts index fc5abe4..939f34e 100644 --- a/test/screenshots/plugin.screen.ts +++ b/test/screenshots/plugin.screen.ts @@ -11,13 +11,16 @@ import { defaultFontsPath, blankDarkStyle, } from '../puppeteer/utils'; +import { PluginOptions } from '../../src/types/plugin'; + +type TestPluginOptions = Pick< + PluginOptions, + 'minZoom' | 'maxZoom' | 'modelsBaseUrl' | 'groundCoveringColor' | 'modelsNearCameraFade' +>; const init = async ( page: Page, - opts: Pick & { - modelsBaseUrl?: string; - groundCoveringColor?: string; - } = {}, + opts: Pick & TestPluginOptions = {}, ) => { await initMapWithOptions(page, { style: blankStyle, @@ -28,26 +31,23 @@ const init = async ( copyright: false, zoomControl: false, key: API_KEY, - zoom: 17.5, + styleZoom: opts.styleZoom ?? 17.5, center: opts.center ?? [82.88657676327911, 54.98075155383938], rotation: opts.rotation ?? -111, - pitch: 45, + pitch: opts.pitch ?? 45, disableAntiAliasing: true, }); - await page.evaluate( - ({ modelsBaseUrl, groundCoveringColor }) => { - window.gltfPlugin = new window.GltfPlugin(window.map, { - modelsLoadStrategy: 'dontWaitAll', - modelsBaseUrl, - groundCoveringColor, - }); - }, - { - modelsBaseUrl: opts.modelsBaseUrl ?? '', - groundCoveringColor: opts.groundCoveringColor ?? '#F8F8EBCC', - }, - ); + await page.evaluate((options: TestPluginOptions) => { + window.gltfPlugin = new window.GltfPlugin(window.map, { + modelsLoadStrategy: 'dontWaitAll', + modelsBaseUrl: options.modelsBaseUrl, + groundCoveringColor: options.groundCoveringColor, + modelsNearCameraFade: options.modelsNearCameraFade, + minZoom: options.minZoom, + maxZoom: options.maxZoom, + }); + }, opts); await waitForReadiness(page); }; @@ -71,7 +71,7 @@ describe('GltfPlugin', () => { it('#addModel', async () => { await init(page); await page.evaluate(() => { - return window.gltfPlugin.addModel(window.MOCKS.models.cubeBig); + return window.gltfPlugin.addModel(window.MOCKS.models.cubeMid); }); await waitForReadiness(page); @@ -82,7 +82,7 @@ describe('GltfPlugin', () => { await init(page); await page.evaluate(() => { return window.gltfPlugin.addModels([ - window.MOCKS.models.cubeBig, + window.MOCKS.models.cubeMid, window.MOCKS.models.cubeSmall, ]); }); @@ -105,10 +105,10 @@ describe('GltfPlugin', () => { it('#removeModel', async () => { await init(page); await page.evaluate(() => { - return window.gltfPlugin.addModel(window.MOCKS.models.cubeBig); + return window.gltfPlugin.addModel(window.MOCKS.models.cubeMid); }); await page.evaluate(() => { - window.gltfPlugin.removeModel(window.MOCKS.models.cubeBig.modelId); + window.gltfPlugin.removeModel(window.MOCKS.models.cubeMid.modelId); }); await waitForReadiness(page); await makeSnapshot(page, dirPath, 'remove_model'); @@ -118,13 +118,13 @@ describe('GltfPlugin', () => { await init(page); await page.evaluate(() => { return window.gltfPlugin.addModels([ - window.MOCKS.models.cubeBig, + window.MOCKS.models.cubeMid, window.MOCKS.models.cubeSmall, ]); }); await page.evaluate(() => { window.gltfPlugin.removeModels([ - window.MOCKS.models.cubeBig.modelId, + window.MOCKS.models.cubeMid.modelId, window.MOCKS.models.cubeSmall.modelId, ]); }); @@ -148,14 +148,150 @@ describe('GltfPlugin', () => { await init(page); await page.evaluate(() => { return window.gltfPlugin.addModels( - [window.MOCKS.models.cubeBig, window.MOCKS.models.cubeSmall], - [window.MOCKS.models.cubeBig.modelId], + [window.MOCKS.models.cubeMid, window.MOCKS.models.cubeSmall], + [window.MOCKS.models.cubeMid.modelId], ); }); await waitForReadiness(page); await makeSnapshot(page, dirPath, 'add_models_partially'); }); + describe('Plugin options', () => { + describe('modelsNearCameraFade', () => { + it('default modelsNearCameraFade', async () => { + await init(page, { styleZoom: 19.65 }); + await page.evaluate(() => { + return window.gltfPlugin.addModel(window.MOCKS.models.cubeBig); + }); + + await waitForReadiness(page); + await makeSnapshot(page, dirPath, 'plugin_options_default_modelsNearCameraFade'); + }); + + it('no modelsNearCameraFade', async () => { + await init(page, { styleZoom: 19.65, modelsNearCameraFade: 0 }); + await page.evaluate(() => { + return window.gltfPlugin.addModel(window.MOCKS.models.cubeBig); + }); + + await waitForReadiness(page); + await makeSnapshot(page, dirPath, 'plugin_options_no_modelsNearCameraFade'); + }); + + it('great modelsNearCameraFade', async () => { + await init(page, { styleZoom: 19.65, modelsNearCameraFade: 50000 }); + await page.evaluate(() => { + return window.gltfPlugin.addModel(window.MOCKS.models.cubeBig); + }); + + await waitForReadiness(page); + await makeSnapshot(page, dirPath, 'plugin_options_great_modelsNearCameraFade'); + }); + }); + + describe('minZoom, maxZoom', () => { + beforeEach(async () => { + await page.setViewport({ + width: 300, + height: 300, + }); + const center = [82.88454852999983, 54.904795707733356]; + await init(page, { + center, + styleZoom: 15.8, + rotation: 0, + pitch: 0, + minZoom: 16, + maxZoom: 18, + }); + await page.evaluate((coordinates) => { + return window.gltfPlugin.addModels([ + { ...window.MOCKS.models.cubeMid, coordinates }, + { ...window.MOCKS.models.palm, minZoom: 16.5, maxZoom: 17.25 }, + { ...window.MOCKS.models.pine, minZoom: 17, maxZoom: 17.5 }, + ]); + }, center); + await waitForReadiness(page); + }); + + it('no visible models', async () => { + await makeSnapshot( + page, + dirPath, + 'plugin_options_minZoom_maxZoom_no_visible_models', + ); + }); + + it('cube is only visible', async () => { + await page.evaluate(() => { + window.map.setStyleZoom(16.2, { animate: false }); + }); + await waitForReadiness(page); + await makeSnapshot(page, dirPath, 'plugin_options_minZoom_maxZoom_visible_cube'); + }); + + it('cube and palm are visible', async () => { + await page.evaluate(() => { + window.map.setStyleZoom(16.7, { animate: false }); + }); + await waitForReadiness(page); + await makeSnapshot( + page, + dirPath, + 'plugin_options_minZoom_maxZoom_visible_cube_and_palm', + ); + }); + + it('all models are visible', async () => { + await page.evaluate(() => { + window.map.setStyleZoom(17, { animate: false }); + }); + await waitForReadiness(page); + await makeSnapshot( + page, + dirPath, + 'plugin_options_minZoom_maxZoom_visible_all_models', + ); + }); + + it('cube and pine are visible', async () => { + await page.evaluate(() => { + window.map.setStyleZoom(17.4, { animate: false }); + }); + await waitForReadiness(page); + await makeSnapshot( + page, + dirPath, + 'plugin_options_minZoom_maxZoom_visible_cube_and_pine', + ); + }); + + it('cube is only visible again', async () => { + await page.evaluate(() => { + window.map.setStyleZoom(17.7, { animate: false }); + }); + await waitForReadiness(page); + await makeSnapshot( + page, + dirPath, + 'plugin_options_minZoom_maxZoom_visible_cube_again', + ); + }); + + it('all models are invisible', async () => { + await page.evaluate(() => { + window.map.setStyleZoom(18, { animate: false }); + }); + await waitForReadiness(page); + await makeSnapshot( + page, + dirPath, + 'plugin_options_minZoom_maxZoom_invisible_all_models', + ); + }); + }); + }); + describe('Realty scene', () => { beforeEach(async () => { await init(page, { @@ -233,7 +369,7 @@ describe('GltfPlugin', () => { it('The model does not disappear after changing the map style.', async () => { await init(page); await page.evaluate(() => { - return window.gltfPlugin.addModel(window.MOCKS.models.cubeBig); + return window.gltfPlugin.addModel(window.MOCKS.models.cubeMid); }); await page.evaluate((style) => { return (window.map as any).setStyle(style); diff --git a/test/test.d.ts b/test/test.d.ts index d549a9b..342cb7c 100644 --- a/test/test.d.ts +++ b/test/test.d.ts @@ -1,4 +1,5 @@ import type { Map } from '@2gis/mapgl/types'; +import { SinonSpy } from 'sinon'; import { GltfPlugin } from '../src'; import { MOCKS } from './mocks'; @@ -9,5 +10,6 @@ declare global { GltfPlugin: typeof GltfPlugin; ready: boolean; MOCKS: typeof MOCKS; + spy: SinonSpy; } } diff --git a/tsconfig.json b/tsconfig.json index 65094f7..ca0e49d 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,6 +1,6 @@ { "compilerOptions": { - "types": ["jest", "node"], + "types": ["jest", "node", "sinon"], "lib": ["dom", "es6"], "target": "es6", "module": "es6",