diff --git a/common/config/rush/pnpm-config.json b/common/config/rush/pnpm-config.json index f0fee158..dcaed3cd 100644 --- a/common/config/rush/pnpm-config.json +++ b/common/config/rush/pnpm-config.json @@ -89,10 +89,10 @@ * PNPM documentation: https://pnpm.io/package_json#pnpmoverrides */ "globalOverrides": { - // "@visactor/vrender": "0.21.2-vstory.2", - // "@visactor/vrender-core": "0.21.2-vstory.2", - // "@visactor/vrender-kits": "0.21.2-vstory.2", - // "@visactor/vrender-components": "0.21.2-vstory.2", + // "@visactor/vrender": "0.21.2-vstory.3", + // "@visactor/vrender-core": "0.21.2-vstory.3", + // "@visactor/vrender-kits": "0.21.2-vstory.3", + // "@visactor/vrender-components": "0.21.2-vstory.3", // "@visactor/vscale": "0.18.5" // "example2": "npm:@company/example2@^1.0.0" }, diff --git a/common/config/rush/pnpm-lock.yaml b/common/config/rush/pnpm-lock.yaml index 5f01b137..70be1323 100644 --- a/common/config/rush/pnpm-lock.yaml +++ b/common/config/rush/pnpm-lock.yaml @@ -138,13 +138,13 @@ importers: '@types/jest': ^26.0.0 '@types/react': ^18.0.0 '@types/react-dom': ^18.0.0 - '@visactor/vchart': 1.13.1-vstory.2 + '@visactor/vchart': 1.13.1-vstory.3 '@visactor/vchart-extension': 0.0.3-vstory.2 '@visactor/vdataset': ~0.18.17 - '@visactor/vrender': 0.21.2-vstory.2 - '@visactor/vrender-components': 0.21.2-vstory.2 - '@visactor/vrender-core': 0.21.2-vstory.2 - '@visactor/vrender-kits': 0.21.2-vstory.2 + '@visactor/vrender': 0.21.2-vstory.3 + '@visactor/vrender-components': 0.21.2-vstory.3 + '@visactor/vrender-core': 0.21.2-vstory.3 + '@visactor/vrender-kits': 0.21.2-vstory.3 '@visactor/vscale': ~0.18.17 '@visactor/vstory-core': workspace:0.0.19 '@visactor/vtable': 1.10.1 @@ -163,13 +163,13 @@ importers: typescript: 4.9.5 vite: 3.2.6 dependencies: - '@visactor/vchart': 1.13.1-vstory.2 + '@visactor/vchart': 1.13.1-vstory.3 '@visactor/vchart-extension': 0.0.3-vstory.2 '@visactor/vdataset': 0.18.18 - '@visactor/vrender': 0.21.2-vstory.2 - '@visactor/vrender-components': 0.21.2-vstory.2 - '@visactor/vrender-core': 0.21.2-vstory.2 - '@visactor/vrender-kits': 0.21.2-vstory.2 + '@visactor/vrender': 0.21.2-vstory.3 + '@visactor/vrender-components': 0.21.2-vstory.3 + '@visactor/vrender-core': 0.21.2-vstory.3 + '@visactor/vrender-kits': 0.21.2-vstory.3 '@visactor/vscale': 0.18.18 '@visactor/vstory-core': link:../vstory-core '@visactor/vtable': 1.10.1 @@ -213,13 +213,13 @@ importers: '@types/jest': ^26.0.0 '@types/react': ^18.0.0 '@types/react-dom': ^18.0.0 - '@visactor/vchart': 1.13.1-vstory.2 + '@visactor/vchart': 1.13.1-vstory.3 '@visactor/vchart-extension': 0.0.3-vstory.2 '@visactor/vdataset': ~0.18.17 - '@visactor/vrender': 0.21.2-vstory.2 - '@visactor/vrender-components': 0.21.2-vstory.2 - '@visactor/vrender-core': 0.21.2-vstory.2 - '@visactor/vrender-kits': 0.21.2-vstory.2 + '@visactor/vrender': 0.21.2-vstory.3 + '@visactor/vrender-components': 0.21.2-vstory.3 + '@visactor/vrender-core': 0.21.2-vstory.3 + '@visactor/vrender-kits': 0.21.2-vstory.3 '@visactor/vscale': ~0.18.17 '@visactor/vtable': 1.10.1 '@visactor/vutils': ~0.18.17 @@ -237,13 +237,13 @@ importers: typescript: 4.9.5 vite: 3.2.6 dependencies: - '@visactor/vchart': 1.13.1-vstory.2 + '@visactor/vchart': 1.13.1-vstory.3 '@visactor/vchart-extension': 0.0.3-vstory.2 '@visactor/vdataset': 0.18.18 - '@visactor/vrender': 0.21.2-vstory.2 - '@visactor/vrender-components': 0.21.2-vstory.2 - '@visactor/vrender-core': 0.21.2-vstory.2 - '@visactor/vrender-kits': 0.21.2-vstory.2 + '@visactor/vrender': 0.21.2-vstory.3 + '@visactor/vrender-components': 0.21.2-vstory.3 + '@visactor/vrender-core': 0.21.2-vstory.3 + '@visactor/vrender-kits': 0.21.2-vstory.3 '@visactor/vscale': 0.18.18 '@visactor/vtable': 1.10.1 '@visactor/vutils': 0.18.18 @@ -286,13 +286,13 @@ importers: '@types/jest': ^26.0.0 '@types/react': ^18.0.0 '@types/react-dom': ^18.0.0 - '@visactor/vchart': 1.13.1-vstory.2 + '@visactor/vchart': 1.13.1-vstory.3 '@visactor/vchart-extension': 0.0.3-vstory.2 '@visactor/vdataset': ~0.18.17 - '@visactor/vrender': 0.21.2-vstory.2 - '@visactor/vrender-components': 0.21.2-vstory.2 - '@visactor/vrender-core': 0.21.2-vstory.2 - '@visactor/vrender-kits': 0.21.2-vstory.2 + '@visactor/vrender': 0.21.2-vstory.3 + '@visactor/vrender-components': 0.21.2-vstory.3 + '@visactor/vrender-core': 0.21.2-vstory.3 + '@visactor/vrender-kits': 0.21.2-vstory.3 '@visactor/vscale': ~0.18.17 '@visactor/vstory-core': workspace:0.0.19 '@visactor/vtable': 1.10.1 @@ -311,13 +311,13 @@ importers: typescript: 4.9.5 vite: 3.2.6 dependencies: - '@visactor/vchart': 1.13.1-vstory.2 + '@visactor/vchart': 1.13.1-vstory.3 '@visactor/vchart-extension': 0.0.3-vstory.2 '@visactor/vdataset': 0.18.18 - '@visactor/vrender': 0.21.2-vstory.2 - '@visactor/vrender-components': 0.21.2-vstory.2 - '@visactor/vrender-core': 0.21.2-vstory.2 - '@visactor/vrender-kits': 0.21.2-vstory.2 + '@visactor/vrender': 0.21.2-vstory.3 + '@visactor/vrender-components': 0.21.2-vstory.3 + '@visactor/vrender-core': 0.21.2-vstory.3 + '@visactor/vrender-kits': 0.21.2-vstory.3 '@visactor/vscale': 0.18.18 '@visactor/vstory-core': link:../vstory-core '@visactor/vtable': 1.10.1 @@ -361,13 +361,13 @@ importers: '@types/jest': ^26.0.0 '@types/react': ^18.0.0 '@types/react-dom': ^18.0.0 - '@visactor/vchart': 1.13.1-vstory.2 + '@visactor/vchart': 1.13.1-vstory.3 '@visactor/vchart-extension': 0.0.3-vstory.2 '@visactor/vdataset': ~0.18.17 - '@visactor/vrender': 0.21.2-vstory.2 - '@visactor/vrender-components': 0.21.2-vstory.2 - '@visactor/vrender-core': 0.21.2-vstory.2 - '@visactor/vrender-kits': 0.21.2-vstory.2 + '@visactor/vrender': 0.21.2-vstory.3 + '@visactor/vrender-components': 0.21.2-vstory.3 + '@visactor/vrender-core': 0.21.2-vstory.3 + '@visactor/vrender-kits': 0.21.2-vstory.3 '@visactor/vscale': ~0.18.17 '@visactor/vstory-animate': workspace:0.0.19 '@visactor/vstory-core': workspace:0.0.19 @@ -388,13 +388,13 @@ importers: typescript: 4.9.5 vite: 3.2.6 dependencies: - '@visactor/vchart': 1.13.1-vstory.2 + '@visactor/vchart': 1.13.1-vstory.3 '@visactor/vchart-extension': 0.0.3-vstory.2 '@visactor/vdataset': 0.18.18 - '@visactor/vrender': 0.21.2-vstory.2 - '@visactor/vrender-components': 0.21.2-vstory.2 - '@visactor/vrender-core': 0.21.2-vstory.2 - '@visactor/vrender-kits': 0.21.2-vstory.2 + '@visactor/vrender': 0.21.2-vstory.3 + '@visactor/vrender-components': 0.21.2-vstory.3 + '@visactor/vrender-core': 0.21.2-vstory.3 + '@visactor/vrender-kits': 0.21.2-vstory.3 '@visactor/vscale': 0.18.18 '@visactor/vstory-animate': link:../vstory-animate '@visactor/vstory-core': link:../vstory-core @@ -440,13 +440,13 @@ importers: '@types/jest': ^26.0.0 '@types/react': ^18.0.0 '@types/react-dom': ^18.0.0 - '@visactor/vchart': 1.13.1-vstory.2 + '@visactor/vchart': 1.13.1-vstory.3 '@visactor/vchart-extension': 0.0.3-vstory.2 '@visactor/vdataset': ~0.18.17 - '@visactor/vrender': 0.21.2-vstory.2 - '@visactor/vrender-components': 0.21.2-vstory.2 - '@visactor/vrender-core': 0.21.2-vstory.2 - '@visactor/vrender-kits': 0.21.2-vstory.2 + '@visactor/vrender': 0.21.2-vstory.3 + '@visactor/vrender-components': 0.21.2-vstory.3 + '@visactor/vrender-core': 0.21.2-vstory.3 + '@visactor/vrender-kits': 0.21.2-vstory.3 '@visactor/vscale': ~0.18.17 '@visactor/vstory-animate': workspace:0.0.19 '@visactor/vstory-core': workspace:0.0.19 @@ -466,13 +466,13 @@ importers: typescript: 4.9.5 vite: 3.2.6 dependencies: - '@visactor/vchart': 1.13.1-vstory.2 + '@visactor/vchart': 1.13.1-vstory.3 '@visactor/vchart-extension': 0.0.3-vstory.2 '@visactor/vdataset': 0.18.18 - '@visactor/vrender': 0.21.2-vstory.2 - '@visactor/vrender-components': 0.21.2-vstory.2 - '@visactor/vrender-core': 0.21.2-vstory.2 - '@visactor/vrender-kits': 0.21.2-vstory.2 + '@visactor/vrender': 0.21.2-vstory.3 + '@visactor/vrender-components': 0.21.2-vstory.3 + '@visactor/vrender-core': 0.21.2-vstory.3 + '@visactor/vrender-kits': 0.21.2-vstory.3 '@visactor/vscale': 0.18.18 '@visactor/vstory-animate': link:../vstory-animate '@visactor/vstory-core': link:../vstory-core @@ -517,13 +517,13 @@ importers: '@types/jest': ^26.0.0 '@types/react': ^18.0.0 '@types/react-dom': ^18.0.0 - '@visactor/vchart': 1.13.1-vstory.2 + '@visactor/vchart': 1.13.1-vstory.3 '@visactor/vchart-extension': 0.0.3-vstory.2 '@visactor/vdataset': ~0.18.17 - '@visactor/vrender': 0.21.2-vstory.2 - '@visactor/vrender-components': 0.21.2-vstory.2 - '@visactor/vrender-core': 0.21.2-vstory.2 - '@visactor/vrender-kits': 0.21.2-vstory.2 + '@visactor/vrender': 0.21.2-vstory.3 + '@visactor/vrender-components': 0.21.2-vstory.3 + '@visactor/vrender-core': 0.21.2-vstory.3 + '@visactor/vrender-kits': 0.21.2-vstory.3 '@visactor/vscale': ~0.18.17 '@visactor/vstory-core': workspace:0.0.19 '@visactor/vtable': 1.10.1 @@ -542,13 +542,13 @@ importers: typescript: 4.9.5 vite: 3.2.6 dependencies: - '@visactor/vchart': 1.13.1-vstory.2 + '@visactor/vchart': 1.13.1-vstory.3 '@visactor/vchart-extension': 0.0.3-vstory.2 '@visactor/vdataset': 0.18.18 - '@visactor/vrender': 0.21.2-vstory.2 - '@visactor/vrender-components': 0.21.2-vstory.2 - '@visactor/vrender-core': 0.21.2-vstory.2 - '@visactor/vrender-kits': 0.21.2-vstory.2 + '@visactor/vrender': 0.21.2-vstory.3 + '@visactor/vrender-components': 0.21.2-vstory.3 + '@visactor/vrender-core': 0.21.2-vstory.3 + '@visactor/vrender-kits': 0.21.2-vstory.3 '@visactor/vscale': 0.18.18 '@visactor/vstory-core': link:../vstory-core '@visactor/vtable': 1.10.1 @@ -3720,24 +3720,24 @@ packages: '@visactor/vutils': 0.18.18 dev: false - /@visactor/vchart/1.13.1-vstory.2: - resolution: {integrity: sha512-c4/6IOYiK+TiBvMTQnxNCtmi1tDiHk7avaNT1MSclJYYuyRKs4Kg7gsV7ENn8uuUXgb2eJCSwcmBMGxFY5Ns8w==} + /@visactor/vchart/1.13.1-vstory.3: + resolution: {integrity: sha512-15IDx6VH1W9PHCUbQiYEZSiS5kIIP0VxgBCV65A7pGj61+QXCJBfTpjQmxthrfeUo5dQa4FAy3TY8tlw/7161g==} dependencies: '@visactor/vdataset': 0.19.2 - '@visactor/vgrammar-core': 0.15.1-vstory.2 - '@visactor/vgrammar-hierarchy': 0.15.1-vstory.2 - '@visactor/vgrammar-projection': 0.15.1-vstory.2 - '@visactor/vgrammar-sankey': 0.15.1-vstory.2 - '@visactor/vgrammar-util': 0.15.1-vstory.2 - '@visactor/vgrammar-venn': 0.15.1-vstory.2 - '@visactor/vgrammar-wordcloud': 0.15.1-vstory.2 - '@visactor/vgrammar-wordcloud-shape': 0.15.1-vstory.2 - '@visactor/vrender-components': 0.21.2-vstory.2 - '@visactor/vrender-core': 0.21.2-vstory.2 - '@visactor/vrender-kits': 0.21.2-vstory.2 + '@visactor/vgrammar-core': 0.15.1-vstory.3 + '@visactor/vgrammar-hierarchy': 0.15.1-vstory.3 + '@visactor/vgrammar-projection': 0.15.1-vstory.3 + '@visactor/vgrammar-sankey': 0.15.1-vstory.3 + '@visactor/vgrammar-util': 0.15.1-vstory.3 + '@visactor/vgrammar-venn': 0.15.1-vstory.3 + '@visactor/vgrammar-wordcloud': 0.15.1-vstory.3 + '@visactor/vgrammar-wordcloud-shape': 0.15.1-vstory.3 + '@visactor/vrender-components': 0.21.2-vstory.3 + '@visactor/vrender-core': 0.21.2-vstory.3 + '@visactor/vrender-kits': 0.21.2-vstory.3 '@visactor/vscale': 0.19.2 '@visactor/vutils': 0.19.2 - '@visactor/vutils-extension': 1.13.1-vstory.2 + '@visactor/vutils-extension': 1.13.1-vstory.3 dev: false /@visactor/vdataset/0.18.18: @@ -3784,90 +3784,90 @@ packages: topojson-client: 3.1.0 dev: false - /@visactor/vgrammar-coordinate/0.15.1-vstory.2: - resolution: {integrity: sha512-eQwqzbtosfjrmoCRrSSOaI7Dp0KFmrnu7M490PVwSSiWEKOAsgjRZxKFRB5x9w0SvKOLR7eUnlW8zNDXod1BLg==} + /@visactor/vgrammar-coordinate/0.15.1-vstory.3: + resolution: {integrity: sha512-VLBaOytdBLBfvXZRewWme+AYMKNOpOrri/citrf5oHhSf3/z3raMkpzYh1nNCaSu2jty9Yz1Ax9jNaIDQOTVqA==} dependencies: - '@visactor/vgrammar-util': 0.15.1-vstory.2 + '@visactor/vgrammar-util': 0.15.1-vstory.3 '@visactor/vutils': 0.19.2 dev: false - /@visactor/vgrammar-core/0.15.1-vstory.2: - resolution: {integrity: sha512-LwJCG1TVcZBwHp4Au4YDufEJCAVKmiaFlNEq/Y0rJaz6lwg2qbsc9mgpoCt7vzykm+tT86wohsQC+O+q2/ABbA==} + /@visactor/vgrammar-core/0.15.1-vstory.3: + resolution: {integrity: sha512-7NLbQFEbgGILg4xi1htOyQXoImkdfMcFsv47RvXeYK1YBa3+3gG3FMHi8ppS49uNpQxj3rVdTORTmG7LA1e3YQ==} dependencies: '@visactor/vdataset': 0.19.2 - '@visactor/vgrammar-coordinate': 0.15.1-vstory.2 - '@visactor/vgrammar-util': 0.15.1-vstory.2 - '@visactor/vrender-components': 0.21.2-vstory.2 - '@visactor/vrender-core': 0.21.2-vstory.2 - '@visactor/vrender-kits': 0.21.2-vstory.2 + '@visactor/vgrammar-coordinate': 0.15.1-vstory.3 + '@visactor/vgrammar-util': 0.15.1-vstory.3 + '@visactor/vrender-components': 0.21.2-vstory.3 + '@visactor/vrender-core': 0.21.2-vstory.3 + '@visactor/vrender-kits': 0.21.2-vstory.3 '@visactor/vscale': 0.19.2 '@visactor/vutils': 0.19.2 dev: false - /@visactor/vgrammar-hierarchy/0.15.1-vstory.2: - resolution: {integrity: sha512-6GP0hJydjA5QUFtioP4ObgLf0cQIefV3Tx+Fx86CJXbtA6DK+v9PC6BSw/9ZkI0qyHKH83IQXI2Ii6HSmTrSaw==} + /@visactor/vgrammar-hierarchy/0.15.1-vstory.3: + resolution: {integrity: sha512-X59lGl3kedC4gjIOsyLaJggpkQcNmyRqTSnOmZJYsdzKYU8tHbEYE9q9fXT00+McI2K0pM7L4Fy/XuyeU1XmGQ==} dependencies: - '@visactor/vgrammar-core': 0.15.1-vstory.2 - '@visactor/vgrammar-util': 0.15.1-vstory.2 - '@visactor/vrender-core': 0.21.2-vstory.2 - '@visactor/vrender-kits': 0.21.2-vstory.2 + '@visactor/vgrammar-core': 0.15.1-vstory.3 + '@visactor/vgrammar-util': 0.15.1-vstory.3 + '@visactor/vrender-core': 0.21.2-vstory.3 + '@visactor/vrender-kits': 0.21.2-vstory.3 '@visactor/vutils': 0.19.2 dev: false - /@visactor/vgrammar-projection/0.15.1-vstory.2: - resolution: {integrity: sha512-dy0YKyHV8qB+uXBwrQOzs4cqK/eGY6zdwfWP5NZniDv5kmvsycxMrK565S3Y5YZAsxXMVN4vwDtVabT3B3TnVg==} + /@visactor/vgrammar-projection/0.15.1-vstory.3: + resolution: {integrity: sha512-LxJMb2Ak7Ev1w3FNI/yQzbacrmkfx8oiv2K+EaWrFgn+/IXiZRZ1g8FTR0LL4PL/1b2KoBZIDbRg/9w042MYGQ==} dependencies: - '@visactor/vgrammar-core': 0.15.1-vstory.2 - '@visactor/vgrammar-util': 0.15.1-vstory.2 + '@visactor/vgrammar-core': 0.15.1-vstory.3 + '@visactor/vgrammar-util': 0.15.1-vstory.3 '@visactor/vutils': 0.19.2 d3-geo: 1.12.1 dev: false - /@visactor/vgrammar-sankey/0.15.1-vstory.2: - resolution: {integrity: sha512-24Cvog0F34nEepcv3PSEWPCJ+GxpMWFeBloLX/oD2LE/uX3CCTzRtnyp5zH9PgRW/wquGPjt3/+52R+dJF7olQ==} + /@visactor/vgrammar-sankey/0.15.1-vstory.3: + resolution: {integrity: sha512-Yfm9jK1xApxduWKE/Y1Pn1Yj64NPuOuq5gCk/dMq+xej83TH+H3nzXqpbspQoUz2+e8SHvwS62Uqf5l+I1mq7Q==} dependencies: - '@visactor/vgrammar-core': 0.15.1-vstory.2 - '@visactor/vgrammar-util': 0.15.1-vstory.2 - '@visactor/vrender-core': 0.21.2-vstory.2 - '@visactor/vrender-kits': 0.21.2-vstory.2 + '@visactor/vgrammar-core': 0.15.1-vstory.3 + '@visactor/vgrammar-util': 0.15.1-vstory.3 + '@visactor/vrender-core': 0.21.2-vstory.3 + '@visactor/vrender-kits': 0.21.2-vstory.3 '@visactor/vutils': 0.19.2 dev: false - /@visactor/vgrammar-util/0.15.1-vstory.2: - resolution: {integrity: sha512-dm1hC3bX0zyOa1QeocIDxlidQIPBox+acxfkN0Y2cw+6UZewk5VwBGpE4HH4boQyR92qX/jbQVe1dAqfkxrAeQ==} + /@visactor/vgrammar-util/0.15.1-vstory.3: + resolution: {integrity: sha512-fods7zFVNiGZiQeTJO1uIuZQq2QHy9ea33b44r70u3SCjGtKWRinISZqrzazeb5YHWLE0+XXU4/1MGPSqKlMmg==} dependencies: - '@visactor/vrender-core': 0.21.2-vstory.2 + '@visactor/vrender-core': 0.21.2-vstory.3 '@visactor/vutils': 0.19.2 dev: false - /@visactor/vgrammar-venn/0.15.1-vstory.2: - resolution: {integrity: sha512-9PJTuDazSvwbiHvVmzPXvTcQlJ0t6Z+u2s/S4ka3/LuX7TXIn8lCb2Ry0vxZiyE9vsQDfDq9Njqgexp2FEE9yg==} + /@visactor/vgrammar-venn/0.15.1-vstory.3: + resolution: {integrity: sha512-6oHKsFt9XWc8XHRzAojvrO6y4TwNop6tgtEhZtlhbyZ2Flv47bIUl1CUqiBFQ36XSWY6nt4Z23ufN8l38buptg==} dependencies: - '@visactor/vgrammar-core': 0.15.1-vstory.2 - '@visactor/vgrammar-util': 0.15.1-vstory.2 - '@visactor/vrender-core': 0.21.2-vstory.2 - '@visactor/vrender-kits': 0.21.2-vstory.2 + '@visactor/vgrammar-core': 0.15.1-vstory.3 + '@visactor/vgrammar-util': 0.15.1-vstory.3 + '@visactor/vrender-core': 0.21.2-vstory.3 + '@visactor/vrender-kits': 0.21.2-vstory.3 '@visactor/vutils': 0.19.2 dev: false - /@visactor/vgrammar-wordcloud-shape/0.15.1-vstory.2: - resolution: {integrity: sha512-h+mdeb/drJZUxIBDxOHs2NPFC3pycl7GgxtxVohnu6TJQDLOHxk4/MANQHSgte3EY4z77WuHJKsLwWMwanBrVg==} + /@visactor/vgrammar-wordcloud-shape/0.15.1-vstory.3: + resolution: {integrity: sha512-b8cignTZN10WxiRH3zlucZjOOzN8mYSqTJm2WCBsmVF++qIgFYYr6sSAdyNILxdC8F2hiIwUHC0SJ3+vGE344Q==} dependencies: - '@visactor/vgrammar-core': 0.15.1-vstory.2 - '@visactor/vgrammar-util': 0.15.1-vstory.2 - '@visactor/vrender-core': 0.21.2-vstory.2 - '@visactor/vrender-kits': 0.21.2-vstory.2 + '@visactor/vgrammar-core': 0.15.1-vstory.3 + '@visactor/vgrammar-util': 0.15.1-vstory.3 + '@visactor/vrender-core': 0.21.2-vstory.3 + '@visactor/vrender-kits': 0.21.2-vstory.3 '@visactor/vscale': 0.19.2 '@visactor/vutils': 0.19.2 dev: false - /@visactor/vgrammar-wordcloud/0.15.1-vstory.2: - resolution: {integrity: sha512-G/zjVhnYUxnWTX59ueTM2n9J2Bh7mtDJ4FmHwcIW8NC9m45stS+XEfRNR7Io4UgHEJUZyBd/tcoaWjPPKNkdag==} + /@visactor/vgrammar-wordcloud/0.15.1-vstory.3: + resolution: {integrity: sha512-UVd0Hh65FTC3Yhy5Btp2lF1QfY6A+ehqf7NMQmcC3nu4ORcx2YoQJAeFYE+7BmUX9XCEAfKkS6mPKWRe9cFU5g==} dependencies: - '@visactor/vgrammar-core': 0.15.1-vstory.2 - '@visactor/vgrammar-util': 0.15.1-vstory.2 - '@visactor/vrender-core': 0.21.2-vstory.2 - '@visactor/vrender-kits': 0.21.2-vstory.2 + '@visactor/vgrammar-core': 0.15.1-vstory.3 + '@visactor/vgrammar-util': 0.15.1-vstory.3 + '@visactor/vrender-core': 0.21.2-vstory.3 + '@visactor/vrender-kits': 0.21.2-vstory.3 '@visactor/vutils': 0.19.2 dev: false @@ -3880,11 +3880,11 @@ packages: '@visactor/vutils': 0.18.18 dev: false - /@visactor/vrender-components/0.21.2-vstory.2: - resolution: {integrity: sha512-yJtw+JEPn8gOl9ycMoGSG61xONIF1Bsk1NdQZNgLj/wcKETdYkQE/Eo6612ViM+4aGd3O5Vqtnz1sViJX+oM3w==} + /@visactor/vrender-components/0.21.2-vstory.3: + resolution: {integrity: sha512-9tpEUsTedESg6h5XSAOFcmqxP/sMbkxIqPmWwZVJreoFxUp+qjMSuUMCSpd1Bvdc3+LiMmI5hR+JTK0jpzDCdg==} dependencies: - '@visactor/vrender-core': 0.21.2-vstory.2 - '@visactor/vrender-kits': 0.21.2-vstory.2 + '@visactor/vrender-core': 0.21.2-vstory.3 + '@visactor/vrender-kits': 0.21.2-vstory.3 '@visactor/vscale': 0.19.2 '@visactor/vutils': 0.19.2 dev: false @@ -3903,8 +3903,8 @@ packages: color-convert: 2.0.1 dev: false - /@visactor/vrender-core/0.21.2-vstory.2: - resolution: {integrity: sha512-Iw0b85qp6v9uT5pXpx2TlCWXEkYqX2fOsT/A2dku9LAw6DBpP85MJn9pxR7JjRPyxc2XF6+8AYlozwFUV18IxQ==} + /@visactor/vrender-core/0.21.2-vstory.3: + resolution: {integrity: sha512-YMR/fExUZgr6/E7e0V9OzvoJVd9A6rfQLtcoXI1QL8SfO19+lR9tRpRq20qQoRgfV5A+rxel/dPEHrvxclq49g==} dependencies: '@visactor/vutils': 0.19.2 color-convert: 2.0.1 @@ -3929,21 +3929,21 @@ packages: roughjs: 4.5.2 dev: false - /@visactor/vrender-kits/0.21.2-vstory.2: - resolution: {integrity: sha512-qGJhcRDj2qGnO4D5vWJuCkhW+J/7uajwn6QmVc/av1PLgwxJVUKBvUzriES7816/szY9dZXxUnWUFRNFpkVFCg==} + /@visactor/vrender-kits/0.21.2-vstory.3: + resolution: {integrity: sha512-mWYClwyIWOMzMLJFVNJrKrks5fr3yeNrNEF0twRyOaDtHRxKsJBSyeshum2MZJd3YA0fFiYvTEX6BscfthRhAg==} dependencies: '@resvg/resvg-js': 2.4.1 - '@visactor/vrender-core': 0.21.2-vstory.2 + '@visactor/vrender-core': 0.21.2-vstory.3 '@visactor/vutils': 0.19.2 lottie-web: 5.12.2 roughjs: 4.5.2 dev: false - /@visactor/vrender/0.21.2-vstory.2: - resolution: {integrity: sha512-b/CaoWVFU9es6/tVV9dUYZkpsS6V1Jtlb9yvO+k8YLwJnUfp3OSBFWqd3b6ttGZwmNl4lUi+fG+aJ24D1N88yQ==} + /@visactor/vrender/0.21.2-vstory.3: + resolution: {integrity: sha512-my+sLFDzBFGojPrgvktjunNEzqfZXsQEwlx+Srn5d7CLjQbrpB46JTwOu56I1ORKGe314hrsynbfGAuWyM0lCg==} dependencies: - '@visactor/vrender-core': 0.21.2-vstory.2 - '@visactor/vrender-kits': 0.21.2-vstory.2 + '@visactor/vrender-core': 0.21.2-vstory.3 + '@visactor/vrender-kits': 0.21.2-vstory.3 dev: false /@visactor/vscale/0.18.18: @@ -3983,8 +3983,8 @@ packages: '@visactor/vutils': 0.18.18 dev: false - /@visactor/vutils-extension/1.13.1-vstory.2: - resolution: {integrity: sha512-tKlJk+FfxSpl+l+a7CIX09sdMvdRd+Bxh1jY1/pXChiuAMIwpbqYWkDan0WHYZRdMpNMmeDkeGqRU7V9SaVT0Q==} + /@visactor/vutils-extension/1.13.1-vstory.3: + resolution: {integrity: sha512-+sNToW0zqMyrQRsd7CDWSc4uuDXk86z8VOdI4UfsCxxCFJhuK4oBN+dkzZ8o71MIi36uLSRjnQzk0UrW3qo7xA==} dependencies: '@visactor/vdataset': 0.19.2 '@visactor/vutils': 0.19.2 diff --git a/docs/assets/examples/en/works-show/national-memorial.md b/docs/assets/examples/en/works-show/national-memorial.md new file mode 100644 index 00000000..9f2e3ab7 --- /dev/null +++ b/docs/assets/examples/en/works-show/national-memorial.md @@ -0,0 +1,1600 @@ +--- +category: examples +group: works-show +title: national-memorial +keywords: national-memorial +order: 1-0 +cover: https://lf9-dp-fe-cms-tos.byteorg.com/obj/bit-cloud/vstory/national-memorial.png +--- + +# `National Memorial` Works Showcase + +Remember history, cherish peace + +## Code Demo + +```javascript livedemo template=vstory +// 注册所有需要的内容 +VStory.registerAll(); + +// 2018 http://www.81.cn/2018njdts81zn/2018-12/12/content_9376268.htm +// 2019 http://www.legaldaily.com.cn/gallery/content/2019-12/13/content_8073861.html +// 2020 https://photo.cctv.com/2020/12/12/PHOA4uUqqopn5Ya9eDCu8u7U201212.shtml#O0RgZnlNmfkz201212_1 +// 2021 http://www.news.cn/politics/2021-12/12/c_1128156191.htm +// 2022 http://www.news.cn/photo/2022-12/12/c_1129202736_2.htm +// 2023 http://www.mod.gov.cn/gfbw/gfjy_index/16272859.html +// 2024 https://www.news.cn/photo/20241212/bbf958bbe701456c9c259612d2db0f6c/c.html?page=1 +const data = [ + { + name: "孙富祥", + year: [] + }, + { + name: "管光镜", + year: [] + }, + { + name: "祝四孜", + year: [] + }, + { + name: "刘庭玉", + year: [] + }, + { + name: "陈玉兰", + year: [] + }, + { + name: "李素芬", + year: [] + }, + { + name: "易翠兰", + year: [] + }, + { + name: "李素云", + year: [] + }, + { + name: "吕金宝", + year: [] + }, + { + name: "陈广顺", + year: [] + }, + { + name: "顾秀兰", + year: [] + }, + { + name: "沈淑静", + year: [] + }, + { + name: "赵金华", + year: [] + }, + { + name: "李高山", + year: [] + }, + { + name: "王秀英", + year: [] + }, + { + name: "张秀红", + year: [] + }, + { + name: "马淑勤", + year: [] + }, + { + name: "林玉红", + year: [] + }, + { + name: "张福智", + year: [] + }, + { + name: "沈桂英", + year: [] + }, + { + name: "张兰英", + year: [] + }, + { + name: "仇秀英", + year: [] + }, + { + name: "王翠英", + year: [] + }, + { + name: "佘子清", + year: [] + }, + { + name: '马秀英', + year: [2018, 2019, 2020] + }, + { + name: '濮业良', + year: [2018, 2019, 2020, 2021] + }, + { + name: '马继武', + year: [2018, 2019, 2020] + }, + { + name: '王义隆', + year: [2018, 2019, 2020, 2021, 2022, 2023, 2024] + }, + { + name: '王长发', + year: [2018, 2019, 2020, 2021, 2022] + }, + { + name: '蒋淑萍', + year: [2018, 2019] + }, + { + name: '薛玉娟', + year: [2018, 2019, 2020, 2021, 2022, 2023, 2024] + }, + { + name: '巫吉英', + year: [2018, 2019, 2020, 2021] + }, + { + name: '谢桂英', + year: [2018, 2019, 2020, 2021, 2022, 2023, 2024] + }, + { + name: '黄桂兰', + year: [2018, 2019, 2020, 2021, 2022, 2023, 2024] + }, + { + name: '岑洪桂', + year: [2018, 2019, 2020, 2021, 2022, 2023, 2024] + }, + { + name: '陈桂香', + year: [2018, 2019, 2020, 2021, 2022, 2023] + }, + { + name: '徐家庆', + year: [2018, 2019, 2020] + }, + { + name: '杨翠英', + year: [2018, 2019, 2020] + }, + { + name: '黄刘氏', + year: [2018, 2019, 2020] + }, + { + name: '关舜华', + year: [2018, 2019, 2020, 2021, 2022, 2023, 2024] + }, + { + name: '陈文英', + year: [2018, 2019, 2020] + }, + { + name: '周智林', + year: [2018, 2019, 2020, 2021, 2022, 2023] + }, + { + name: '蔡丽华', + year: [2018, 2019, 2020] + }, + { + name: '魏桂如', + year: [2018, 2019, 2020, 2021, 2022, 2023, 2024] + }, + { + name: '易兰英', + year: [2018, 2019, 2020, 2021, 2022, 2023, 2024] + }, + { + name: '石秀英', + year: [2018, 2019, 2020, 2021, 2022, 2023] + }, + { + name: '高恒发', + year: [2018, 2019, 2020, 2021, 2022] + }, + { + name: '王福义', + year: [2018] + }, + { + name: '李美兰', + year: [2018, 2019, 2020, 2021, 2022] + }, + { + name: '葛道荣', + year: [2018, 2019, 2020, 2021, 2022] + }, + { + name: '马月华', + year: [2018] + }, + { + name: '李长富', + year: [2018, 2019, 2020, 2021, 2022, 2023, 2024] + }, + { + name: '余昌祥', + year: [2018, 2019, 2020, 2021] + }, + { + name: '金茂芝', + year: [2018] + }, + { + name: '常志强', + year: [2018, 2019, 2020, 2021, 2022] + }, + { + name: '郑锦阳', + year: [2018, 2019, 2020, 2021, 2022] + }, + { + name: '万秀英', + year: [2018] + }, + { + name: '艾义英', + year: [2018, 2019, 2020, 2021, 2022, 2023, 2024] + }, + { + name: '龚德年', + year: [2018, 2019, 2020, 2021, 2022, 2023, 2024] + }, + { + name: '向远松', + year: [2018, 2019, 2020, 2021] + }, + { + name: '朱惟平', + year: [2018] + }, + { + name: '经智珍', + year: [2018, 2019, 2020, 2021, 2022, 2023, 2024] + }, + { + name: '朱秀英', + year: [2018, 2019] + }, + { + name: '贺孝和', + year: [2018, 2019, 2020] + }, + { + name: '陈素华', + year: [2018] + }, + { + name: '夏淑琴', + year: [2018, 2019, 2020, 2021, 2022, 2023, 2024] + }, + { + name: '杨静秋', + year: [2018, 2019, 2020, 2021, 2022] + }, + { + name: '张惠霞', + year: [2018, 2019, 2020, 2021, 2022] + }, + { + name: '周湘萍', + year: [2018, 2019, 2020, 2021, 2022] + }, + { + name: '蒋树珍', + year: [2018, 2019, 2020, 2021, 2022, 2023, 2024] + }, + { + name: '徐德明', + year: [2018, 2019, 2020, 2021, 2022, 2023, 2024] + }, + { + name: '刘贵祥', + year: [2018, 2019, 2020, 2021, 2022, 2023, 2024] + }, + { + name: '郭林大', + year: [2018, 2019, 2020, 2021, 2022] + }, + { + name: '张仕翔', + year: [2018, 2019, 2020, 2021, 2022] + }, + { + name: '马承年', + year: [2018] + }, + { + name: '姚秀英', + year: [2018, 2019] + }, + { + name: '王津', + year: [2018, 2019, 2020, 2021, 2022] + }, + { + name: '熊淑兰', + year: [2018, 2019, 2020, 2021, 2022, 2023, 2024] + }, + { + name: '刘素珍', + year: [2018, 2019, 2020, 2021, 2022, 2023] + }, + { + name: '潘巧英', + year: [2018, 2019, 2020, 2021, 2022, 2023, 2024] + }, + { + name: '郭秀兰', + year: [2018, 2019, 2020, 2021, 2022, 2023, 2024] + }, + { + name: '祝再强', + year: [2018, 2019, 2020, 2021] + }, + { + name: '陈德寿', + year: [2018, 2019, 2020, 2021, 2022, 2023, 2024] + }, + { + name: '王子华', + year: [2018, 2019, 2020, 2021, 2022, 2023, 2024] + }, + { + name: '程福保', + year: [2018, 2019, 2020, 2021, 2022, 2023] + }, + { + name: '伍秀英', + year: [2018, 2019, 2020, 2021, 2022, 2023, 2024] + }, + { + name: '路洪才', + year: [2018, 2019, 2020, 2021, 2022, 2023, 2024] + }, + { + name: '阮秀英', + year: [2018, 2019, 2020, 2021, 2022] + }, + { + name: '高如琴', + year: [2018, 2019, 2020, 2021, 2022, 2023] + }, + { + name: '马庭禄', + year: [2018, 2019, 2020, 2021, 2022] + }, + { + name: '袁桂龙', + year: [2018, 2019, 2020, 2021, 2022] + }, + { + name: '岑洪兰', + year: [2018, 2019, 2020, 2021, 2022, 2023, 2024] + }, + { + name: '刘民生', + year: [2018, 2019, 2020, 2021, 2022, 2023, 2024] + }, + { + name: '方素霞', + year: [2018, 2019, 2020, 2021, 2022, 2023, 2024] + }, + { + name: '唐复龙', + year: [2018, 2019, 2020, 2021, 2022, 2023, 2024] + }, + { + name: '刘兴铭', + year: [2018] + }, + { + name: '王素明', + year: [2018, 2019, 2020, 2021] + }, + { + name: '程文英', + year: [2018, 2019, 2020, 2021, 2022, 2023, 2024] + }, + { + name: '马庭宝', + year: [2018, 2019, 2020, 2021, 2022, 2023, 2024] + }, + { + name: '陶承义', + year: [2018, 2019, 2020, 2021, 2022, 2023, 2024] + }, + { + name: '傅兆增', + year: [2018, 2019, 2020] + }, + { + name: '阮定东', + year: [2018, 2019, 2020, 2021, 2022, 2023, 2024] + }, + { + name: '苏承祺', + year: [2018, 2019, 2020, 2021, 2022] + }, + { + name: '周文彬', + year: [2018, 2019, 2020, 2021, 2022, 2023, 2024] + } +]; + +const data2018 = data.map(item => ({ ...item, death: !item.year.includes(2018), value: 100 })); +const data2019 = data.map(item => ({ ...item, death: !item.year.includes(2019), value: 100 })); +const data2020 = data.map(item => ({ ...item, death: !item.year.includes(2020), value: 100 })); +const data2021 = data.map(item => ({ ...item, death: !item.year.includes(2021), value: 100 })); +const data2022 = data.map(item => ({ ...item, death: !item.year.includes(2022), value: 100 })); +const data2023 = data.map(item => ({ ...item, death: !item.year.includes(2023), value: 100 })); +const data2024 = data.map(item => ({ ...item, death: !item.year.includes(2024), value: 100 })); + +const names = [ + '佘培庚', + '张华亮', + '刘茂清', + '刘茂源', + '易周氏', + '崔正桂', + '殷玉汉', + '夏赵氏', + '吴三根', + '姚小姗', + '苏义华', + '李秀华', + '杨福杨', + '刘寿金', + '夏路氏', + '刘贵宝', + '刘文光', + '炒文迎', + '刘寿银', + '徐江氏', + '徐带娣', + '徐毛七', + '徐兆荣', + '徐吕氏', + '戎金寿', + '戎陈氏', + '赵民', + '商广礼', + '方正廉', + '冯永渭', + '傅锦山', + '高恒保', + '高祁氏:', + '高庆浩', + '方志山', + '冯兴棠', + '傅克忠', + '高恒法', + '宵瑞伯', + '高流渊', + '方子友', + '傅奎年', + '高恒云', + '费长华', + '冯学才', + '傅理奇', + '殷玉汉', + '孙道树', + '王阿富', + '汪江氏', + '朱庭财', + '张外三', + '朱启兴', + '石永祥', + '谢道清', + '周庆财', + '卞朝镛', + '刘永贵', + '杨嘉敬', + '王长富', + '孙俊武', + '梁传炳', + '许泽林', + '王家龄', + '郭声楠', + '朱瑞庭', + '任自先', + '韩德顺', + '张桥生', + '朱文泉', + '白庆增', + '吴少洪', + '汪世清', + '钱延模', + '韩少停', + '张济山', + '汪四盲', + '王进财', + '小九子', + '徐良生', + '你孝文', + '许嘉盛', + '韦明发', + '小扣子', + '徐长喜', + '徐金尧', + '王逵昆', + '徐京生', + '徐辛氏', + '许嘉兴', + '汪太炳', + '魏大', + '徐长银', + '徐新潮', + '王老九', + '小来子', + '徐俊田', + '许江生', + '魏丙昆', + '徐长英', + '徐兴祥', + '汪汪氏', + '小六子', + '徐昆发', + '许老汉', + '徐成春', + '徐徐氏', + '徐老三', + '许老太', + '汪小掌', + '徐成林', + '徐宣氏', + '徐老四', + '许老五', + '徐丫头', + '徐成要', + '许礼和', + '汪兴德' +]; + +const aliveSpec = { + type: 'wordCloud', + background: 'transparent', + fontSizeRange: [18, 18], + random: false, + nameField: 'name', + valueField: 'value', + seriesField: 'name', + animationAppear: false, + // maskShape: { + // type: 'text', + // text: text, + // fill: 'red', + // fontWeight: 'bolder' + // }, + // animationAppear: false, + // wordMask: { + // visible: false, + // style: { + // backgroundOpacity: 0 + // } + // }, + word: { + style: { + fill: 'white', + opacity: (datum) => (datum.death ? 0.2 : 1), + fontWeight: 'bolder' + } + } +}; + +const spec = (text) => ({ + type: 'wordCloud', + background: 'transparent', + fontSizeRange: [6, 12], + random: false, + nameField: 'name', + valueField: 'value', + seriesField: 'name', + maskShape: { + type: 'text', + text: text, + fill: 'red', + fontWeight: 'bolder' + }, + // animationAppear: false, + wordMask: { + visible: false, + style: { + backgroundOpacity: 0 + } + }, + word: { + style: { + fill: 'white', + // opacity: (datum: any) => (datum.death ? 0.2 : 1), + fontWeight: 'bolder' + } + } +}); + +// function merge(target, source) { +// // 确保目标是一个对象 +// if (typeof target !== 'object' || target === null) { +// target = {}; +// } + +// // 遍历源对象的每个属性 +// for (const key in source) { +// if (source.hasOwnProperty(key)) { +// const value = source[key]; + +// // 如果值是对象,则递归合并 +// if (typeof value === 'object' && value !== null) { +// // 如果目标对象中没有这个键,初始化为一个空对象 +// if (!target[key]) { +// target[key] = Array.isArray(value) ? [] : {}; +// } +// // 递归调用 +// merge(target[key], value); +// } else { +// // 直接赋值 +// target[key] = value; +// } +// } +// } + +// return target; +// } + +const merge = VStory.VUtils.merge; + +const width = 1280 / 2; +const height = 1960 / 2; +const defaultAppearAction = { + action: 'appear', + payload: { + animation: { + duration: 1000, + easing: 'linear' + } + } +}; +const defaultDisappearAction = (startTime, duration = 1000) => { + return { + action: 'disappear', + startTime, + payload: { + animation: { + duration, + easing: 'linear' + } + } + }; +}; +const moveInEasing = VStory.generatorPathEasingFunc('M0,0,C0.46,0,0.496,0.014,0.616,0.088,0.734,0.161,0.884,0.4,1,1'); +VStory.Easing['powerIn'] = moveInEasing; + +const scene1Characters = [ + { + character: { + id: 'scene1-bg', + type: 'Image', + position: { + x: 0, + y: 0, + width, + height + }, + options: { + graphic: { + image: 'https://lf9-dp-fe-cms-tos.byteorg.com/obj/bit-cloud/vstory/nationalMemory/dark.jpeg' + } + } + }, + appearAction: { + action: 'appear', + payload: { + animation: { + duration: 1000, + easing: 'easeInOut' + } + } + }, + disappearAction: false + }, + { + character: { + id: 'scene1-candle', + type: 'Image', + position: { + x: 0, + y: 600, + width, + height: 400 + }, + options: { + graphic: { + image: 'https://lf9-dp-fe-cms-tos.byteorg.com/obj/bit-cloud/vstory/nationalMemory/candle.png' + } + } + } + }, + { + character: { + id: 'scene1-monument', + type: 'Image', + position: { + x: 0, + y: 440, + width, + height: 360 + }, + options: { + graphic: { + opacity: 0.3, + image: 'https://lf9-dp-fe-cms-tos.byteorg.com/obj/bit-cloud/vstory/nationalMemory/monument.png' + } + } + } + }, + { + character: { + id: 'scene1-title', + type: 'Text', + position: { + x: width / 2, + y: 200, + width, + height + }, + options: { + graphic: { + text: '南 京', + fill: 'rgb(92, 20, 14)', + fontSize: 150, + textAlign: 'center', + textBaseline: 'middle', + fontWeight: 'bold' + // shadowBlur: 300, + // shadowColor: 'blue', + // shadowOffsetX: 30, + // shadowOffsetY: 30 + } + } + }, + appearAction: { + action: 'appear', + payload: { + animation: { + effect: 'wipe' + } + } + } + }, + { + character: { + id: 'scene1-title-date', + type: 'Text', + position: { + x: width / 2, + y: 350, + width, + height + }, + options: { + graphic: { + text: '12.13', + fill: 'white', + fontSize: 150, + textAlign: 'center', + textBaseline: 'middle', + fontWeight: 'bold', + shadowBlur: 200 + } + } + }, + appearAction: { + action: 'appear', + payload: { + animation: { + effect: 'wipe' + } + } + } + }, + { + character: { + id: 'scene1-subtitle', + type: 'Text', + position: { + x: width / 2, + y: 460, + width, + height + }, + options: { + graphic: { + text: '国 家 公 祭 日', + fill: 'white', + fontSize: 40, + textAlign: 'center', + textBaseline: 'middle', + fontWeight: 300 + } + } + }, + appearAction: { + action: 'appear', + payload: { + animation: { + effect: 'wipe' + } + } + } + }, + { + character: { + id: 'scene1-leftText', + type: 'Text', + position: { + x: width - 30, + y: 260, + width: height, + height, + anchor: [width - 60, 200], + angle: (Math.PI / 2) * 3 + }, + options: { + graphic: { + text: '铭记历史 祭奠同胞', + fill: 'white', + fontSize: 60, + textAlign: 'center', + textBaseline: 'middle', + fontWeight: 600, + opacity: 0.2 + } + } + }, + appearAction: { + action: 'appear', + payload: { + animation: { + duration: 2000, + effect: 'typewriter' + } + } + } + } +]; +const scene1 = { + id: 'scene1', + actions: scene1Characters.map(({ character, appearAction, disappearAction }) => { + const characterId = character.id; + const characterActions = []; + if (appearAction !== false) { + characterActions.push(merge({}, defaultAppearAction, appearAction)); + } + + if (disappearAction !== false) { + characterActions.push(merge({}, defaultDisappearAction(2000), disappearAction)); + } + + return { + characterId, + characterActions + }; + }) +}; +const scene2Characters = [ + { + character: { + id: 'scene2-title', + type: 'Text', + position: { + x: width / 2, + y: 160, + width, + height + }, + options: { + graphic: { + text: '遇难同胞', + fill: 'white', + fontSize: 40, + textAlign: 'center', + textBaseline: 'middle', + fontWeight: 300 + } + } + }, + appearAction: { + action: 'appear', + startTime: 200, + payload: { + animation: { + duration: 1200, + effect: 'typewriter' + } + } + }, + actions: [ + { + action: 'moveTo', + startTime: 2400, + payload: { + destination: { + x: 120, + y: 120 + }, + animation: { + duration: 800, + easing: 'quadInOut' + } + } + } + ] + }, + { + character: { + id: 'scene2-title-count', + type: 'Text', + position: { + x: width / 2, + y: 280, + width, + height + }, + options: { + graphic: { + text: '300000', + fill: 'white', + fontSize: 100, + textAlign: 'center', + textBaseline: 'middle', + fontWeight: 'bold' + } + } + }, + appearAction: { + action: 'appear', + startTime: 700, + payload: { + animation: { + duration: 2000, + effect: 'move', + pos: 'top', + easing: 'powerIn' + } + } + }, + actions: [ + { + action: 'moveTo', + startTime: 4000, + payload: { + destination: { + x: 400, + y: 120 + }, + animation: { + duration: 400, + easing: 'quadInOut' + } + } + } + ] + }, + { + character: { + id: 'scene2-title-2', + type: 'Text', + position: { + x: width / 2, + y: 220, + width, + height + }, + options: { + graphic: { + text: '其中', + fill: 'white', + fontSize: 60, + textAlign: 'center', + textBaseline: 'middle', + fontWeight: 'bold' + } + } + }, + appearAction: { + action: 'appear', + startTime: 4500, + payload: { + animation: { + duration: 200, + effect: 'typewriter' + } + } + } + }, + { + character: { + id: 'scene2-title-3', + type: 'Text', + position: { + x: width / 2, + y: 320, + width, + height + }, + options: { + graphic: { + text: '枪杀占比达到惊人的 32%', + fill: 'white', + fontSize: 44, + textAlign: 'center', + textBaseline: 'middle', + fontWeight: 'bold' + } + } + }, + appearAction: { + action: 'appear', + startTime: 5000, + payload: { + animation: { + duration: 1000, + effect: 'typewriter' + } + } + } + }, + { + character: { + id: '1', + type: 'VChart', + zIndex: 0, + position: { + x: 72, + y: 400, + width: 500, + height: 500 + }, + options: { + initOption: { animation: true, interactive: true, disableTriggerEvent: true }, + spec: { + type: 'pie', + data: [ + { + id: 'id0', + values: [ + { name: '开枪', value: '32' }, + { name: '刺刀', value: '20' }, + { name: '打死', value: '16' }, + { name: '烧死', value: '9' }, + { name: '强奸', value: '8' }, + { name: '其他', value: '15' } + ] + } + ], + + outerRadius: 0.9, + valueField: 'value', + categoryField: 'name', + color: ['#1F1F1F', '#383838', '#505050', '#686868', '#909090', '#B8B8B8'], + animationNormal: { + pie: { + loop: 1, + partitioner: data => { + return data.name === '开枪'; + }, + timeSlices: [ + { + effects: { + channel: { + outerRadius: { to: 240 }, + fill: { to: 'rgb(92, 20, 14)' } + }, + easing: 'elasticInOut' + }, + delay: 8800, + duration: 2000 + } + ] + } + }, + label: { + visible: true, + position: 'inside', + offsetRadius: -40, + smartInvert: true, + rotate: false, + formatMethod: (label, data) => { + return { + type: 'rich', + text: [ + { + text: `${data.name}\n`, + fontSize: 16, + fontWeight: 500, + stroke: false + }, + { + text: `${data.value}%`, + fontSize: 16, + fontWeight: 500, + stroke: false + } + ] + }; + } + } + } + } + }, + appearAction: { + action: 'appear', + startTime: 2800, + payload: { + animation: { + duration: 1200 + } + } + } + } +]; +const scene2 = { + id: 'scene2', + actions: scene2Characters.map(({ character, appearAction, disappearAction, actions }) => { + const characterId = character.id; + const characterActions = []; + if (appearAction !== false) { + characterActions.push(merge({}, defaultAppearAction, appearAction)); + } + if (actions) { + characterActions.push(...actions); + } + if (disappearAction !== false) { + characterActions.push(merge({}, defaultDisappearAction(11000), disappearAction)); + } + + return { + characterId, + characterActions + }; + }) +}; +const scene3Characters = [ + { + character: { + id: 'scene3-content', + type: 'Text', + position: { + x: width / 2, + y: 300, + width: width - 60, + height + }, + options: { + graphic: { + textConfig: [ + { + text: '87年岁月流逝,截至2024年12月13日,南京侵华日军受害者援助协会登记在册的在世幸存者仅剩', + fontSize: 22 + }, + { text: '32人', fontWeight: 'bolder' } + ], + fill: 'white', + fontSize: 40, + textAlign: 'center', + textBaseline: 'top', + fontWeight: 300 + } + } + }, + appearAction: { + action: 'appear', + startTime: 200, + payload: { + animation: { + duration: 2000, + easing: 'linear', + effect: 'typewriter' + } + } + }, + actions: [ + { + action: 'disappear', + startTime: 6000, + payload: { + animation: { + duration: 1200, + easing: 'quadInOut', + effect: 'fade' + } + } + } + ] + }, + { + character: { + id: 'scene3-desc', + type: 'Text', + position: { + x: width / 2, + y: 80, + width, + height + }, + options: { + graphic: { + text: '部分幸存者名录', + fill: 'white', + fontSize: 40, + textAlign: 'center', + textBaseline: 'top', + fontWeight: 300 + } + } + }, + appearAction: { + action: 'appear', + startTime: 7200, + payload: { + animation: { + duration: 300, + effect: 'wipe' + } + } + }, + }, + { + character: { + id: 'scene3-year', + type: 'Text', + position: { + x: width / 2, + y: 160, + width, + height + }, + options: { + graphic: { + text: `2018年 - ${data.filter(item => item.year.includes(2018)).length}人`, + fill: 'white', + fontSize: 80, + fontWeight: 'bolder', + textAlign: 'center', + textBaseline: 'top' + } + } + }, + appearAction: { + action: 'appear', + startTime: 7200, + payload: { + animation: { + duration: 300, + effect: 'fade' + } + } + }, + actions: [2019, 2020, 2021, 2022, 2023, 2024].map((year, index) => { + return { + action: 'style', + startTime: 10000 + index * 2000, + payload: { + animation: { + duration: 0, + easing: 'quadInOut' + }, + text: { + text: `${year}年 - ${data.filter(item => item.year.includes(year)).length}人` + } + } + } + }).concat([2019, 2020, 2021, 2022, 2023, 2024].map((year, index) => { + return { + action: 'style', + startTime: 10000 + index * 2000 - 100, + payload: { + animation: { + duration: 100, + easing: 'quadInOut' + }, + graphic: { + opacity: 0 + }, + } + } + })).concat([2019, 2020, 2021, 2022, 2023, 2024].map((year, index) => { + return { + action: 'style', + startTime: 10000 + index * 2000, + payload: { + animation: { + duration: 100, + easing: 'quadInOut' + }, + graphic: { + opacity: 1 + }, + } + } + })), + }, + { + character: { + id: 'alive-wordcloud', + type: 'VChart', + position: { + x: 0, + y: 300, + width, + height: height - 300 + }, + options: { + spec: aliveSpec, + data: [ + { + id: 'data', + values: data2018 + } + ] + // panel: { + // fill: 'grey', + // shadowColor: 'rgba(0, 0, 0, 0.05)', + // shadowBlur: 10, + // shadowOffsetX: 4, + // shadowOffsetY: 4, + // cornerRadius: 20 + // } + } + }, + appearAction: { + action: 'appear', + startTime: 8000, + payload: [ + { + // 关闭所有动画 + selector: '', + animation: { + duration: 200, + } + }, + { + // 一个整体做动画 + selector: '*', + animation: { + oneByOne: false, + duration: 200, + effect: 'fade' + } + } + ] + }, + actions: [ + ...[data2019, data2020, data2021, data2022, data2023, data2024].map((data, index) => { + return { + action: 'update', + startTime: 8000 + (index + 1) * 2000, + payload: { + duration: 1000, + id: 'data', + values: data + } + }; + }) + ] + } +]; +const scene3 = { + id: 'scene3', + actions: scene3Characters.map(({ character, appearAction, disappearAction, actions }) => { + const characterId = character.id; + const characterActions = []; + if (appearAction !== false) { + characterActions.push(merge({}, defaultAppearAction, appearAction)); + } + if (actions) { + characterActions.push(...actions); + } + if (disappearAction !== false) { + characterActions.push(merge({}, defaultDisappearAction(26000, 100), disappearAction)); + } + + return { + characterId, + characterActions + }; + }) +}; +const scene4Characters = [ + { + character: { + id: 'scene4-content', + type: 'Text', + position: { + x: width / 2, + y: 300, + width: width - 60, + height + }, + options: { + graphic: { + textConfig: [ + { + text: '1937年12月13日,日军攻破南京城,制造了惨绝人寰的南京大屠杀惨案,日军屠杀中国战俘与难民总计', + fontSize: 22 + }, + { text: '30余万人', fontWeight: 'bolder' } + ], + fill: 'white', + fontSize: 40, + textAlign: 'center', + textBaseline: 'top', + fontWeight: 300 + } + } + }, + appearAction: { + action: 'appear', + startTime: 200, + payload: { + animation: { + duration: 2000, + easing: 'linear', + effect: 'typewriter' + } + } + }, + actions: [ + { + action: 'disappear', + startTime: 6000, + payload: { + animation: { + duration: 1200, + easing: 'quadInOut', + effect: 'fade' + } + } + } + ] + }, + ...['三', '十', '萬'].map((t, index) => { + return { + character: { + id: `name-wordcloud-${index}`, + type: 'VChart', + position: { + x: 0, + y: (index * height) / 3 - 50 + (index === 0 ? 10 : index === 2 ? 0 : 0), + width, + height: (height / 5) * 2 + }, + options: { + padding: { top: 30, bottom: 30 }, + spec: spec(t), + data: [ + { + id: 'data', + values: names.map(name => { + return { + name, + value: 100 + }; + }) + } + ] + // panel: { + // fill: 'grey', + // shadowColor: 'rgba(0, 0, 0, 0.05)', + // shadowBlur: 10, + // shadowOffsetX: 4, + // shadowOffsetY: 4, + // cornerRadius: 20 + // } + } + }, + appearAction: { + action: 'appear', + startTime: 8000, + payload: [ + // { + // // 关闭所有动画 + // selector: '', + // animation: { + // duration: 200, + // } + // }, + { + // 一个整体做动画 + // selector: 'text', + animation: { + oneByOne: true, + duration: 200, + effect: 'fade' + } + } + ] + }, + disappearAction: false + // actions: [ + // ...[data2019, data2020, data2021, data2022, data2023, data2024].map((data, index) => { + // return { + // action: 'update', + // startTime: 4000 + (index + 1) * 2000, + // payload: { + // duration: 1000, + // id: 'data', + // values: data + // } + // }; + // }) + // ] + }; + }) +]; +const scene4 = { + id: 'scene4', + actions: scene4Characters.map(({ character, appearAction, disappearAction, actions }) => { + const characterId = character.id; + const characterActions = []; + if (appearAction !== false) { + characterActions.push(merge({}, defaultAppearAction, appearAction)); + } + if (actions) { + characterActions.push(...actions); + } + if (disappearAction !== false) { + characterActions.push(merge({}, defaultDisappearAction(6000), disappearAction)); + } + + return { + characterId, + characterActions + }; + }) +}; +const dsl = { + acts: [ + { + id: 'defaultAct', + scenes: [scene1, scene2, scene3, scene4] + } + ], + characters: [ + ...scene1Characters.map(({ character }) => character), + ...scene2Characters.map(({ character }) => character), + ...scene3Characters.map(({ character }) => character), + ...scene4Characters.map(({ character }) => character), + ] +}; + +const story = new VStory.Story(dsl, { dom: CONTAINER_ID, width: width / 2, height: height / 2, background: '#ebecf0', scaleX: 0.5, scaleY: 0.5 }); +const player = new VStory.Player(story); +story.init(player); + +player.play(0); + +window['story'] = story; +window['vstory'] = story; +``` diff --git a/docs/assets/examples/menu.json b/docs/assets/examples/menu.json index 9ad7decf..5728eaba 100644 --- a/docs/assets/examples/menu.json +++ b/docs/assets/examples/menu.json @@ -8,6 +8,13 @@ "en": "works show" }, "children": [ + { + "path": "national-memorial", + "title": { + "zh": "国家公祭日", + "en": "national memorial" + } + }, { "path": "visualize-history", "title": { diff --git a/docs/assets/examples/zh/works-show/national-memorial.md b/docs/assets/examples/zh/works-show/national-memorial.md new file mode 100644 index 00000000..2b3ede1a --- /dev/null +++ b/docs/assets/examples/zh/works-show/national-memorial.md @@ -0,0 +1,1600 @@ +--- +category: examples +group: works-show +title: national-memorial +keywords: national-memorial +order: 1-0 +cover: https://lf9-dp-fe-cms-tos.byteorg.com/obj/bit-cloud/vstory/national-memorial.png +--- + +# `国家公祭日` 作品展示 + +铭记历史,珍爱和平 + +## 代码演示 + +```javascript livedemo template=vstory +// 注册所有需要的内容 +VStory.registerAll(); + +// 2018 http://www.81.cn/2018njdts81zn/2018-12/12/content_9376268.htm +// 2019 http://www.legaldaily.com.cn/gallery/content/2019-12/13/content_8073861.html +// 2020 https://photo.cctv.com/2020/12/12/PHOA4uUqqopn5Ya9eDCu8u7U201212.shtml#O0RgZnlNmfkz201212_1 +// 2021 http://www.news.cn/politics/2021-12/12/c_1128156191.htm +// 2022 http://www.news.cn/photo/2022-12/12/c_1129202736_2.htm +// 2023 http://www.mod.gov.cn/gfbw/gfjy_index/16272859.html +// 2024 https://www.news.cn/photo/20241212/bbf958bbe701456c9c259612d2db0f6c/c.html?page=1 +const data = [ + { + name: "孙富祥", + year: [] + }, + { + name: "管光镜", + year: [] + }, + { + name: "祝四孜", + year: [] + }, + { + name: "刘庭玉", + year: [] + }, + { + name: "陈玉兰", + year: [] + }, + { + name: "李素芬", + year: [] + }, + { + name: "易翠兰", + year: [] + }, + { + name: "李素云", + year: [] + }, + { + name: "吕金宝", + year: [] + }, + { + name: "陈广顺", + year: [] + }, + { + name: "顾秀兰", + year: [] + }, + { + name: "沈淑静", + year: [] + }, + { + name: "赵金华", + year: [] + }, + { + name: "李高山", + year: [] + }, + { + name: "王秀英", + year: [] + }, + { + name: "张秀红", + year: [] + }, + { + name: "马淑勤", + year: [] + }, + { + name: "林玉红", + year: [] + }, + { + name: "张福智", + year: [] + }, + { + name: "沈桂英", + year: [] + }, + { + name: "张兰英", + year: [] + }, + { + name: "仇秀英", + year: [] + }, + { + name: "王翠英", + year: [] + }, + { + name: "佘子清", + year: [] + }, + { + name: '马秀英', + year: [2018, 2019, 2020] + }, + { + name: '濮业良', + year: [2018, 2019, 2020, 2021] + }, + { + name: '马继武', + year: [2018, 2019, 2020] + }, + { + name: '王义隆', + year: [2018, 2019, 2020, 2021, 2022, 2023, 2024] + }, + { + name: '王长发', + year: [2018, 2019, 2020, 2021, 2022] + }, + { + name: '蒋淑萍', + year: [2018, 2019] + }, + { + name: '薛玉娟', + year: [2018, 2019, 2020, 2021, 2022, 2023, 2024] + }, + { + name: '巫吉英', + year: [2018, 2019, 2020, 2021] + }, + { + name: '谢桂英', + year: [2018, 2019, 2020, 2021, 2022, 2023, 2024] + }, + { + name: '黄桂兰', + year: [2018, 2019, 2020, 2021, 2022, 2023, 2024] + }, + { + name: '岑洪桂', + year: [2018, 2019, 2020, 2021, 2022, 2023, 2024] + }, + { + name: '陈桂香', + year: [2018, 2019, 2020, 2021, 2022, 2023] + }, + { + name: '徐家庆', + year: [2018, 2019, 2020] + }, + { + name: '杨翠英', + year: [2018, 2019, 2020] + }, + { + name: '黄刘氏', + year: [2018, 2019, 2020] + }, + { + name: '关舜华', + year: [2018, 2019, 2020, 2021, 2022, 2023, 2024] + }, + { + name: '陈文英', + year: [2018, 2019, 2020] + }, + { + name: '周智林', + year: [2018, 2019, 2020, 2021, 2022, 2023] + }, + { + name: '蔡丽华', + year: [2018, 2019, 2020] + }, + { + name: '魏桂如', + year: [2018, 2019, 2020, 2021, 2022, 2023, 2024] + }, + { + name: '易兰英', + year: [2018, 2019, 2020, 2021, 2022, 2023, 2024] + }, + { + name: '石秀英', + year: [2018, 2019, 2020, 2021, 2022, 2023] + }, + { + name: '高恒发', + year: [2018, 2019, 2020, 2021, 2022] + }, + { + name: '王福义', + year: [2018] + }, + { + name: '李美兰', + year: [2018, 2019, 2020, 2021, 2022] + }, + { + name: '葛道荣', + year: [2018, 2019, 2020, 2021, 2022] + }, + { + name: '马月华', + year: [2018] + }, + { + name: '李长富', + year: [2018, 2019, 2020, 2021, 2022, 2023, 2024] + }, + { + name: '余昌祥', + year: [2018, 2019, 2020, 2021] + }, + { + name: '金茂芝', + year: [2018] + }, + { + name: '常志强', + year: [2018, 2019, 2020, 2021, 2022] + }, + { + name: '郑锦阳', + year: [2018, 2019, 2020, 2021, 2022] + }, + { + name: '万秀英', + year: [2018] + }, + { + name: '艾义英', + year: [2018, 2019, 2020, 2021, 2022, 2023, 2024] + }, + { + name: '龚德年', + year: [2018, 2019, 2020, 2021, 2022, 2023, 2024] + }, + { + name: '向远松', + year: [2018, 2019, 2020, 2021] + }, + { + name: '朱惟平', + year: [2018] + }, + { + name: '经智珍', + year: [2018, 2019, 2020, 2021, 2022, 2023, 2024] + }, + { + name: '朱秀英', + year: [2018, 2019] + }, + { + name: '贺孝和', + year: [2018, 2019, 2020] + }, + { + name: '陈素华', + year: [2018] + }, + { + name: '夏淑琴', + year: [2018, 2019, 2020, 2021, 2022, 2023, 2024] + }, + { + name: '杨静秋', + year: [2018, 2019, 2020, 2021, 2022] + }, + { + name: '张惠霞', + year: [2018, 2019, 2020, 2021, 2022] + }, + { + name: '周湘萍', + year: [2018, 2019, 2020, 2021, 2022] + }, + { + name: '蒋树珍', + year: [2018, 2019, 2020, 2021, 2022, 2023, 2024] + }, + { + name: '徐德明', + year: [2018, 2019, 2020, 2021, 2022, 2023, 2024] + }, + { + name: '刘贵祥', + year: [2018, 2019, 2020, 2021, 2022, 2023, 2024] + }, + { + name: '郭林大', + year: [2018, 2019, 2020, 2021, 2022] + }, + { + name: '张仕翔', + year: [2018, 2019, 2020, 2021, 2022] + }, + { + name: '马承年', + year: [2018] + }, + { + name: '姚秀英', + year: [2018, 2019] + }, + { + name: '王津', + year: [2018, 2019, 2020, 2021, 2022] + }, + { + name: '熊淑兰', + year: [2018, 2019, 2020, 2021, 2022, 2023, 2024] + }, + { + name: '刘素珍', + year: [2018, 2019, 2020, 2021, 2022, 2023] + }, + { + name: '潘巧英', + year: [2018, 2019, 2020, 2021, 2022, 2023, 2024] + }, + { + name: '郭秀兰', + year: [2018, 2019, 2020, 2021, 2022, 2023, 2024] + }, + { + name: '祝再强', + year: [2018, 2019, 2020, 2021] + }, + { + name: '陈德寿', + year: [2018, 2019, 2020, 2021, 2022, 2023, 2024] + }, + { + name: '王子华', + year: [2018, 2019, 2020, 2021, 2022, 2023, 2024] + }, + { + name: '程福保', + year: [2018, 2019, 2020, 2021, 2022, 2023] + }, + { + name: '伍秀英', + year: [2018, 2019, 2020, 2021, 2022, 2023, 2024] + }, + { + name: '路洪才', + year: [2018, 2019, 2020, 2021, 2022, 2023, 2024] + }, + { + name: '阮秀英', + year: [2018, 2019, 2020, 2021, 2022] + }, + { + name: '高如琴', + year: [2018, 2019, 2020, 2021, 2022, 2023] + }, + { + name: '马庭禄', + year: [2018, 2019, 2020, 2021, 2022] + }, + { + name: '袁桂龙', + year: [2018, 2019, 2020, 2021, 2022] + }, + { + name: '岑洪兰', + year: [2018, 2019, 2020, 2021, 2022, 2023, 2024] + }, + { + name: '刘民生', + year: [2018, 2019, 2020, 2021, 2022, 2023, 2024] + }, + { + name: '方素霞', + year: [2018, 2019, 2020, 2021, 2022, 2023, 2024] + }, + { + name: '唐复龙', + year: [2018, 2019, 2020, 2021, 2022, 2023, 2024] + }, + { + name: '刘兴铭', + year: [2018] + }, + { + name: '王素明', + year: [2018, 2019, 2020, 2021] + }, + { + name: '程文英', + year: [2018, 2019, 2020, 2021, 2022, 2023, 2024] + }, + { + name: '马庭宝', + year: [2018, 2019, 2020, 2021, 2022, 2023, 2024] + }, + { + name: '陶承义', + year: [2018, 2019, 2020, 2021, 2022, 2023, 2024] + }, + { + name: '傅兆增', + year: [2018, 2019, 2020] + }, + { + name: '阮定东', + year: [2018, 2019, 2020, 2021, 2022, 2023, 2024] + }, + { + name: '苏承祺', + year: [2018, 2019, 2020, 2021, 2022] + }, + { + name: '周文彬', + year: [2018, 2019, 2020, 2021, 2022, 2023, 2024] + } +]; + +const data2018 = data.map(item => ({ ...item, death: !item.year.includes(2018), value: 100 })); +const data2019 = data.map(item => ({ ...item, death: !item.year.includes(2019), value: 100 })); +const data2020 = data.map(item => ({ ...item, death: !item.year.includes(2020), value: 100 })); +const data2021 = data.map(item => ({ ...item, death: !item.year.includes(2021), value: 100 })); +const data2022 = data.map(item => ({ ...item, death: !item.year.includes(2022), value: 100 })); +const data2023 = data.map(item => ({ ...item, death: !item.year.includes(2023), value: 100 })); +const data2024 = data.map(item => ({ ...item, death: !item.year.includes(2024), value: 100 })); + +const names = [ + '佘培庚', + '张华亮', + '刘茂清', + '刘茂源', + '易周氏', + '崔正桂', + '殷玉汉', + '夏赵氏', + '吴三根', + '姚小姗', + '苏义华', + '李秀华', + '杨福杨', + '刘寿金', + '夏路氏', + '刘贵宝', + '刘文光', + '炒文迎', + '刘寿银', + '徐江氏', + '徐带娣', + '徐毛七', + '徐兆荣', + '徐吕氏', + '戎金寿', + '戎陈氏', + '赵民', + '商广礼', + '方正廉', + '冯永渭', + '傅锦山', + '高恒保', + '高祁氏:', + '高庆浩', + '方志山', + '冯兴棠', + '傅克忠', + '高恒法', + '宵瑞伯', + '高流渊', + '方子友', + '傅奎年', + '高恒云', + '费长华', + '冯学才', + '傅理奇', + '殷玉汉', + '孙道树', + '王阿富', + '汪江氏', + '朱庭财', + '张外三', + '朱启兴', + '石永祥', + '谢道清', + '周庆财', + '卞朝镛', + '刘永贵', + '杨嘉敬', + '王长富', + '孙俊武', + '梁传炳', + '许泽林', + '王家龄', + '郭声楠', + '朱瑞庭', + '任自先', + '韩德顺', + '张桥生', + '朱文泉', + '白庆增', + '吴少洪', + '汪世清', + '钱延模', + '韩少停', + '张济山', + '汪四盲', + '王进财', + '小九子', + '徐良生', + '你孝文', + '许嘉盛', + '韦明发', + '小扣子', + '徐长喜', + '徐金尧', + '王逵昆', + '徐京生', + '徐辛氏', + '许嘉兴', + '汪太炳', + '魏大', + '徐长银', + '徐新潮', + '王老九', + '小来子', + '徐俊田', + '许江生', + '魏丙昆', + '徐长英', + '徐兴祥', + '汪汪氏', + '小六子', + '徐昆发', + '许老汉', + '徐成春', + '徐徐氏', + '徐老三', + '许老太', + '汪小掌', + '徐成林', + '徐宣氏', + '徐老四', + '许老五', + '徐丫头', + '徐成要', + '许礼和', + '汪兴德' +]; + +const aliveSpec = { + type: 'wordCloud', + background: 'transparent', + fontSizeRange: [18, 18], + random: false, + nameField: 'name', + valueField: 'value', + seriesField: 'name', + animationAppear: false, + // maskShape: { + // type: 'text', + // text: text, + // fill: 'red', + // fontWeight: 'bolder' + // }, + // animationAppear: false, + // wordMask: { + // visible: false, + // style: { + // backgroundOpacity: 0 + // } + // }, + word: { + style: { + fill: 'white', + opacity: (datum) => (datum.death ? 0.2 : 1), + fontWeight: 'bolder' + } + } +}; + +const spec = (text) => ({ + type: 'wordCloud', + background: 'transparent', + fontSizeRange: [6, 12], + random: false, + nameField: 'name', + valueField: 'value', + seriesField: 'name', + maskShape: { + type: 'text', + text: text, + fill: 'red', + fontWeight: 'bolder' + }, + // animationAppear: false, + wordMask: { + visible: false, + style: { + backgroundOpacity: 0 + } + }, + word: { + style: { + fill: 'white', + // opacity: (datum: any) => (datum.death ? 0.2 : 1), + fontWeight: 'bolder' + } + } +}); + +// function merge(target, source) { +// // 确保目标是一个对象 +// if (typeof target !== 'object' || target === null) { +// target = {}; +// } + +// // 遍历源对象的每个属性 +// for (const key in source) { +// if (source.hasOwnProperty(key)) { +// const value = source[key]; + +// // 如果值是对象,则递归合并 +// if (typeof value === 'object' && value !== null) { +// // 如果目标对象中没有这个键,初始化为一个空对象 +// if (!target[key]) { +// target[key] = Array.isArray(value) ? [] : {}; +// } +// // 递归调用 +// merge(target[key], value); +// } else { +// // 直接赋值 +// target[key] = value; +// } +// } +// } + +// return target; +// } + +const merge = VStory.VUtils.merge; + +const width = 1280 / 2; +const height = 1960 / 2; +const defaultAppearAction = { + action: 'appear', + payload: { + animation: { + duration: 1000, + easing: 'linear' + } + } +}; +const defaultDisappearAction = (startTime, duration = 1000) => { + return { + action: 'disappear', + startTime, + payload: { + animation: { + duration, + easing: 'linear' + } + } + }; +}; +const moveInEasing = VStory.generatorPathEasingFunc('M0,0,C0.46,0,0.496,0.014,0.616,0.088,0.734,0.161,0.884,0.4,1,1'); +VStory.Easing['powerIn'] = moveInEasing; + +const scene1Characters = [ + { + character: { + id: 'scene1-bg', + type: 'Image', + position: { + x: 0, + y: 0, + width, + height + }, + options: { + graphic: { + image: 'https://lf9-dp-fe-cms-tos.byteorg.com/obj/bit-cloud/vstory/nationalMemory/dark.jpeg' + } + } + }, + appearAction: { + action: 'appear', + payload: { + animation: { + duration: 1000, + easing: 'easeInOut' + } + } + }, + disappearAction: false + }, + { + character: { + id: 'scene1-candle', + type: 'Image', + position: { + x: 0, + y: 600, + width, + height: 400 + }, + options: { + graphic: { + image: 'https://lf9-dp-fe-cms-tos.byteorg.com/obj/bit-cloud/vstory/nationalMemory/candle.png' + } + } + } + }, + { + character: { + id: 'scene1-monument', + type: 'Image', + position: { + x: 0, + y: 440, + width, + height: 360 + }, + options: { + graphic: { + opacity: 0.3, + image: 'https://lf9-dp-fe-cms-tos.byteorg.com/obj/bit-cloud/vstory/nationalMemory/monument.png' + } + } + } + }, + { + character: { + id: 'scene1-title', + type: 'Text', + position: { + x: width / 2, + y: 200, + width, + height + }, + options: { + graphic: { + text: '南 京', + fill: 'rgb(92, 20, 14)', + fontSize: 150, + textAlign: 'center', + textBaseline: 'middle', + fontWeight: 'bold' + // shadowBlur: 300, + // shadowColor: 'blue', + // shadowOffsetX: 30, + // shadowOffsetY: 30 + } + } + }, + appearAction: { + action: 'appear', + payload: { + animation: { + effect: 'wipe' + } + } + } + }, + { + character: { + id: 'scene1-title-date', + type: 'Text', + position: { + x: width / 2, + y: 350, + width, + height + }, + options: { + graphic: { + text: '12.13', + fill: 'white', + fontSize: 150, + textAlign: 'center', + textBaseline: 'middle', + fontWeight: 'bold', + shadowBlur: 200 + } + } + }, + appearAction: { + action: 'appear', + payload: { + animation: { + effect: 'wipe' + } + } + } + }, + { + character: { + id: 'scene1-subtitle', + type: 'Text', + position: { + x: width / 2, + y: 460, + width, + height + }, + options: { + graphic: { + text: '国 家 公 祭 日', + fill: 'white', + fontSize: 40, + textAlign: 'center', + textBaseline: 'middle', + fontWeight: 300 + } + } + }, + appearAction: { + action: 'appear', + payload: { + animation: { + effect: 'wipe' + } + } + } + }, + { + character: { + id: 'scene1-leftText', + type: 'Text', + position: { + x: width - 30, + y: 260, + width: height, + height, + anchor: [width - 60, 200], + angle: (Math.PI / 2) * 3 + }, + options: { + graphic: { + text: '铭记历史 祭奠同胞', + fill: 'white', + fontSize: 60, + textAlign: 'center', + textBaseline: 'middle', + fontWeight: 600, + opacity: 0.2 + } + } + }, + appearAction: { + action: 'appear', + payload: { + animation: { + duration: 2000, + effect: 'typewriter' + } + } + } + } +]; +const scene1 = { + id: 'scene1', + actions: scene1Characters.map(({ character, appearAction, disappearAction }) => { + const characterId = character.id; + const characterActions = []; + if (appearAction !== false) { + characterActions.push(merge({}, defaultAppearAction, appearAction)); + } + + if (disappearAction !== false) { + characterActions.push(merge({}, defaultDisappearAction(2000), disappearAction)); + } + + return { + characterId, + characterActions + }; + }) +}; +const scene2Characters = [ + { + character: { + id: 'scene2-title', + type: 'Text', + position: { + x: width / 2, + y: 160, + width, + height + }, + options: { + graphic: { + text: '遇难同胞', + fill: 'white', + fontSize: 40, + textAlign: 'center', + textBaseline: 'middle', + fontWeight: 300 + } + } + }, + appearAction: { + action: 'appear', + startTime: 200, + payload: { + animation: { + duration: 1200, + effect: 'typewriter' + } + } + }, + actions: [ + { + action: 'moveTo', + startTime: 2400, + payload: { + destination: { + x: 120, + y: 120 + }, + animation: { + duration: 800, + easing: 'quadInOut' + } + } + } + ] + }, + { + character: { + id: 'scene2-title-count', + type: 'Text', + position: { + x: width / 2, + y: 280, + width, + height + }, + options: { + graphic: { + text: '300000', + fill: 'white', + fontSize: 100, + textAlign: 'center', + textBaseline: 'middle', + fontWeight: 'bold' + } + } + }, + appearAction: { + action: 'appear', + startTime: 700, + payload: { + animation: { + duration: 2000, + effect: 'move', + pos: 'top', + easing: 'powerIn' + } + } + }, + actions: [ + { + action: 'moveTo', + startTime: 4000, + payload: { + destination: { + x: 400, + y: 120 + }, + animation: { + duration: 400, + easing: 'quadInOut' + } + } + } + ] + }, + { + character: { + id: 'scene2-title-2', + type: 'Text', + position: { + x: width / 2, + y: 220, + width, + height + }, + options: { + graphic: { + text: '其中', + fill: 'white', + fontSize: 60, + textAlign: 'center', + textBaseline: 'middle', + fontWeight: 'bold' + } + } + }, + appearAction: { + action: 'appear', + startTime: 4500, + payload: { + animation: { + duration: 200, + effect: 'typewriter' + } + } + } + }, + { + character: { + id: 'scene2-title-3', + type: 'Text', + position: { + x: width / 2, + y: 320, + width, + height + }, + options: { + graphic: { + text: '枪杀占比达到惊人的 32%', + fill: 'white', + fontSize: 44, + textAlign: 'center', + textBaseline: 'middle', + fontWeight: 'bold' + } + } + }, + appearAction: { + action: 'appear', + startTime: 5000, + payload: { + animation: { + duration: 1000, + effect: 'typewriter' + } + } + } + }, + { + character: { + id: '1', + type: 'VChart', + zIndex: 0, + position: { + x: 72, + y: 400, + width: 500, + height: 500 + }, + options: { + initOption: { animation: true, interactive: true, disableTriggerEvent: true }, + spec: { + type: 'pie', + data: [ + { + id: 'id0', + values: [ + { name: '开枪', value: '32' }, + { name: '刺刀', value: '20' }, + { name: '打死', value: '16' }, + { name: '烧死', value: '9' }, + { name: '强奸', value: '8' }, + { name: '其他', value: '15' } + ] + } + ], + + outerRadius: 0.9, + valueField: 'value', + categoryField: 'name', + color: ['#1F1F1F', '#383838', '#505050', '#686868', '#909090', '#B8B8B8'], + animationNormal: { + pie: { + loop: 1, + partitioner: data => { + return data.name === '开枪'; + }, + timeSlices: [ + { + effects: { + channel: { + outerRadius: { to: 240 }, + fill: { to: 'rgb(92, 20, 14)' } + }, + easing: 'elasticInOut' + }, + delay: 8800, + duration: 2000 + } + ] + } + }, + label: { + visible: true, + position: 'inside', + offsetRadius: -40, + smartInvert: true, + rotate: false, + formatMethod: (label, data) => { + return { + type: 'rich', + text: [ + { + text: `${data.name}\n`, + fontSize: 16, + fontWeight: 500, + stroke: false + }, + { + text: `${data.value}%`, + fontSize: 16, + fontWeight: 500, + stroke: false + } + ] + }; + } + } + } + } + }, + appearAction: { + action: 'appear', + startTime: 2800, + payload: { + animation: { + duration: 1200 + } + } + } + } +]; +const scene2 = { + id: 'scene2', + actions: scene2Characters.map(({ character, appearAction, disappearAction, actions }) => { + const characterId = character.id; + const characterActions = []; + if (appearAction !== false) { + characterActions.push(merge({}, defaultAppearAction, appearAction)); + } + if (actions) { + characterActions.push(...actions); + } + if (disappearAction !== false) { + characterActions.push(merge({}, defaultDisappearAction(11000), disappearAction)); + } + + return { + characterId, + characterActions + }; + }) +}; +const scene3Characters = [ + { + character: { + id: 'scene3-content', + type: 'Text', + position: { + x: width / 2, + y: 300, + width: width - 60, + height + }, + options: { + graphic: { + textConfig: [ + { + text: '87年岁月流逝,截至2024年12月13日,南京侵华日军受害者援助协会登记在册的在世幸存者仅剩', + fontSize: 22 + }, + { text: '32人', fontWeight: 'bolder' } + ], + fill: 'white', + fontSize: 40, + textAlign: 'center', + textBaseline: 'top', + fontWeight: 300 + } + } + }, + appearAction: { + action: 'appear', + startTime: 200, + payload: { + animation: { + duration: 2000, + easing: 'linear', + effect: 'typewriter' + } + } + }, + actions: [ + { + action: 'disappear', + startTime: 6000, + payload: { + animation: { + duration: 1200, + easing: 'quadInOut', + effect: 'fade' + } + } + } + ] + }, + { + character: { + id: 'scene3-desc', + type: 'Text', + position: { + x: width / 2, + y: 80, + width, + height + }, + options: { + graphic: { + text: '部分幸存者名录', + fill: 'white', + fontSize: 40, + textAlign: 'center', + textBaseline: 'top', + fontWeight: 300 + } + } + }, + appearAction: { + action: 'appear', + startTime: 7200, + payload: { + animation: { + duration: 300, + effect: 'wipe' + } + } + }, + }, + { + character: { + id: 'scene3-year', + type: 'Text', + position: { + x: width / 2, + y: 160, + width, + height + }, + options: { + graphic: { + text: `2018年 - ${data.filter(item => item.year.includes(2018)).length}人`, + fill: 'white', + fontSize: 80, + fontWeight: 'bolder', + textAlign: 'center', + textBaseline: 'top' + } + } + }, + appearAction: { + action: 'appear', + startTime: 7200, + payload: { + animation: { + duration: 300, + effect: 'fade' + } + } + }, + actions: [2019, 2020, 2021, 2022, 2023, 2024].map((year, index) => { + return { + action: 'style', + startTime: 10000 + index * 2000, + payload: { + animation: { + duration: 0, + easing: 'quadInOut' + }, + text: { + text: `${year}年 - ${data.filter(item => item.year.includes(year)).length}人` + } + } + } + }).concat([2019, 2020, 2021, 2022, 2023, 2024].map((year, index) => { + return { + action: 'style', + startTime: 10000 + index * 2000 - 100, + payload: { + animation: { + duration: 100, + easing: 'quadInOut' + }, + graphic: { + opacity: 0 + }, + } + } + })).concat([2019, 2020, 2021, 2022, 2023, 2024].map((year, index) => { + return { + action: 'style', + startTime: 10000 + index * 2000, + payload: { + animation: { + duration: 100, + easing: 'quadInOut' + }, + graphic: { + opacity: 1 + }, + } + } + })), + }, + { + character: { + id: 'alive-wordcloud', + type: 'VChart', + position: { + x: 0, + y: 300, + width, + height: height - 300 + }, + options: { + spec: aliveSpec, + data: [ + { + id: 'data', + values: data2018 + } + ] + // panel: { + // fill: 'grey', + // shadowColor: 'rgba(0, 0, 0, 0.05)', + // shadowBlur: 10, + // shadowOffsetX: 4, + // shadowOffsetY: 4, + // cornerRadius: 20 + // } + } + }, + appearAction: { + action: 'appear', + startTime: 8000, + payload: [ + { + // 关闭所有动画 + selector: '', + animation: { + duration: 200, + } + }, + { + // 一个整体做动画 + selector: '*', + animation: { + oneByOne: false, + duration: 200, + effect: 'fade' + } + } + ] + }, + actions: [ + ...[data2019, data2020, data2021, data2022, data2023, data2024].map((data, index) => { + return { + action: 'update', + startTime: 8000 + (index + 1) * 2000, + payload: { + duration: 1000, + id: 'data', + values: data + } + }; + }) + ] + } +]; +const scene3 = { + id: 'scene3', + actions: scene3Characters.map(({ character, appearAction, disappearAction, actions }) => { + const characterId = character.id; + const characterActions = []; + if (appearAction !== false) { + characterActions.push(merge({}, defaultAppearAction, appearAction)); + } + if (actions) { + characterActions.push(...actions); + } + if (disappearAction !== false) { + characterActions.push(merge({}, defaultDisappearAction(26000, 100), disappearAction)); + } + + return { + characterId, + characterActions + }; + }) +}; +const scene4Characters = [ + { + character: { + id: 'scene4-content', + type: 'Text', + position: { + x: width / 2, + y: 300, + width: width - 60, + height + }, + options: { + graphic: { + textConfig: [ + { + text: '1937年12月13日,日军攻破南京城,制造了惨绝人寰的南京大屠杀惨案,日军屠杀中国战俘与难民总计', + fontSize: 22 + }, + { text: '30余万人', fontWeight: 'bolder' } + ], + fill: 'white', + fontSize: 40, + textAlign: 'center', + textBaseline: 'top', + fontWeight: 300 + } + } + }, + appearAction: { + action: 'appear', + startTime: 200, + payload: { + animation: { + duration: 2000, + easing: 'linear', + effect: 'typewriter' + } + } + }, + actions: [ + { + action: 'disappear', + startTime: 6000, + payload: { + animation: { + duration: 1200, + easing: 'quadInOut', + effect: 'fade' + } + } + } + ] + }, + ...['三', '十', '萬'].map((t, index) => { + return { + character: { + id: `name-wordcloud-${index}`, + type: 'VChart', + position: { + x: 0, + y: (index * height) / 3 - 50 + (index === 0 ? 10 : index === 2 ? 0 : 0), + width, + height: (height / 5) * 2 + }, + options: { + padding: { top: 30, bottom: 30 }, + spec: spec(t), + data: [ + { + id: 'data', + values: names.map(name => { + return { + name, + value: 100 + }; + }) + } + ] + // panel: { + // fill: 'grey', + // shadowColor: 'rgba(0, 0, 0, 0.05)', + // shadowBlur: 10, + // shadowOffsetX: 4, + // shadowOffsetY: 4, + // cornerRadius: 20 + // } + } + }, + appearAction: { + action: 'appear', + startTime: 8000, + payload: [ + // { + // // 关闭所有动画 + // selector: '', + // animation: { + // duration: 200, + // } + // }, + { + // 一个整体做动画 + // selector: 'text', + animation: { + oneByOne: true, + duration: 200, + effect: 'fade' + } + } + ] + }, + disappearAction: false + // actions: [ + // ...[data2019, data2020, data2021, data2022, data2023, data2024].map((data, index) => { + // return { + // action: 'update', + // startTime: 4000 + (index + 1) * 2000, + // payload: { + // duration: 1000, + // id: 'data', + // values: data + // } + // }; + // }) + // ] + }; + }) +]; +const scene4 = { + id: 'scene4', + actions: scene4Characters.map(({ character, appearAction, disappearAction, actions }) => { + const characterId = character.id; + const characterActions = []; + if (appearAction !== false) { + characterActions.push(merge({}, defaultAppearAction, appearAction)); + } + if (actions) { + characterActions.push(...actions); + } + if (disappearAction !== false) { + characterActions.push(merge({}, defaultDisappearAction(6000), disappearAction)); + } + + return { + characterId, + characterActions + }; + }) +}; +const dsl = { + acts: [ + { + id: 'defaultAct', + scenes: [scene1, scene2, scene3, scene4] + } + ], + characters: [ + ...scene1Characters.map(({ character }) => character), + ...scene2Characters.map(({ character }) => character), + ...scene3Characters.map(({ character }) => character), + ...scene4Characters.map(({ character }) => character), + ] +}; + +const story = new VStory.Story(dsl, { dom: CONTAINER_ID, width: width / 2, height: height / 2, background: '#ebecf0', scaleX: 0.5, scaleY: 0.5 }); +const player = new VStory.Player(story); +story.init(player); + +player.play(0); + +window['story'] = story; +window['vstory'] = story; +``` diff --git a/packages/vstory-animate/package.json b/packages/vstory-animate/package.json index fb17b3be..2489869e 100644 --- a/packages/vstory-animate/package.json +++ b/packages/vstory-animate/package.json @@ -24,12 +24,12 @@ "test-watch": "DEBUG_MODE=1 jest --watch" }, "dependencies": { - "@visactor/vchart": "1.13.1-vstory.2", + "@visactor/vchart": "1.13.1-vstory.3", "@visactor/vtable": "1.10.1", - "@visactor/vrender": "0.21.2-vstory.2", - "@visactor/vrender-core": "0.21.2-vstory.2", - "@visactor/vrender-kits": "0.21.2-vstory.2", - "@visactor/vrender-components": "0.21.2-vstory.2", + "@visactor/vrender": "0.21.2-vstory.3", + "@visactor/vrender-core": "0.21.2-vstory.3", + "@visactor/vrender-kits": "0.21.2-vstory.3", + "@visactor/vrender-components": "0.21.2-vstory.3", "@visactor/vutils": "~0.18.17", "@visactor/vchart-extension": "0.0.3-vstory.2", "@visactor/vdataset": "~0.18.17", diff --git a/packages/vstory-animate/src/customAnimates/typewirter.ts b/packages/vstory-animate/src/customAnimates/typewirter.ts index c0eff8ab..e32c8ec9 100644 --- a/packages/vstory-animate/src/customAnimates/typewirter.ts +++ b/packages/vstory-animate/src/customAnimates/typewirter.ts @@ -49,7 +49,7 @@ export class TypeWriter extends ACustomAnimate<{ text: string }> { // update text // const { textConfig = [] } = this.target.attribute; const totalLength = this.targetTextConfig.reduce( - (a, b) => (a + (b as any).text ? (b as any).text.toString().length : 1), + (a, b) => a + ((b as any).text ? (b as any).text.toString().length : 1), 0 ); const nextLength = totalLength * ratio; diff --git a/packages/vstory-animate/src/index.ts b/packages/vstory-animate/src/index.ts index fb066a44..dc6c6abc 100644 --- a/packages/vstory-animate/src/index.ts +++ b/packages/vstory-animate/src/index.ts @@ -6,3 +6,4 @@ export * from './customAnimates/pie-leap'; export * from './customAnimates/symbol-throw'; export * from './customAnimates/symbol-swing'; export * from './easing/registerEasing'; +export { Easing, generatorPathEasingFunc } from '@visactor/vrender'; diff --git a/packages/vstory-core/package.json b/packages/vstory-core/package.json index fe08f33a..cb0ce622 100644 --- a/packages/vstory-core/package.json +++ b/packages/vstory-core/package.json @@ -24,12 +24,12 @@ "test-watch": "DEBUG_MODE=1 jest --watch" }, "dependencies": { - "@visactor/vchart": "1.13.1-vstory.2", + "@visactor/vchart": "1.13.1-vstory.3", "@visactor/vtable": "1.10.1", - "@visactor/vrender": "0.21.2-vstory.2", - "@visactor/vrender-core": "0.21.2-vstory.2", - "@visactor/vrender-kits": "0.21.2-vstory.2", - "@visactor/vrender-components": "0.21.2-vstory.2", + "@visactor/vrender": "0.21.2-vstory.3", + "@visactor/vrender-core": "0.21.2-vstory.3", + "@visactor/vrender-kits": "0.21.2-vstory.3", + "@visactor/vrender-components": "0.21.2-vstory.3", "@visactor/vutils": "~0.18.17", "@visactor/vchart-extension": "0.0.3-vstory.2", "@visactor/vdataset": "~0.18.17", diff --git a/packages/vstory-editor/package.json b/packages/vstory-editor/package.json index 6f2d7f3a..e63ae46c 100644 --- a/packages/vstory-editor/package.json +++ b/packages/vstory-editor/package.json @@ -24,12 +24,12 @@ "test-watch": "DEBUG_MODE=1 jest --watch" }, "dependencies": { - "@visactor/vchart": "1.13.1-vstory.2", + "@visactor/vchart": "1.13.1-vstory.3", "@visactor/vtable": "1.10.1", - "@visactor/vrender": "0.21.2-vstory.2", - "@visactor/vrender-core": "0.21.2-vstory.2", - "@visactor/vrender-kits": "0.21.2-vstory.2", - "@visactor/vrender-components": "0.21.2-vstory.2", + "@visactor/vrender": "0.21.2-vstory.3", + "@visactor/vrender-core": "0.21.2-vstory.3", + "@visactor/vrender-kits": "0.21.2-vstory.3", + "@visactor/vrender-components": "0.21.2-vstory.3", "@visactor/vutils": "~0.18.17", "@visactor/vchart-extension": "0.0.3-vstory.2", "@visactor/vdataset": "~0.18.17", diff --git a/packages/vstory-external/package.json b/packages/vstory-external/package.json index 47310f0a..66292400 100644 --- a/packages/vstory-external/package.json +++ b/packages/vstory-external/package.json @@ -24,12 +24,12 @@ "test-watch": "DEBUG_MODE=1 jest --watch" }, "dependencies": { - "@visactor/vchart": "1.13.1-vstory.2", + "@visactor/vchart": "1.13.1-vstory.3", "@visactor/vtable": "1.10.1", - "@visactor/vrender": "0.21.2-vstory.2", - "@visactor/vrender-core": "0.21.2-vstory.2", - "@visactor/vrender-kits": "0.21.2-vstory.2", - "@visactor/vrender-components": "0.21.2-vstory.2", + "@visactor/vrender": "0.21.2-vstory.3", + "@visactor/vrender-core": "0.21.2-vstory.3", + "@visactor/vrender-kits": "0.21.2-vstory.3", + "@visactor/vrender-components": "0.21.2-vstory.3", "@visactor/vutils": "~0.18.17", "@visactor/vchart-extension": "0.0.3-vstory.2", "@visactor/vdataset": "~0.18.17", diff --git a/packages/vstory-player/package.json b/packages/vstory-player/package.json index cd0092e5..122f7526 100644 --- a/packages/vstory-player/package.json +++ b/packages/vstory-player/package.json @@ -24,12 +24,12 @@ "test-watch": "DEBUG_MODE=1 jest --watch" }, "dependencies": { - "@visactor/vchart": "1.13.1-vstory.2", + "@visactor/vchart": "1.13.1-vstory.3", "@visactor/vtable": "1.10.1", - "@visactor/vrender": "0.21.2-vstory.2", - "@visactor/vrender-core": "0.21.2-vstory.2", - "@visactor/vrender-kits": "0.21.2-vstory.2", - "@visactor/vrender-components": "0.21.2-vstory.2", + "@visactor/vrender": "0.21.2-vstory.3", + "@visactor/vrender-core": "0.21.2-vstory.3", + "@visactor/vrender-kits": "0.21.2-vstory.3", + "@visactor/vrender-components": "0.21.2-vstory.3", "@visactor/vutils": "~0.18.17", "@visactor/vchart-extension": "0.0.3-vstory.2", "@visactor/vdataset": "~0.18.17", diff --git a/packages/vstory-player/src/processor/component/common/style.ts b/packages/vstory-player/src/processor/component/common/style.ts index 360eac43..67ba1c69 100644 --- a/packages/vstory-player/src/processor/component/common/style.ts +++ b/packages/vstory-player/src/processor/component/common/style.ts @@ -37,7 +37,7 @@ export class CommonStyleActionProcessor extends ActionProcessorItem { super.preRun(character, actionSpec); const { animation = {}, - graphic: graphicStyle, + graphic: graphicStyle = {}, text: textStyle, panel: panelStyle } = getPayload(actionSpec) as IComponentStylePayLoad; diff --git a/packages/vstory-templates/package.json b/packages/vstory-templates/package.json index e477edc3..6c26ce5c 100644 --- a/packages/vstory-templates/package.json +++ b/packages/vstory-templates/package.json @@ -24,12 +24,12 @@ "test-watch": "DEBUG_MODE=1 jest --watch" }, "dependencies": { - "@visactor/vchart": "1.13.1-vstory.2", + "@visactor/vchart": "1.13.1-vstory.3", "@visactor/vtable": "1.10.1", - "@visactor/vrender": "0.21.2-vstory.2", - "@visactor/vrender-core": "0.21.2-vstory.2", - "@visactor/vrender-kits": "0.21.2-vstory.2", - "@visactor/vrender-components": "0.21.2-vstory.2", + "@visactor/vrender": "0.21.2-vstory.3", + "@visactor/vrender-core": "0.21.2-vstory.3", + "@visactor/vrender-kits": "0.21.2-vstory.3", + "@visactor/vrender-components": "0.21.2-vstory.3", "@visactor/vutils": "~0.18.17", "@visactor/vchart-extension": "0.0.3-vstory.2", "@visactor/vdataset": "~0.18.17", diff --git a/packages/vstory/demo/src/App.tsx b/packages/vstory/demo/src/App.tsx index d2db772b..6e0e88f9 100644 --- a/packages/vstory/demo/src/App.tsx +++ b/packages/vstory/demo/src/App.tsx @@ -37,6 +37,8 @@ import { PopTipAnimate } from './demos/component/poptip'; import { LabelItemAnimate } from './demos/component/label-item'; import { BarHIV } from './demos/infographic/bar-hiv'; import { LabelWorks } from './demos/works/label'; +import { NanJinWordCloud } from './demos/works/nanjin-wordcloud'; +import { NationalMemorial } from './demos/works/NationalMemorial'; import { BarWorkingInSameIndustry } from './demos/infographic/bar-work-in-same-industry'; type MenusType = ( @@ -148,6 +150,14 @@ const App = () => { { name: 'SomeCharts', component: SomeCharts + }, + { + name: 'NanJinWordCloud', + component: NanJinWordCloud + }, + { + name: 'NationalMemorial', + component: NationalMemorial } ] }, diff --git a/packages/vstory/demo/src/assets/nationalMemory/candle.png b/packages/vstory/demo/src/assets/nationalMemory/candle.png new file mode 100644 index 00000000..26e273b2 Binary files /dev/null and b/packages/vstory/demo/src/assets/nationalMemory/candle.png differ diff --git a/packages/vstory/demo/src/assets/nationalMemory/dark.jpeg b/packages/vstory/demo/src/assets/nationalMemory/dark.jpeg new file mode 100644 index 00000000..d170d3fe Binary files /dev/null and b/packages/vstory/demo/src/assets/nationalMemory/dark.jpeg differ diff --git a/packages/vstory/demo/src/assets/nationalMemory/monument.png b/packages/vstory/demo/src/assets/nationalMemory/monument.png new file mode 100644 index 00000000..54d08e45 Binary files /dev/null and b/packages/vstory/demo/src/assets/nationalMemory/monument.png differ diff --git a/packages/vstory/demo/src/demos/works/NationalMemorial.tsx b/packages/vstory/demo/src/demos/works/NationalMemorial.tsx new file mode 100644 index 00000000..29bdd527 --- /dev/null +++ b/packages/vstory/demo/src/demos/works/NationalMemorial.tsx @@ -0,0 +1,1584 @@ +import React, { useEffect } from 'react'; +import { Player, Story } from '../../../../../vstory-core/src'; +import { registerAll } from '../../../../../vstory/src'; +import darkBg from '../../assets/nationalMemory/dark.jpeg'; +import candle from '../../assets/nationalMemory/candle.png'; +import monument from '../../assets/nationalMemory/monument.png'; +import { merge } from '@visactor/vutils'; +import { generatorPathEasingFunc, Easing } from '@visactor/vrender'; +import { exportVideo } from '../utils'; + +registerAll(); + +// 2018 http://www.81.cn/2018njdts81zn/2018-12/12/content_9376268.htm +// 2019 http://www.legaldaily.com.cn/gallery/content/2019-12/13/content_8073861.html +// 2020 https://photo.cctv.com/2020/12/12/PHOA4uUqqopn5Ya9eDCu8u7U201212.shtml#O0RgZnlNmfkz201212_1 +// 2021 http://www.news.cn/politics/2021-12/12/c_1128156191.htm +// 2022 http://www.news.cn/photo/2022-12/12/c_1129202736_2.htm +// 2023 http://www.mod.gov.cn/gfbw/gfjy_index/16272859.html +// 2024 https://www.news.cn/photo/20241212/bbf958bbe701456c9c259612d2db0f6c/c.html?page=1 +const data = [ + { + name: '孙富祥', + year: [] + }, + { + name: '管光镜', + year: [] + }, + { + name: '祝四孜', + year: [] + }, + { + name: '刘庭玉', + year: [] + }, + { + name: '陈玉兰', + year: [] + }, + { + name: '李素芬', + year: [] + }, + { + name: '易翠兰', + year: [] + }, + { + name: '李素云', + year: [] + }, + { + name: '吕金宝', + year: [] + }, + { + name: '陈广顺', + year: [] + }, + { + name: '顾秀兰', + year: [] + }, + { + name: '沈淑静', + year: [] + }, + { + name: '赵金华', + year: [] + }, + { + name: '李高山', + year: [] + }, + { + name: '王秀英', + year: [] + }, + { + name: '张秀红', + year: [] + }, + { + name: '马淑勤', + year: [] + }, + { + name: '林玉红', + year: [] + }, + { + name: '张福智', + year: [] + }, + { + name: '沈桂英', + year: [] + }, + { + name: '张兰英', + year: [] + }, + { + name: '仇秀英', + year: [] + }, + { + name: '王翠英', + year: [] + }, + { + name: '佘子清', + year: [] + }, + { + name: '马秀英', + year: [2018, 2019, 2020] + }, + { + name: '濮业良', + year: [2018, 2019, 2020, 2021] + }, + { + name: '马继武', + year: [2018, 2019, 2020] + }, + { + name: '王义隆', + year: [2018, 2019, 2020, 2021, 2022, 2023, 2024] + }, + { + name: '王长发', + year: [2018, 2019, 2020, 2021, 2022] + }, + { + name: '蒋淑萍', + year: [2018, 2019] + }, + { + name: '薛玉娟', + year: [2018, 2019, 2020, 2021, 2022, 2023, 2024] + }, + { + name: '巫吉英', + year: [2018, 2019, 2020, 2021] + }, + { + name: '谢桂英', + year: [2018, 2019, 2020, 2021, 2022, 2023, 2024] + }, + { + name: '黄桂兰', + year: [2018, 2019, 2020, 2021, 2022, 2023, 2024] + }, + { + name: '岑洪桂', + year: [2018, 2019, 2020, 2021, 2022, 2023, 2024] + }, + { + name: '陈桂香', + year: [2018, 2019, 2020, 2021, 2022, 2023] + }, + { + name: '徐家庆', + year: [2018, 2019, 2020] + }, + { + name: '杨翠英', + year: [2018, 2019, 2020] + }, + { + name: '黄刘氏', + year: [2018, 2019, 2020] + }, + { + name: '关舜华', + year: [2018, 2019, 2020, 2021, 2022, 2023, 2024] + }, + { + name: '陈文英', + year: [2018, 2019, 2020] + }, + { + name: '周智林', + year: [2018, 2019, 2020, 2021, 2022, 2023] + }, + { + name: '蔡丽华', + year: [2018, 2019, 2020] + }, + { + name: '魏桂如', + year: [2018, 2019, 2020, 2021, 2022, 2023, 2024] + }, + { + name: '易兰英', + year: [2018, 2019, 2020, 2021, 2022, 2023, 2024] + }, + { + name: '石秀英', + year: [2018, 2019, 2020, 2021, 2022, 2023] + }, + { + name: '高恒发', + year: [2018, 2019, 2020, 2021, 2022] + }, + { + name: '王福义', + year: [2018] + }, + { + name: '李美兰', + year: [2018, 2019, 2020, 2021, 2022] + }, + { + name: '葛道荣', + year: [2018, 2019, 2020, 2021, 2022] + }, + { + name: '马月华', + year: [2018] + }, + { + name: '李长富', + year: [2018, 2019, 2020, 2021, 2022, 2023, 2024] + }, + { + name: '余昌祥', + year: [2018, 2019, 2020, 2021] + }, + { + name: '金茂芝', + year: [2018] + }, + { + name: '常志强', + year: [2018, 2019, 2020, 2021, 2022] + }, + { + name: '郑锦阳', + year: [2018, 2019, 2020, 2021, 2022] + }, + { + name: '万秀英', + year: [2018] + }, + { + name: '艾义英', + year: [2018, 2019, 2020, 2021, 2022, 2023, 2024] + }, + { + name: '龚德年', + year: [2018, 2019, 2020, 2021, 2022, 2023, 2024] + }, + { + name: '向远松', + year: [2018, 2019, 2020, 2021] + }, + { + name: '朱惟平', + year: [2018] + }, + { + name: '经智珍', + year: [2018, 2019, 2020, 2021, 2022, 2023, 2024] + }, + { + name: '朱秀英', + year: [2018, 2019] + }, + { + name: '贺孝和', + year: [2018, 2019, 2020] + }, + { + name: '陈素华', + year: [2018] + }, + { + name: '夏淑琴', + year: [2018, 2019, 2020, 2021, 2022, 2023, 2024] + }, + { + name: '杨静秋', + year: [2018, 2019, 2020, 2021, 2022] + }, + { + name: '张惠霞', + year: [2018, 2019, 2020, 2021, 2022] + }, + { + name: '周湘萍', + year: [2018, 2019, 2020, 2021, 2022] + }, + { + name: '蒋树珍', + year: [2018, 2019, 2020, 2021, 2022, 2023, 2024] + }, + { + name: '徐德明', + year: [2018, 2019, 2020, 2021, 2022, 2023, 2024] + }, + { + name: '刘贵祥', + year: [2018, 2019, 2020, 2021, 2022, 2023, 2024] + }, + { + name: '郭林大', + year: [2018, 2019, 2020, 2021, 2022] + }, + { + name: '张仕翔', + year: [2018, 2019, 2020, 2021, 2022] + }, + { + name: '马承年', + year: [2018] + }, + { + name: '姚秀英', + year: [2018, 2019] + }, + { + name: '王津', + year: [2018, 2019, 2020, 2021, 2022] + }, + { + name: '熊淑兰', + year: [2018, 2019, 2020, 2021, 2022, 2023, 2024] + }, + { + name: '刘素珍', + year: [2018, 2019, 2020, 2021, 2022, 2023] + }, + { + name: '潘巧英', + year: [2018, 2019, 2020, 2021, 2022, 2023, 2024] + }, + { + name: '郭秀兰', + year: [2018, 2019, 2020, 2021, 2022, 2023, 2024] + }, + { + name: '祝再强', + year: [2018, 2019, 2020, 2021] + }, + { + name: '陈德寿', + year: [2018, 2019, 2020, 2021, 2022, 2023, 2024] + }, + { + name: '王子华', + year: [2018, 2019, 2020, 2021, 2022, 2023, 2024] + }, + { + name: '程福保', + year: [2018, 2019, 2020, 2021, 2022, 2023] + }, + { + name: '伍秀英', + year: [2018, 2019, 2020, 2021, 2022, 2023, 2024] + }, + { + name: '路洪才', + year: [2018, 2019, 2020, 2021, 2022, 2023, 2024] + }, + { + name: '阮秀英', + year: [2018, 2019, 2020, 2021, 2022] + }, + { + name: '高如琴', + year: [2018, 2019, 2020, 2021, 2022, 2023] + }, + { + name: '马庭禄', + year: [2018, 2019, 2020, 2021, 2022] + }, + { + name: '袁桂龙', + year: [2018, 2019, 2020, 2021, 2022] + }, + { + name: '岑洪兰', + year: [2018, 2019, 2020, 2021, 2022, 2023, 2024] + }, + { + name: '刘民生', + year: [2018, 2019, 2020, 2021, 2022, 2023, 2024] + }, + { + name: '方素霞', + year: [2018, 2019, 2020, 2021, 2022, 2023, 2024] + }, + { + name: '唐复龙', + year: [2018, 2019, 2020, 2021, 2022, 2023, 2024] + }, + { + name: '刘兴铭', + year: [2018] + }, + { + name: '王素明', + year: [2018, 2019, 2020, 2021] + }, + { + name: '程文英', + year: [2018, 2019, 2020, 2021, 2022, 2023, 2024] + }, + { + name: '马庭宝', + year: [2018, 2019, 2020, 2021, 2022, 2023, 2024] + }, + { + name: '陶承义', + year: [2018, 2019, 2020, 2021, 2022, 2023, 2024] + }, + { + name: '傅兆增', + year: [2018, 2019, 2020] + }, + { + name: '阮定东', + year: [2018, 2019, 2020, 2021, 2022, 2023, 2024] + }, + { + name: '苏承祺', + year: [2018, 2019, 2020, 2021, 2022] + }, + { + name: '周文彬', + year: [2018, 2019, 2020, 2021, 2022, 2023, 2024] + } +]; + +const data2018 = data.map(item => ({ ...item, death: !item.year.includes(2018), value: 100 })); +const data2019 = data.map(item => ({ ...item, death: !item.year.includes(2019), value: 100 })); +const data2020 = data.map(item => ({ ...item, death: !item.year.includes(2020), value: 100 })); +const data2021 = data.map(item => ({ ...item, death: !item.year.includes(2021), value: 100 })); +const data2022 = data.map(item => ({ ...item, death: !item.year.includes(2022), value: 100 })); +const data2023 = data.map(item => ({ ...item, death: !item.year.includes(2023), value: 100 })); +const data2024 = data.map(item => ({ ...item, death: !item.year.includes(2024), value: 100 })); + +const names = [ + '佘培庚', + '张华亮', + '刘茂清', + '刘茂源', + '易周氏', + '崔正桂', + '殷玉汉', + '夏赵氏', + '吴三根', + '姚小姗', + '苏义华', + '李秀华', + '杨福杨', + '刘寿金', + '夏路氏', + '刘贵宝', + '刘文光', + '炒文迎', + '刘寿银', + '徐江氏', + '徐带娣', + '徐毛七', + '徐兆荣', + '徐吕氏', + '戎金寿', + '戎陈氏', + '赵民', + '商广礼', + '方正廉', + '冯永渭', + '傅锦山', + '高恒保', + '高祁氏:', + '高庆浩', + '方志山', + '冯兴棠', + '傅克忠', + '高恒法', + '宵瑞伯', + '高流渊', + '方子友', + '傅奎年', + '高恒云', + '费长华', + '冯学才', + '傅理奇', + '殷玉汉', + '孙道树', + '王阿富', + '汪江氏', + '朱庭财', + '张外三', + '朱启兴', + '石永祥', + '谢道清', + '周庆财', + '卞朝镛', + '刘永贵', + '杨嘉敬', + '王长富', + '孙俊武', + '梁传炳', + '许泽林', + '王家龄', + '郭声楠', + '朱瑞庭', + '任自先', + '韩德顺', + '张桥生', + '朱文泉', + '白庆增', + '吴少洪', + '汪世清', + '钱延模', + '韩少停', + '张济山', + '汪四盲', + '王进财', + '小九子', + '徐良生', + '你孝文', + '许嘉盛', + '韦明发', + '小扣子', + '徐长喜', + '徐金尧', + '王逵昆', + '徐京生', + '徐辛氏', + '许嘉兴', + '汪太炳', + '魏大', + '徐长银', + '徐新潮', + '王老九', + '小来子', + '徐俊田', + '许江生', + '魏丙昆', + '徐长英', + '徐兴祥', + '汪汪氏', + '小六子', + '徐昆发', + '许老汉', + '徐成春', + '徐徐氏', + '徐老三', + '许老太', + '汪小掌', + '徐成林', + '徐宣氏', + '徐老四', + '许老五', + '徐丫头', + '徐成要', + '许礼和', + '汪兴德' +]; + +const aliveSpec = { + type: 'wordCloud', + background: 'transparent', + fontSizeRange: [18, 18], + random: false, + nameField: 'name', + valueField: 'value', + seriesField: 'name', + animationAppear: false, + // maskShape: { + // type: 'text', + // text: text, + // fill: 'red', + // fontWeight: 'bolder' + // }, + // animationAppear: false, + // wordMask: { + // visible: false, + // style: { + // backgroundOpacity: 0 + // } + // }, + word: { + style: { + fill: 'white', + opacity: (datum: any) => (datum.death ? 0.2 : 1), + fontWeight: 'bolder' + } + } +}; + +const spec = (text: string) => ({ + type: 'wordCloud', + background: 'transparent', + fontSizeRange: [6, 12], + random: false, + nameField: 'name', + valueField: 'value', + seriesField: 'name', + maskShape: { + type: 'text', + text: text, + fill: 'red', + fontWeight: 'bolder' + }, + // animationAppear: false, + wordMask: { + visible: false, + style: { + backgroundOpacity: 0 + } + }, + word: { + style: { + fill: 'white', + // opacity: (datum: any) => (datum.death ? 0.2 : 1), + fontWeight: 'bolder' + } + } +}); + +export const NationalMemorial = () => { + const id = 'NationalMemorial'; + const width = 1280 / 2; + const height = 1960 / 2; + const defaultAppearAction = { + action: 'appear', + payload: { + animation: { + duration: 1000, + easing: 'linear' + } + } + }; + const defaultDisappearAction = (startTime, duration: number = 1000) => { + return { + action: 'disappear', + startTime, + payload: { + animation: { + duration, + easing: 'linear' + } + } + }; + }; + const moveInEasing = generatorPathEasingFunc('M0,0,C0.46,0,0.496,0.014,0.616,0.088,0.734,0.161,0.884,0.4,1,1'); + Easing['powerIn'] = moveInEasing; + + useEffect(() => { + const container = document.getElementById(id); + const canvas = document.createElement('canvas'); + container?.appendChild(canvas); + const scene1Characters = [ + { + character: { + id: 'scene1-bg', + type: 'Image', + position: { + x: 0, + y: 0, + width, + height + }, + options: { + graphic: { + image: darkBg + } + } + }, + appearAction: { + action: 'appear', + payload: { + animation: { + duration: 1000, + easing: 'easeInOut' + } + } + }, + disappearAction: false + }, + { + character: { + id: 'scene1-candle', + type: 'Image', + position: { + x: 0, + y: 600, + width, + height: 400 + }, + options: { + graphic: { + image: candle + } + } + } + }, + { + character: { + id: 'scene1-monument', + type: 'Image', + position: { + x: 0, + y: 440, + width, + height: 360 + }, + options: { + graphic: { + opacity: 0.3, + image: monument + } + } + } + }, + { + character: { + id: 'scene1-title', + type: 'Text', + position: { + x: width / 2, + y: 200, + width, + height + }, + options: { + graphic: { + text: '南 京', + fill: 'rgb(92, 20, 14)', + fontSize: 150, + textAlign: 'center', + textBaseline: 'middle', + fontWeight: 'bold' + // shadowBlur: 300, + // shadowColor: 'blue', + // shadowOffsetX: 30, + // shadowOffsetY: 30 + } + } + }, + appearAction: { + action: 'appear', + payload: { + animation: { + effect: 'wipe' + } + } + } + }, + { + character: { + id: 'scene1-title-date', + type: 'Text', + position: { + x: width / 2, + y: 350, + width, + height + }, + options: { + graphic: { + text: '12.13', + fill: 'white', + fontSize: 150, + textAlign: 'center', + textBaseline: 'middle', + fontWeight: 'bold', + shadowBlur: 200 + } + } + }, + appearAction: { + action: 'appear', + payload: { + animation: { + effect: 'wipe' + } + } + } + }, + { + character: { + id: 'scene1-subtitle', + type: 'Text', + position: { + x: width / 2, + y: 460, + width, + height + }, + options: { + graphic: { + text: '国 家 公 祭 日', + fill: 'white', + fontSize: 40, + textAlign: 'center', + textBaseline: 'middle', + fontWeight: 300 + } + } + }, + appearAction: { + action: 'appear', + payload: { + animation: { + effect: 'wipe' + } + } + } + }, + { + character: { + id: 'scene1-leftText', + type: 'Text', + position: { + x: width - 30, + y: 260, + width: height, + height, + anchor: [width - 60, 200], + angle: (Math.PI / 2) * 3 + }, + options: { + graphic: { + text: '铭记历史 祭奠同胞', + fill: 'white', + fontSize: 60, + textAlign: 'center', + textBaseline: 'middle', + fontWeight: 600, + opacity: 0.2 + } + } + }, + appearAction: { + action: 'appear', + payload: { + animation: { + duration: 2000, + effect: 'typewriter' + } + } + } + } + ]; + const scene1 = { + id: 'scene1', + actions: scene1Characters.map(({ character, appearAction, disappearAction }) => { + const characterId = character.id; + const characterActions = []; + if (appearAction !== false) { + characterActions.push(merge({}, defaultAppearAction, appearAction)); + } + + if (disappearAction !== false) { + characterActions.push(merge({}, defaultDisappearAction(2000), disappearAction)); + } + + return { + characterId, + characterActions + }; + }) + }; + const scene2Characters = [ + { + character: { + id: 'scene2-title', + type: 'Text', + position: { + x: width / 2, + y: 160, + width, + height + }, + options: { + graphic: { + text: '遇难同胞', + fill: 'white', + fontSize: 40, + textAlign: 'center', + textBaseline: 'middle', + fontWeight: 300 + } + } + }, + appearAction: { + action: 'appear', + startTime: 200, + payload: { + animation: { + duration: 1200, + effect: 'typewriter' + } + } + }, + actions: [ + { + action: 'moveTo', + startTime: 2400, + payload: { + destination: { + x: 120, + y: 120 + }, + animation: { + duration: 800, + easing: 'quadInOut' + } + } + } + ] + }, + { + character: { + id: 'scene2-title-count', + type: 'Text', + position: { + x: width / 2, + y: 280, + width, + height + }, + options: { + graphic: { + text: '300000', + fill: 'white', + fontSize: 100, + textAlign: 'center', + textBaseline: 'middle', + fontWeight: 'bold' + } + } + }, + appearAction: { + action: 'appear', + startTime: 700, + payload: { + animation: { + duration: 2000, + effect: 'move', + pos: 'top', + easing: 'powerIn' + } + } + }, + actions: [ + { + action: 'moveTo', + startTime: 4000, + payload: { + destination: { + x: 400, + y: 120 + }, + animation: { + duration: 400, + easing: 'quadInOut' + } + } + } + ] + }, + { + character: { + id: 'scene2-title-2', + type: 'Text', + position: { + x: width / 2, + y: 220, + width, + height + }, + options: { + graphic: { + text: '其中', + fill: 'white', + fontSize: 60, + textAlign: 'center', + textBaseline: 'middle', + fontWeight: 'bold' + } + } + }, + appearAction: { + action: 'appear', + startTime: 4500, + payload: { + animation: { + duration: 200, + effect: 'typewriter' + } + } + } + }, + { + character: { + id: 'scene2-title-3', + type: 'Text', + position: { + x: width / 2, + y: 320, + width, + height + }, + options: { + graphic: { + text: '枪杀占比达到惊人的 32%', + fill: 'white', + fontSize: 44, + textAlign: 'center', + textBaseline: 'middle', + fontWeight: 'bold' + } + } + }, + appearAction: { + action: 'appear', + startTime: 5000, + payload: { + animation: { + duration: 1000, + effect: 'typewriter' + } + } + } + }, + { + character: { + id: '1', + type: 'VChart', + zIndex: 0, + position: { + x: 72, + y: 400, + width: 500, + height: 500 + }, + options: { + initOption: { animation: true, interactive: true, disableTriggerEvent: true }, + spec: { + type: 'pie', + data: [ + { + id: 'id0', + values: [ + { name: '开枪', value: '32' }, + { name: '刺刀', value: '20' }, + { name: '打死', value: '16' }, + { name: '烧死', value: '9' }, + { name: '强奸', value: '8' }, + { name: '其他', value: '15' } + ] + } + ], + + outerRadius: 0.9, + valueField: 'value', + categoryField: 'name', + color: ['#1F1F1F', '#383838', '#505050', '#686868', '#909090', '#B8B8B8'], + animationNormal: { + pie: { + loop: 1, + partitioner: data => { + return data.name === '开枪'; + }, + timeSlices: [ + { + effects: { + channel: { + outerRadius: { to: 240 }, + fill: { to: 'rgb(92, 20, 14)' } + }, + easing: 'elasticInOut' + }, + delay: 8800, + duration: 2000 + } + ] + } + }, + label: { + visible: true, + position: 'inside', + offsetRadius: -40, + smartInvert: true, + rotate: false, + formatMethod: (label, data) => { + return { + type: 'rich', + text: [ + { + text: `${data.name}\n`, + fontSize: 16, + fontWeight: 500, + stroke: false + }, + { + text: `${data.value}%`, + fontSize: 16, + fontWeight: 500, + stroke: false + } + ] + }; + } + } + } + } + }, + appearAction: { + action: 'appear', + startTime: 2800, + payload: { + animation: { + duration: 1200 + } + } + } + } + ]; + const scene2 = { + id: 'scene2', + actions: scene2Characters.map(({ character, appearAction, disappearAction, actions }) => { + const characterId = character.id; + const characterActions = []; + if (appearAction !== false) { + characterActions.push(merge({}, defaultAppearAction, appearAction)); + } + if (actions) { + characterActions.push(...actions); + } + if (disappearAction !== false) { + characterActions.push(merge({}, defaultDisappearAction(11000), disappearAction)); + } + + return { + characterId, + characterActions + }; + }) + }; + const scene3Characters = [ + { + character: { + id: 'scene3-content', + type: 'Text', + position: { + x: width / 2, + y: 300, + width: width - 60, + height + }, + options: { + graphic: { + textConfig: [ + { + text: '87年岁月流逝,截至2024年12月13日,南京侵华日军受害者援助协会登记在册的在世幸存者仅剩', + fontSize: 22 + }, + { text: '32人', fontWeight: 'bolder' } + ], + fill: 'white', + fontSize: 40, + textAlign: 'center', + textBaseline: 'top', + fontWeight: 300 + } + } + }, + appearAction: { + action: 'appear', + startTime: 200, + payload: { + animation: { + duration: 2000, + easing: 'linear', + effect: 'typewriter' + } + } + }, + actions: [ + { + action: 'disappear', + startTime: 6000, + payload: { + animation: { + duration: 1200, + easing: 'quadInOut', + effect: 'fade' + } + } + } + ] + }, + { + character: { + id: 'scene3-desc', + type: 'Text', + position: { + x: width / 2, + y: 80, + width, + height + }, + options: { + graphic: { + text: '部分幸存者名录', + fill: 'white', + fontSize: 40, + textAlign: 'center', + textBaseline: 'top', + fontWeight: 300 + } + } + }, + appearAction: { + action: 'appear', + startTime: 7200, + payload: { + animation: { + duration: 300, + effect: 'wipe' + } + } + } + }, + { + character: { + id: 'scene3-year', + type: 'Text', + position: { + x: width / 2, + y: 160, + width, + height + }, + options: { + graphic: { + text: `2018年 - ${data.filter(item => item.year.includes(2018)).length}人`, + fill: 'white', + fontSize: 80, + fontWeight: 'bolder', + textAlign: 'center', + textBaseline: 'top' + } + } + }, + appearAction: { + action: 'appear', + startTime: 7200, + payload: { + animation: { + duration: 300, + effect: 'fade' + } + } + }, + actions: [2019, 2020, 2021, 2022, 2023, 2024] + .map((year, index) => { + return { + action: 'style', + startTime: 10000 + index * 2000, + payload: { + animation: { + duration: 0, + easing: 'quadInOut' + }, + text: { + text: `${year}年 - ${data.filter(item => item.year.includes(year)).length}人` + } + } + }; + }) + .concat( + [2019, 2020, 2021, 2022, 2023, 2024].map((year, index) => { + return { + action: 'style', + startTime: 10000 + index * 2000 - 100, + payload: { + animation: { + duration: 100, + easing: 'quadInOut' + }, + graphic: { + opacity: 0 + } + } + }; + }) as any + ) + .concat( + [2019, 2020, 2021, 2022, 2023, 2024].map((year, index) => { + return { + action: 'style', + startTime: 10000 + index * 2000, + payload: { + animation: { + duration: 100, + easing: 'quadInOut' + }, + graphic: { + opacity: 1 + } + } + }; + }) as any + ) + }, + { + character: { + id: 'alive-wordcloud', + type: 'VChart', + position: { + x: 0, + y: 300, + width, + height: height - 300 + }, + options: { + spec: aliveSpec, + data: [ + { + id: 'data', + values: data2018 + } + ] + // panel: { + // fill: 'grey', + // shadowColor: 'rgba(0, 0, 0, 0.05)', + // shadowBlur: 10, + // shadowOffsetX: 4, + // shadowOffsetY: 4, + // cornerRadius: 20 + // } + } + }, + appearAction: { + action: 'appear', + startTime: 8000, + payload: [ + { + // 关闭所有动画 + selector: '', + animation: { + duration: 200 + } + }, + { + // 一个整体做动画 + selector: '*', + animation: { + oneByOne: false, + duration: 200, + effect: 'fade' + } + } + ] + }, + actions: [ + ...[data2019, data2020, data2021, data2022, data2023, data2024].map((data, index) => { + return { + action: 'update', + startTime: 8000 + (index + 1) * 2000, + payload: { + duration: 1000, + id: 'data', + values: data + } + } as any; + }) + ] + } + ]; + const scene3 = { + id: 'scene3', + actions: scene3Characters.map(({ character, appearAction, disappearAction, actions }) => { + const characterId = character.id; + const characterActions = []; + if (appearAction !== false) { + characterActions.push(merge({}, defaultAppearAction, appearAction)); + } + if (actions) { + characterActions.push(...actions); + } + if (disappearAction !== false) { + characterActions.push(merge({}, defaultDisappearAction(26000, 100), disappearAction)); + } + + return { + characterId, + characterActions + }; + }) + }; + const scene4Characters = [ + { + character: { + id: 'scene4-content', + type: 'Text', + position: { + x: width / 2, + y: 300, + width: width - 60, + height + }, + options: { + graphic: { + textConfig: [ + { + text: '1937年12月13日,日军攻破南京城,制造了惨绝人寰的南京大屠杀惨案,日军屠杀中国战俘与难民总计', + fontSize: 22 + }, + { text: '30余万人', fontWeight: 'bolder' } + ], + fill: 'white', + fontSize: 40, + textAlign: 'center', + textBaseline: 'top', + fontWeight: 300 + } + } + }, + appearAction: { + action: 'appear', + startTime: 200, + payload: { + animation: { + duration: 2000, + easing: 'linear', + effect: 'typewriter' + } + } + }, + actions: [ + { + action: 'disappear', + startTime: 6000, + payload: { + animation: { + duration: 1200, + easing: 'quadInOut', + effect: 'fade' + } + } + } + ] + }, + ...['三', '十', '萬'].map((t, index) => { + return { + character: { + id: `name-wordcloud-${index}`, + type: 'VChart', + position: { + x: 0, + y: (index * height) / 3 - 50 + (index === 0 ? 10 : index === 2 ? 0 : 0), + width, + height: (height / 5) * 2 + }, + options: { + padding: { top: 30, bottom: 30 }, + spec: spec(t), + data: [ + { + id: 'data', + values: names.map(name => { + return { + name, + value: 100 + }; + }) + } + ] + // panel: { + // fill: 'grey', + // shadowColor: 'rgba(0, 0, 0, 0.05)', + // shadowBlur: 10, + // shadowOffsetX: 4, + // shadowOffsetY: 4, + // cornerRadius: 20 + // } + } + }, + appearAction: { + action: 'appear', + startTime: 8000, + payload: [ + // { + // // 关闭所有动画 + // selector: '', + // animation: { + // duration: 200, + // } + // }, + { + // 一个整体做动画 + // selector: 'text', + animation: { + oneByOne: true, + duration: 200, + effect: 'fade' + } + } + ] + }, + disappearAction: false + // actions: [ + // ...[data2019, data2020, data2021, data2022, data2023, data2024].map((data, index) => { + // return { + // action: 'update', + // startTime: 4000 + (index + 1) * 2000, + // payload: { + // duration: 1000, + // id: 'data', + // values: data + // } + // } as any; + // }) + // ] + }; + }) + ]; + const scene4 = { + id: 'scene4', + actions: scene4Characters.map(({ character, appearAction, disappearAction, actions }) => { + const characterId = character.id; + const characterActions = []; + if (appearAction !== false) { + characterActions.push(merge({}, defaultAppearAction, appearAction)); + } + if (actions) { + characterActions.push(...actions); + } + if (disappearAction !== false) { + characterActions.push(merge({}, defaultDisappearAction(6000), disappearAction)); + } + + return { + characterId, + characterActions + }; + }) + }; + const dsl = { + acts: [ + { + id: 'defaultAct', + scenes: [scene1, scene2, scene3, scene4] + } + ], + characters: [ + ...scene1Characters.map(({ character }) => character), + ...scene2Characters.map(({ character }) => character), + ...scene3Characters.map(({ character }) => character), + ...scene4Characters.map(({ character }) => character) + ] + }; + + const story = new Story(dsl, { + canvas, + width, + height + }); + const player = new Player(story); + story.init(player); + player.play(-1); + + exportVideo(story); + + return () => { + story.release(); + }; + }, []); + + return
; +}; diff --git a/packages/vstory/demo/src/demos/works/nanjin-wordcloud.tsx b/packages/vstory/demo/src/demos/works/nanjin-wordcloud.tsx new file mode 100644 index 00000000..38361ed6 --- /dev/null +++ b/packages/vstory/demo/src/demos/works/nanjin-wordcloud.tsx @@ -0,0 +1,467 @@ +import React, { createRef, useEffect } from 'react'; +import { Player, Story, initVR, registerGraphics, registerCharacters } from '../../../../../vstory-core/src'; +import { registerVComponentAction, registerVChartAction } from '../../../../../vstory-player/src'; +import { encodeToVideo } from '../../../../../vstory-player/src/encode'; +import { registerAll } from '../../../../src'; + +registerAll(); +initVR(); + +// 2018 http://www.81.cn/2018njdts81zn/2018-12/12/content_9376268.htm +// 2019 http://www.legaldaily.com.cn/gallery/content/2019-12/13/content_8073861.html +// 2020 https://photo.cctv.com/2020/12/12/PHOA4uUqqopn5Ya9eDCu8u7U201212.shtml#O0RgZnlNmfkz201212_1 +// 2021 http://www.news.cn/politics/2021-12/12/c_1128156191.htm +// 2022 http://www.news.cn/photo/2022-12/12/c_1129202736_2.htm +// 2023 http://www.mod.gov.cn/gfbw/gfjy_index/16272859.html +// 2024 https://www.news.cn/photo/20241212/bbf958bbe701456c9c259612d2db0f6c/c.html?page=1 + +const data = [ + { + name: '马秀英', + year: [2018, 2019, 2020] + }, + { + name: '濮业良', + year: [2018, 2019, 2020, 2021] + }, + { + name: '马继武', + year: [2018, 2019, 2020] + }, + { + name: '王义隆', + year: [2018, 2019, 2020, 2021, 2022, 2023, 2024] + }, + { + name: '王长发', + year: [2018, 2019, 2020, 2021, 2022] + }, + { + name: '蒋淑萍', + year: [2018, 2019] + }, + { + name: '薛玉娟', + year: [2018, 2019, 2020, 2021, 2022, 2023, 2024] + }, + { + name: '巫吉英', + year: [2018, 2019, 2020, 2021] + }, + { + name: '谢桂英', + year: [2018, 2019, 2020, 2021, 2022, 2023, 2024] + }, + { + name: '黄桂兰', + year: [2018, 2019, 2020, 2021, 2022, 2023, 2024] + }, + { + name: '岑洪桂', + year: [2018, 2019, 2020, 2021, 2022, 2023, 2024] + }, + { + name: '陈桂香', + year: [2018, 2019, 2020, 2021, 2022, 2023] + }, + { + name: '徐家庆', + year: [2018, 2019, 2020] + }, + { + name: '杨翠英', + year: [2018, 2019, 2020] + }, + { + name: '黄刘氏', + year: [2018, 2019, 2020] + }, + { + name: '关舜华', + year: [2018, 2019, 2020, 2021, 2022, 2023, 2024] + }, + { + name: '陈文英', + year: [2018, 2019, 2020] + }, + { + name: '周智林', + year: [2018, 2019, 2020, 2021, 2022, 2023] + }, + { + name: '蔡丽华', + year: [2018, 2019, 2020] + }, + { + name: '魏桂如', + year: [2018, 2019, 2020, 2021, 2022, 2023, 2024] + }, + { + name: '易兰英', + year: [2018, 2019, 2020, 2021, 2022, 2023, 2024] + }, + { + name: '石秀英', + year: [2018, 2019, 2020, 2021, 2022, 2023] + }, + { + name: '高恒发', + year: [2018, 2019, 2020, 2021, 2022] + }, + { + name: '王福义', + year: [2018] + }, + { + name: '李美兰', + year: [2018, 2019, 2020, 2021, 2022] + }, + { + name: '葛道荣', + year: [2018, 2019, 2020, 2021, 2022] + }, + { + name: '马月华', + year: [2018] + }, + { + name: '李长富', + year: [2018, 2019, 2020, 2021, 2022, 2023, 2024] + }, + { + name: '余昌祥', + year: [2018, 2019, 2020, 2021] + }, + { + name: '金茂芝', + year: [2018] + }, + { + name: '常志强', + year: [2018, 2019, 2020, 2021, 2022] + }, + { + name: '郑锦阳', + year: [2018, 2019, 2020, 2021, 2022] + }, + { + name: '万秀英', + year: [2018] + }, + { + name: '艾义英', + year: [2018, 2019, 2020, 2021, 2022, 2023, 2024] + }, + { + name: '龚德年', + year: [2018, 2019, 2020, 2021, 2022, 2023, 2024] + }, + { + name: '向远松', + year: [2018, 2019, 2020, 2021] + }, + { + name: '朱惟平', + year: [2018] + }, + { + name: '经智珍', + year: [2018, 2019, 2020, 2021, 2022, 2023, 2024] + }, + { + name: '朱秀英', + year: [2018, 2019] + }, + { + name: '贺孝和', + year: [2018, 2019, 2020] + }, + { + name: '陈素华', + year: [2018] + }, + { + name: '夏淑琴', + year: [2018, 2019, 2020, 2021, 2022, 2023, 2024] + }, + { + name: '杨静秋', + year: [2018, 2019, 2020, 2021, 2022] + }, + { + name: '张惠霞', + year: [2018, 2019, 2020, 2021, 2022] + }, + { + name: '周湘萍', + year: [2018, 2019, 2020, 2021, 2022] + }, + { + name: '蒋树珍', + year: [2018, 2019, 2020, 2021, 2022, 2023, 2024] + }, + { + name: '徐德明', + year: [2018, 2019, 2020, 2021, 2022, 2023, 2024] + }, + { + name: '刘贵祥', + year: [2018, 2019, 2020, 2021, 2022, 2023, 2024] + }, + { + name: '郭林大', + year: [2018, 2019, 2020, 2021, 2022] + }, + { + name: '张仕翔', + year: [2018, 2019, 2020, 2021, 2022] + }, + { + name: '马承年', + year: [2018] + }, + { + name: '姚秀英', + year: [2018, 2019] + }, + { + name: '王津', + year: [2018, 2019, 2020, 2021, 2022] + }, + { + name: '熊淑兰', + year: [2018, 2019, 2020, 2021, 2022, 2023, 2024] + }, + { + name: '刘素珍', + year: [2018, 2019, 2020, 2021, 2022, 2023] + }, + { + name: '潘巧英', + year: [2018, 2019, 2020, 2021, 2022, 2023, 2024] + }, + { + name: '郭秀兰', + year: [2018, 2019, 2020, 2021, 2022, 2023, 2024] + }, + { + name: '祝再强', + year: [2018, 2019, 2020, 2021] + }, + { + name: '陈德寿', + year: [2018, 2019, 2020, 2021, 2022, 2023, 2024] + }, + { + name: '王子华', + year: [2018, 2019, 2020, 2021, 2022, 2023, 2024] + }, + { + name: '程福保', + year: [2018, 2019, 2020, 2021, 2022, 2023] + }, + { + name: '伍秀英', + year: [2018, 2019, 2020, 2021, 2022, 2023, 2024] + }, + { + name: '路洪才', + year: [2018, 2019, 2020, 2021, 2022, 2023, 2024] + }, + { + name: '阮秀英', + year: [2018, 2019, 2020, 2021, 2022] + }, + { + name: '高如琴', + year: [2018, 2019, 2020, 2021, 2022, 2023] + }, + { + name: '马庭禄', + year: [2018, 2019, 2020, 2021, 2022] + }, + { + name: '袁桂龙', + year: [2018, 2019, 2020, 2021, 2022] + }, + { + name: '岑洪兰', + year: [2018, 2019, 2020, 2021, 2022, 2023, 2024] + }, + { + name: '刘民生', + year: [2018, 2019, 2020, 2021, 2022, 2023, 2024] + }, + { + name: '方素霞', + year: [2018, 2019, 2020, 2021, 2022, 2023, 2024] + }, + { + name: '唐复龙', + year: [2018, 2019, 2020, 2021, 2022, 2023, 2024] + }, + { + name: '刘兴铭', + year: [2018] + }, + { + name: '王素明', + year: [2018, 2019, 2020, 2021] + }, + { + name: '程文英', + year: [2018, 2019, 2020, 2021, 2022, 2023, 2024] + }, + { + name: '马庭宝', + year: [2018, 2019, 2020, 2021, 2022, 2023, 2024] + }, + { + name: '陶承义', + year: [2018, 2019, 2020, 2021, 2022, 2023, 2024] + }, + { + name: '傅兆增', + year: [2018, 2019, 2020] + }, + { + name: '阮定东', + year: [2018, 2019, 2020, 2021, 2022, 2023, 2024] + }, + { + name: '苏承祺', + year: [2018, 2019, 2020, 2021, 2022] + }, + { + name: '周文彬', + year: [2018, 2019, 2020, 2021, 2022, 2023, 2024] + } +]; + +const data2018 = data.map(item => ({ ...item, death: false, value: 100 })); +const data2019 = data.map(item => ({ ...item, death: !item.year.includes(2019), value: 100 })); +const data2020 = data.map(item => ({ ...item, death: !item.year.includes(2020), value: 100 })); +const data2021 = data.map(item => ({ ...item, death: !item.year.includes(2021), value: 100 })); +const data2022 = data.map(item => ({ ...item, death: !item.year.includes(2022), value: 100 })); +const data2023 = data.map(item => ({ ...item, death: !item.year.includes(2023), value: 100 })); +const data2024 = data.map(item => ({ ...item, death: !item.year.includes(2024), value: 100 })); + +export const NanJinWordCloud = () => { + const id = 'NanJinWordCloud'; + + useEffect(() => { + const container = document.getElementById(id); + const canvas = document.createElement('canvas'); + container?.appendChild(canvas); + + const story = new Story(null, { + canvas, + // canvas的宽高,设置后仅对canvas大小生效,不影响内容,如果内容过大会被裁剪 + width: 2000 / 2, + height: 800 / 2, + background: 'black', + // 对内容的缩放,不影响canvas的宽高 + scaleX: 0.5, + scaleY: 0.5 + }); + const player = new Player(story); + story.init(player); + + const spec = { + type: 'wordCloud', + wordCloudShapeConfig: { + fillingTimes: 0 + }, + background: 'transparent', + fontSizeRange: [30, 30], + random: false, + nameField: 'name', + valueField: 'value', + seriesField: 'name', + // maskShape: { + // type: 'text', + // text: '南京', + // fill: '#eee', + // fontWeight: 'bolder' + // }, + // wordMask: { + // visible: true + // }, + word: { + style: { + fill: 'black', + opacity: (datum: any) => (datum.death ? 0.2 : 1), + fontWeight: 'bolder' + } + } + }; + + story.addCharacter( + { + type: 'VChart', + id: 'radar1', + zIndex: 3, + position: { + top: 50, + left: 50, + width: 900, + height: 600 + }, + options: { + padding: { left: 0, right: 0, top: 0, bottom: 0 }, + spec, + data: [ + { + id: 'data', + values: data2018 + } + ], + panel: { + fill: 'grey', + shadowColor: 'rgba(0, 0, 0, 0.05)', + shadowBlur: 10, + shadowOffsetX: 4, + shadowOffsetY: 4, + cornerRadius: 20 + } + } + }, + { + sceneId: 'defaultScene', + actions: [ + { + startTime: 0, + action: 'appear', + payload: [ + { + animation: { + duration: 1000, + easing: 'linear' + } + } + ] + }, + ...[data2019, data2020, data2021, data2022, data2023, data2024].map((data, index) => { + return { + action: 'update', + startTime: 1000 + index * 2000, + payload: { + duration: 1000, + id: 'data', + values: data + } + } as any; + }) + ] + } + ); + + player.play(-1); + + return () => { + story.release(); + }; + }, []); + + return ; +}; diff --git a/packages/vstory/src/index.ts b/packages/vstory/src/index.ts index da0f0bf8..b529df24 100644 --- a/packages/vstory/src/index.ts +++ b/packages/vstory/src/index.ts @@ -17,3 +17,4 @@ export function registerAll() { registerEasing(); initVR(); } +export * as VUtils from '@visactor/vutils';