diff --git a/.eslintignore b/.eslintignore index 60a4e5bd5..19eeadf09 100644 --- a/.eslintignore +++ b/.eslintignore @@ -5,3 +5,5 @@ lib dist node_modules rollup.config.js +site +__tests__ diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 752f64ed1..0d6744069 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -40,7 +40,7 @@ jobs: "link": { "title": "🚀 开始自动发布 🚀", "text": "🔗 请点击链接查看详情", - "messageUrl": "https://github.com/antvis/G/actions/workflows/auto-release.yml", + "messageUrl": "https://github.com/antvis/G/actions/workflows/release.yml", "picUrl": "https://gw.alipayobjects.com/zos/antfincdn/9Ivxcn0hFl/Gtoutu.png" } } @@ -73,7 +73,7 @@ jobs: "link": { "title": "🚨 自动发布失败 🚨", "text": "🔗 请点击链接查看具体原因, 及时修复, 尝试点击右上角 [Re-run all jobs] 重试, 或手动发布 🚑", - "messageUrl": "https://github.com/antvis/G/actions/workflows/auto-release.yml", + "messageUrl": "https://github.com/antvis/G/actions/workflows/release.yml", "picUrl": "https://gw.alipayobjects.com/zos/antfincdn/9Ivxcn0hFl/Gtoutu.png" } } diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index d2cc7f655..384d9614b 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -8,6 +8,7 @@ concurrency: jobs: test: + name: Test # jest-electron 需要 macOS 环境, 但是 免费用户 并发有限制, 容易排队 https://docs.github.com/en/actions/using-github-hosted-runners/about-github-hosted-runners # runs-on: macos-latest # (目前 macos-latest 对应的是 Big Sur 11, macos-12 对应 Monterey 12) # macOS 3-core CPU, 其他 2-core CPU diff --git a/__tests__/integration/__node__tests__/webgl/d3-barchart.spec.js b/__tests__/integration/__node__tests__/webgl/d3-barchart.spec.js new file mode 100644 index 000000000..11de64307 --- /dev/null +++ b/__tests__/integration/__node__tests__/webgl/d3-barchart.spec.js @@ -0,0 +1,213 @@ +const fs = require('fs'); +const { createCanvas } = require('canvas'); +const d3 = require('d3'); +const { Canvas, Rectangle } = require('@antv/g'); +const { Renderer } = require('@antv/g-webgl'); +const { createPNGFromRawdata, sleep, diff } = require('../../util'); +const weatherDataset = require('../../data/weather.json'); + +// create a renderer, unregister plugin relative to DOM +const renderer = new Renderer({ + targets: ['webgl1'], +}); +const domInteractionPlugin = renderer.getPlugin('dom-interaction'); +renderer.unregisterPlugin(domInteractionPlugin); + +const width = 600; +const height = 500; +const gl = require('gl')(width, height, { + antialias: false, + preserveDrawingBuffer: true, + stencil: true, +}); +const mockCanvas = { + width, + height, + getContext: () => { + gl.canvas = mockCanvas; + // 模拟 DOM API,返回小程序 context,它应当和 CanvasRenderingContext2D 一致 + // @see https://developer.mozilla.org/zh-CN/docs/Web/API/HTMLCanvasElement/getContext + return gl; + }, + getBoundingClientRect: () => { + // 模拟 DOM API,返回小程序 context 相对于视口的位置 + // @see https://developer.mozilla.org/zh-CN/docs/Web/API/Element/getBoundingClientRect + return new Rectangle(0, 0, width, height); + }, +}; + +// create a node-canvas +const offscreenNodeCanvas = createCanvas(1, 1); +const canvas = new Canvas({ + width, + height, + canvas: mockCanvas, // use headless-gl + renderer, + offscreenCanvas: offscreenNodeCanvas, +}); + +const RESULT_IMAGE = '/d3-barchart.png'; +const BASELINE_IMAGE_DIR = '/snapshots'; + +describe('Render D3 barchart with g-webgl', () => { + afterEach(() => { + canvas.removeChildren(); + fs.rmSync(__dirname + RESULT_IMAGE); + }); + + afterAll(() => { + canvas.destroy(); + }); + + it('should render D3 barchart on server-side correctly.', async () => { + await canvas.ready; + + const drawBars = async () => { + // 1. Access data + const dataset = weatherDataset; + const metricAccessor = (d) => d.humidity; + const yAccessor = (d) => d.length; + + // 2. Create chart dimensions + const width = 600; + let dimensions = { + width: width, + height: width * 0.6, + margin: { + top: 30, + right: 10, + bottom: 50, + left: 50, + }, + }; + dimensions.boundedWidth = + dimensions.width - dimensions.margin.left - dimensions.margin.right; + dimensions.boundedHeight = + dimensions.height - dimensions.margin.top - dimensions.margin.bottom; + + // 3. Draw canvas + const wrapper = d3.select( + canvas.document.documentElement, // use GCanvas' document element instead of a real DOM + ); + + const bounds = wrapper + .append('g') + .style( + 'transform', + `translate(${dimensions.margin.left}px, ${dimensions.margin.top}px)`, + ); + + // 4. Create scales + + const xScale = d3 + .scaleLinear() + .domain(d3.extent(dataset, metricAccessor)) + .range([0, dimensions.boundedWidth]) + .nice(); + + const binsGenerator = d3 + .bin() + .domain(xScale.domain()) + .value(metricAccessor) + .thresholds(12); + + const bins = binsGenerator(dataset); + + const yScale = d3 + .scaleLinear() + .domain([0, d3.max(bins, yAccessor)]) + .range([dimensions.boundedHeight, 0]) + .nice(); + + // 5. Draw data + const binsGroup = bounds.append('g'); + const binGroups = binsGroup + .selectAll('g') + .data(bins) + .join('g') + .attr('class', 'bin'); + + const barPadding = 1; + const barRects = binGroups + .append('rect') + .attr('x', (d) => xScale(d.x0) + barPadding / 2) + .attr('y', (d) => yScale(yAccessor(d))) + .attr('width', (d) => + d3.max([0, xScale(d.x1) - xScale(d.x0) - barPadding]), + ) + .attr('height', (d) => dimensions.boundedHeight - yScale(yAccessor(d))) + .attr('fill', 'cornflowerblue') + .on('mouseenter', function (e) { + d3.select(e.target).attr('fill', 'red'); + }) + .on('mouseleave', function (e) { + d3.select(e.target).attr('fill', 'cornflowerblue'); + }); + + const barText = binGroups + .filter(yAccessor) + .append('text') + .attr('x', (d) => xScale(d.x0) + (xScale(d.x1) - xScale(d.x0)) / 2) + .attr('y', (d) => yScale(yAccessor(d)) - 5) + .text(yAccessor) + .attr('fill', 'darkgrey') + .style('text-anchor', 'middle') + .style('font-size', '12px') + .style('font-family', 'sans-serif'); + + const mean = d3.mean(dataset, metricAccessor); + const meanLine = bounds + .append('line') + .attr('x1', xScale(mean)) + .attr('x2', xScale(mean)) + .attr('y1', -15) + .attr('y2', dimensions.boundedHeight) + .attr('stroke-width', 1) + .attr('stroke', 'maroon') + .attr('stroke-dasharray', '2px 4px'); + + const meanLabel = bounds + .append('text') + .attr('x', xScale(mean)) + .attr('y', -20) + .text('mean') + .attr('fill', 'maroon') + .style('font-size', '12px') + .style('text-anchor', 'middle'); + + // 6. Draw peripherals + const xAxisGenerator = d3.axisBottom().scale(xScale); + + const xAxis = bounds + .append('g') + .call(xAxisGenerator) + .attr('transform', `translateY(${dimensions.boundedHeight}px)`) + .attr('fill', 'black'); + + const xAxisLabel = xAxis + .append('text') + .attr('x', dimensions.boundedWidth / 2) + .attr('y', dimensions.margin.bottom - 10) + .attr('fill', 'black') + .style('font-size', '10px') + .text('Humidity') + .style('text-transform', 'capitalize'); + }; + + drawBars(); + + await sleep(200); + + const pixels = new Uint8Array(width * height * 4); + gl.readPixels(0, 0, width, height, gl.RGBA, gl.UNSIGNED_BYTE, pixels); + + await createPNGFromRawdata(__dirname + RESULT_IMAGE, width, height, pixels); + + expect( + diff( + __dirname + RESULT_IMAGE, + __dirname + BASELINE_IMAGE_DIR + RESULT_IMAGE, + ), + ).toBeLessThan(50); + }); +}); diff --git a/__tests__/integration/__node__tests__/webgl/d3-linechart.spec.js b/__tests__/integration/__node__tests__/webgl/d3-linechart.spec.js new file mode 100644 index 000000000..1ae48d158 --- /dev/null +++ b/__tests__/integration/__node__tests__/webgl/d3-linechart.spec.js @@ -0,0 +1,177 @@ +const fs = require('fs'); +const { createCanvas } = require('canvas'); +const d3 = require('d3'); +const { Canvas, Rectangle } = require('@antv/g'); +const { Renderer } = require('@antv/g-webgl'); +const { createPNGFromRawdata, sleep, diff } = require('../../util'); +const weatherDataset = require('../../data/weather.json'); + +// create a renderer, unregister plugin relative to DOM +const renderer = new Renderer({ + targets: ['webgl1'], +}); +const domInteractionPlugin = renderer.getPlugin('dom-interaction'); +renderer.unregisterPlugin(domInteractionPlugin); + +const width = 600; +const height = 500; +const gl = require('gl')(width, height, { + antialias: false, + preserveDrawingBuffer: true, + stencil: true, +}); +const mockCanvas = { + width, + height, + getContext: () => { + gl.canvas = mockCanvas; + // 模拟 DOM API,返回小程序 context,它应当和 CanvasRenderingContext2D 一致 + // @see https://developer.mozilla.org/zh-CN/docs/Web/API/HTMLCanvasElement/getContext + return gl; + }, + getBoundingClientRect: () => { + // 模拟 DOM API,返回小程序 context 相对于视口的位置 + // @see https://developer.mozilla.org/zh-CN/docs/Web/API/Element/getBoundingClientRect + return new Rectangle(0, 0, width, height); + }, +}; + +// create a node-canvas +const offscreenNodeCanvas = createCanvas(1, 1); +const canvas = new Canvas({ + width, + height, + canvas: mockCanvas, // use headless-gl + renderer, + offscreenCanvas: offscreenNodeCanvas, +}); + +const RESULT_IMAGE = '/d3-linechart.png'; +const BASELINE_IMAGE_DIR = '/snapshots'; + +describe('Render D3 linechart with g-webgl', () => { + afterEach(() => { + canvas.removeChildren(); + fs.rmSync(__dirname + RESULT_IMAGE); + }); + + afterAll(() => { + canvas.destroy(); + }); + + it('should render D3 linechart on server-side correctly.', async () => { + await canvas.ready; + + const drawLineChart = () => { + // 1. Access data + const data = weatherDataset; + const parseDate = d3.timeParse('%Y-%m-%d'); + //define x axis with xAccessor, wrape with parseDate from above + const xAccessor = (d) => parseDate(d['date']); + const yAccessor = (d) => d['temperatureMax']; + + // 2. Create chart dimensions + const width = 600; + let dimensions = { + width: width, + height: width * 0.6, + margin: { + top: 30, + right: 10, + bottom: 50, + left: 50, + }, + }; + dimensions.boundedWidth = + dimensions.width - dimensions.margin.left - dimensions.margin.right; + dimensions.boundedHeight = + dimensions.height - dimensions.margin.top - dimensions.margin.bottom; + + // 3. Draw canvas + const container = d3 + .select( + canvas.document.documentElement, // use GCanvas' document element instead of a real DOM + ) + .append('g') + .attr('x', dimensions.margin.left) + .attr('y', dimensions.margin.top); + + // 4. Create scales + + const yScale = d3 + .scaleLinear() + //domain is the min and max input value, range is min and max output + //domain should be the smallest and largest numbers our y axis will need to handle — in this case the lowest and highest max temperature in our dataset. + // could define ourselves with .domain([0, 100]) + //better to use d3.extent, which will figure if out for us + //needs two parameters, the data and the yAccessor (temp max) + .domain(d3.extent(data, yAccessor)) + //range, in this case, should be min and max on xaxis. Can use boundedHeight to stay within margins + .range([dimensions.boundedHeight, 0]); + + //Draw a rectangle covering all temps below freezing. + //define scale - 32 degrees + const freezingTemperaturePlacement = yScale(32); + //create the rectangle with x,y, width and height + const freezingTemperatures = container + .append('rect') + .attr('x', 0) + .attr('width', dimensions.boundedWidth) + .attr('y', freezingTemperaturePlacement) + .attr('height', dimensions.boundedHeight - freezingTemperaturePlacement) + .attr('fill', '#e0f3f3'); + + const xScale = d3 + .scaleTime() + .domain(d3.extent(data, xAccessor)) + .range([0, dimensions.boundedWidth]); + + // 5. Draw data + + //We transform our data point with both the accessor function and the scale to get the scaled value in pixel space. + + const lineGenerator = d3 + .line() + .x((d) => xScale(xAccessor(d))) + .y((d) => yScale(yAccessor(d))); + + //Now add the path element to the points + // Will be filled by default. Use styles to add a stroke + const line = container + .append('path') + .attr('d', lineGenerator(data)) + .attr('fill', 'none') + .attr('stroke', '#af9358') + .attr('stroke-width', 2); + + // 6. Draw Axis + + const yAxisGenerator = d3.axisLeft().scale(yScale); + + const yAxis = container.append('g').call(yAxisGenerator); + + const xAxisGenerator = d3.axisBottom().scale(xScale); + + const xAxis = container + .append('g') + .call(xAxisGenerator) + .style('transform', `translateY(${dimensions.boundedHeight}px)`); + }; + + drawLineChart(); + + await sleep(200); + + const pixels = new Uint8Array(width * height * 4); + gl.readPixels(0, 0, width, height, gl.RGBA, gl.UNSIGNED_BYTE, pixels); + + await createPNGFromRawdata(__dirname + RESULT_IMAGE, width, height, pixels); + + expect( + diff( + __dirname + RESULT_IMAGE, + __dirname + BASELINE_IMAGE_DIR + RESULT_IMAGE, + ), + ).toBeLessThan(Infinity); + }); +}); diff --git a/__tests__/integration/__node__tests__/webgl/d3-scatterchart.spec.js b/__tests__/integration/__node__tests__/webgl/d3-scatterchart.spec.js new file mode 100644 index 000000000..f919e1b82 --- /dev/null +++ b/__tests__/integration/__node__tests__/webgl/d3-scatterchart.spec.js @@ -0,0 +1,185 @@ +const fs = require('fs'); +const { createCanvas } = require('canvas'); +const d3 = require('d3'); +const { Canvas, Rectangle } = require('@antv/g'); +const { Renderer } = require('@antv/g-webgl'); +const { createPNGFromRawdata, sleep, diff } = require('../../util'); +const weatherDataset = require('../../data/weather.json'); + +// create a renderer, unregister plugin relative to DOM +const renderer = new Renderer({ + targets: ['webgl1'], +}); +const domInteractionPlugin = renderer.getPlugin('dom-interaction'); +renderer.unregisterPlugin(domInteractionPlugin); + +const width = 600; +const height = 500; +const gl = require('gl')(width, height, { + antialias: false, + preserveDrawingBuffer: true, + stencil: true, +}); +const mockCanvas = { + width, + height, + getContext: () => { + gl.canvas = mockCanvas; + // 模拟 DOM API,返回小程序 context,它应当和 CanvasRenderingContext2D 一致 + // @see https://developer.mozilla.org/zh-CN/docs/Web/API/HTMLCanvasElement/getContext + return gl; + }, + getBoundingClientRect: () => { + // 模拟 DOM API,返回小程序 context 相对于视口的位置 + // @see https://developer.mozilla.org/zh-CN/docs/Web/API/Element/getBoundingClientRect + return new Rectangle(0, 0, width, height); + }, +}; + +// create a node-canvas +const offscreenNodeCanvas = createCanvas(1, 1); +const canvas = new Canvas({ + width, + height, + canvas: mockCanvas, // use headless-gl + renderer, + offscreenCanvas: offscreenNodeCanvas, +}); + +const RESULT_IMAGE = '/d3-scatterchart.png'; +const BASELINE_IMAGE_DIR = '/snapshots'; + +describe('Render D3 scatterchart with g-webgl', () => { + afterEach(() => { + canvas.removeChildren(); + fs.rmSync(__dirname + RESULT_IMAGE); + }); + + afterAll(() => { + canvas.destroy(); + }); + + it('should render D3 linechart on server-side correctly.', async () => { + await canvas.ready; + + const drawScatter = () => { + // 1. Access data + const dataset = weatherDataset; + const xAccessor = (d) => d.dewPoint; + const yAccessor = (d) => d.humidity; + const colorAccessor = (d) => d.cloudCover; + + // 2. Create chart dimensions + const width = 600; + let dimensions = { + width: width, + height: width, + margin: { + top: 10, + right: 10, + bottom: 50, + left: 50, + }, + }; + dimensions.boundedWidth = + dimensions.width - dimensions.margin.left - dimensions.margin.right; + dimensions.boundedHeight = + dimensions.height - dimensions.margin.top - dimensions.margin.bottom; + + // 3. Draw canvas + const bounds = d3 + .select( + canvas.document.documentElement, // use GCanvas' document element instead of a real DOM + ) + .append('g') + .attr('x', dimensions.margin.left) + .attr('y', dimensions.margin.top); + + // 4. Create scales + + const xScale = d3 + .scaleLinear() + .domain(d3.extent(dataset, xAccessor)) + .range([0, dimensions.boundedWidth]) + .nice(); + + const yScale = d3 + .scaleLinear() + .domain(d3.extent(dataset, yAccessor)) + .range([dimensions.boundedHeight, 0]) + .nice(); + + const colorScale = d3 + .scaleLinear() + .domain(d3.extent(dataset, colorAccessor)) + .range(['skyblue', 'darkslategrey']); + + // 5. Draw data + + const dots = bounds.selectAll('circle').data(dataset); + + dots + .join('circle') + .attr('cx', (d) => xScale(xAccessor(d))) + .attr('cy', (d) => yScale(yAccessor(d))) + .attr('r', 5) + .attr('fill', (d) => colorScale(colorAccessor(d))); + + // 6. Draw Preipherals - x axis and y axis + + //create a variable for xaxis and define it + const xAxisGenerator = d3.axisBottom().scale(xScale); + + //add to the bounds + const xAxis = bounds + .append('g') + .call(xAxisGenerator) + //move to the bottom of the screen + .style('transform', `translateY(${dimensions.boundedHeight}px)`); + + const xAxisLabel = xAxis + .append('text') + .attr('x', dimensions.boundedWidth / 2) + .attr('y', dimensions.margin.bottom - 10) + .attr('fill', 'black') + .style('font-size', '1.4em') + .html('Dew point (°F)'); + + //same thing with the y axis + const yAxisGenerator = d3 + .axisLeft() + .scale(yScale) + //define the number of ticks that you want + .ticks(4); + + const yAxis = bounds.append('g').call(yAxisGenerator); + + const yAxisLabel = yAxis + .append('text') + //using negative dimensions so we can rotate below with transform + .attr('x', -dimensions.boundedHeight / 2) + .attr('y', -dimensions.margin.left + 10) + .style('fill', 'black') + .text('Relative Humidity') + .style('transform', 'rotate(-90deg)') + .style('font-size', '1.4em') + .style('text-anchor', 'middle'); + }; + + drawScatter(); + + await sleep(200); + + const pixels = new Uint8Array(width * height * 4); + gl.readPixels(0, 0, width, height, gl.RGBA, gl.UNSIGNED_BYTE, pixels); + + await createPNGFromRawdata(__dirname + RESULT_IMAGE, width, height, pixels); + + expect( + diff( + __dirname + RESULT_IMAGE, + __dirname + BASELINE_IMAGE_DIR + RESULT_IMAGE, + ), + ).toBeLessThan(50); + }); +}); diff --git a/__tests__/integration/__node__tests__/webgl/snapshots/d3-barchart.png b/__tests__/integration/__node__tests__/webgl/snapshots/d3-barchart.png new file mode 100644 index 000000000..ced8c8df4 Binary files /dev/null and b/__tests__/integration/__node__tests__/webgl/snapshots/d3-barchart.png differ diff --git a/__tests__/integration/__node__tests__/webgl/snapshots/d3-linechart.png b/__tests__/integration/__node__tests__/webgl/snapshots/d3-linechart.png new file mode 100644 index 000000000..eb7cefeb0 Binary files /dev/null and b/__tests__/integration/__node__tests__/webgl/snapshots/d3-linechart.png differ diff --git a/__tests__/integration/__node__tests__/webgl/snapshots/d3-scatterchart.png b/__tests__/integration/__node__tests__/webgl/snapshots/d3-scatterchart.png new file mode 100644 index 000000000..41103c7af Binary files /dev/null and b/__tests__/integration/__node__tests__/webgl/snapshots/d3-scatterchart.png differ diff --git a/__tests__/unit/camera/camera.spec.ts b/__tests__/unit/camera/camera.spec.ts index 82de6b138..d108f7294 100644 --- a/__tests__/unit/camera/camera.spec.ts +++ b/__tests__/unit/camera/camera.spec.ts @@ -5,6 +5,7 @@ import { AdvancedCamera, CameraProjectionMode, Canvas, + ClipSpaceNearZ, } from '../../../packages/g/src'; expect.extend({ toBeDeepCloseTo, toMatchCloseTo }); @@ -127,6 +128,153 @@ describe('Camera', () => { expect(camera.getAzimuth()).toBe(0); }); + it('should create an orthoZO camera correctly', () => { + const width = 600; + const height = 500; + const camera = new AdvancedCamera(); + camera.clipSpaceNearZ = ClipSpaceNearZ.ZERO; + camera + .setPosition(width / 2, height / 2, 500) + .setFocalPoint(width / 2, height / 2, 0) + .setOrthographic( + width / -2, + width / 2, + height / -2, + height / 2, + 0.1, + 1000, + ); + + expect(camera.getProjectionMode()).toBe(CameraProjectionMode.ORTHOGRAPHIC); + expect(camera.getZoom()).toBe(1); + expect(camera.getFar()).toBe(1000); + expect(camera.getNear()).toBe(0.1); + expect(camera.getPosition()).toStrictEqual(vec3.fromValues(300, 250, 500)); + expect(camera.getFocalPoint()).toStrictEqual(vec3.fromValues(300, 250, 0)); + expect(camera.getDistance()).toBe(500); + + expect(camera.getViewTransform()).toStrictEqual( + mat4.fromValues(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -300, -250, -500, 1), + ); + expect(camera.getWorldTransform()).toStrictEqual( + mat4.fromValues(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 300, 250, 500, 1), + ); + + expect(camera.getPerspective()).toBeDeepCloseTo( + mat4.fromValues( + 0.0033333334140479565, + 0, + 0, + 0, + -0, + 0.004000000189989805, + -0, + -0, + 0, + 0, + -0.0020002000965178013, + 0, + -0, + 0, + -0.00010001000191550702, + 1, + ), + ); + }); + + it('should create an perspective camera correctly', () => { + const width = 600; + const height = 500; + const camera = new AdvancedCamera(); + camera + .setPosition(width / 2, height / 2, 500) + .setFocalPoint(width / 2, height / 2, 0) + .setPerspective(0.1, 1000, 45, width / height); + + expect(camera.getProjectionMode()).toBe(CameraProjectionMode.PERSPECTIVE); + expect(camera.getZoom()).toBe(1); + expect(camera.getFar()).toBe(1000); + expect(camera.getNear()).toBe(0.1); + expect(camera.getPosition()).toStrictEqual(vec3.fromValues(300, 250, 500)); + expect(camera.getFocalPoint()).toStrictEqual(vec3.fromValues(300, 250, 0)); + expect(camera.getDistance()).toBe(500); + + expect(camera.getViewTransform()).toStrictEqual( + mat4.fromValues(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -300, -250, -500, 1), + ); + expect(camera.getWorldTransform()).toStrictEqual( + mat4.fromValues(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 300, 250, 500, 1), + ); + + expect(camera.getPerspective()).toBeDeepCloseTo( + mat4.fromValues( + 2.0118446350097656, + 0, + 0, + 0, + -0, + -2.4142136573791504, + -0, + -0, + 0, + 0, + -1.0002000331878662, + -1, + -0, + 0, + -0.20002000033855438, + 0, + ), + ); + }); + + it('should create an perspectiveZO camera correctly', () => { + const width = 600; + const height = 500; + const camera = new AdvancedCamera(); + camera.clipSpaceNearZ = ClipSpaceNearZ.ZERO; + camera + .setPosition(width / 2, height / 2, 500) + .setFocalPoint(width / 2, height / 2, 0) + .setPerspective(0.1, 1000, 45, width / height); + + expect(camera.getProjectionMode()).toBe(CameraProjectionMode.PERSPECTIVE); + expect(camera.getZoom()).toBe(1); + expect(camera.getFar()).toBe(1000); + expect(camera.getNear()).toBe(0.1); + expect(camera.getPosition()).toStrictEqual(vec3.fromValues(300, 250, 500)); + expect(camera.getFocalPoint()).toStrictEqual(vec3.fromValues(300, 250, 0)); + expect(camera.getDistance()).toBe(500); + + expect(camera.getViewTransform()).toStrictEqual( + mat4.fromValues(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -300, -250, -500, 1), + ); + expect(camera.getWorldTransform()).toStrictEqual( + mat4.fromValues(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 300, 250, 500, 1), + ); + + expect(camera.getPerspective()).toBeDeepCloseTo( + mat4.fromValues( + 2.0118446350097656, + 0, + 0, + 0, + -0, + -2.4142136573791504, + -0, + -0, + 0, + 0, + -1.0002000331878662, + -1, + -0, + 0, + -0.10001000016927719, + 0, + ), + ); + }); + it('should setDistance correctly.', () => { const width = 600; const height = 500; diff --git a/__tests__/unit/css/properties/transform.spec.ts b/__tests__/unit/css/properties/transform.spec.ts index a1d98ed9d..ac7411e23 100644 --- a/__tests__/unit/css/properties/transform.spec.ts +++ b/__tests__/unit/css/properties/transform.spec.ts @@ -232,4 +232,27 @@ describe('CSSPropertyTransform', () => { expect(circle.getLocalBounds().center).toStrictEqual([10, 10, 0]); expect(circle.getLocalBounds().halfExtents).toStrictEqual([25, 25, 0]); }); + + it("should reset transform with 'none' keyword correctly.", async () => { + const circle = new Circle({ + style: { + cx: 10, + cy: 10, + r: 50, + transform: 'translate(10, 10)', + }, + }); + + await canvas.ready; + canvas.appendChild(circle); + + expect(circle.getLocalPosition()).toStrictEqual([20, 20, 0]); + expect(circle.getLocalBounds().center).toStrictEqual([20, 20, 0]); + expect(circle.getLocalBounds().halfExtents).toStrictEqual([50, 50, 0]); + + circle.style.transform = 'none'; + expect(circle.getLocalPosition()).toStrictEqual([10, 10, 0]); + expect(circle.getLocalBounds().center).toStrictEqual([10, 10, 0]); + expect(circle.getLocalBounds().halfExtents).toStrictEqual([50, 50, 0]); + }); }); diff --git a/packages/g-camera-api/CHANGELOG.md b/packages/g-camera-api/CHANGELOG.md index e23042e59..3aa625f8f 100644 --- a/packages/g-camera-api/CHANGELOG.md +++ b/packages/g-camera-api/CHANGELOG.md @@ -1,5 +1,13 @@ # @antv/g-camera-api +## 1.2.2 + +### Patch Changes + +- Updated dependencies [0eb5142d] +- Updated dependencies [71990540] + - @antv/g-lite@1.2.2 + ## 1.2.1 ### Patch Changes diff --git a/packages/g-camera-api/package.json b/packages/g-camera-api/package.json index 6663c6104..a658d28ef 100644 --- a/packages/g-camera-api/package.json +++ b/packages/g-camera-api/package.json @@ -1,6 +1,6 @@ { "name": "@antv/g-camera-api", - "version": "1.2.1", + "version": "1.2.2", "description": "A simple implementation of Camera API.", "keywords": [ "antv", diff --git a/packages/g-canvas/CHANGELOG.md b/packages/g-canvas/CHANGELOG.md index acad9bc7a..e51b91174 100644 --- a/packages/g-canvas/CHANGELOG.md +++ b/packages/g-canvas/CHANGELOG.md @@ -1,5 +1,19 @@ # @antv/g-canvas +## 1.11.2 + +### Patch Changes + +- Updated dependencies [0eb5142d] +- Updated dependencies [71990540] + - @antv/g-lite@1.2.2 + - @antv/g-plugin-canvas-path-generator@1.3.2 + - @antv/g-plugin-canvas-picker@1.10.2 + - @antv/g-plugin-canvas-renderer@1.9.2 + - @antv/g-plugin-dom-interaction@1.9.2 + - @antv/g-plugin-html-renderer@1.9.2 + - @antv/g-plugin-image-loader@1.3.2 + ## 1.11.1 ### Patch Changes diff --git a/packages/g-canvas/package.json b/packages/g-canvas/package.json index 35215da72..181d9458f 100644 --- a/packages/g-canvas/package.json +++ b/packages/g-canvas/package.json @@ -1,6 +1,6 @@ { "name": "@antv/g-canvas", - "version": "1.11.1", + "version": "1.11.2", "description": "A renderer implemented by Canvas 2D API", "keywords": [ "antv", diff --git a/packages/g-canvaskit/CHANGELOG.md b/packages/g-canvaskit/CHANGELOG.md index c343c250c..c33851d5a 100644 --- a/packages/g-canvaskit/CHANGELOG.md +++ b/packages/g-canvaskit/CHANGELOG.md @@ -1,5 +1,19 @@ # @antv/g-canvaskit +## 0.10.2 + +### Patch Changes + +- Updated dependencies [0eb5142d] +- Updated dependencies [71990540] + - @antv/g-lite@1.2.2 + - @antv/g-plugin-canvas-path-generator@1.3.2 + - @antv/g-plugin-canvas-picker@1.10.2 + - @antv/g-plugin-canvaskit-renderer@1.3.2 + - @antv/g-plugin-dom-interaction@1.9.2 + - @antv/g-plugin-html-renderer@1.9.2 + - @antv/g-plugin-image-loader@1.3.2 + ## 0.10.1 ### Patch Changes diff --git a/packages/g-canvaskit/package.json b/packages/g-canvaskit/package.json index 0dbc60f04..4c7051469 100644 --- a/packages/g-canvaskit/package.json +++ b/packages/g-canvaskit/package.json @@ -1,6 +1,6 @@ { "name": "@antv/g-canvaskit", - "version": "0.10.1", + "version": "0.10.2", "description": "A renderer implemented by CanvasKit", "keywords": [ "antv", diff --git a/packages/g-components/CHANGELOG.md b/packages/g-components/CHANGELOG.md index c0193b394..80549c369 100644 --- a/packages/g-components/CHANGELOG.md +++ b/packages/g-components/CHANGELOG.md @@ -1,5 +1,13 @@ # @antv/g-components +## 1.9.2 + +### Patch Changes + +- Updated dependencies [0eb5142d] +- Updated dependencies [71990540] + - @antv/g-lite@1.2.2 + ## 1.9.1 ### Patch Changes diff --git a/packages/g-components/package.json b/packages/g-components/package.json index f58929c4f..ab1197861 100644 --- a/packages/g-components/package.json +++ b/packages/g-components/package.json @@ -1,6 +1,6 @@ { "name": "@antv/g-components", - "version": "1.9.1", + "version": "1.9.2", "description": "Components for g", "keywords": [ "antv", diff --git a/packages/g-dom-mutation-observer-api/CHANGELOG.md b/packages/g-dom-mutation-observer-api/CHANGELOG.md index 5372a11ba..35f96bd73 100644 --- a/packages/g-dom-mutation-observer-api/CHANGELOG.md +++ b/packages/g-dom-mutation-observer-api/CHANGELOG.md @@ -1,5 +1,13 @@ # @antv/g-dom-mutation-observer-api +## 1.2.2 + +### Patch Changes + +- Updated dependencies [0eb5142d] +- Updated dependencies [71990540] + - @antv/g-lite@1.2.2 + ## 1.2.1 ### Patch Changes diff --git a/packages/g-dom-mutation-observer-api/package.json b/packages/g-dom-mutation-observer-api/package.json index 5622f64cf..bbdac0736 100644 --- a/packages/g-dom-mutation-observer-api/package.json +++ b/packages/g-dom-mutation-observer-api/package.json @@ -1,6 +1,6 @@ { "name": "@antv/g-dom-mutation-observer-api", - "version": "1.2.1", + "version": "1.2.2", "description": "A simple implementation of DOM MutationObserver API.", "keywords": [ "antv", diff --git a/packages/g-gesture/CHANGELOG.md b/packages/g-gesture/CHANGELOG.md index 920883a37..9669f3ee2 100644 --- a/packages/g-gesture/CHANGELOG.md +++ b/packages/g-gesture/CHANGELOG.md @@ -1,5 +1,13 @@ # @antv/g-gesture +## 2.2.2 + +### Patch Changes + +- Updated dependencies [0eb5142d] +- Updated dependencies [71990540] + - @antv/g-lite@1.2.2 + ## 2.2.1 ### Patch Changes diff --git a/packages/g-gesture/package.json b/packages/g-gesture/package.json index b8a3810a3..69d7f1de7 100644 --- a/packages/g-gesture/package.json +++ b/packages/g-gesture/package.json @@ -1,6 +1,6 @@ { "name": "@antv/g-gesture", - "version": "2.2.1", + "version": "2.2.2", "description": "G Gesture", "keywords": [ "antv", diff --git a/packages/g-image-exporter/CHANGELOG.md b/packages/g-image-exporter/CHANGELOG.md index db54d6d38..c08be0159 100644 --- a/packages/g-image-exporter/CHANGELOG.md +++ b/packages/g-image-exporter/CHANGELOG.md @@ -1,5 +1,13 @@ # @antv/g-image-exporter +## 0.7.2 + +### Patch Changes + +- Updated dependencies [0eb5142d] +- Updated dependencies [71990540] + - @antv/g-lite@1.2.2 + ## 0.7.1 ### Patch Changes diff --git a/packages/g-image-exporter/package.json b/packages/g-image-exporter/package.json index f7ecc6b93..6cae9dc87 100644 --- a/packages/g-image-exporter/package.json +++ b/packages/g-image-exporter/package.json @@ -1,6 +1,6 @@ { "name": "@antv/g-image-exporter", - "version": "0.7.1", + "version": "0.7.2", "description": "A image exporter for G using DOM API", "keywords": [ "antv", diff --git a/packages/g-lite/CHANGELOG.md b/packages/g-lite/CHANGELOG.md index be0c2e76f..589ad4259 100644 --- a/packages/g-lite/CHANGELOG.md +++ b/packages/g-lite/CHANGELOG.md @@ -1,5 +1,12 @@ # @antv/g-lite +## 1.2.2 + +### Patch Changes + +- 0eb5142d: Avoid overriding defXY when parsing path +- 71990540: Make picking process async for WebGL2 & WebGPU implementations + ## 1.2.1 ### Patch Changes diff --git a/packages/g-lite/package.json b/packages/g-lite/package.json index 2686c8f2a..9448bb669 100644 --- a/packages/g-lite/package.json +++ b/packages/g-lite/package.json @@ -1,6 +1,6 @@ { "name": "@antv/g-lite", - "version": "1.2.1", + "version": "1.2.2", "description": "A core module for rendering engine implements DOM API.", "keywords": [ "antv", diff --git a/packages/g-lite/src/AbstractRenderer.ts b/packages/g-lite/src/AbstractRenderer.ts index 1d4a1771d..8fd28d759 100644 --- a/packages/g-lite/src/AbstractRenderer.ts +++ b/packages/g-lite/src/AbstractRenderer.ts @@ -1,7 +1,7 @@ import type { CanvasContext } from './dom'; import { GlobalRuntime } from './global-runtime'; import type { RenderingPlugin } from './services'; -import type { RendererConfig } from './types'; +import { ClipSpaceNearZ, RendererConfig } from './types'; export interface RendererPlugin { name: string; @@ -36,6 +36,12 @@ export abstract class AbstractRendererPlugin } export interface IRenderer { + /** + * The near/far clip planes correspond to a normalized device coordinate Z range of [0, 1], + * which matches WebGPU/Vulkan/DirectX/Metal's clip volume, while [-1, 1] matches WebGL/OpenGL's clip volume. + */ + clipSpaceNearZ: ClipSpaceNearZ; + getConfig: () => RendererConfig; /** @@ -60,6 +66,7 @@ export interface IRenderer { } export class AbstractRenderer implements IRenderer { + clipSpaceNearZ = ClipSpaceNearZ.NEGATIVE_ONE; private plugins: RendererPlugin[] = []; private config: RendererConfig; diff --git a/packages/g-lite/src/Canvas.ts b/packages/g-lite/src/Canvas.ts index 3040e02dd..ded778205 100644 --- a/packages/g-lite/src/Canvas.ts +++ b/packages/g-lite/src/Canvas.ts @@ -21,7 +21,12 @@ import { FrustumCullingStrategy } from './plugins/FrustumCullingStrategy'; import { PrepareRendererPlugin } from './plugins/PrepareRendererPlugin'; import { EventService, RenderReason, RenderingService } from './services'; import type { PointLike } from './shapes'; -import type { CanvasConfig, Cursor, InteractivePointerEvent } from './types'; +import type { + CanvasConfig, + ClipSpaceNearZ, + Cursor, + InteractivePointerEvent, +} from './types'; import { caf, cleanExistedCanvas, @@ -227,7 +232,7 @@ export class Canvas extends EventTarget implements ICanvas { alwaysTriggerPointerEventOnCanvas, }); - this.initDefaultCamera(canvasWidth, canvasHeight); + this.initDefaultCamera(canvasWidth, canvasHeight, renderer.clipSpaceNearZ); this.initRenderer(renderer, true); } @@ -251,9 +256,14 @@ export class Canvas extends EventTarget implements ICanvas { }; } - private initDefaultCamera(width: number, height: number) { + private initDefaultCamera( + width: number, + height: number, + clipSpaceNearZ: ClipSpaceNearZ, + ) { // set a default ortho camera const camera = new runtime.CameraContribution(); + camera.clipSpaceNearZ = clipSpaceNearZ; camera .setType(CameraType.EXPLORING, CameraTrackingMode.DEFAULT) diff --git a/packages/g-lite/src/camera/Camera.ts b/packages/g-lite/src/camera/Camera.ts index 7f9799eae..b0955eda2 100644 --- a/packages/g-lite/src/camera/Camera.ts +++ b/packages/g-lite/src/camera/Camera.ts @@ -3,7 +3,7 @@ import type { vec2 } from 'gl-matrix'; import { mat3, mat4, quat, vec3, vec4 } from 'gl-matrix'; import type { Canvas } from '../Canvas'; import { Frustum } from '../shapes'; -import type { TypeEasingFunction } from '../types'; +import { ClipSpaceNearZ, TypeEasingFunction } from '../types'; import { ERROR_MSG_METHOD_NOT_IMPLEMENTED } from '../utils/error'; import { createVec3, @@ -37,47 +37,50 @@ const MIN_DISTANCE = 0.0002; export class Camera implements ICamera { canvas: Canvas; + /** + * Clip space near Z, default to range `[-1, 1]` + */ + clipSpaceNearZ = ClipSpaceNearZ.NEGATIVE_ONE; + eventEmitter = new EventEmitter(); /** - * 相机矩阵 + * Matrix of camera */ protected matrix = mat4.create(); /** - * u 轴 + * u axis +X is right * @see http://learnwebgl.brown37.net/07_cameras/camera_introduction.html#a-camera-definition */ protected right = vec3.fromValues(1, 0, 0); /** - * v 轴 +Y is down + * v axis +Y is up */ protected up = vec3.fromValues(0, 1, 0); /** - * n 轴 +Z is inside + * n axis +Z is inside */ protected forward = vec3.fromValues(0, 0, 1); /** - * 相机位置 + * Position of camera. */ protected position = vec3.fromValues(0, 0, 1); /** - * 视点位置 + * Position of focal point. */ protected focalPoint = vec3.fromValues(0, 0, 0); /** - * 视点到相机位置的向量 - * focalPoint - position + * vector from focalPoint to position */ protected distanceVector = vec3.fromValues(0, 0, -1); /** - * 相机位置到视点距离 * length(focalPoint - position) */ protected distance = 1; @@ -490,6 +493,7 @@ export class Camera implements ICamera { top - height, near, this.far, + this.clipSpaceNearZ === ClipSpaceNearZ.ZERO, ); // flipY since the origin of OpenGL/WebGL is bottom-left compared with top-left in Canvas2D mat4.scale( @@ -542,7 +546,11 @@ export class Camera implements ICamera { bottom = top - scaleH * this.view.height; } - mat4.ortho(this.projectionMatrix, left, right, bottom, top, near, far); + if (this.clipSpaceNearZ === ClipSpaceNearZ.NEGATIVE_ONE) { + mat4.ortho(this.projectionMatrix, left, right, bottom, top, near, far); + } else { + mat4.orthoZO(this.projectionMatrix, left, right, bottom, top, near, far); + } // flipY since the origin of OpenGL/WebGL is bottom-left compared with top-left in Canvas2D mat4.scale( diff --git a/packages/g-lite/src/css/StyleValueRegistry.ts b/packages/g-lite/src/css/StyleValueRegistry.ts index 0627a97b9..335f48281 100644 --- a/packages/g-lite/src/css/StyleValueRegistry.ts +++ b/packages/g-lite/src/css/StyleValueRegistry.ts @@ -757,8 +757,10 @@ export class DefaultStyleValueRegistry implements StyleValueRegistry { object.parsedStyle.path = parsePath( // @ts-ignore attributes.path, - object, ); + + object.parsedStyle.defX = object.parsedStyle.path.rect.x; + object.parsedStyle.defY = object.parsedStyle.path.rect.y; } // Text if (attributes.textTransform) { diff --git a/packages/g-lite/src/css/parser/path.ts b/packages/g-lite/src/css/parser/path.ts index 745d82daf..4f6e6bf27 100644 --- a/packages/g-lite/src/css/parser/path.ts +++ b/packages/g-lite/src/css/parser/path.ts @@ -9,10 +9,7 @@ import { path2Curve, reverseCurve, } from '@antv/util'; -import type { - DisplayObject, - ParsedPathStyleProps, -} from '../../display-objects'; +import type { ParsedPathStyleProps } from '../../display-objects'; import type { IElement } from '../../dom'; import { memoize } from '../../utils/memoize'; import { @@ -82,18 +79,10 @@ const memoizedParsePath = memoize(internalParsePath); export function parsePath( path: string | PathArray, - object?: DisplayObject, ): ParsedPathStyleProps['path'] { - const result = ( + return ( isString(path) ? memoizedParsePath(path) : internalParsePath(path) ) as ParsedPathStyleProps['path']; - - if (object) { - object.parsedStyle.defX = result.rect.x; - object.parsedStyle.defY = result.rect.y; - } - - return result; } export function mergePaths( diff --git a/packages/g-lite/src/css/properties/CSSPropertyPath.ts b/packages/g-lite/src/css/properties/CSSPropertyPath.ts index d1c51416a..42b003efb 100644 --- a/packages/g-lite/src/css/properties/CSSPropertyPath.ts +++ b/packages/g-lite/src/css/properties/CSSPropertyPath.ts @@ -48,6 +48,9 @@ export class CSSPropertyPath * update local position */ postProcessor(object: DisplayObject, attributes: string[]) { + object.parsedStyle.defX = object.parsedStyle.path.rect.x; + object.parsedStyle.defY = object.parsedStyle.path.rect.y; + if ( object.nodeName === Shape.PATH && attributes.indexOf('transform') === -1 diff --git a/packages/g-lite/src/display-objects/Path.ts b/packages/g-lite/src/display-objects/Path.ts index f69a25941..a2926dcf0 100644 --- a/packages/g-lite/src/display-objects/Path.ts +++ b/packages/g-lite/src/display-objects/Path.ts @@ -40,6 +40,8 @@ export interface PathStyleProps extends BaseStyleProps { * offset relative to original position */ markerEndOffset?: number; + + isBillboard?: boolean; } export interface PathSegmentBBox { @@ -105,6 +107,7 @@ export interface ParsedPathStyleProps extends ParsedBaseStyleProps { markerEnd?: DisplayObject | null; markerStartOffset?: number; markerEndOffset?: number; + isBillboard?: boolean; } export class Path extends DisplayObject { private markerStartAngle = 0; diff --git a/packages/g-lite/src/plugins/EventPlugin.ts b/packages/g-lite/src/plugins/EventPlugin.ts index 3ae830171..3163eb24d 100644 --- a/packages/g-lite/src/plugins/EventPlugin.ts +++ b/packages/g-lite/src/plugins/EventPlugin.ts @@ -29,14 +29,17 @@ export class EventPlugin implements RenderingPlugin { const canvas = this.context.renderingContext.root.ownerDocument.defaultView; - this.context.eventService.setPickHandler((position: EventPosition) => { - const { picked } = this.context.renderingService.hooks.pickSync.call({ - position, - picked: [], - topmost: true, // we only concern the topmost element - }); - return picked[0] || null; - }); + this.context.eventService.setPickHandler( + async (position: EventPosition) => { + const { picked } = + await this.context.renderingService.hooks.pick.promise({ + position, + picked: [], + topmost: true, // we only concern the topmost element + }); + return picked[0] || null; + }, + ); renderingService.hooks.pointerWheel.tap( EventPlugin.tag, diff --git a/packages/g-lite/src/services/EventService.ts b/packages/g-lite/src/services/EventService.ts index ba4e141d0..ca665410d 100644 --- a/packages/g-lite/src/services/EventService.ts +++ b/packages/g-lite/src/services/EventService.ts @@ -18,7 +18,7 @@ import { Point } from '../shapes'; import type { Cursor, EventPosition } from '../types'; import { isElement } from '../utils/dom'; -type Picker = (position: EventPosition) => IEventTarget | null; +type Picker = (position: EventPosition) => Promise; type TrackingData = { pressTargetsByButton: Record; clicksByButton: Record< @@ -180,12 +180,8 @@ export class EventService { } } - onPointerDown = (from: FederatedPointerEvent) => { - // if (!(from instanceof FederatedPointerEvent)) { - // return; - // } - - const e = this.createPointerEvent(from); + onPointerDown = async (from: FederatedPointerEvent) => { + const e = await this.createPointerEvent(from); this.dispatchEvent(e, 'pointerdown'); @@ -203,13 +199,9 @@ export class EventService { this.freeEvent(e); }; - onPointerUp = (from: FederatedPointerEvent) => { - // if (!(from instanceof FederatedPointerEvent)) { - // return; - // } - + onPointerUp = async (from: FederatedPointerEvent) => { const now = performance.now(); - const e = this.createPointerEvent( + const e = await this.createPointerEvent( from, undefined, undefined, @@ -315,12 +307,8 @@ export class EventService { this.freeEvent(e); }; - onPointerMove = (from: FederatedPointerEvent) => { - // if (!(from instanceof FederatedPointerEvent)) { - // return; - // } - - const e = this.createPointerEvent( + onPointerMove = async (from: FederatedPointerEvent) => { + const e = await this.createPointerEvent( from, undefined, undefined, @@ -337,7 +325,7 @@ export class EventService { if (trackingData.overTargets && outTarget !== e.target) { // pointerout always occurs on the overTarget when the pointer hovers over another element. const outType = from.type === 'mousemove' ? 'mouseout' : 'pointerout'; - const outEvent = this.createPointerEvent( + const outEvent = await this.createPointerEvent( from, outType, outTarget || undefined, @@ -349,7 +337,7 @@ export class EventService { // If the pointer exits overTarget and its descendants, then a pointerleave event is also fired. This event // is dispatched to all ancestors that no longer capture the pointer. if (!e.composedPath().includes(outTarget!)) { - const leaveEvent = this.createPointerEvent( + const leaveEvent = await this.createPointerEvent( from, 'pointerleave', outTarget || undefined, @@ -451,11 +439,7 @@ export class EventService { this.freeEvent(e); }; - onPointerOut = (from: FederatedPointerEvent) => { - // if (!(from instanceof FederatedPointerEvent)) { - // return; - // } - + onPointerOut = async (from: FederatedPointerEvent) => { const trackingData = this.trackingData(from.pointerId); if (trackingData.overTargets) { @@ -464,7 +448,7 @@ export class EventService { const outTarget = this.findMountedTarget(trackingData.overTargets); // pointerout first - const outEvent = this.createPointerEvent( + const outEvent = await this.createPointerEvent( from, 'pointerout', outTarget || undefined, @@ -475,7 +459,7 @@ export class EventService { // pointerleave(s) are also dispatched b/c the pointer must've left rootTarget and its descendants to // get an upstream pointerout event (upstream events do not know rootTarget has descendants). - const leaveEvent = this.createPointerEvent( + const leaveEvent = await this.createPointerEvent( from, 'pointerleave', outTarget || undefined, @@ -509,13 +493,9 @@ export class EventService { this.cursor = null; }; - onPointerOver = (from: FederatedPointerEvent) => { - // if (!(from instanceof FederatedPointerEvent)) { - // return; - // } - + onPointerOver = async (from: FederatedPointerEvent) => { const trackingData = this.trackingData(from.pointerId); - const e = this.createPointerEvent(from); + const e = await this.createPointerEvent(from); const isMouse = e.pointerType === 'mouse' || e.pointerType === 'pen'; @@ -553,16 +533,12 @@ export class EventService { this.freeEvent(enterEvent); }; - onPointerUpOutside = (from: FederatedPointerEvent) => { - // if (!(from instanceof FederatedPointerEvent)) { - // return; - // } - + onPointerUpOutside = async (from: FederatedPointerEvent) => { const trackingData = this.trackingData(from.pointerId); const pressTarget = this.findMountedTarget( trackingData.pressTargetsByButton[from.button], ); - const e = this.createPointerEvent(from); + const e = await this.createPointerEvent(from); if (pressTarget) { let currentTarget: IEventTarget | null = pressTarget; @@ -592,27 +568,27 @@ export class EventService { this.freeEvent(e); }; - onWheel = (from: FederatedWheelEvent) => { + onWheel = async (from: FederatedWheelEvent) => { // if (!(from instanceof FederatedWheelEvent)) { // return; // } - const wheelEvent = this.createWheelEvent(from); + const wheelEvent = await this.createWheelEvent(from); this.dispatchEvent(wheelEvent); this.freeEvent(wheelEvent); }; - onClick = (from: FederatedPointerEvent) => { + onClick = async (from: FederatedPointerEvent) => { if (this.context.config.useNativeClickEvent) { - const e = this.createPointerEvent(from); + const e = await this.createPointerEvent(from); this.dispatchEvent(e); this.freeEvent(e); } }; - onPointerCancel = (from: FederatedPointerEvent) => { - const e = this.createPointerEvent( + onPointerCancel = async (from: FederatedPointerEvent) => { + const e = await this.createPointerEvent( from, undefined, undefined, @@ -707,7 +683,7 @@ export class EventService { return propagationPath; } - hitTest(position: EventPosition): IEventTarget | null { + async hitTest(position: EventPosition): Promise { const { viewportX, viewportY } = position; const { width, height } = this.context.config; // outside canvas @@ -721,7 +697,7 @@ export class EventService { } return ( - this.pickHandler(position) || + (await this.pickHandler(position)) || this.rootTarget || // return Document null ); @@ -772,9 +748,9 @@ export class EventService { return null; } - private pickTarget( + private async pickTarget( event: FederatedPointerEvent | FederatedWheelEvent, - ): INode { + ): Promise { return this.hitTest({ clientX: event.clientX, clientY: event.clientY, @@ -782,15 +758,15 @@ export class EventService { viewportY: event.viewportY, x: event.canvasX, y: event.canvasY, - }) as INode; + }) as Promise; } - private createPointerEvent( + private async createPointerEvent( from: FederatedPointerEvent, type?: string, target?: IEventTarget, fallbackTarget?: IEventTarget, - ): FederatedPointerEvent { + ): Promise { const event = this.allocateEvent(FederatedPointerEvent); this.copyPointerData(from, event); @@ -804,7 +780,8 @@ export class EventService { event.target = target ?? (existedHTML || - (this.isNativeEventFromCanvas(event) && this.pickTarget(event)) || + (this.isNativeEventFromCanvas(event) && + (await this.pickTarget(event))) || fallbackTarget); if (typeof type === 'string') { @@ -814,7 +791,9 @@ export class EventService { return event; } - private createWheelEvent(from: FederatedWheelEvent): FederatedWheelEvent { + private async createWheelEvent( + from: FederatedWheelEvent, + ): Promise { const event = this.allocateEvent(FederatedWheelEvent); this.copyWheelData(from, event); @@ -826,7 +805,7 @@ export class EventService { const existedHTML = this.getExistedHTML(event); event.target = existedHTML || - (this.isNativeEventFromCanvas(event) && this.pickTarget(event)); + (this.isNativeEventFromCanvas(event) && (await this.pickTarget(event))); return event; } diff --git a/packages/g-lite/src/types.ts b/packages/g-lite/src/types.ts index 0558e77e1..e543390ce 100644 --- a/packages/g-lite/src/types.ts +++ b/packages/g-lite/src/types.ts @@ -331,6 +331,11 @@ export type Cursor = | 'zoom-in' | 'zoom-out'; +export enum ClipSpaceNearZ { + ZERO, + NEGATIVE_ONE, +} + export interface RendererConfig { /** * enable dirty check for displayobject diff --git a/packages/g-lite/src/utils/math.ts b/packages/g-lite/src/utils/math.ts index 9ba806a1e..28c5c1cec 100644 --- a/packages/g-lite/src/utils/math.ts +++ b/packages/g-lite/src/utils/math.ts @@ -222,14 +222,24 @@ export function makePerspective( bottom: number, near: number, far: number, + zero = false, ) { const x = (2 * near) / (right - left); const y = (2 * near) / (top - bottom); const a = (right + left) / (right - left); const b = (top + bottom) / (top - bottom); - const c = -(far + near) / (far - near); - const d = (-2 * far * near) / (far - near); + + let c: number; + let d: number; + + if (zero) { + c = -far / (far - near); + d = (-far * near) / (far - near); + } else { + c = -(far + near) / (far - near); + d = (-2 * far * near) / (far - near); + } out[0] = x; out[1] = 0; diff --git a/packages/g-lite/src/utils/transform-mat4.ts b/packages/g-lite/src/utils/transform-mat4.ts index 3e5badc9f..26766b4d0 100644 --- a/packages/g-lite/src/utils/transform-mat4.ts +++ b/packages/g-lite/src/utils/transform-mat4.ts @@ -9,117 +9,115 @@ export function parsedTransformToMat4( transform: ParsedTransform[], object: DisplayObject, ): mat4 { - if (transform && transform.length) { - const defX = object.parsedStyle.defX || 0; - const defY = object.parsedStyle.defY || 0; - // reset transform - object.resetLocalTransform(); - object.setLocalPosition(defX, defY); + const defX = object.parsedStyle.defX || 0; + const defY = object.parsedStyle.defY || 0; + // reset transform + object.resetLocalTransform(); + object.setLocalPosition(defX, defY); - transform.forEach((parsed) => { - const { t, d } = parsed; - if (t === 'scale') { - // scale(1) scale(1, 1) - const newScale = d?.map((s) => s.value) || [1, 1]; - object.scaleLocal(newScale[0], newScale[1], 1); - } else if (t === 'scalex') { - const newScale = d?.map((s) => s.value) || [1]; - object.scaleLocal(newScale[0], 1, 1); - } else if (t === 'scaley') { - const newScale = d?.map((s) => s.value) || [1]; - object.scaleLocal(1, newScale[0], 1); - } else if (t === 'scalez') { - const newScale = d?.map((s) => s.value) || [1]; - object.scaleLocal(1, 1, newScale[0]); - } else if (t === 'scale3d') { - const newScale = d?.map((s) => s.value) || [1, 1, 1]; - object.scaleLocal(newScale[0], newScale[1], newScale[2]); - } else if (t === 'translate') { - const newTranslation = d || [Opx, Opx]; - object.translateLocal( - newTranslation[0].value, - newTranslation[1].value, + transform.forEach((parsed) => { + const { t, d } = parsed; + if (t === 'scale') { + // scale(1) scale(1, 1) + const newScale = d?.map((s) => s.value) || [1, 1]; + object.scaleLocal(newScale[0], newScale[1], 1); + } else if (t === 'scalex') { + const newScale = d?.map((s) => s.value) || [1]; + object.scaleLocal(newScale[0], 1, 1); + } else if (t === 'scaley') { + const newScale = d?.map((s) => s.value) || [1]; + object.scaleLocal(1, newScale[0], 1); + } else if (t === 'scalez') { + const newScale = d?.map((s) => s.value) || [1]; + object.scaleLocal(1, 1, newScale[0]); + } else if (t === 'scale3d') { + const newScale = d?.map((s) => s.value) || [1, 1, 1]; + object.scaleLocal(newScale[0], newScale[1], newScale[2]); + } else if (t === 'translate') { + const newTranslation = d || [Opx, Opx]; + object.translateLocal( + newTranslation[0].value, + newTranslation[1].value, + 0, + ); + } else if (t === 'translatex') { + const newTranslation = d || [Opx]; + object.translateLocal(newTranslation[0].value, 0, 0); + } else if (t === 'translatey') { + const newTranslation = d || [Opx]; + object.translateLocal(0, newTranslation[0].value, 0); + } else if (t === 'translatez') { + const newTranslation = d || [Opx]; + object.translateLocal(0, 0, newTranslation[0].value); + } else if (t === 'translate3d') { + const newTranslation = d || [Opx, Opx, Opx]; + object.translateLocal( + newTranslation[0].value, + newTranslation[1].value, + newTranslation[2].value, + ); + } else if (t === 'rotate') { + const newAngles = d || [Odeg]; + object.rotateLocal(0, 0, convertAngleUnit(newAngles[0])); + } else if (t === 'rotatex') { + const newAngles = d || [Odeg]; + object.rotateLocal(convertAngleUnit(newAngles[0]), 0, 0); + } else if (t === 'rotatey') { + const newAngles = d || [Odeg]; + object.rotateLocal(0, convertAngleUnit(newAngles[0]), 0); + } else if (t === 'rotatez') { + const newAngles = d || [Odeg]; + object.rotateLocal(0, 0, convertAngleUnit(newAngles[0])); + } else if (t === 'rotate3d') { + // 暂不支持绕指定轴旋转 + // const newAngles = value && value.d || [Odeg, Odeg, Odeg]; + // const oldAngles = old && old.d || [Odeg, Odeg, Odeg]; + // object.rotateLocal( + // newAngles[0].value - oldAngles[0].value, + // newAngles[1].value - oldAngles[1].value, + // newAngles[2].value - oldAngles[2].value, + // ); + } else if (t === 'skew') { + const newSkew = d?.map((s) => s.value) || [0, 0]; + object.setLocalSkew(deg2rad(newSkew[0]), deg2rad(newSkew[1])); + } else if (t === 'skewx') { + const newSkew = d?.map((s) => s.value) || [0]; + object.setLocalSkew(deg2rad(newSkew[0]), object.getLocalSkew()[1]); + } else if (t === 'skewy') { + const newSkew = d?.map((s) => s.value) || [0]; + object.setLocalSkew(object.getLocalSkew()[0], deg2rad(newSkew[0])); + } else if (t === 'matrix') { + const [a, b, c, dd, tx, ty] = d.map((s) => s.value); + object.setLocalTransform( + mat4.set( + tmpMat4, + a, + b, 0, - ); - } else if (t === 'translatex') { - const newTranslation = d || [Opx]; - object.translateLocal(newTranslation[0].value, 0, 0); - } else if (t === 'translatey') { - const newTranslation = d || [Opx]; - object.translateLocal(0, newTranslation[0].value, 0); - } else if (t === 'translatez') { - const newTranslation = d || [Opx]; - object.translateLocal(0, 0, newTranslation[0].value); - } else if (t === 'translate3d') { - const newTranslation = d || [Opx, Opx, Opx]; - object.translateLocal( - newTranslation[0].value, - newTranslation[1].value, - newTranslation[2].value, - ); - } else if (t === 'rotate') { - const newAngles = d || [Odeg]; - object.rotateLocal(0, 0, convertAngleUnit(newAngles[0])); - } else if (t === 'rotatex') { - const newAngles = d || [Odeg]; - object.rotateLocal(convertAngleUnit(newAngles[0]), 0, 0); - } else if (t === 'rotatey') { - const newAngles = d || [Odeg]; - object.rotateLocal(0, convertAngleUnit(newAngles[0]), 0); - } else if (t === 'rotatez') { - const newAngles = d || [Odeg]; - object.rotateLocal(0, 0, convertAngleUnit(newAngles[0])); - } else if (t === 'rotate3d') { - // 暂不支持绕指定轴旋转 - // const newAngles = value && value.d || [Odeg, Odeg, Odeg]; - // const oldAngles = old && old.d || [Odeg, Odeg, Odeg]; - // object.rotateLocal( - // newAngles[0].value - oldAngles[0].value, - // newAngles[1].value - oldAngles[1].value, - // newAngles[2].value - oldAngles[2].value, - // ); - } else if (t === 'skew') { - const newSkew = d?.map((s) => s.value) || [0, 0]; - object.setLocalSkew(deg2rad(newSkew[0]), deg2rad(newSkew[1])); - } else if (t === 'skewx') { - const newSkew = d?.map((s) => s.value) || [0]; - object.setLocalSkew(deg2rad(newSkew[0]), object.getLocalSkew()[1]); - } else if (t === 'skewy') { - const newSkew = d?.map((s) => s.value) || [0]; - object.setLocalSkew(object.getLocalSkew()[0], deg2rad(newSkew[0])); - } else if (t === 'matrix') { - const [a, b, c, dd, tx, ty] = d.map((s) => s.value); - object.setLocalTransform( - mat4.set( - tmpMat4, - a, - b, - 0, - 0, - c, - dd, - 0, - 0, - 0, - 0, - 1, - 0, - tx + defX, - ty + defY, - 0, - 1, - ), - ); - } else if (t === 'matrix3d') { - // @ts-ignore - mat4.set(tmpMat4, ...d.map((s) => s.value)); + 0, + c, + dd, + 0, + 0, + 0, + 0, + 1, + 0, + tx + defX, + ty + defY, + 0, + 1, + ), + ); + } else if (t === 'matrix3d') { + // @ts-ignore + mat4.set(tmpMat4, ...d.map((s) => s.value)); - tmpMat4[12] += defX; - tmpMat4[13] += defY; - object.setLocalTransform(tmpMat4); - } - }); - } + tmpMat4[12] += defX; + tmpMat4[13] += defY; + object.setLocalTransform(tmpMat4); + } + }); return object.getLocalTransform(); } diff --git a/packages/g-lottie-player/CHANGELOG.md b/packages/g-lottie-player/CHANGELOG.md index e25c2a88f..62b38dd99 100644 --- a/packages/g-lottie-player/CHANGELOG.md +++ b/packages/g-lottie-player/CHANGELOG.md @@ -1,5 +1,13 @@ # @antv/g-lottie-player +## 0.2.2 + +### Patch Changes + +- Updated dependencies [0eb5142d] +- Updated dependencies [71990540] + - @antv/g-lite@1.2.2 + ## 0.2.1 ### Patch Changes diff --git a/packages/g-lottie-player/package.json b/packages/g-lottie-player/package.json index f3715cc12..068b0156a 100644 --- a/packages/g-lottie-player/package.json +++ b/packages/g-lottie-player/package.json @@ -1,6 +1,6 @@ { "name": "@antv/g-lottie-player", - "version": "0.2.1", + "version": "0.2.2", "description": "A lottie player for G", "keywords": [ "antv", diff --git a/packages/g-mobile-canvas-element/CHANGELOG.md b/packages/g-mobile-canvas-element/CHANGELOG.md index 1e1bb00df..c915d4dbe 100644 --- a/packages/g-mobile-canvas-element/CHANGELOG.md +++ b/packages/g-mobile-canvas-element/CHANGELOG.md @@ -1,5 +1,13 @@ # @antv/g-mobile-canvas-element +## 0.8.2 + +### Patch Changes + +- Updated dependencies [0eb5142d] +- Updated dependencies [71990540] + - @antv/g-lite@1.2.2 + ## 0.8.1 ### Patch Changes diff --git a/packages/g-mobile-canvas-element/package.json b/packages/g-mobile-canvas-element/package.json index ce8fbb940..6a3c7092f 100644 --- a/packages/g-mobile-canvas-element/package.json +++ b/packages/g-mobile-canvas-element/package.json @@ -1,6 +1,6 @@ { "name": "@antv/g-mobile-canvas-element", - "version": "0.8.1", + "version": "0.8.2", "description": "Create a CanvasLike element from existed context in mobile environment", "keywords": [ "antv", diff --git a/packages/g-mobile-canvas/CHANGELOG.md b/packages/g-mobile-canvas/CHANGELOG.md index 78179004c..4904eb4b5 100644 --- a/packages/g-mobile-canvas/CHANGELOG.md +++ b/packages/g-mobile-canvas/CHANGELOG.md @@ -1,5 +1,19 @@ # @antv/g-mobile-canvas +## 0.10.2 + +### Patch Changes + +- Updated dependencies [0eb5142d] +- Updated dependencies [71990540] + - @antv/g-lite@1.2.2 + - @antv/g-plugin-canvas-path-generator@1.3.2 + - @antv/g-plugin-canvas-picker@1.10.2 + - @antv/g-plugin-canvas-renderer@1.9.2 + - @antv/g-plugin-dragndrop@1.8.2 + - @antv/g-plugin-image-loader@1.3.2 + - @antv/g-plugin-mobile-interaction@0.9.2 + ## 0.10.1 ### Patch Changes diff --git a/packages/g-mobile-canvas/package.json b/packages/g-mobile-canvas/package.json index 7b4805f24..cc8b2f895 100644 --- a/packages/g-mobile-canvas/package.json +++ b/packages/g-mobile-canvas/package.json @@ -1,6 +1,6 @@ { "name": "@antv/g-mobile-canvas", - "version": "0.10.1", + "version": "0.10.2", "description": "A renderer implemented with Canvas2D API in mobile environment", "keywords": [ "antv", diff --git a/packages/g-mobile-svg/CHANGELOG.md b/packages/g-mobile-svg/CHANGELOG.md index 5e1f922f2..574750d47 100644 --- a/packages/g-mobile-svg/CHANGELOG.md +++ b/packages/g-mobile-svg/CHANGELOG.md @@ -1,5 +1,17 @@ # @antv/g-mobile-svg +## 0.10.2 + +### Patch Changes + +- Updated dependencies [0eb5142d] +- Updated dependencies [71990540] + - @antv/g-lite@1.2.2 + - @antv/g-plugin-dragndrop@1.8.2 + - @antv/g-plugin-mobile-interaction@0.9.2 + - @antv/g-plugin-svg-picker@1.9.2 + - @antv/g-plugin-svg-renderer@1.10.2 + ## 0.10.1 ### Patch Changes diff --git a/packages/g-mobile-svg/package.json b/packages/g-mobile-svg/package.json index 412884ba1..fbe99c9ae 100644 --- a/packages/g-mobile-svg/package.json +++ b/packages/g-mobile-svg/package.json @@ -1,6 +1,6 @@ { "name": "@antv/g-mobile-svg", - "version": "0.10.1", + "version": "0.10.2", "description": "A renderer implemented by SVG in mobile environment", "keywords": [ "antv", diff --git a/packages/g-mobile-webgl/CHANGELOG.md b/packages/g-mobile-webgl/CHANGELOG.md index d72dffc93..4fcb076ce 100644 --- a/packages/g-mobile-webgl/CHANGELOG.md +++ b/packages/g-mobile-webgl/CHANGELOG.md @@ -1,5 +1,19 @@ # @antv/g-mobile-webgl +## 0.9.2 + +### Patch Changes + +- Updated dependencies [0eb5142d] +- Updated dependencies [71990540] + - @antv/g-plugin-device-renderer@1.9.2 + - @antv/g-plugin-webgl-device@1.9.2 + - @antv/g-lite@1.2.2 + - @antv/g-plugin-dragndrop@1.8.2 + - @antv/g-plugin-html-renderer@1.9.2 + - @antv/g-plugin-image-loader@1.3.2 + - @antv/g-plugin-mobile-interaction@0.9.2 + ## 0.9.1 ### Patch Changes diff --git a/packages/g-mobile-webgl/package.json b/packages/g-mobile-webgl/package.json index 8ce60f32d..24d3049ca 100644 --- a/packages/g-mobile-webgl/package.json +++ b/packages/g-mobile-webgl/package.json @@ -1,6 +1,6 @@ { "name": "@antv/g-mobile-webgl", - "version": "0.9.1", + "version": "0.9.2", "description": "A renderer implemented by WebGL1/2 in mobile environment", "keywords": [ "antv", diff --git a/packages/g-pattern/CHANGELOG.md b/packages/g-pattern/CHANGELOG.md index f63251726..095734df8 100644 --- a/packages/g-pattern/CHANGELOG.md +++ b/packages/g-pattern/CHANGELOG.md @@ -1,5 +1,13 @@ # @antv/g-pattern +## 1.2.2 + +### Patch Changes + +- Updated dependencies [0eb5142d] +- Updated dependencies [71990540] + - @antv/g-lite@1.2.2 + ## 1.2.1 ### Patch Changes diff --git a/packages/g-pattern/package.json b/packages/g-pattern/package.json index bcdc68341..02be6e0a2 100644 --- a/packages/g-pattern/package.json +++ b/packages/g-pattern/package.json @@ -1,6 +1,6 @@ { "name": "@antv/g-pattern", - "version": "1.2.1", + "version": "1.2.2", "description": "A pattern libs for G", "keywords": [ "antv", diff --git a/packages/g-plugin-3d/CHANGELOG.md b/packages/g-plugin-3d/CHANGELOG.md index b3e2c1433..a610e7ee2 100644 --- a/packages/g-plugin-3d/CHANGELOG.md +++ b/packages/g-plugin-3d/CHANGELOG.md @@ -1,5 +1,14 @@ # @antv/g-plugin-3d +## 1.9.2 + +### Patch Changes + +- Updated dependencies [0eb5142d] +- Updated dependencies [71990540] + - @antv/g-plugin-device-renderer@1.9.2 + - @antv/g-lite@1.2.2 + ## 1.9.1 ### Patch Changes diff --git a/packages/g-plugin-3d/package.json b/packages/g-plugin-3d/package.json index a0f95f19b..aa6f06ba1 100644 --- a/packages/g-plugin-3d/package.json +++ b/packages/g-plugin-3d/package.json @@ -1,6 +1,6 @@ { "name": "@antv/g-plugin-3d", - "version": "1.9.1", + "version": "1.9.2", "description": "Provide 3D extension for G", "keywords": [ "antv", diff --git a/packages/g-plugin-a11y/CHANGELOG.md b/packages/g-plugin-a11y/CHANGELOG.md index 9df7eb6fc..1ecaafcd3 100644 --- a/packages/g-plugin-a11y/CHANGELOG.md +++ b/packages/g-plugin-a11y/CHANGELOG.md @@ -1,5 +1,13 @@ # @antv/g-plugin-a11y +## 0.6.2 + +### Patch Changes + +- Updated dependencies [0eb5142d] +- Updated dependencies [71990540] + - @antv/g-lite@1.2.2 + ## 0.6.1 ### Patch Changes diff --git a/packages/g-plugin-a11y/package.json b/packages/g-plugin-a11y/package.json index d231e067e..301a912cb 100644 --- a/packages/g-plugin-a11y/package.json +++ b/packages/g-plugin-a11y/package.json @@ -1,6 +1,6 @@ { "name": "@antv/g-plugin-a11y", - "version": "0.6.1", + "version": "0.6.2", "description": "A G plugin for accessibility", "keywords": [ "antv", diff --git a/packages/g-plugin-annotation/CHANGELOG.md b/packages/g-plugin-annotation/CHANGELOG.md index bb78a8559..b26b059bc 100644 --- a/packages/g-plugin-annotation/CHANGELOG.md +++ b/packages/g-plugin-annotation/CHANGELOG.md @@ -1,5 +1,13 @@ # @antv/g-plugin-annotation +## 0.4.2 + +### Patch Changes + +- Updated dependencies [0eb5142d] +- Updated dependencies [71990540] + - @antv/g-lite@1.2.2 + ## 0.4.1 ### Patch Changes diff --git a/packages/g-plugin-annotation/package.json b/packages/g-plugin-annotation/package.json index 631723ebe..978a3baaf 100644 --- a/packages/g-plugin-annotation/package.json +++ b/packages/g-plugin-annotation/package.json @@ -1,6 +1,6 @@ { "name": "@antv/g-plugin-annotation", - "version": "0.4.1", + "version": "0.4.2", "description": "A G plugin for annotation", "keywords": [ "antv", diff --git a/packages/g-plugin-box2d/CHANGELOG.md b/packages/g-plugin-box2d/CHANGELOG.md index 7e0cd1699..6c5ade3e2 100644 --- a/packages/g-plugin-box2d/CHANGELOG.md +++ b/packages/g-plugin-box2d/CHANGELOG.md @@ -1,5 +1,15 @@ # @antv/g-plugin-box2d +## 1.9.2 + +### Patch Changes + +- 0eb5142d: Avoid overriding defXY when parsing path +- 71990540: Make picking process async for WebGL2 & WebGPU implementations +- Updated dependencies [0eb5142d] +- Updated dependencies [71990540] + - @antv/g-lite@1.2.2 + ## 1.9.1 ### Patch Changes diff --git a/packages/g-plugin-box2d/package.json b/packages/g-plugin-box2d/package.json index b33f472ae..cefd31dc5 100644 --- a/packages/g-plugin-box2d/package.json +++ b/packages/g-plugin-box2d/package.json @@ -1,6 +1,6 @@ { "name": "@antv/g-plugin-box2d", - "version": "1.9.1", + "version": "1.9.2", "description": "A G plugin for Box2D", "keywords": [ "antv", diff --git a/packages/g-plugin-box2d/src/Box2DPlugin.ts b/packages/g-plugin-box2d/src/Box2DPlugin.ts index 098e7b2f6..4023501d8 100644 --- a/packages/g-plugin-box2d/src/Box2DPlugin.ts +++ b/packages/g-plugin-box2d/src/Box2DPlugin.ts @@ -399,34 +399,39 @@ export class Box2DPlugin implements RenderingPlugin { } private async loadBox2D(): Promise { - const hasSIMD = WebAssembly.validate( - new Uint8Array([ - 0, 97, 115, 109, 1, 0, 0, 0, 1, 5, 1, 96, 0, 1, 123, 3, 2, 1, 0, 10, 10, - 1, 8, 0, 65, 0, 253, 15, 253, 98, 11, - ]), - ); - const moduleName = hasSIMD ? './Box2D.simd' : './Box2D'; - - // awaiting gives us a better stack trace (at the cost of an extra microtask) - const modulePromise = await new Promise((resolve, reject) => { - const tag = document.createElement('script'); - tag.onload = () => { - resolve(window.Box2D); - return false; - }; - tag.onerror = () => { - reject( - new Error( - `Failed to load Box2D. Check your browser console for network errors.`, - ), - ); - return false; - }; - tag.src = `${BOX2D_UMD_DIR}/${moduleName}.js`; - document.getElementsByTagName('head')[0].appendChild(tag); - }); - - const Box2DFactory = await modulePromise; - return await Box2DFactory(); + if (window.Box2D) { + // @ts-ignore + return await (window.Box2D()); + } else { + const hasSIMD = WebAssembly.validate( + new Uint8Array([ + 0, 97, 115, 109, 1, 0, 0, 0, 1, 5, 1, 96, 0, 1, 123, 3, 2, 1, 0, 10, + 10, 1, 8, 0, 65, 0, 253, 15, 253, 98, 11, + ]), + ); + const moduleName = hasSIMD ? './Box2D.simd' : './Box2D'; + + // awaiting gives us a better stack trace (at the cost of an extra microtask) + const modulePromise = await new Promise((resolve, reject) => { + const tag = document.createElement('script'); + tag.onload = () => { + resolve(window.Box2D); + return false; + }; + tag.onerror = () => { + reject( + new Error( + `Failed to load Box2D. Check your browser console for network errors.`, + ), + ); + return false; + }; + tag.src = `${BOX2D_UMD_DIR}/${moduleName}.js`; + document.getElementsByTagName('head')[0].appendChild(tag); + }); + + const Box2DFactory = await modulePromise; + return await Box2DFactory(); + } } } diff --git a/packages/g-plugin-canvas-path-generator/CHANGELOG.md b/packages/g-plugin-canvas-path-generator/CHANGELOG.md index ba2b576b3..0c3b2f1c6 100644 --- a/packages/g-plugin-canvas-path-generator/CHANGELOG.md +++ b/packages/g-plugin-canvas-path-generator/CHANGELOG.md @@ -1,5 +1,13 @@ # @antv/g-plugin-canvas-path-generator +## 1.3.2 + +### Patch Changes + +- Updated dependencies [0eb5142d] +- Updated dependencies [71990540] + - @antv/g-lite@1.2.2 + ## 1.3.1 ### Patch Changes diff --git a/packages/g-plugin-canvas-path-generator/package.json b/packages/g-plugin-canvas-path-generator/package.json index bb66e006e..772c36cad 100644 --- a/packages/g-plugin-canvas-path-generator/package.json +++ b/packages/g-plugin-canvas-path-generator/package.json @@ -1,6 +1,6 @@ { "name": "@antv/g-plugin-canvas-path-generator", - "version": "1.3.1", + "version": "1.3.2", "description": "A G plugin of path generator with Canvas2D API", "keywords": [ "antv", diff --git a/packages/g-plugin-canvas-picker/CHANGELOG.md b/packages/g-plugin-canvas-picker/CHANGELOG.md index 235ecc216..33781c675 100644 --- a/packages/g-plugin-canvas-picker/CHANGELOG.md +++ b/packages/g-plugin-canvas-picker/CHANGELOG.md @@ -1,5 +1,15 @@ # @antv/g-plugin-canvas-picker +## 1.10.2 + +### Patch Changes + +- Updated dependencies [0eb5142d] +- Updated dependencies [71990540] + - @antv/g-lite@1.2.2 + - @antv/g-plugin-canvas-path-generator@1.3.2 + - @antv/g-plugin-canvas-renderer@1.9.2 + ## 1.10.1 ### Patch Changes diff --git a/packages/g-plugin-canvas-picker/package.json b/packages/g-plugin-canvas-picker/package.json index b347c3bf2..c54e88866 100644 --- a/packages/g-plugin-canvas-picker/package.json +++ b/packages/g-plugin-canvas-picker/package.json @@ -1,6 +1,6 @@ { "name": "@antv/g-plugin-canvas-picker", - "version": "1.10.1", + "version": "1.10.2", "description": "A G plugin for picking in canvas", "keywords": [ "antv", diff --git a/packages/g-plugin-canvas-renderer/CHANGELOG.md b/packages/g-plugin-canvas-renderer/CHANGELOG.md index dece53126..0eeaac3ae 100644 --- a/packages/g-plugin-canvas-renderer/CHANGELOG.md +++ b/packages/g-plugin-canvas-renderer/CHANGELOG.md @@ -1,5 +1,15 @@ # @antv/g-plugin-canvas-renderer +## 1.9.2 + +### Patch Changes + +- Updated dependencies [0eb5142d] +- Updated dependencies [71990540] + - @antv/g-lite@1.2.2 + - @antv/g-plugin-canvas-path-generator@1.3.2 + - @antv/g-plugin-image-loader@1.3.2 + ## 1.9.1 ### Patch Changes diff --git a/packages/g-plugin-canvas-renderer/package.json b/packages/g-plugin-canvas-renderer/package.json index c56569004..f03f27d08 100644 --- a/packages/g-plugin-canvas-renderer/package.json +++ b/packages/g-plugin-canvas-renderer/package.json @@ -1,6 +1,6 @@ { "name": "@antv/g-plugin-canvas-renderer", - "version": "1.9.1", + "version": "1.9.2", "description": "A G plugin of renderer implementation with Canvas2D API", "keywords": [ "antv", diff --git a/packages/g-plugin-canvaskit-renderer/CHANGELOG.md b/packages/g-plugin-canvaskit-renderer/CHANGELOG.md index 99ccd73ce..c62c266b4 100644 --- a/packages/g-plugin-canvaskit-renderer/CHANGELOG.md +++ b/packages/g-plugin-canvaskit-renderer/CHANGELOG.md @@ -1,5 +1,14 @@ # @antv/g-plugin-canvaskit-renderer +## 1.3.2 + +### Patch Changes + +- Updated dependencies [0eb5142d] +- Updated dependencies [71990540] + - @antv/g-lite@1.2.2 + - @antv/g-plugin-image-loader@1.3.2 + ## 1.3.1 ### Patch Changes diff --git a/packages/g-plugin-canvaskit-renderer/package.json b/packages/g-plugin-canvaskit-renderer/package.json index 886c499c1..72831bd0b 100644 --- a/packages/g-plugin-canvaskit-renderer/package.json +++ b/packages/g-plugin-canvaskit-renderer/package.json @@ -1,6 +1,6 @@ { "name": "@antv/g-plugin-canvaskit-renderer", - "version": "1.3.1", + "version": "1.3.2", "description": "A G plugin of renderer implementation with CanvasKit", "keywords": [ "antv", diff --git a/packages/g-plugin-control/CHANGELOG.md b/packages/g-plugin-control/CHANGELOG.md index aa945d31f..743da7484 100644 --- a/packages/g-plugin-control/CHANGELOG.md +++ b/packages/g-plugin-control/CHANGELOG.md @@ -1,5 +1,13 @@ # @antv/g-plugin-control +## 1.9.2 + +### Patch Changes + +- Updated dependencies [0eb5142d] +- Updated dependencies [71990540] + - @antv/g-lite@1.2.2 + ## 1.9.1 ### Patch Changes diff --git a/packages/g-plugin-control/package.json b/packages/g-plugin-control/package.json index 9736a39b0..18efc6666 100644 --- a/packages/g-plugin-control/package.json +++ b/packages/g-plugin-control/package.json @@ -1,6 +1,6 @@ { "name": "@antv/g-plugin-control", - "version": "1.9.1", + "version": "1.9.2", "description": "A G plugin for orbit control", "keywords": [ "antv", diff --git a/packages/g-plugin-css-select/CHANGELOG.md b/packages/g-plugin-css-select/CHANGELOG.md index 63bec8b05..2ff318bb1 100644 --- a/packages/g-plugin-css-select/CHANGELOG.md +++ b/packages/g-plugin-css-select/CHANGELOG.md @@ -1,5 +1,13 @@ # @antv/g-plugin-css-select +## 1.9.2 + +### Patch Changes + +- Updated dependencies [0eb5142d] +- Updated dependencies [71990540] + - @antv/g-lite@1.2.2 + ## 1.9.1 ### Patch Changes diff --git a/packages/g-plugin-css-select/package.json b/packages/g-plugin-css-select/package.json index 7b3dacd5d..879075a37 100644 --- a/packages/g-plugin-css-select/package.json +++ b/packages/g-plugin-css-select/package.json @@ -1,6 +1,6 @@ { "name": "@antv/g-plugin-css-select", - "version": "1.9.1", + "version": "1.9.2", "description": "A G plugin for using CSS select syntax in query selector", "keywords": [ "antv", diff --git a/packages/g-plugin-device-renderer/CHANGELOG.md b/packages/g-plugin-device-renderer/CHANGELOG.md index 73fb53a6a..199cf8848 100644 --- a/packages/g-plugin-device-renderer/CHANGELOG.md +++ b/packages/g-plugin-device-renderer/CHANGELOG.md @@ -1,5 +1,16 @@ # @antv/g-plugin-device-renderer +## 1.9.2 + +### Patch Changes + +- 0eb5142d: Avoid overriding defXY when parsing path +- 71990540: Make picking process async for WebGL2 & WebGPU implementations +- Updated dependencies [0eb5142d] +- Updated dependencies [71990540] + - @antv/g-lite@1.2.2 + - @antv/g-plugin-image-loader@1.3.2 + ## 1.9.1 ### Patch Changes diff --git a/packages/g-plugin-device-renderer/package.json b/packages/g-plugin-device-renderer/package.json index ccb447a26..14cb01c0c 100644 --- a/packages/g-plugin-device-renderer/package.json +++ b/packages/g-plugin-device-renderer/package.json @@ -1,6 +1,6 @@ { "name": "@antv/g-plugin-device-renderer", - "version": "1.9.1", + "version": "1.9.2", "description": "A G plugin of renderer implementation with GPUDevice", "keywords": [ "antv", diff --git a/packages/g-plugin-device-renderer/src/PickingPlugin.ts b/packages/g-plugin-device-renderer/src/PickingPlugin.ts index 6ed25ddaa..d1339de3d 100644 --- a/packages/g-plugin-device-renderer/src/PickingPlugin.ts +++ b/packages/g-plugin-device-renderer/src/PickingPlugin.ts @@ -83,18 +83,20 @@ export class PickingPlugin implements RenderingPlugin { */ renderingService.hooks.pickSync.tap( PickingPlugin.tag, - (result: PickingResult) => this.pick(result), + (result: PickingResult) => { + throw new Error('Sync version is not implemented.'); + }, ); renderingService.hooks.pick.tapPromise( PickingPlugin.tag, - async (result: PickingResult) => { + (result: PickingResult) => { return this.pick(result); }, ); } - private pick(result: PickingResult) { + private async pick(result: PickingResult) { const { topmost, position } = result; // use viewportX/Y @@ -119,7 +121,7 @@ export class PickingPlugin implements RenderingPlugin { // implements multi-layer picking // @see https://github.com/antvis/g/issues/948 - const pickedDisplayObjects = this.pickByRectangleInDepth( + const pickedDisplayObjects = await this.pickByRectangleInDepth( new Rectangle( clamp(Math.round(xInDevicePixel), 0, width - 1), clamp(Math.round(yInDevicePixel), 0, height - 1), @@ -133,16 +135,16 @@ export class PickingPlugin implements RenderingPlugin { return result; } - private pickByRectangleInDepth( + private async pickByRectangleInDepth( rect: Rectangle, depth = MAX_PICKING_DEPTH, - ): DisplayObject[] { + ): Promise { let picked = null; let counter = 1; const targets = []; do { - picked = this.pickByRectangle(rect, picked); + picked = await this.pickByRectangle(rect, picked); if (picked) { counter++; @@ -169,10 +171,10 @@ export class PickingPlugin implements RenderingPlugin { /** * return displayobjects in target rectangle */ - private pickByRectangle( + private async pickByRectangle( rect: Rectangle, picked: DisplayObject, - ): DisplayObject | null { + ): Promise { const device = this.renderGraphPlugin.getDevice(); const renderLists = this.renderGraphPlugin.getRenderLists(); @@ -213,161 +215,168 @@ export class PickingPlugin implements RenderingPlugin { // account for current view offset const currentView = { ...camera.getView() }; - // prevent unused RTs like main color being destroyed - this.renderHelper.renderGraph.renderTargetDeadPool.forEach((rt) => { - rt.age = -1; - }); + return new Promise((resolve) => { + // prevent unused RTs like main color being destroyed + this.renderHelper.renderGraph.renderTargetDeadPool.forEach((rt) => { + rt.age = -1; + }); - // picking pass - let target: DisplayObject; - builder.pushPass((pass) => { - pass.setDebugName('Picking Pass'); - pass.attachRenderTargetID(RGAttachmentSlot.Color0, pickingColorTargetID); - pass.attachRenderTargetID( - RGAttachmentSlot.DepthStencil, - mainDepthTargetID, - ); - pass.exec((passRenderer) => { - renderLists.picking.drawOnPassRenderer( - renderInstManager.renderCache, - passRenderer, + // picking pass + builder.pushPass((pass) => { + pass.setDebugName('Picking Pass'); + pass.attachRenderTargetID( + RGAttachmentSlot.Color0, + pickingColorTargetID, ); - }); - pass.post((scope) => { - const texture = scope.getRenderTargetTexture(RGAttachmentSlot.Color0); - - const readback = device.createReadback(); - - // restore previous view - if (currentView && currentView.enabled) { - camera.setViewOffset( - currentView.fullWidth, - currentView.fullHeight, - currentView.offsetX, - currentView.offsetY, - currentView.width, - currentView.height, + pass.attachRenderTargetID( + RGAttachmentSlot.DepthStencil, + mainDepthTargetID, + ); + pass.exec((passRenderer) => { + renderLists.picking.drawOnPassRenderer( + renderInstManager.renderCache, + passRenderer, ); - } else { - camera.clearViewOffset(); - } - - camera.setEnableUpdate(true); - - const pickedColors = readback.readTexture( - texture, - 0, - 0, - width, - height, - new Uint8Array(width * height * 4), - ) as Uint8Array; - - let pickedFeatureIdx = -1; - - if ( - pickedColors && - (pickedColors[0] !== 0 || - pickedColors[1] !== 0 || - pickedColors[2] !== 0) - ) { - pickedFeatureIdx = - this.pickingIdGenerator.decodePickingColor(pickedColors); - } - - if (pickedFeatureIdx > -1) { - const pickedDisplayObject = - this.pickingIdGenerator.getById(pickedFeatureIdx); - - if ( - pickedDisplayObject && - pickedDisplayObject.isVisible() && - pickedDisplayObject.isInteractive() - ) { - target = pickedDisplayObject; + }); + pass.post((scope) => { + const texture = scope.getRenderTargetTexture(RGAttachmentSlot.Color0); + + const readback = device.createReadback(); + + // restore previous view + if (currentView && currentView.enabled) { + camera.setViewOffset( + currentView.fullWidth, + currentView.fullHeight, + currentView.offsetX, + currentView.offsetY, + currentView.width, + currentView.height, + ); + } else { + camera.clearViewOffset(); } - } - readback.destroy(); + + camera.setEnableUpdate(true); + + readback + .readTexture( + texture, + 0, + 0, + width, + height, + new Uint8Array(width * height * 4), + ) + .then((pickedColors: Uint8Array) => { + let target: DisplayObject; + let pickedFeatureIdx = -1; + + if ( + pickedColors && + (pickedColors[0] !== 0 || + pickedColors[1] !== 0 || + pickedColors[2] !== 0) + ) { + pickedFeatureIdx = + this.pickingIdGenerator.decodePickingColor(pickedColors); + } + + if (pickedFeatureIdx > -1) { + const pickedDisplayObject = + this.pickingIdGenerator.getById(pickedFeatureIdx); + + if ( + pickedDisplayObject && + pickedDisplayObject.isVisible() && + pickedDisplayObject.isInteractive() + ) { + target = pickedDisplayObject; + } + } + readback.destroy(); + + resolve(target); + }); + }); }); - }); - // Push our outer template, which contains the dynamic UBO bindings... - const template = this.renderHelper.pushTemplateRenderInst(); - // SceneParams: binding = 0, ObjectParams: binding = 1 - template.setBindingLayouts([{ numUniformBuffers: 2, numSamplers: 0 }]); - template.setMegaStateFlags( - setAttachmentStateSimple( + // Push our outer template, which contains the dynamic UBO bindings... + const template = this.renderHelper.pushTemplateRenderInst(); + // SceneParams: binding = 0, ObjectParams: binding = 1 + template.setBindingLayouts([{ numUniformBuffers: 2, numSamplers: 0 }]); + template.setMegaStateFlags( + setAttachmentStateSimple( + { + depthWrite: true, + }, + { + rgbBlendMode: BlendMode.Add, + rgbBlendSrcFactor: BlendFactor.One, + rgbBlendDstFactor: BlendFactor.Zero, + alphaBlendMode: BlendMode.Add, + alphaBlendSrcFactor: BlendFactor.One, + alphaBlendDstFactor: BlendFactor.Zero, + }, + ), + ); + + // Update Scene Params + const { width: canvasWidth, height: canvasHeight } = this.context.config; + const dpr = this.context.contextService.getDPR(); + + camera.setEnableUpdate(false); + camera.setViewOffset( + canvasWidth * dpr, + canvasHeight * dpr, + x, + y, + width, + height, + ); + + template.setUniforms(SceneUniformBufferIndex, [ { - depthWrite: true, + name: SceneUniform.PROJECTION_MATRIX, + value: camera.getPerspective(), }, { - rgbBlendMode: BlendMode.Add, - rgbBlendSrcFactor: BlendFactor.One, - rgbBlendDstFactor: BlendFactor.Zero, - alphaBlendMode: BlendMode.Add, - alphaBlendSrcFactor: BlendFactor.One, - alphaBlendDstFactor: BlendFactor.Zero, + name: SceneUniform.VIEW_MATRIX, + value: camera.getViewTransform(), }, - ), - ); - - // Update Scene Params - const { width: canvasWidth, height: canvasHeight } = this.context.config; - const dpr = this.context.contextService.getDPR(); - - camera.setEnableUpdate(false); - camera.setViewOffset( - canvasWidth * dpr, - canvasHeight * dpr, - x, - y, - width, - height, - ); - - template.setUniforms(SceneUniformBufferIndex, [ - { - name: SceneUniform.PROJECTION_MATRIX, - value: camera.getPerspective(), - }, - { - name: SceneUniform.VIEW_MATRIX, - value: camera.getViewTransform(), - }, - { - name: SceneUniform.CAMERA_POSITION, - value: camera.getPosition(), - }, - { - name: SceneUniform.DEVICE_PIXEL_RATIO, - value: this.context.contextService.getDPR(), - }, - { - name: SceneUniform.VIEWPORT, - value: [canvasWidth, canvasHeight], - }, - { - name: SceneUniform.IS_ORTHO, - value: camera.isOrtho() ? 1 : 0, - }, - { - name: SceneUniform.IS_PICKING, - value: 1, - }, - ]); - - if (picked) { - this.batchManager.updateAttribute(picked, 'pointerEvents', false, true); - } - this.batchManager.render(renderLists.picking, true); + { + name: SceneUniform.CAMERA_POSITION, + value: camera.getPosition(), + }, + { + name: SceneUniform.DEVICE_PIXEL_RATIO, + value: this.context.contextService.getDPR(), + }, + { + name: SceneUniform.VIEWPORT, + value: [canvasWidth, canvasHeight], + }, + { + name: SceneUniform.IS_ORTHO, + value: camera.isOrtho() ? 1 : 0, + }, + { + name: SceneUniform.IS_PICKING, + value: 1, + }, + ]); - renderInstManager.popTemplateRenderInst(); + if (picked) { + this.batchManager.updateAttribute(picked, 'pointerEvents', false, true); + } + this.batchManager.render(renderLists.picking, true); - this.renderHelper.prepareToRender(); - this.renderHelper.renderGraph.execute(); + renderInstManager.popTemplateRenderInst(); - renderInstManager.resetRenderInsts(); + this.renderHelper.prepareToRender(); + this.renderHelper.renderGraph.execute(); - return target; + renderInstManager.resetRenderInsts(); + }); } } diff --git a/packages/g-plugin-device-renderer/src/RenderGraphPlugin.ts b/packages/g-plugin-device-renderer/src/RenderGraphPlugin.ts index 0de67c12d..7c41ad3e5 100644 --- a/packages/g-plugin-device-renderer/src/RenderGraphPlugin.ts +++ b/packages/g-plugin-device-renderer/src/RenderGraphPlugin.ts @@ -17,6 +17,7 @@ import { SwapChain, Texture, TextureDescriptor, + TransparentBlack, TransparentWhite, } from './platform'; import { @@ -240,20 +241,26 @@ export class RenderGraphPlugin implements RenderingPlugin { const renderInstManager = this.renderHelper.renderInstManager; this.builder = this.renderHelper.renderGraph.newGraphBuilder(); - // use canvas.background - const backgroundColor = parseColor( - this.context.config.background, - ) as CSSRGB; - const clearColor = this.context.config.background - ? // use premultipliedAlpha - // @see https://canvatechblog.com/alpha-blending-and-webgl-99feb392779e - colorNewFromRGBA( - (Number(backgroundColor.r) / 255) * Number(backgroundColor.alpha), - (Number(backgroundColor.g) / 255) * Number(backgroundColor.alpha), - (Number(backgroundColor.b) / 255) * Number(backgroundColor.alpha), - Number(backgroundColor.alpha), - ) - : TransparentWhite; + let clearColor; + if (this.context.config.background === 'transparent') { + clearColor = TransparentBlack; + } else { + // use canvas.background + const backgroundColor = parseColor( + this.context.config.background, + ) as CSSRGB; + + clearColor = this.context.config.background + ? // use premultipliedAlpha + // @see https://canvatechblog.com/alpha-blending-and-webgl-99feb392779e + colorNewFromRGBA( + (Number(backgroundColor.r) / 255) * Number(backgroundColor.alpha), + (Number(backgroundColor.g) / 255) * Number(backgroundColor.alpha), + (Number(backgroundColor.b) / 255) * Number(backgroundColor.alpha), + Number(backgroundColor.alpha), + ) + : TransparentWhite; + } // retrieve at each frame since canvas may resize const renderInput = { @@ -328,7 +335,7 @@ export class RenderGraphPlugin implements RenderingPlugin { setAttachmentStateSimple( { depthWrite: true, - blendConstant: TransparentWhite, + blendConstant: TransparentBlack, }, { rgbBlendMode: BlendMode.Add, diff --git a/packages/g-plugin-device-renderer/src/TexturePool.ts b/packages/g-plugin-device-renderer/src/TexturePool.ts index 37c683a1e..97e6719f2 100644 --- a/packages/g-plugin-device-renderer/src/TexturePool.ts +++ b/packages/g-plugin-device-renderer/src/TexturePool.ts @@ -80,11 +80,28 @@ export class TexturePool { if (image) { image.onload = () => { - this.textureCache[id].setImageData(image); - this.textureCache[id].emit(TextureEvent.LOADED); - this.context.renderingService.dirtify(); - if (successCallback) { - successCallback(this.textureCache[id]); + const onSuccess = (bitmap: ImageBitmap | HTMLImageElement) => { + this.textureCache[id].setImageData(bitmap); + this.textureCache[id].emit(TextureEvent.LOADED); + this.context.renderingService.dirtify(); + if (successCallback) { + successCallback(this.textureCache[id]); + } + }; + + if (runtime.globalThis.createImageBitmap) { + runtime.globalThis + .createImageBitmap(image) + .then((bitmap: ImageBitmap) => onSuccess(bitmap)) + .catch(() => { + // Unhandled Rejection (InvalidStateError): + // Failed to execute 'createImageBitmap' on 'Window': + // The image element contains an SVG image without intrinsic dimensions, + // and no resize options or crop region are specified. + onSuccess(image); + }); + } else { + onSuccess(image); } }; image.onerror = () => {}; diff --git a/packages/g-plugin-device-renderer/src/geometries/BufferGeometry.ts b/packages/g-plugin-device-renderer/src/geometries/BufferGeometry.ts index 19df8a414..dcaaf9c41 100644 --- a/packages/g-plugin-device-renderer/src/geometries/BufferGeometry.ts +++ b/packages/g-plugin-device-renderer/src/geometries/BufferGeometry.ts @@ -13,17 +13,17 @@ import { Format, PrimitiveTopology, } from '../platform'; -import { align } from '../platform/utils'; -export function makeStaticDataBuffer( +export function makeDataBuffer( device: Device, usage: BufferUsage, data: ArrayBufferLike, + hint = BufferFrequencyHint.Static, ): Buffer { const buffer = device.createBuffer({ - viewOrSize: align(data.byteLength, 4) / 4, + viewOrSize: data.byteLength, usage, - hint: BufferFrequencyHint.Static, + hint, }); buffer.setSubData(0, new Uint8Array(data)); return buffer; @@ -127,7 +127,7 @@ export class BufferGeometry extends EventEmitter { this.indexBuffer.destroy(); } - this.indexBuffer = makeStaticDataBuffer( + this.indexBuffer = makeDataBuffer( this.device, BufferUsage.INDEX, new Uint32Array(ArrayBuffer.isView(indices) ? indices.buffer : indices) @@ -178,10 +178,11 @@ export class BufferGeometry extends EventEmitter { this.vertexBuffers[bufferIndex].destroy(); } - const buffer = makeStaticDataBuffer( + const buffer = makeDataBuffer( this.device, BufferUsage.VERTEX, data.buffer, + BufferFrequencyHint.Dynamic, ); this.vertexBuffers[bufferIndex] = buffer; diff --git a/packages/g-plugin-device-renderer/src/meshes/Instanced.ts b/packages/g-plugin-device-renderer/src/meshes/Instanced.ts index 498d34cf3..a355c64cd 100644 --- a/packages/g-plugin-device-renderer/src/meshes/Instanced.ts +++ b/packages/g-plugin-device-renderer/src/meshes/Instanced.ts @@ -140,6 +140,11 @@ export abstract class Instanced { */ protected lightReceived = false; + /** + * + */ + protected divisor = 1; + protected abstract createMaterial(objects: DisplayObject[]): void; get instance() { @@ -263,6 +268,7 @@ export abstract class Instanced { const packedFillStroke: number[] = []; const packedStyle: number[] = []; const packedPicking: number[] = []; + const divisor = this.divisor; // const useNormal = this.material.defines.NORMAL; @@ -358,19 +364,19 @@ export abstract class Instanced { // format: Format.F32_RGB, // bufferByteOffset: 4 * 0, // location: Number(NORMAL_MATRIX0), - // divisor: 1, + // divisor // }, // { // format: Format.F32_RGB, // bufferByteOffset: 4 * 3, // location: Number(NORMAL_MATRIX1), - // divisor: 1, + // divisor // }, // { // format: Format.F32_RGB, // bufferByteOffset: 4 * 6, // location: Number(NORMAL_MATRIX2), - // divisor: 1, + // divisor // }, // ], // data: new Float32Array(normalMatrix), @@ -389,25 +395,25 @@ export abstract class Instanced { format: Format.F32_RGBA, bufferByteOffset: 4 * 0, location: VertexAttributeLocation.MODEL_MATRIX0, - divisor: 1, + divisor, }, { format: Format.F32_RGBA, bufferByteOffset: 4 * 4, location: VertexAttributeLocation.MODEL_MATRIX1, - divisor: 1, + divisor, }, { format: Format.F32_RGBA, bufferByteOffset: 4 * 8, location: VertexAttributeLocation.MODEL_MATRIX2, - divisor: 1, + divisor, }, { format: Format.F32_RGBA, bufferByteOffset: 4 * 12, location: VertexAttributeLocation.MODEL_MATRIX3, - divisor: 1, + divisor, }, ], data: new Float32Array(packedModelMatrix), @@ -422,7 +428,7 @@ export abstract class Instanced { format: Format.F32_RGBA, bufferByteOffset: 4 * 0, location: VertexAttributeLocation.PACKED_COLOR, - divisor: 1, + divisor, }, ], data: new Float32Array(packedFillStroke), @@ -437,13 +443,13 @@ export abstract class Instanced { format: Format.F32_RGBA, bufferByteOffset: 4 * 0, location: VertexAttributeLocation.PACKED_STYLE1, - divisor: 1, + divisor, }, { format: Format.F32_RGBA, bufferByteOffset: 4 * 4, location: VertexAttributeLocation.PACKED_STYLE2, - divisor: 1, + divisor, }, ], data: new Float32Array(packedStyle), @@ -458,7 +464,7 @@ export abstract class Instanced { format: Format.F32_RGBA, bufferByteOffset: 4 * 0, location: VertexAttributeLocation.PICKING_COLOR, - divisor: 1, + divisor, }, ], data: new Float32Array(packedPicking), diff --git a/packages/g-plugin-device-renderer/src/meshes/InstancedLine.ts b/packages/g-plugin-device-renderer/src/meshes/InstancedLine.ts index 2e8fbc1df..7b7b95197 100644 --- a/packages/g-plugin-device-renderer/src/meshes/InstancedLine.ts +++ b/packages/g-plugin-device-renderer/src/meshes/InstancedLine.ts @@ -2,7 +2,14 @@ * Instanced line which has a better performance. * @see https://www.yuque.com/antv/ou292n/gg1gh5 */ -import type { Line, ParsedLineStyleProps, Path, Polyline } from '@antv/g-lite'; +import type { + Line, + ParsedLineStyleProps, + Path, + Polyline, + ParsedPathStyleProps, + ParsedPolylineStyleProps, +} from '@antv/g-lite'; import { DisplayObject, Shape, isDisplayObject } from '@antv/g-lite'; import { Format, VertexBufferFrequency } from '../platform'; import frag from '../shader/instanced-line.frag'; @@ -40,6 +47,42 @@ const LineCap_MAP = { }; export class InstancedLineMesh extends Instanced { + static isLine(object: DisplayObject) { + if (object.nodeName === Shape.PATH) { + const { + path: { absolutePath }, + } = object.parsedStyle as ParsedPathStyleProps; + + // only contains M & L commands + if ( + absolutePath.length === 2 && + absolutePath[0][0] === 'M' && + absolutePath[1][0] === 'L' + ) { + return true; + } + } else if (object.nodeName === Shape.POLYLINE) { + const { + points: { points }, + } = object.parsedStyle as ParsedPolylineStyleProps; + const tangent = + (points[1][0] - points[1][1]) / (points[0][0] - points[0][1]); + for (let i = 1; i < points.length - 1; i++) { + if ( + (points[i + 1][0] - points[i + 1][1]) / + (points[i][0] - points[i][1]) !== + tangent + ) { + return false; + } + } + + return true; + } + + return false; + } + shouldMerge(object: DisplayObject, index: number) { const shouldMerge = super.shouldMerge(object, index); if (!shouldMerge) { diff --git a/packages/g-plugin-device-renderer/src/meshes/InstancedPath.ts b/packages/g-plugin-device-renderer/src/meshes/InstancedPath.ts new file mode 100644 index 000000000..f81beec0e --- /dev/null +++ b/packages/g-plugin-device-renderer/src/meshes/InstancedPath.ts @@ -0,0 +1,328 @@ +/** + * Instanced line which has a better performance. + * @see https://www.yuque.com/antv/ou292n/gg1gh5 + */ +import { DisplayObject, ParsedPathStyleProps, Path, Shape } from '@antv/g-lite'; +import { Format, VertexBufferFrequency } from '../platform'; +import frag from '../shader/line.frag'; +import vert from '../shader/line.vert'; +import { enumToObject } from '../utils/enum'; +import { + Instanced, + VertexAttributeBufferIndex, + VertexAttributeLocation, +} from './Instanced'; +import { updateBuffer } from './Line'; + +enum LineVertexAttributeBufferIndex { + PACKED = VertexAttributeBufferIndex.POSITION + 1, + VERTEX_NUM, + TRAVEL, + DASH, +} + +enum LineVertexAttributeLocation { + PREV = VertexAttributeLocation.POSITION, + POINT1, + POINT2, + NEXT, + VERTEX_JOINT, + VERTEX_NUM, + TRAVEL, + DASH, +} + +const SEGMENT_NUM = 12; + +/** + * Used for Curve only contains 2 commands, e.g. [[M], [C | Q | A]] + */ +export class InstancedPathMesh extends Instanced { + static isOneCommandCurve(object: DisplayObject) { + if (object.nodeName === Shape.PATH) { + const { + path: { absolutePath }, + } = object.parsedStyle as ParsedPathStyleProps; + if ( + absolutePath.length === 2 && + absolutePath[0][0] === 'M' && + (absolutePath[1][0] === 'C' || + absolutePath[1][0] === 'A' || + absolutePath[1][0] === 'Q') + ) { + return true; + } + } + return false; + } + + shouldMerge(object: DisplayObject, index: number) { + const shouldMerge = super.shouldMerge(object, index); + if (!shouldMerge) { + return false; + } + + return true; + } + + createMaterial(objects: DisplayObject[]): void { + this.material.vertexShader = vert; + this.material.fragmentShader = frag; + this.material.defines = { + ...this.material.defines, + ...enumToObject(LineVertexAttributeLocation), + INSTANCED: true, + }; + } + + createGeometry(objects: DisplayObject[]): void { + const indices: number[] = []; + const pointsBuffer: number[] = []; + const travelBuffer: number[] = []; + const packedDash: number[] = []; + let instancedCount = 0; + let offset = 0; + objects.forEach((object) => { + const { + pointsBuffer: pBuffer, + travelBuffer: tBuffer, + instancedCount: count, + } = updateBuffer(object, false, SEGMENT_NUM); + + const { lineDash, lineDashOffset, isBillboard } = (object as Path) + .parsedStyle; + + packedDash.push( + (lineDash && lineDash[0]) || 0, // DASH + (lineDash && lineDash[1]) || 0, // GAP + lineDashOffset || 0, + isBillboard ? 1 : 0, + ); + + instancedCount += count; + + // Can't use interleaved buffer here, we should spread them like: + // | prev - pointA - pointB - next |. This will allocate ~4x buffer memory space. + for (let i = 0; i < pBuffer.length - 3 * 3; i += 3) { + pointsBuffer.push( + pBuffer[i], + pBuffer[i + 1], + pBuffer[i + 2], + pBuffer[i + 3], + pBuffer[i + 4], + pBuffer[i + 5], + pBuffer[i + 6], + pBuffer[i + 7], + pBuffer[i + 8], + pBuffer[i + 9], + pBuffer[i + 10], + pBuffer[i + 11], + ); + } + + travelBuffer.push(...tBuffer); + + indices.push( + 0 + offset, + 2 + offset, + 1 + offset, + 0 + offset, + 3 + offset, + 2 + offset, + 4 + offset, + 6 + offset, + 5 + offset, + 4 + offset, + 7 + offset, + 6 + offset, + 4 + offset, + 7 + offset, + 8 + offset, + ); + offset += 9; + }); + + this.geometry.setVertexBuffer({ + bufferIndex: LineVertexAttributeBufferIndex.PACKED, + byteStride: 4 * (3 + 3 + 3 + 3), + frequency: VertexBufferFrequency.PerInstance, + attributes: [ + { + format: Format.F32_RG, + bufferByteOffset: 4 * 0, + location: LineVertexAttributeLocation.PREV, + divisor: 1, + }, + { + format: Format.F32_RG, + bufferByteOffset: 4 * 3, + location: LineVertexAttributeLocation.POINT1, + divisor: 1, + }, + { + format: Format.F32_R, + bufferByteOffset: 4 * 5, + location: LineVertexAttributeLocation.VERTEX_JOINT, + divisor: 1, + }, + { + format: Format.F32_RG, + bufferByteOffset: 4 * 6, + location: LineVertexAttributeLocation.POINT2, + divisor: 1, + }, + { + format: Format.F32_RG, + bufferByteOffset: 4 * 9, + location: LineVertexAttributeLocation.NEXT, + divisor: 1, + }, + ], + data: new Float32Array(pointsBuffer), + }); + this.geometry.setVertexBuffer({ + bufferIndex: LineVertexAttributeBufferIndex.VERTEX_NUM, + byteStride: 4 * 1, + frequency: VertexBufferFrequency.PerInstance, + attributes: [ + { + format: Format.F32_R, + bufferByteOffset: 4 * 0, + byteStride: 4 * 1, + location: LineVertexAttributeLocation.VERTEX_NUM, + divisor: 0, + }, + ], + data: new Float32Array([0, 1, 2, 3, 4, 5, 6, 7, 8]), + }); + this.geometry.setVertexBuffer({ + bufferIndex: LineVertexAttributeBufferIndex.TRAVEL, + byteStride: 4 * 1, + frequency: VertexBufferFrequency.PerInstance, + attributes: [ + { + format: Format.F32_R, + bufferByteOffset: 4 * 0, + byteStride: 4 * 1, + location: LineVertexAttributeLocation.TRAVEL, + divisor: 1, + }, + ], + data: new Float32Array(travelBuffer), + }); + + // this attribute only changes for each n instance + this.divisor = instancedCount / objects.length; + + this.geometry.setVertexBuffer({ + bufferIndex: LineVertexAttributeBufferIndex.DASH, + byteStride: 4 * 4, + frequency: VertexBufferFrequency.PerInstance, + attributes: [ + { + format: Format.F32_RGBA, + bufferByteOffset: 4 * 0, + location: LineVertexAttributeLocation.DASH, + divisor: this.divisor, + }, + ], + data: new Float32Array(packedDash), + }); + + // use default common attributes + super.createGeometry(objects); + + this.geometry.vertexCount = 15; + this.geometry.instancedCount = instancedCount; + this.geometry.setIndexBuffer(new Uint32Array(indices)); + } + + updateAttribute( + objects: DisplayObject[], + startIndex: number, + name: string, + value: any, + ) { + super.updateAttribute(objects, startIndex, name, value); + + this.updateBatchedAttribute(objects, startIndex, name, value); + + if ( + name === 'path' || + name === 'markerStartOffset' || + name === 'markerEndOffset' || + name === 'markerStart' || + name === 'markerEnd' + ) { + const pointsBuffer: number[] = []; + const travelBuffer: number[] = []; + let instancedCount = 0; + objects.forEach((object) => { + const { + pointsBuffer: pBuffer, + travelBuffer: tBuffer, + instancedCount: iCount, + } = updateBuffer(object, false, SEGMENT_NUM); + instancedCount = iCount; + + // Can't use interleaved buffer here, we should spread them like: + // | prev - pointA - pointB - next |. This will allocate ~4x buffer memory space. + for (let i = 0; i < pBuffer.length - 3 * 3; i += 3) { + pointsBuffer.push( + pBuffer[i], + pBuffer[i + 1], + pBuffer[i + 2], + pBuffer[i + 3], + pBuffer[i + 4], + pBuffer[i + 5], + pBuffer[i + 6], + pBuffer[i + 7], + pBuffer[i + 8], + pBuffer[i + 9], + pBuffer[i + 10], + pBuffer[i + 11], + ); + } + + travelBuffer.push(...tBuffer); + }); + + this.geometry.updateVertexBuffer( + LineVertexAttributeBufferIndex.PACKED, + LineVertexAttributeLocation.PREV, + startIndex * instancedCount, + new Uint8Array(new Float32Array(pointsBuffer).buffer), + ); + this.geometry.updateVertexBuffer( + LineVertexAttributeBufferIndex.TRAVEL, + LineVertexAttributeLocation.TRAVEL, + startIndex, + new Uint8Array(new Float32Array(travelBuffer).buffer), + ); + } else if ( + name === 'lineDashOffset' || + name === 'lineDash' || + name === 'isBillboard' + ) { + const packedDash: number[] = []; + objects.forEach((object) => { + const { lineDash, lineDashOffset, isBillboard } = (object as Path) + .parsedStyle; + + packedDash.push( + (lineDash && lineDash[0]) || 0, // DASH + (lineDash && lineDash[1]) || 0, // GAP + lineDashOffset || 0, + isBillboard ? 1 : 0, + ); + }); + + this.geometry.updateVertexBuffer( + LineVertexAttributeBufferIndex.DASH, + LineVertexAttributeBufferIndex.DASH, + startIndex, + new Uint8Array(new Float32Array(packedDash).buffer), + ); + } + } +} diff --git a/packages/g-plugin-device-renderer/src/meshes/Line.ts b/packages/g-plugin-device-renderer/src/meshes/Line.ts index e5e51f6dd..3ec79751e 100644 --- a/packages/g-plugin-device-renderer/src/meshes/Line.ts +++ b/packages/g-plugin-device-renderer/src/meshes/Line.ts @@ -392,7 +392,11 @@ export class LineMesh extends Instanced { } } -export function updateBuffer(object: DisplayObject, needEarcut = false) { +export function updateBuffer( + object: DisplayObject, + needEarcut = false, + segmentNum?: number, +) { const { lineCap, lineJoin } = object.parsedStyle as ParsedBaseStyleProps; let { defX, defY } = object.parsedStyle; const { markerStart, markerEnd, markerStartOffset, markerEndOffset } = @@ -480,10 +484,7 @@ export function updateBuffer(object: DisplayObject, needEarcut = false) { ) { let path: ParsedPathStyleProps['path']; if (object.nodeName !== Shape.PATH) { - path = parsePath( - convertToPath(object, mat4.identity(mat4.create())), - object, - ); + path = parsePath(convertToPath(object, mat4.identity(mat4.create()))); defX = path.rect.x; defY = path.rect.y; @@ -574,6 +575,7 @@ export function updateBuffer(object: DisplayObject, needEarcut = false) { params[2] - defX, params[3] - defY, points[mCommandsNum], + segmentNum, ); if (useEndOffset) { points[mCommandsNum].push( @@ -608,6 +610,7 @@ export function updateBuffer(object: DisplayObject, needEarcut = false) { args[i + 4] - defX, args[i + 5] - defY, points[mCommandsNum], + segmentNum, ); } if (useEndOffset) { @@ -625,6 +628,7 @@ export function updateBuffer(object: DisplayObject, needEarcut = false) { params[4] - defX, params[5] - defY, points[mCommandsNum], + segmentNum, ); if (useEndOffset) { points[mCommandsNum].push( @@ -694,14 +698,13 @@ export function updateBuffer(object: DisplayObject, needEarcut = false) { endJoint = JOINT_TYPE.JOINT_CAP_SQUARE; } + let j = (Math.round(0 / stridePoints) + 2) * strideFloats; return points .map((points) => { - let j = (Math.round(0 / stridePoints) + 2) * strideFloats; - // const needDash = !isNil(lineDash); let dist = 0; - const pointsBuffer = []; - const travelBuffer = []; + const pointsBuffer: number[] = []; + const travelBuffer: number[] = []; for (let i = 0; i < points.length; i += stridePoints) { // calc travel // if (needDash) { diff --git a/packages/g-plugin-device-renderer/src/meshes/Text.ts b/packages/g-plugin-device-renderer/src/meshes/Text.ts index f84805cf5..8f54226b4 100644 --- a/packages/g-plugin-device-renderer/src/meshes/Text.ts +++ b/packages/g-plugin-device-renderer/src/meshes/Text.ts @@ -154,64 +154,47 @@ export class TextMesh extends Instanced { this.geometry.setVertexBuffer({ bufferIndex: TextVertexAttributeBufferIndex.INSTANCED, byteStride: 4 * (4 * 4 + 4 + 4 + 4 + 4), // 32 - // frequency: VertexBufferFrequency.PerInstance, frequency: VertexBufferFrequency.PerVertex, attributes: [ { format: Format.F32_RGBA, bufferByteOffset: 4 * 0, location: VertexAttributeLocation.MODEL_MATRIX0, - // byteStride: 4 * 4, - // divisor: 1, }, { format: Format.F32_RGBA, bufferByteOffset: 4 * 4, location: VertexAttributeLocation.MODEL_MATRIX1, - // byteStride: 4 * 4, - // divisor: 1, }, { format: Format.F32_RGBA, bufferByteOffset: 4 * 8, location: VertexAttributeLocation.MODEL_MATRIX2, - // byteStride: 4 * 4, - // divisor: 1, }, { format: Format.F32_RGBA, bufferByteOffset: 4 * 12, location: VertexAttributeLocation.MODEL_MATRIX3, - // byteStride: 4 * 4, - // divisor: 1, }, { format: Format.F32_RGBA, bufferByteOffset: 4 * 16, location: VertexAttributeLocation.PACKED_COLOR, - // byteStride: 4 * 4, - // divisor: 1, }, { format: Format.F32_RGBA, bufferByteOffset: 4 * 20, location: VertexAttributeLocation.PACKED_STYLE1, - // byteStride: 4 * 4, - // divisor: 1, }, { format: Format.F32_RGBA, bufferByteOffset: 4 * 24, location: VertexAttributeLocation.PACKED_STYLE2, - // byteStride: 4 * 4, - // divisor: 1, }, { format: Format.F32_RGBA, bufferByteOffset: 4 * 28, location: VertexAttributeLocation.PICKING_COLOR, - // byteStride: 4 * 4, - // divisor: 1, }, ], data: new Float32Array(packed), @@ -540,7 +523,7 @@ export class TextMesh extends Instanced { ...encodedPickingColor, object.sortable.renderOrder * RENDER_ORDER_SCALE, ]; - // FIXME: instanced + // Can't use instanced here since the total number of each Text can be different. charPackedBuffer.push(...packed, ...packed, ...packed, ...packed); // interleaved uv & offsets diff --git a/packages/g-plugin-device-renderer/src/meshes/index.ts b/packages/g-plugin-device-renderer/src/meshes/index.ts index 60b51eb20..701e9e8a7 100644 --- a/packages/g-plugin-device-renderer/src/meshes/index.ts +++ b/packages/g-plugin-device-renderer/src/meshes/index.ts @@ -1,6 +1,7 @@ export * from './Instanced'; export * from './SDF'; export * from './InstancedLine'; +export * from './InstancedPath'; export * from './Line'; export * from './Fill'; export * from './Image'; diff --git a/packages/g-plugin-device-renderer/src/platform/interfaces.ts b/packages/g-plugin-device-renderer/src/platform/interfaces.ts index 3ca52f1b4..bf9133fb4 100644 --- a/packages/g-plugin-device-renderer/src/platform/interfaces.ts +++ b/packages/g-plugin-device-renderer/src/platform/interfaces.ts @@ -79,7 +79,7 @@ export interface Readback extends ResourceBase { dst: ArrayBufferView, dstOffset?: number, length?: number, - ) => ArrayBufferView; + ) => Promise; readBuffer: ( b: Buffer, diff --git a/packages/g-plugin-device-renderer/src/platform/utils/states.ts b/packages/g-plugin-device-renderer/src/platform/utils/states.ts index 553a431b1..f89308138 100644 --- a/packages/g-plugin-device-renderer/src/platform/utils/states.ts +++ b/packages/g-plugin-device-renderer/src/platform/utils/states.ts @@ -15,7 +15,7 @@ import { StencilOp, TextureDimension, } from '../interfaces'; -import { colorCopy, colorNewCopy, TransparentWhite } from './color'; +import { colorCopy, colorNewCopy, TransparentBlack } from './color'; // import { reverseDepthForCompareMode } from './depth'; export function isPowerOfTwo(n: number): boolean { @@ -231,7 +231,7 @@ export const defaultMegaState: MegaStateDescriptor = { }, ], - blendConstant: colorNewCopy(TransparentWhite), + blendConstant: colorNewCopy(TransparentBlack), depthWrite: true, depthCompare: CompareMode.LessEqual, // depthCompare: reverseDepthForCompareMode(CompareMode.LessEqual), diff --git a/packages/g-plugin-device-renderer/src/render/DynamicUniformBuffer.ts b/packages/g-plugin-device-renderer/src/render/DynamicUniformBuffer.ts index b6738470c..5aa198230 100644 --- a/packages/g-plugin-device-renderer/src/render/DynamicUniformBuffer.ts +++ b/packages/g-plugin-device-renderer/src/render/DynamicUniformBuffer.ts @@ -8,6 +8,9 @@ export class DynamicUniformBuffer { private uniformBufferWordAlignment: number; private uniformBufferMaxPageWordSize: number; + /** + * Word count, 4 bytes per word + */ private currentBufferWordSize = -1; private currentWordOffset = 0; buffer: Buffer | null = null; @@ -108,7 +111,8 @@ export class DynamicUniformBuffer { } this.buffer = this.device.createBuffer({ - viewOrSize: this.currentBufferWordSize, + // in bytes length + viewOrSize: this.currentBufferWordSize * 4, usage: BufferUsage.UNIFORM, hint: BufferFrequencyHint.Dynamic, }); diff --git a/packages/g-plugin-device-renderer/src/renderer/BatchManager.ts b/packages/g-plugin-device-renderer/src/renderer/BatchManager.ts index 14dd05f30..22aafec97 100644 --- a/packages/g-plugin-device-renderer/src/renderer/BatchManager.ts +++ b/packages/g-plugin-device-renderer/src/renderer/BatchManager.ts @@ -202,6 +202,8 @@ export class BatchManager { existedMesh.index = i; existedMesh.init(this.context); this.meshes.push(existedMesh); + } else { + existedMesh.geometryDirty = true; } if (existedMesh) { diff --git a/packages/g-plugin-device-renderer/src/renderer/Path.ts b/packages/g-plugin-device-renderer/src/renderer/Path.ts index c3edd4ace..594a5b677 100644 --- a/packages/g-plugin-device-renderer/src/renderer/Path.ts +++ b/packages/g-plugin-device-renderer/src/renderer/Path.ts @@ -1,42 +1,57 @@ /** * @see https://www.khronos.org/assets/uploads/developers/presentations/Crazy_Panda_How_to_draw_lines_in_WebGL.pdf */ -import type { - CSSRGB, - DisplayObject, - ParsedBaseStyleProps, - ParsedPathStyleProps, - ParsedPolylineStyleProps, -} from '@antv/g-lite'; +import type { CSSRGB, DisplayObject, ParsedBaseStyleProps } from '@antv/g-lite'; import { Shape } from '@antv/g-lite'; -import { FillMesh, InstancedLineMesh, LineMesh } from '../meshes'; +import { + FillMesh, + InstancedLineMesh, + InstancedPathMesh, + LineMesh, +} from '../meshes'; import { Batch } from './Batch'; /** - * Try downgrading the "simple" Path / Polyline to InstancedLine. + * Use the following perf enhancements: + * * Downgrading the "simple" Path / Polyline to {@link InstancedLineMesh}, e.g. 'M 0 0 L 100 0' + * * Merge the Path into {@link InstancedPathMesh} which contains only one curve command, e.g 'M 0 0 Q 10 10 100 100' * @see https://github.com/antvis/G/issues/1113 */ export class PathRenderer extends Batch { - meshes = [FillMesh, LineMesh, InstancedLineMesh]; + meshes = [FillMesh, LineMesh, InstancedLineMesh, InstancedPathMesh]; shouldSubmitRenderInst(object: DisplayObject, index: number) { const { fill, stroke, opacity, strokeOpacity, lineDash, lineWidth } = object.parsedStyle as ParsedBaseStyleProps; const nodeName = object.nodeName; const hasStroke = stroke && !(stroke as CSSRGB).isNone; - const hasDash = lineDash && lineDash.length && lineDash.every((item) => item !== 0); - const isLine = this.isLine(object); + const hasDash = + lineDash && lineDash.length && lineDash.every((item) => item !== 0); + const isLine = InstancedLineMesh.isLine(object); + const isOneCommandCurve = InstancedPathMesh.isOneCommandCurve(object); object.renderable.proxyNodeName = isLine ? Shape.LINE : null; // Polyline don't need fill - if (index === 0 && (object.nodeName === Shape.POLYLINE || (fill as CSSRGB).isNone)) { + if ( + index === 0 && + (isOneCommandCurve || + object.nodeName === Shape.POLYLINE || + (fill as CSSRGB).isNone) + ) { return false; } // stroke mesh if (index === 1) { - if (isLine || strokeOpacity === 0 || opacity === 0 || lineWidth === 0 || !hasStroke) { + if ( + isLine || + isOneCommandCurve || + strokeOpacity === 0 || + opacity === 0 || + lineWidth === 0 || + !hasStroke + ) { return false; } @@ -51,33 +66,10 @@ export class PathRenderer extends Batch { return isLine; } - return true; - } - - private isLine(object: DisplayObject) { - if (object.nodeName === Shape.PATH) { - const { - path: { absolutePath }, - } = object.parsedStyle as ParsedPathStyleProps; - - // only contains M & L commands - if (absolutePath.length === 2 && absolutePath[0][0] === 'M' && absolutePath[1][0] === 'L') { - return true; - } - } else if (object.nodeName === Shape.POLYLINE) { - const { - points: { points }, - } = object.parsedStyle as ParsedPolylineStyleProps; - const tangent = (points[1][0] - points[1][1]) / (points[0][0] - points[0][1]); - for (let i = 1; i < points.length - 1; i++) { - if ((points[i + 1][0] - points[i + 1][1]) / (points[i][0] - points[i][1]) !== tangent) { - return false; - } - } - - return true; + if (index === 3) { + return isOneCommandCurve; } - return false; + return true; } } diff --git a/packages/g-plugin-device-renderer/src/shader/compiler.ts b/packages/g-plugin-device-renderer/src/shader/compiler.ts index 63e6aa6de..ecd1fcb49 100644 --- a/packages/g-plugin-device-renderer/src/shader/compiler.ts +++ b/packages/g-plugin-device-renderer/src/shader/compiler.ts @@ -201,7 +201,7 @@ layout(set = ${set}, binding = ${binding++}) uniform sampler S_${samplerName}; }); rest = rest.replace( - type === 'frag' ? /^\b(varying|in)\b/gm : /^\b(varying|out)\b/gm, + type === 'frag' ? /^\s*\b\s*(varying|in)\b/gm : /^\s*\b(varying|out)\b/gm, (substr, tok) => { return `layout(location = ${location++}) ${tok}`; }, diff --git a/packages/g-plugin-device-renderer/src/shader/line.frag b/packages/g-plugin-device-renderer/src/shader/line.frag index 70e2aa446..9f2e40f9d 100644 --- a/packages/g-plugin-device-renderer/src/shader/line.frag +++ b/packages/g-plugin-device-renderer/src/shader/line.frag @@ -1,19 +1,28 @@ #pragma glslify: import('@antv/g-shader-components/scene.both.glsl') -#pragma glslify: import('@antv/g-shader-components/line.both.glsl') + +#ifdef INSTANCED + #pragma glslify: import('@antv/g-shader-components/batch.declaration.frag') + in vec4 v_Dash; +#else + #pragma glslify: import('@antv/g-shader-components/line.both.glsl') +#endif in vec4 v_Distance; in vec4 v_Arc; in float v_Type; in float v_Travel; +in float v_ScalingFactor; out vec4 outputColor; -#define COLOR_SCALE 1. / 255. - void main(){ - if (u_Visible < 0.5) { - discard; - } + #ifdef INSTANCED + #pragma glslify: import('@antv/g-shader-components/batch.frag') + #else + if (u_Visible < 0.5) { + discard; + } + #endif float alpha = 1.0; float lineWidth = v_Distance.w; @@ -56,16 +65,24 @@ void main(){ alpha *= max(min(v_Distance.z + 0.5, 1.0), 0.0); } + #ifdef INSTANCED + float u_Dash = v_Dash.x; + float u_Gap = v_Dash.y; + float u_DashOffset = v_Dash.z; + #endif if (u_Dash + u_Gap > 1.0) { - float scalingFactor = sqrt(u_ModelMatrix[0][0] * u_ModelMatrix[0][0] + u_ModelMatrix[0][1] * u_ModelMatrix[0][1] + u_ModelMatrix[0][2] * u_ModelMatrix[0][2]); - float travel = mod(v_Travel + u_Gap * scalingFactor * 0.5 + u_DashOffset, u_Dash * scalingFactor + u_Gap * scalingFactor) - (u_Gap * scalingFactor * 0.5); + float travel = mod(v_Travel + u_Gap * v_ScalingFactor * 0.5 + u_DashOffset, u_Dash * v_ScalingFactor + u_Gap * v_ScalingFactor) - (u_Gap * v_ScalingFactor * 0.5); float left = max(travel - 0.5, -0.5); - float right = min(travel + 0.5, u_Gap * scalingFactor + 0.5); + float right = min(travel + 0.5, u_Gap * v_ScalingFactor + 0.5); alpha *= max(0.0, right - left); } if (u_IsPicking > 0.5) { - vec3 pickingColor = COLOR_SCALE * u_PickingColor; + #ifdef INSTANCED + vec3 pickingColor = u_PickingColor; + #else + vec3 pickingColor = u_PickingColor / 255.0; + #endif if (pickingColor.x == 0.0 && pickingColor.y == 0.0 && pickingColor.z == 0.0) { discard; } diff --git a/packages/g-plugin-device-renderer/src/shader/line.vert b/packages/g-plugin-device-renderer/src/shader/line.vert index 2c9456ab4..02507160f 100644 --- a/packages/g-plugin-device-renderer/src/shader/line.vert +++ b/packages/g-plugin-device-renderer/src/shader/line.vert @@ -1,5 +1,10 @@ #pragma glslify: import('@antv/g-shader-components/scene.both.glsl') -#pragma glslify: import('@antv/g-shader-components/line.both.glsl') + +#ifdef INSTANCED + #pragma glslify: import('@antv/g-shader-components/batch.declaration.vert') +#else + #pragma glslify: import('@antv/g-shader-components/line.both.glsl') +#endif layout(location = PREV) in vec2 a_Prev; layout(location = POINT1) in vec2 a_Point1; @@ -9,6 +14,11 @@ layout(location = VERTEX_JOINT) in float a_VertexJoint; layout(location = VERTEX_NUM) in float a_VertexNum; layout(location = TRAVEL) in float a_Travel; +#ifdef INSTANCED + layout(location = DASH) in vec4 a_Dash; + out vec4 v_Dash; +#endif + const float FILL = 1.0; const float BEVEL = 4.0; const float MITER = 8.0; @@ -22,10 +32,18 @@ const float CAP_SQUARE = 2.0; const float CAP_ROUND = 3.0; const float CAP_BUTT2 = 4.0; +#ifdef INSTANCED + const float u_Expand = 1.0; + const float u_MiterLimit = 5.0; + const float u_ScaleMode = 1.0; + const float u_Alignment = 0.5; +#endif + out vec4 v_Distance; out vec4 v_Arc; out float v_Type; out float v_Travel; +out float v_ScalingFactor; vec2 doBisect( vec2 norm, float len, vec2 norm2, float len2, float dy, float inner @@ -48,6 +66,11 @@ vec2 doBisect( } void main() { + #ifdef INSTANCED + #pragma glslify: import('@antv/g-shader-components/batch.vert') + v_Dash = a_Dash; + #endif + vec2 pointA = (u_ModelMatrix * vec4(a_Point1, 0., 1.0)).xy; vec2 pointB = (u_ModelMatrix * vec4(a_Point2, 0., 1.0)).xy; @@ -66,12 +89,12 @@ void main() { } if (u_ScaleMode > 2.5) { - lineWidth *= length(u_ModelMatrix * vec4(1.0, 0.0, 0.0, 0.0)); + lineWidth *= length(u_ModelMatrix * vec4(1.0, 0.0, 0.0, 0.0)); } else if (u_ScaleMode > 1.5) { - lineWidth *= length(u_ModelMatrix * vec4(0.0, 1.0, 0.0, 0.0)); + lineWidth *= length(u_ModelMatrix * vec4(0.0, 1.0, 0.0, 0.0)); } else if (u_ScaleMode > 0.5) { - vec2 avgDiag = (u_ModelMatrix * vec4(1.0, 1.0, 0.0, 0.0)).xy; - lineWidth *= sqrt(dot(avgDiag, avgDiag) * 0.5); + vec2 avgDiag = (u_ModelMatrix * vec4(1.0, 1.0, 0.0, 0.0)).xy; + lineWidth *= sqrt(dot(avgDiag, avgDiag) * 0.5); } float capType = floor(type / 32.0); type -= capType * 32.0; @@ -82,214 +105,213 @@ void main() { vec2 pos; if (capType == CAP_ROUND) { - if (a_VertexNum < 3.5) { + if (a_VertexNum < 3.5) { gl_Position = vec4(0.0, 0.0, 0.0, 1.0); return; - } - type = JOINT_CAP_ROUND; - capType = 0.0; + } + type = JOINT_CAP_ROUND; + capType = 0.0; } if (type >= BEVEL) { - float dy = lineWidth + u_Expand; - float inner = 0.0; - if (a_VertexNum >= 1.5) { + float dy = lineWidth + u_Expand; + float inner = 0.0; + if (a_VertexNum >= 1.5) { dy = -dy; inner = 1.0; - } + } - vec2 base, next, xBasis2, bisect; - float flag = 0.0; - float sign2 = 1.0; - if (a_VertexNum < 0.5 || a_VertexNum > 2.5 && a_VertexNum < 3.5) { + vec2 base, next, xBasis2, bisect; + float flag = 0.0; + float sign2 = 1.0; + if (a_VertexNum < 0.5 || a_VertexNum > 2.5 && a_VertexNum < 3.5) { next = (u_ModelMatrix * vec4(a_Prev, 0.0, 1.0)).xy; base = pointA; flag = type - floor(type / 2.0) * 2.0; sign2 = -1.0; - - } else { + } else { next = (u_ModelMatrix * vec4(a_Next, 0.0, 1.0)).xy; base = pointB; if (type >= MITER && type < MITER + 3.5) { - flag = step(MITER + 1.5, type); - // check miter limit here? + flag = step(MITER + 1.5, type); + // check miter limit here? } - } - xBasis2 = next - base; - float len2 = length(xBasis2); - vec2 norm2 = vec2(xBasis2.y, -xBasis2.x) / len2; - float D = norm.x * norm2.y - norm.y * norm2.x; - if (D < 0.0) { + } + xBasis2 = next - base; + float len2 = length(xBasis2); + vec2 norm2 = vec2(xBasis2.y, -xBasis2.x) / len2; + float D = norm.x * norm2.y - norm.y * norm2.x; + if (D < 0.0) { inner = 1.0 - inner; - } - norm2 *= sign2; + } + norm2 *= sign2; - if (abs(lineAlignment) > 0.01) { + if (abs(lineAlignment) > 0.01) { float shift = lineWidth * lineAlignment; pointA += norm * shift; pointB += norm * shift; if (abs(D) < 0.01) { - base += norm * shift; + base += norm * shift; } else { - base += doBisect(norm, len, norm2, len2, shift, 0.0); - } + base += doBisect(norm, len, norm2, len2, shift, 0.0); } + } - float collinear = step(0.0, dot(norm, norm2)); - v_Type = 0.0; - float dy2 = -1000.0; - float dy3 = -1000.0; - if (abs(D) < 0.01 && collinear < 0.5) { + float collinear = step(0.0, dot(norm, norm2)); + v_Type = 0.0; + float dy2 = -1000.0; + float dy3 = -1000.0; + if (abs(D) < 0.01 && collinear < 0.5) { if (type >= ROUND && type < ROUND + 1.5) { - type = JOINT_CAP_ROUND; - } - //TODO: BUTT here too + type = JOINT_CAP_ROUND; } + // TODO: BUTT here too + } - if (a_VertexNum < 3.5) { + if (a_VertexNum < 3.5) { if (abs(D) < 0.01) { - pos = dy * norm; + pos = dy * norm; } else { - if (flag < 0.5 && inner < 0.5) { + if (flag < 0.5 && inner < 0.5) { pos = dy * norm; - } else { + } else { pos = doBisect(norm, len, norm2, len2, dy, inner); - } + } } if (capType >= CAP_BUTT && capType < CAP_ROUND) { - float extra = step(CAP_SQUARE, capType) * lineWidth; - vec2 back = -forward; - if (a_VertexNum < 0.5 || a_VertexNum > 2.5) { + float extra = step(CAP_SQUARE, capType) * lineWidth; + vec2 back = -forward; + if (a_VertexNum < 0.5 || a_VertexNum > 2.5) { pos += back * (u_Expand + extra); dy2 = u_Expand; - } else { + } else { dy2 = dot(pos + base - pointA, back) - extra; - } + } } if (type >= JOINT_CAP_BUTT && type < JOINT_CAP_SQUARE + 0.5) { - float extra = step(JOINT_CAP_SQUARE, type) * lineWidth; - if (a_VertexNum < 0.5 || a_VertexNum > 2.5) { + float extra = step(JOINT_CAP_SQUARE, type) * lineWidth; + if (a_VertexNum < 0.5 || a_VertexNum > 2.5) { dy3 = dot(pos + base - pointB, forward) - extra; - } else { + } else { pos += forward * (u_Expand + extra); dy3 = u_Expand; if (capType >= CAP_BUTT) { - dy2 -= u_Expand + extra; - } + dy2 -= u_Expand + extra; } + } } - } else if (type >= JOINT_CAP_ROUND && type < JOINT_CAP_ROUND + 1.5) { + } else if (type >= JOINT_CAP_ROUND && type < JOINT_CAP_ROUND + 1.5) { if (inner > 0.5) { - dy = -dy; - inner = 0.0; + dy = -dy; + inner = 0.0; } vec2 d2 = abs(dy) * forward; if (a_VertexNum < 4.5) { - dy = -dy; - pos = dy * norm; + dy = -dy; + pos = dy * norm; } else if (a_VertexNum < 5.5) { - pos = dy * norm; + pos = dy * norm; } else if (a_VertexNum < 6.5) { - pos = dy * norm + d2; - v_Arc.x = abs(dy); + pos = dy * norm + d2; + v_Arc.x = abs(dy); } else { - dy = -dy; - pos = dy * norm + d2; - v_Arc.x = abs(dy); + dy = -dy; + pos = dy * norm + d2; + v_Arc.x = abs(dy); } dy2 = 0.0; v_Arc.y = dy; v_Arc.z = 0.0; v_Arc.w = lineWidth; v_Type = 3.0; - } else if (abs(D) < 0.01) { + } else if (abs(D) < 0.01) { pos = dy * norm; - } else { + } else { if (type >= ROUND && type < ROUND + 1.5) { - if (inner > 0.5) { + if (inner > 0.5) { dy = -dy; inner = 0.0; - } - if (a_VertexNum < 4.5) { + } + if (a_VertexNum < 4.5) { pos = doBisect(norm, len, norm2, len2, -dy, 1.0); - } else if (a_VertexNum < 5.5) { + } else if (a_VertexNum < 5.5) { pos = dy * norm; - } else if (a_VertexNum > 7.5) { + } else if (a_VertexNum > 7.5) { pos = dy * norm2; - } else { + } else { pos = doBisect(norm, len, norm2, len2, dy, 0.0); float d2 = abs(dy); if (length(pos) > abs(dy) * 1.5) { - if (a_VertexNum < 6.5) { + if (a_VertexNum < 6.5) { pos.x = dy * norm.x - d2 * norm.y; pos.y = dy * norm.y + d2 * norm.x; - } else { + } else { pos.x = dy * norm2.x + d2 * norm2.y; pos.y = dy * norm2.y - d2 * norm2.x; - } - } + } } - vec2 norm3 = normalize(norm + norm2); - float sign = step(0.0, dy) * 2.0 - 1.0; - v_Arc.x = sign * dot(pos, norm3); - v_Arc.y = pos.x * norm3.y - pos.y * norm3.x; - v_Arc.z = dot(norm, norm3) * lineWidth; - v_Arc.w = lineWidth; - dy = -sign * dot(pos, norm); - dy2 = -sign * dot(pos, norm2); - dy3 = v_Arc.z - v_Arc.x; - v_Type = 3.0; + } + vec2 norm3 = normalize(norm + norm2); + float sign = step(0.0, dy) * 2.0 - 1.0; + v_Arc.x = sign * dot(pos, norm3); + v_Arc.y = pos.x * norm3.y - pos.y * norm3.x; + v_Arc.z = dot(norm, norm3) * lineWidth; + v_Arc.w = lineWidth; + dy = -sign * dot(pos, norm); + dy2 = -sign * dot(pos, norm2); + dy3 = v_Arc.z - v_Arc.x; + v_Type = 3.0; } else { - float hit = 0.0; - if (type >= BEVEL && type < BEVEL + 1.5) { + float hit = 0.0; + if (type >= BEVEL && type < BEVEL + 1.5) { if (dot(norm, norm2) > 0.0) { - type = MITER; - } + type = MITER; } - if (type >= MITER && type < MITER + 3.5) { + } + if (type >= MITER && type < MITER + 3.5) { if (inner > 0.5) { - dy = -dy; - inner = 0.0; + dy = -dy; + inner = 0.0; } float sign = step(0.0, dy) * 2.0 - 1.0; pos = doBisect(norm, len, norm2, len2, dy, 0.0); if (length(pos) > abs(dy) * u_MiterLimit) { - type = BEVEL; + type = BEVEL; } else { - if (a_VertexNum < 4.5) { + if (a_VertexNum < 4.5) { dy = -dy; pos = doBisect(norm, len, norm2, len2, dy, 1.0); - } else if (a_VertexNum < 5.5) { + } else if (a_VertexNum < 5.5) { pos = dy * norm; - } else if (a_VertexNum > 6.5) { + } else if (a_VertexNum > 6.5) { pos = dy * norm2; - } - v_Type = 1.0; - dy = -sign * dot(pos, norm); - dy2 = -sign * dot(pos, norm2); - hit = 1.0; - } + } + v_Type = 1.0; + dy = -sign * dot(pos, norm); + dy2 = -sign * dot(pos, norm2); + hit = 1.0; } - if (type >= BEVEL && type < BEVEL + 1.5) { + } + if (type >= BEVEL && type < BEVEL + 1.5) { if (inner > 0.5) { - dy = -dy; - inner = 0.0; + dy = -dy; + inner = 0.0; } float d2 = abs(dy); vec2 pos3 = vec2(dy * norm.x - d2 * norm.y, dy * norm.y + d2 * norm.x); vec2 pos4 = vec2(dy * norm2.x + d2 * norm2.y, dy * norm2.y - d2 * norm2.x); if (a_VertexNum < 4.5) { - pos = doBisect(norm, len, norm2, len2, -dy, 1.0); + pos = doBisect(norm, len, norm2, len2, -dy, 1.0); } else if (a_VertexNum < 5.5) { - pos = dy * norm; + pos = dy * norm; } else if (a_VertexNum > 7.5) { - pos = dy * norm2; + pos = dy * norm2; } else { - if (a_VertexNum < 6.5) { + if (a_VertexNum < 6.5) { pos = pos3; - } else { + } else { pos = pos4; - } + } } vec2 norm3 = normalize(norm + norm2); float sign = step(0.0, dy) * 2.0 - 1.0; @@ -298,18 +320,20 @@ void main() { dy3 = (-sign * dot(pos, norm3)) + lineWidth; v_Type = 4.0; hit = 1.0; - } - if (hit < 0.5) { + } + if (hit < 0.5) { gl_Position = vec4(0.0, 0.0, 0.0, 1.0); return; - } + } } - } - pos += base; - v_Distance = vec4(dy, dy2, dy3, lineWidth) * u_DevicePixelRatio; - v_Arc = v_Arc * u_DevicePixelRatio; - v_Travel = a_Travel + dot(pos - pointA, vec2(-norm.y, norm.x)); + } + pos += base; + v_Distance = vec4(dy, dy2, dy3, lineWidth) * u_DevicePixelRatio; + v_Arc = v_Arc * u_DevicePixelRatio; + v_Travel = a_Travel + dot(pos - pointA, vec2(-norm.y, norm.x)); } + v_ScalingFactor = sqrt(u_ModelMatrix[0][0] * u_ModelMatrix[0][0] + u_ModelMatrix[0][1] * u_ModelMatrix[0][1] + u_ModelMatrix[0][2] * u_ModelMatrix[0][2]); + gl_Position = u_ProjectionMatrix * u_ViewMatrix * vec4(pos, u_ZIndex, 1.0); } \ No newline at end of file diff --git a/packages/g-plugin-device-renderer/src/utils/sample.ts b/packages/g-plugin-device-renderer/src/utils/sample.ts index f50b3bf30..268c59775 100644 --- a/packages/g-plugin-device-renderer/src/utils/sample.ts +++ b/packages/g-plugin-device-renderer/src/utils/sample.ts @@ -11,12 +11,18 @@ export function quadCurveTo( toX: number, toY: number, points: number[], + segmentNum?: number, ) { const fromX = points[points.length - 2]; const fromY = points[points.length - 1]; - const l = quadLength(fromX, fromY, cpX, cpY, toX, toY); - const n = clamp(l / SEGMENT_LENGTH, MIN_SEGMENT_NUM, MAX_SEGMENT_NUM); + const n = + segmentNum ?? + clamp( + quadLength(fromX, fromY, cpX, cpY, toX, toY) / SEGMENT_LENGTH, + MIN_SEGMENT_NUM, + MAX_SEGMENT_NUM, + ); let xa = 0; let ya = 0; @@ -42,14 +48,21 @@ export function bezierCurveTo( toX: number, toY: number, points: number[], + segmentNum?: number, ): void { const fromX = points[points.length - 2]; const fromY = points[points.length - 1]; points.length -= 2; - const l = cubicLength(fromX, fromY, cpX, cpY, cpX2, cpY2, toX, toY); - const n = clamp(l / SEGMENT_LENGTH, MIN_SEGMENT_NUM, MAX_SEGMENT_NUM); + const n = + segmentNum ?? + clamp( + cubicLength(fromX, fromY, cpX, cpY, cpX2, cpY2, toX, toY) / + SEGMENT_LENGTH, + MIN_SEGMENT_NUM, + MAX_SEGMENT_NUM, + ); let dt = 0; let dt2 = 0; diff --git a/packages/g-plugin-dom-interaction/CHANGELOG.md b/packages/g-plugin-dom-interaction/CHANGELOG.md index 323801197..363941f8d 100644 --- a/packages/g-plugin-dom-interaction/CHANGELOG.md +++ b/packages/g-plugin-dom-interaction/CHANGELOG.md @@ -1,5 +1,13 @@ # @antv/g-plugin-dom-interaction +## 1.9.2 + +### Patch Changes + +- Updated dependencies [0eb5142d] +- Updated dependencies [71990540] + - @antv/g-lite@1.2.2 + ## 1.9.1 ### Patch Changes diff --git a/packages/g-plugin-dom-interaction/package.json b/packages/g-plugin-dom-interaction/package.json index 324ac3ff2..3f5481e6a 100644 --- a/packages/g-plugin-dom-interaction/package.json +++ b/packages/g-plugin-dom-interaction/package.json @@ -1,6 +1,6 @@ { "name": "@antv/g-plugin-dom-interaction", - "version": "1.9.1", + "version": "1.9.2", "description": "A G plugin", "keywords": [ "antv", diff --git a/packages/g-plugin-dragndrop/CHANGELOG.md b/packages/g-plugin-dragndrop/CHANGELOG.md index 516b232c7..39de0e4e7 100644 --- a/packages/g-plugin-dragndrop/CHANGELOG.md +++ b/packages/g-plugin-dragndrop/CHANGELOG.md @@ -1,5 +1,13 @@ # @antv/g-plugin-dragndrop +## 1.8.2 + +### Patch Changes + +- Updated dependencies [0eb5142d] +- Updated dependencies [71990540] + - @antv/g-lite@1.2.2 + ## 1.8.1 ### Patch Changes diff --git a/packages/g-plugin-dragndrop/package.json b/packages/g-plugin-dragndrop/package.json index c9af3c422..f982e06fc 100644 --- a/packages/g-plugin-dragndrop/package.json +++ b/packages/g-plugin-dragndrop/package.json @@ -1,6 +1,6 @@ { "name": "@antv/g-plugin-dragndrop", - "version": "1.8.1", + "version": "1.8.2", "description": "A G plugin for Drag n Drop implemented with PointerEvents", "keywords": [ "antv", diff --git a/packages/g-plugin-gpgpu/CHANGELOG.md b/packages/g-plugin-gpgpu/CHANGELOG.md index 9e7af8121..854a668c5 100644 --- a/packages/g-plugin-gpgpu/CHANGELOG.md +++ b/packages/g-plugin-gpgpu/CHANGELOG.md @@ -1,5 +1,14 @@ # @antv/g-plugin-gpgpu +## 1.9.2 + +### Patch Changes + +- Updated dependencies [0eb5142d] +- Updated dependencies [71990540] + - @antv/g-webgpu@1.9.2 + - @antv/g-lite@1.2.2 + ## 1.9.1 ### Patch Changes diff --git a/packages/g-plugin-gpgpu/package.json b/packages/g-plugin-gpgpu/package.json index bcab19ebc..fba79b9de 100644 --- a/packages/g-plugin-gpgpu/package.json +++ b/packages/g-plugin-gpgpu/package.json @@ -1,6 +1,6 @@ { "name": "@antv/g-plugin-gpgpu", - "version": "1.9.1", + "version": "1.9.2", "description": "A G plugin for GPGPU based on WebGPU", "keywords": [ "webgpu", diff --git a/packages/g-plugin-html-renderer/CHANGELOG.md b/packages/g-plugin-html-renderer/CHANGELOG.md index bfe2ba8e2..a72ce196d 100644 --- a/packages/g-plugin-html-renderer/CHANGELOG.md +++ b/packages/g-plugin-html-renderer/CHANGELOG.md @@ -1,5 +1,13 @@ # @antv/g-plugin-html-renderer +## 1.9.2 + +### Patch Changes + +- Updated dependencies [0eb5142d] +- Updated dependencies [71990540] + - @antv/g-lite@1.2.2 + ## 1.9.1 ### Patch Changes diff --git a/packages/g-plugin-html-renderer/package.json b/packages/g-plugin-html-renderer/package.json index 2a4f79d93..cc78fce89 100644 --- a/packages/g-plugin-html-renderer/package.json +++ b/packages/g-plugin-html-renderer/package.json @@ -1,6 +1,6 @@ { "name": "@antv/g-plugin-html-renderer", - "version": "1.9.1", + "version": "1.9.2", "description": "A G plugin for rendering HTML", "keywords": [ "antv", diff --git a/packages/g-plugin-image-loader/CHANGELOG.md b/packages/g-plugin-image-loader/CHANGELOG.md index 8c9774ca5..347279ba9 100644 --- a/packages/g-plugin-image-loader/CHANGELOG.md +++ b/packages/g-plugin-image-loader/CHANGELOG.md @@ -1,5 +1,13 @@ # @antv/g-plugin-image-loader +## 1.3.2 + +### Patch Changes + +- Updated dependencies [0eb5142d] +- Updated dependencies [71990540] + - @antv/g-lite@1.2.2 + ## 1.3.1 ### Patch Changes diff --git a/packages/g-plugin-image-loader/package.json b/packages/g-plugin-image-loader/package.json index c0e5026f3..0613f437e 100644 --- a/packages/g-plugin-image-loader/package.json +++ b/packages/g-plugin-image-loader/package.json @@ -1,6 +1,6 @@ { "name": "@antv/g-plugin-image-loader", - "version": "1.3.1", + "version": "1.3.2", "description": "A G plugin for loading image", "keywords": [ "antv", diff --git a/packages/g-plugin-matterjs/CHANGELOG.md b/packages/g-plugin-matterjs/CHANGELOG.md index 542afea69..508e0dd98 100644 --- a/packages/g-plugin-matterjs/CHANGELOG.md +++ b/packages/g-plugin-matterjs/CHANGELOG.md @@ -1,5 +1,13 @@ # @antv/g-plugin-matterjs +## 1.9.2 + +### Patch Changes + +- Updated dependencies [0eb5142d] +- Updated dependencies [71990540] + - @antv/g-lite@1.2.2 + ## 1.9.1 ### Patch Changes diff --git a/packages/g-plugin-matterjs/package.json b/packages/g-plugin-matterjs/package.json index f8bc8bca2..3a4577a3f 100644 --- a/packages/g-plugin-matterjs/package.json +++ b/packages/g-plugin-matterjs/package.json @@ -1,6 +1,6 @@ { "name": "@antv/g-plugin-matterjs", - "version": "1.9.1", + "version": "1.9.2", "description": "A G plugin for matter.js physics engine", "keywords": [ "antv", diff --git a/packages/g-plugin-mobile-interaction/CHANGELOG.md b/packages/g-plugin-mobile-interaction/CHANGELOG.md index ce5c817c0..e62422de1 100644 --- a/packages/g-plugin-mobile-interaction/CHANGELOG.md +++ b/packages/g-plugin-mobile-interaction/CHANGELOG.md @@ -1,5 +1,13 @@ # @antv/g-plugin-mobile-interaction +## 0.9.2 + +### Patch Changes + +- Updated dependencies [0eb5142d] +- Updated dependencies [71990540] + - @antv/g-lite@1.2.2 + ## 0.9.1 ### Patch Changes diff --git a/packages/g-plugin-mobile-interaction/package.json b/packages/g-plugin-mobile-interaction/package.json index 874ffd867..3b7f47751 100644 --- a/packages/g-plugin-mobile-interaction/package.json +++ b/packages/g-plugin-mobile-interaction/package.json @@ -1,6 +1,6 @@ { "name": "@antv/g-plugin-mobile-interaction", - "version": "0.9.1", + "version": "0.9.2", "description": "A G plugin listening events in mobile environment", "keywords": [ "antv", diff --git a/packages/g-plugin-physx/CHANGELOG.md b/packages/g-plugin-physx/CHANGELOG.md index 1902390a8..c2ced2a80 100644 --- a/packages/g-plugin-physx/CHANGELOG.md +++ b/packages/g-plugin-physx/CHANGELOG.md @@ -1,5 +1,15 @@ # @antv/g-plugin-physx +## 1.9.2 + +### Patch Changes + +- 0eb5142d: Avoid overriding defXY when parsing path +- 71990540: Make picking process async for WebGL2 & WebGPU implementations +- Updated dependencies [0eb5142d] +- Updated dependencies [71990540] + - @antv/g-lite@1.2.2 + ## 1.9.1 ### Patch Changes diff --git a/packages/g-plugin-physx/package.json b/packages/g-plugin-physx/package.json index c9824706e..480069782 100644 --- a/packages/g-plugin-physx/package.json +++ b/packages/g-plugin-physx/package.json @@ -1,6 +1,6 @@ { "name": "@antv/g-plugin-physx", - "version": "1.9.1", + "version": "1.9.2", "description": "A G plugin for PhysX", "keywords": [ "antv", @@ -39,6 +39,7 @@ }, "dependencies": { "@antv/g-lite": "workspace:*", + "gl-matrix": "^3.4.3", "tslib": "^2.5.3" }, "publishConfig": { diff --git a/packages/g-plugin-physx/src/PhysXPlugin.ts b/packages/g-plugin-physx/src/PhysXPlugin.ts index 2a961ed9c..490b729cd 100644 --- a/packages/g-plugin-physx/src/PhysXPlugin.ts +++ b/packages/g-plugin-physx/src/PhysXPlugin.ts @@ -1,3 +1,4 @@ +import { quat } from 'gl-matrix'; import type { DisplayObject, FederatedEvent, @@ -19,6 +20,32 @@ export enum PhysXRuntimeMode { JavaScript, } +/** + * Flags which affect the behavior of Shapes. + */ +export enum ShapeFlag { + /** The shape will partake in collision in the physical simulation. */ + SIMULATION_SHAPE = 1 << 0, + /** The shape will partake in scene queries (ray casts, overlap tests, sweeps, ...). */ + SCENE_QUERY_SHAPE = 1 << 1, + /** The shape is a trigger which can send reports whenever other shapes enter/leave its volume. */ + TRIGGER_SHAPE = 1 << 2, +} + +/** + * Describes how physics materials of the colliding objects are combined. + */ +enum CombineMode { + /** Averages the friction/bounce of the two colliding materials. */ + Average, + /** Uses the smaller friction/bounce of the two colliding materials. */ + Minimum, + /** Multiplies the friction/bounce of the two colliding materials. */ + Multiply, + /** Uses the larger friction/bounce of the two colliding materials. */ + Maximum, +} + export class PhysXPlugin implements RenderingPlugin { static tag = 'PhysX'; @@ -40,8 +67,18 @@ export class PhysXPlugin implements RenderingPlugin { } }; + const handleUnmounted = (e: FederatedEvent) => { + const PhysX = this.PhysX; + const target = e.target as DisplayObject; + + if (PhysX) { + this.bodies.get(target).body.release(); + } + }; + renderingService.hooks.initAsync.tapPromise(PhysXPlugin.tag, async () => { canvas.addEventListener(ElementEvent.MOUNTED, handleMounted); + canvas.addEventListener(ElementEvent.UNMOUNTED, handleUnmounted); this.PhysX = (await this.initPhysX()) as any; this.createScene(); @@ -57,6 +94,9 @@ export class PhysXPlugin implements RenderingPlugin { this.bodies.forEach(({ body, displayObject }) => { const transform = body.getGlobalPose(); const { translation, rotation } = transform; + + // console.log(translation, rotation, displayObject); + displayObject.setPosition( translation.x, translation.y, @@ -76,60 +116,66 @@ export class PhysXPlugin implements RenderingPlugin { renderingService.hooks.destroy.tap(PhysXPlugin.tag, () => { canvas.removeEventListener(ElementEvent.MOUNTED, handleMounted); + canvas.removeEventListener(ElementEvent.UNMOUNTED, handleUnmounted); }); } // @see https://github.com/oasis-engine/engine/blob/main/packages/physics-physx/src/PhysXPhysics.ts#L39 - private initPhysX( + private async initPhysX( runtimeMode: PhysXRuntimeMode = PhysXRuntimeMode.Auto, ): Promise { - const scriptPromise = new Promise((resolve) => { - const script = document.createElement('script'); - document.body.appendChild(script); - script.async = true; - script.onload = resolve; - - const supported = (() => { - try { - if ( - typeof WebAssembly === 'object' && - typeof WebAssembly.instantiate === 'function' - ) { - const module = new WebAssembly.Module( - Uint8Array.of(0x0, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00), - ); - if (module instanceof WebAssembly.Module) - return ( - new WebAssembly.Instance(module) instanceof WebAssembly.Instance + if ((window).PHYSX) { + return await (window).PHYSX(); + } else { + const scriptPromise = new Promise((resolve) => { + const script = document.createElement('script'); + document.body.appendChild(script); + script.async = true; + script.onload = resolve; + + const supported = (() => { + try { + if ( + typeof WebAssembly === 'object' && + typeof WebAssembly.instantiate === 'function' + ) { + const module = new WebAssembly.Module( + Uint8Array.of(0x0, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00), ); + if (module instanceof WebAssembly.Module) + return ( + new WebAssembly.Instance(module) instanceof + WebAssembly.Instance + ); + } + } catch (e) {} + return false; + })(); + if (runtimeMode == PhysXRuntimeMode.Auto) { + if (supported) { + runtimeMode = PhysXRuntimeMode.WebAssembly; + } else { + runtimeMode = PhysXRuntimeMode.JavaScript; } - } catch (e) {} - return false; - })(); - if (runtimeMode == PhysXRuntimeMode.Auto) { - if (supported) { - runtimeMode = PhysXRuntimeMode.WebAssembly; - } else { - runtimeMode = PhysXRuntimeMode.JavaScript; } - } - if (runtimeMode == PhysXRuntimeMode.JavaScript) { - script.src = - 'https://gw.alipayobjects.com/os/lib/oasis-engine/physics-physx/0.6.0-alpha.1/dist/physx.release.js'; - } else if (runtimeMode == PhysXRuntimeMode.WebAssembly) { - script.src = - 'https://gw.alipayobjects.com/os/lib/oasis-engine/physics-physx/0.6.0-alpha.1/dist/physx.release.js'; - } - }); + if (runtimeMode == PhysXRuntimeMode.JavaScript) { + script.src = + 'https://gw.alipayobjects.com/os/lib/oasis-engine/physics-physx/1.0.0-alpha.4/libs/physx.release.js.js'; + } else if (runtimeMode == PhysXRuntimeMode.WebAssembly) { + script.src = + 'https://gw.alipayobjects.com/os/lib/oasis-engine/physics-physx/1.0.0-alpha.4/libs/physx.release.js'; + } + }); - return new Promise((resolve) => { - scriptPromise.then(() => { - (window).PHYSX().then((PHYSX: any) => { - resolve(PHYSX); + return new Promise((resolve) => { + scriptPromise.then(() => { + (window).PHYSX().then((PHYSX: any) => { + resolve(PHYSX); + }); }); }); - }); + } } private createScene() { @@ -143,11 +189,19 @@ export class PhysXPlugin implements RenderingPlugin { defaultErrorCallback, ); const triggerCallback = { - onContactBegin: () => {}, - onContactEnd: () => {}, + onContactBegin: () => { + console.log('begin...'); + }, + onContactEnd: (index1, index2) => { + console.log('end...', index1, index2); + }, onContactPersist: () => {}, - onTriggerBegin: () => {}, - onTriggerEnd: () => {}, + onTriggerBegin: () => { + console.log('triggerbegin...'); + }, + onTriggerEnd: () => { + console.log('triggerend...'); + }, }; const physxSimulationCallbackInstance = PhysX.PxSimulationEventCallback.implement(triggerCallback); @@ -166,6 +220,11 @@ export class PhysXPlugin implements RenderingPlugin { physxSimulationCallbackInstance, ); this.scene = this.physics.createScene(sceneDesc); + this.scene.setGravity({ + x: 0, + y: 100, + z: 0, + }); } private addActor(target: DisplayObject) { @@ -175,7 +234,7 @@ export class PhysXPlugin implements RenderingPlugin { const PhysX = this.PhysX; const pos = target.getPosition(); - const rotation = target.getRotation(); + const rotation = quat.normalize(quat.create(), target.getRotation()); // use box by default const geometry = new PhysX.PxBoxGeometry( @@ -184,14 +243,19 @@ export class PhysXPlugin implements RenderingPlugin { halfExtents[1], halfExtents[2] || 0.1, // account for 2D shapes ); - const material = this.physics.createMaterial(0.2, 0.2, 0.2); + const material = this.physics.createMaterial(0.5, 0.1, 2); + material.setFrictionCombineMode(CombineMode.Average); + material.setRestitutionCombineMode(CombineMode.Average); + + // @see https://gameworksdocs.nvidia.com/PhysX/4.1/documentation/physxapi/files/structPxShapeFlag.html#a6edb481aaa3a998c5d6dd3fc4ad87f1aa7fa4fea0eecda9cc80a7aaa11a22df52 const flags = new PhysX.PxShapeFlags( - // @see https://gameworksdocs.nvidia.com/PhysX/4.1/documentation/physxapi/files/structPxShapeFlag.html#a6edb481aaa3a998c5d6dd3fc4ad87f1aa7fa4fea0eecda9cc80a7aaa11a22df52 - PhysX.PxShapeFlag.eSCENE_QUERY_Shape.value | - PhysX.PxShapeFlag.eSIMULATION_Shape.value, + ShapeFlag.SCENE_QUERY_SHAPE | ShapeFlag.SIMULATION_SHAPE, + // ShapeFlag.TRIGGER_SHAPE, ); // @see https://gameworksdocs.nvidia.com/PhysX/4.1/documentation/physxapi/files/classPxPhysics.html#abc564607f208cbc1944880172a3d62fe - const shape = this.physics.createShape(geometry, material, false, flags); + const shape = this.physics.createShape(geometry, material, true, flags); + shape.setUUID(target.entity); + const transform = { translation: { x: pos[0], @@ -217,6 +281,13 @@ export class PhysXPlugin implements RenderingPlugin { // @see https://gameworksdocs.nvidia.com/PhysX/4.1/documentation/physxapi/files/classPxRigidActor.html#a022e098ea67bc8ec87f93c2f18a4db6f body.attachShape(shape); + + // if (body.setRigidBodyFlag) { + // body.setRigidBodyFlag(PhysX.PxRigidBodyFlag.eENABLE_CCD, true); + // } + + body.setGlobalPose(transform, true); + this.bodies.set(target, { displayObject: target, body, @@ -224,11 +295,6 @@ export class PhysXPlugin implements RenderingPlugin { // @see https://gameworksdocs.nvidia.com/PhysX/4.1/documentation/physxapi/files/classPxScene.html#a033c70c3094db21a2c51246e1a65a0e5 this.scene.addActor(body, null); - this.scene.setGravity({ - x: 0, - y: 100, // flipY - z: 0, - }); } } } diff --git a/packages/g-plugin-rough-canvas-renderer/CHANGELOG.md b/packages/g-plugin-rough-canvas-renderer/CHANGELOG.md index 43abd112e..165e938f6 100644 --- a/packages/g-plugin-rough-canvas-renderer/CHANGELOG.md +++ b/packages/g-plugin-rough-canvas-renderer/CHANGELOG.md @@ -1,5 +1,14 @@ # @antv/g-plugin-rough-canvas-renderer +## 1.9.2 + +### Patch Changes + +- Updated dependencies [0eb5142d] +- Updated dependencies [71990540] + - @antv/g-lite@1.2.2 + - @antv/g-canvas@1.11.2 + ## 1.9.1 ### Patch Changes diff --git a/packages/g-plugin-rough-canvas-renderer/package.json b/packages/g-plugin-rough-canvas-renderer/package.json index d52b7a4ea..02bb54317 100644 --- a/packages/g-plugin-rough-canvas-renderer/package.json +++ b/packages/g-plugin-rough-canvas-renderer/package.json @@ -1,6 +1,6 @@ { "name": "@antv/g-plugin-rough-canvas-renderer", - "version": "1.9.1", + "version": "1.9.2", "description": "A G plugin of renderer implementation with rough.js", "keywords": [ "antv", diff --git a/packages/g-plugin-rough-svg-renderer/CHANGELOG.md b/packages/g-plugin-rough-svg-renderer/CHANGELOG.md index 6924b0c03..5cc72f423 100644 --- a/packages/g-plugin-rough-svg-renderer/CHANGELOG.md +++ b/packages/g-plugin-rough-svg-renderer/CHANGELOG.md @@ -1,5 +1,14 @@ # @antv/g-plugin-rough-svg-renderer +## 1.9.2 + +### Patch Changes + +- Updated dependencies [0eb5142d] +- Updated dependencies [71990540] + - @antv/g-lite@1.2.2 + - @antv/g-svg@1.10.2 + ## 1.9.1 ### Patch Changes diff --git a/packages/g-plugin-rough-svg-renderer/package.json b/packages/g-plugin-rough-svg-renderer/package.json index 755050fa7..cac0a83a7 100644 --- a/packages/g-plugin-rough-svg-renderer/package.json +++ b/packages/g-plugin-rough-svg-renderer/package.json @@ -1,6 +1,6 @@ { "name": "@antv/g-plugin-rough-svg-renderer", - "version": "1.9.1", + "version": "1.9.2", "description": "A G plugin of renderer implementation with rough.js", "keywords": [ "antv", diff --git a/packages/g-plugin-svg-picker/CHANGELOG.md b/packages/g-plugin-svg-picker/CHANGELOG.md index 28efa20ba..d2ece25c5 100644 --- a/packages/g-plugin-svg-picker/CHANGELOG.md +++ b/packages/g-plugin-svg-picker/CHANGELOG.md @@ -1,5 +1,14 @@ # @antv/g-plugin-svg-picker +## 1.9.2 + +### Patch Changes + +- Updated dependencies [0eb5142d] +- Updated dependencies [71990540] + - @antv/g-lite@1.2.2 + - @antv/g-plugin-svg-renderer@1.10.2 + ## 1.9.1 ### Patch Changes diff --git a/packages/g-plugin-svg-picker/package.json b/packages/g-plugin-svg-picker/package.json index 8aa5759c5..2ff5669b7 100644 --- a/packages/g-plugin-svg-picker/package.json +++ b/packages/g-plugin-svg-picker/package.json @@ -1,6 +1,6 @@ { "name": "@antv/g-plugin-svg-picker", - "version": "1.9.1", + "version": "1.9.2", "description": "A G plugin for picking in SVG", "keywords": [ "antv", diff --git a/packages/g-plugin-svg-renderer/CHANGELOG.md b/packages/g-plugin-svg-renderer/CHANGELOG.md index 30e891713..df87a9a75 100644 --- a/packages/g-plugin-svg-renderer/CHANGELOG.md +++ b/packages/g-plugin-svg-renderer/CHANGELOG.md @@ -1,5 +1,13 @@ # @antv/g-plugin-svg-renderer +## 1.10.2 + +### Patch Changes + +- Updated dependencies [0eb5142d] +- Updated dependencies [71990540] + - @antv/g-lite@1.2.2 + ## 1.10.1 ### Patch Changes diff --git a/packages/g-plugin-svg-renderer/package.json b/packages/g-plugin-svg-renderer/package.json index 1dfaa3d77..4bcc30cd4 100644 --- a/packages/g-plugin-svg-renderer/package.json +++ b/packages/g-plugin-svg-renderer/package.json @@ -1,6 +1,6 @@ { "name": "@antv/g-plugin-svg-renderer", - "version": "1.10.1", + "version": "1.10.2", "description": "A G plugin of renderer implementation with SVG", "keywords": [ "antv", diff --git a/packages/g-plugin-webgl-device/CHANGELOG.md b/packages/g-plugin-webgl-device/CHANGELOG.md index 9956b27b2..439ba8271 100644 --- a/packages/g-plugin-webgl-device/CHANGELOG.md +++ b/packages/g-plugin-webgl-device/CHANGELOG.md @@ -1,5 +1,16 @@ # @antv/g-plugin-webgl-device +## 1.9.2 + +### Patch Changes + +- 0eb5142d: Avoid overriding defXY when parsing path +- 71990540: Make picking process async for WebGL2 & WebGPU implementations +- Updated dependencies [0eb5142d] +- Updated dependencies [71990540] + - @antv/g-plugin-device-renderer@1.9.2 + - @antv/g-lite@1.2.2 + ## 1.9.1 ### Patch Changes diff --git a/packages/g-plugin-webgl-device/package.json b/packages/g-plugin-webgl-device/package.json index aac713006..8cc138bcc 100644 --- a/packages/g-plugin-webgl-device/package.json +++ b/packages/g-plugin-webgl-device/package.json @@ -1,6 +1,6 @@ { "name": "@antv/g-plugin-webgl-device", - "version": "1.9.1", + "version": "1.9.2", "description": "A G plugin implements GPUDevice interface with WebGL API", "keywords": [ "antv", diff --git a/packages/g-plugin-webgl-device/src/WebGLDeviceContribution.ts b/packages/g-plugin-webgl-device/src/WebGLDeviceContribution.ts index a50533194..b2e91b229 100644 --- a/packages/g-plugin-webgl-device/src/WebGLDeviceContribution.ts +++ b/packages/g-plugin-webgl-device/src/WebGLDeviceContribution.ts @@ -14,7 +14,7 @@ export class WebGLDeviceContribution implements DeviceContribution { // @see https://webglfundamentals.org/webgl/lessons/webgl-qna-how-to-use-the-stencil-buffer.html stencil: true, // @see https://webglfundamentals.org/webgl/lessons/webgl-and-alpha.html - // premultipliedAlpha: true, + premultipliedAlpha: true, }; this.handleContextEvents($canvas); diff --git a/packages/g-plugin-webgl-device/src/platform/Buffer.ts b/packages/g-plugin-webgl-device/src/platform/Buffer.ts index 0a5ee46be..aa3c4feea 100644 --- a/packages/g-plugin-webgl-device/src/platform/Buffer.ts +++ b/packages/g-plugin-webgl-device/src/platform/Buffer.ts @@ -1,7 +1,8 @@ -import type { +import { Buffer, BufferDescriptor, BufferFrequencyHint, + align, } from '@antv/g-plugin-device-renderer'; import { assert, @@ -72,9 +73,14 @@ export class Buffer_GL extends ResourceBase_GL implements Buffer { } } + // const byteSize = isNumber(viewOrSize) + // ? viewOrSize * 4 + // : viewOrSize.byteLength * 4; + const byteSize = isNumber(viewOrSize) - ? viewOrSize * 4 - : viewOrSize.byteLength * 4; + ? align(viewOrSize, 4) + : align(viewOrSize.byteLength, 4); + this.gl_buffer_pages = []; let pageByteSize: number; @@ -129,22 +135,21 @@ export class Buffer_GL extends ResourceBase_GL implements Buffer { pageByteSize: dstPageByteSize, } = this; // Account for setSubData being called with a dstByteOffset that is beyond the end of the buffer. - // if (isWebGL2(gl) && gl_target === gl.UNIFORM_BUFFER) { - // // Manually check asserts for speed. - // if (!(dstByteOffset % dstPageByteSize === 0)) - // throw new Error( - // `Assert fail: (dstByteOffset [${dstByteOffset}] % dstPageByteSize [${dstPageByteSize}]) === 0`, - // ); - // if (!(byteSize % dstPageByteSize === 0)) - // throw new Error( - // `Assert fail: (byteSize [${byteSize}] % dstPageByteSize [${dstPageByteSize}]) === 0`, - // ); - // } + if (isWebGL2(gl) && gl_target === gl.UNIFORM_BUFFER) { + // Manually check asserts for speed. + if (!(dstByteOffset % dstPageByteSize === 0)) + throw new Error( + `Assert fail: (dstByteOffset [${dstByteOffset}] % dstPageByteSize [${dstPageByteSize}]) === 0`, + ); + if (!(byteSize % dstPageByteSize === 0)) + throw new Error( + `Assert fail: (byteSize [${byteSize}] % dstPageByteSize [${dstPageByteSize}]) === 0`, + ); + } if (!(dstByteOffset + byteSize <= dstByteSize)) { throw new Error( `Assert fail: (dstByteOffset [${dstByteOffset}] + byteSize [${byteSize}]) <= dstByteSize [${dstByteSize}], gl_target ${gl_target}`, ); - // exceed, need to recreate } diff --git a/packages/g-plugin-webgl-device/src/platform/Device.ts b/packages/g-plugin-webgl-device/src/platform/Device.ts index d0272a557..5a36b9368 100644 --- a/packages/g-plugin-webgl-device/src/platform/Device.ts +++ b/packages/g-plugin-webgl-device/src/platform/Device.ts @@ -60,7 +60,7 @@ import { getFormatFlags, getFormatTypeFlags, GL, - makeStaticDataBuffer, + makeDataBuffer, nullify, prependLineNo, preprocessProgramObj_GLSL, @@ -2332,7 +2332,7 @@ export class Device_GL implements SwapChain, Device { resolveTo: Texture_GL, ) { if (!this.blitRenderPipeline) { - const vertexBuffer = makeStaticDataBuffer( + const vertexBuffer = makeDataBuffer( this, BufferUsage.VERTEX | BufferUsage.COPY_DST, new Float32Array([-4, -4, 4, -4, 0, 4]).buffer, diff --git a/packages/g-plugin-webgl-device/src/platform/Readback.ts b/packages/g-plugin-webgl-device/src/platform/Readback.ts index cce958537..170ddb34d 100644 --- a/packages/g-plugin-webgl-device/src/platform/Readback.ts +++ b/packages/g-plugin-webgl-device/src/platform/Readback.ts @@ -1,4 +1,9 @@ -import type { Buffer, Readback, Texture } from '@antv/g-plugin-device-renderer'; +import { + Buffer, + Readback, + Texture, + getFormatByteSize, +} from '@antv/g-plugin-device-renderer'; import { GL, ResourceType } from '@antv/g-plugin-device-renderer'; import { clamp } from '@antv/util'; import type { Device_GL } from './Device'; @@ -71,7 +76,7 @@ export class Readback_GL extends ResourceBase_GL implements Readback { /** * @see https://developer.mozilla.org/en-US/docs/Web/API/WebGL_API/WebGL_best_practices#use_non-blocking_async_data_readback */ - readTexture( + async readTexture( t: Texture, x: number, y: number, @@ -80,60 +85,68 @@ export class Readback_GL extends ResourceBase_GL implements Readback { dstBuffer: ArrayBufferView, dstOffset = 0, length = dstBuffer.byteLength || 0, - ): ArrayBufferView { + ): Promise { const gl = this.device.gl; const texture = t as Texture_GL; - // const gl_format = this.device.translateTextureFormat(texture.pixelFormat); + const gl_format = this.device.translateTextureFormat(texture.pixelFormat); const gl_type = this.device.translateTextureType(texture.pixelFormat); - // const formatByteSize = getFormatByteSize(texture.pixelFormat); - - // if (isWebGL2(gl)) { - // this.gl_pbo = this.device.ensureResourceExists(gl.createBuffer()); - // // PIXEL_PACK_BUFFER: Buffer used for pixel transfer operations - // // @see https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/bindBuffer - // gl.bindBuffer(gl.PIXEL_PACK_BUFFER, this.gl_pbo); - // // STREAM_READ: The contents are intended to be specified once by reading data from WebGL, and queried at most a few times by the application - // // @see https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/bufferData - // gl.bufferData(gl.PIXEL_PACK_BUFFER, length, gl.STREAM_READ); - // gl.bindBuffer(gl.PIXEL_PACK_BUFFER, null); - - // gl.bindFramebuffer(GL.READ_FRAMEBUFFER, this.device.readbackFramebuffer); - // gl.framebufferTexture2D( - // GL.READ_FRAMEBUFFER, - // GL.COLOR_ATTACHMENT0, - // GL.TEXTURE_2D, - // texture.gl_texture, - // 0, - // ); - - // gl.bindBuffer(gl.PIXEL_PACK_BUFFER, this.gl_pbo); - // gl.readPixels(x, y, width, height, gl_format, gl_type, dstOffset * formatByteSize); - // gl.bindBuffer(gl.PIXEL_PACK_BUFFER, null); - - // return this.getBufferSubDataAsync( - // gl.PIXEL_PACK_BUFFER, - // this.gl_pbo, - // 0, - // dstBuffer, - // dstOffset, - // length, - // ); - // } else { - gl.bindFramebuffer(GL.FRAMEBUFFER, this.device.readbackFramebuffer); - gl.framebufferTexture2D( - GL.FRAMEBUFFER, - GL.COLOR_ATTACHMENT0, - GL.TEXTURE_2D, - texture.gl_texture, - 0, - ); - // slow requires roundtrip to GPU - // @see https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/pixelStorei - gl.pixelStorei(gl.PACK_ALIGNMENT, 4); - gl.readPixels(x, y, width, height, gl.RGBA, gl_type, dstBuffer); - return dstBuffer; - // } + const formatByteSize = getFormatByteSize(texture.pixelFormat); + + if (isWebGL2(gl)) { + this.gl_pbo = this.device.ensureResourceExists(gl.createBuffer()); + // PIXEL_PACK_BUFFER: Buffer used for pixel transfer operations + // @see https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/bindBuffer + gl.bindBuffer(gl.PIXEL_PACK_BUFFER, this.gl_pbo); + // STREAM_READ: The contents are intended to be specified once by reading data from WebGL, and queried at most a few times by the application + // @see https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/bufferData + gl.bufferData(gl.PIXEL_PACK_BUFFER, length, gl.STREAM_READ); + gl.bindBuffer(gl.PIXEL_PACK_BUFFER, null); + + gl.bindFramebuffer(GL.READ_FRAMEBUFFER, this.device.readbackFramebuffer); + gl.framebufferTexture2D( + GL.READ_FRAMEBUFFER, + GL.COLOR_ATTACHMENT0, + GL.TEXTURE_2D, + texture.gl_texture, + 0, + ); + + gl.bindBuffer(gl.PIXEL_PACK_BUFFER, this.gl_pbo); + gl.readPixels( + x, + y, + width, + height, + gl_format, + gl_type, + dstOffset * formatByteSize, + ); + gl.bindBuffer(gl.PIXEL_PACK_BUFFER, null); + + return this.getBufferSubDataAsync( + gl.PIXEL_PACK_BUFFER, + this.gl_pbo, + 0, + dstBuffer, + dstOffset, + length, + ); + } else { + gl.bindFramebuffer(GL.FRAMEBUFFER, this.device.readbackFramebuffer); + gl.framebufferTexture2D( + GL.FRAMEBUFFER, + GL.COLOR_ATTACHMENT0, + GL.TEXTURE_2D, + texture.gl_texture, + 0, + ); + // slow requires roundtrip to GPU + // @see https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/pixelStorei + gl.pixelStorei(gl.PACK_ALIGNMENT, 4); + gl.readPixels(x, y, width, height, gl.RGBA, gl_type, dstBuffer); + return dstBuffer; + } } async readBuffer( diff --git a/packages/g-plugin-webgpu-device/CHANGELOG.md b/packages/g-plugin-webgpu-device/CHANGELOG.md index 14eb2a2d4..43f51af3d 100644 --- a/packages/g-plugin-webgpu-device/CHANGELOG.md +++ b/packages/g-plugin-webgpu-device/CHANGELOG.md @@ -1,5 +1,16 @@ # @antv/g-plugin-webgpu-device +## 1.9.2 + +### Patch Changes + +- 0eb5142d: Avoid overriding defXY when parsing path +- 71990540: Make picking process async for WebGL2 & WebGPU implementations +- Updated dependencies [0eb5142d] +- Updated dependencies [71990540] + - @antv/g-plugin-device-renderer@1.9.2 + - @antv/g-lite@1.2.2 + ## 1.9.1 ### Patch Changes diff --git a/packages/g-plugin-webgpu-device/package.json b/packages/g-plugin-webgpu-device/package.json index 744c37cc8..7ec688448 100644 --- a/packages/g-plugin-webgpu-device/package.json +++ b/packages/g-plugin-webgpu-device/package.json @@ -1,6 +1,6 @@ { "name": "@antv/g-plugin-webgpu-device", - "version": "1.9.1", + "version": "1.9.2", "description": "A G plugin implements GPUDevice interface with WebGPU API", "keywords": [ "antv", diff --git a/packages/g-plugin-webgpu-device/src/platform/Buffer.ts b/packages/g-plugin-webgpu-device/src/platform/Buffer.ts index f76ab8191..195205cc0 100644 --- a/packages/g-plugin-webgpu-device/src/platform/Buffer.ts +++ b/packages/g-plugin-webgpu-device/src/platform/Buffer.ts @@ -1,14 +1,13 @@ -import type { Buffer, BufferDescriptor } from '@antv/g-plugin-device-renderer'; +import { + Buffer, + BufferDescriptor, + align, +} from '@antv/g-plugin-device-renderer'; import { BufferUsage, ResourceType } from '@antv/g-plugin-device-renderer'; import type { IDevice_WebGPU } from './interfaces'; import { ResourceBase_WebGPU } from './ResourceBase'; import { translateBufferUsage } from './utils'; - -function isView( - viewOrSize: ArrayBufferView | number, -): viewOrSize is ArrayBufferView { - return (viewOrSize as ArrayBufferView).byteLength !== undefined; -} +import { isNumber } from '@antv/util'; export class Buffer_WebGPU extends ResourceBase_WebGPU implements Buffer { type: ResourceType.Buffer = ResourceType.Buffer; @@ -17,9 +16,12 @@ export class Buffer_WebGPU extends ResourceBase_WebGPU implements Buffer { */ gpuBuffer: GPUBuffer; + /** + * size in bytes + */ size: number; - view: ArrayBufferView; + view: ArrayBufferView | null; usage: BufferUsage; @@ -37,10 +39,6 @@ export class Buffer_WebGPU extends ResourceBase_WebGPU implements Buffer { const { usage, viewOrSize } = descriptor; const useMapRead = !!(usage & BufferUsage.MAP_READ); - // const alignedLength = isView(viewOrSize) - // ? viewOrSize.byteLength - // : viewOrSize * 4; // 4 bytes alignments (because of the upload which requires this) - this.usage = translateBufferUsage(usage); // Buffer usages (BufferUsage::(MapRead|CopyDst|Storage)) is invalid. If a buffer usage contains BufferUsage::MapRead the only other allowed usage is BufferUsage::CopyDst. @@ -49,20 +47,26 @@ export class Buffer_WebGPU extends ResourceBase_WebGPU implements Buffer { this.usage = BufferUsage.MAP_READ | BufferUsage.COPY_DST; } - const mapBuffer = isView(viewOrSize); + const mapBuffer = !isNumber(viewOrSize); + + // this.size = isView(viewOrSize) ? viewOrSize.byteLength : viewOrSize * 4; + this.view = !isNumber(viewOrSize) ? viewOrSize : null; - this.size = isView(viewOrSize) ? viewOrSize.byteLength : viewOrSize * 4; - this.view = isView(viewOrSize) ? viewOrSize : null; + // 4 bytes alignments (because of the upload which requires this) + this.size = isNumber(viewOrSize) + ? align(viewOrSize, 4) + : align(viewOrSize.byteLength, 4); - if (isView(viewOrSize)) { - // this.setSubData(0, new Uint8Array(viewOrSize.buffer)); + if (!isNumber(viewOrSize)) { this.gpuBuffer = this.device.device.createBuffer({ usage: this.usage, size: this.size, mappedAtCreation: true, }); + + const ctor = (viewOrSize && viewOrSize.constructor) || Float32Array; // @ts-ignore - new Uint8Array(this.gpuBuffer.getMappedRange()).set(viewOrSize); + new ctor(this.gpuBuffer.getMappedRange()).set(viewOrSize); this.gpuBuffer.unmap(); } else { this.gpuBuffer = this.device.device.createBuffer({ diff --git a/packages/g-plugin-webgpu-device/src/platform/Device.ts b/packages/g-plugin-webgpu-device/src/platform/Device.ts index fcb07e9dc..3d5830d69 100644 --- a/packages/g-plugin-webgpu-device/src/platform/Device.ts +++ b/packages/g-plugin-webgpu-device/src/platform/Device.ts @@ -206,8 +206,9 @@ export class Device_WebGPU implements SwapChain, IDevice_WebGPU { device: this.device, format: this.swapChainFormat, usage: this.swapChainTextureUsage, - // @see https://www.w3.org/TR/webgpu/#enumdef-gpucanvascompositingalphamode - alphaMode: 'opaque', + // @see https://www.w3.org/TR/webgpu/#gpucanvasalphamode + // alphaMode: 'opaque', + alphaMode: 'premultiplied', }); } diff --git a/packages/g-plugin-webgpu-device/src/platform/Readback.ts b/packages/g-plugin-webgpu-device/src/platform/Readback.ts index a5ac50534..7d67b2d90 100644 --- a/packages/g-plugin-webgpu-device/src/platform/Readback.ts +++ b/packages/g-plugin-webgpu-device/src/platform/Readback.ts @@ -20,7 +20,7 @@ export class Readback_WebGPU extends ResourceBase_WebGPU implements Readback { super({ id, device }); } - readTexture( + async readTexture( t: Texture, x: number, y: number, @@ -29,8 +29,10 @@ export class Readback_WebGPU extends ResourceBase_WebGPU implements Readback { dst: ArrayBufferView, dstOffset = 0, length = 0, - ): ArrayBufferView { + ): Promise { const texture = t as Texture_WebGPU; + + // FIXME: default to 0 for now const faceIndex = 0; const blockInformation = this.getBlockInformationFromFormat(texture.format); @@ -38,6 +40,7 @@ export class Readback_WebGPU extends ResourceBase_WebGPU implements Readback { const bytesPerRow = Math.ceil(width / blockInformation.width) * blockInformation.length; + // bytesPerRow (4) is not a multiple of 256, so we need to align it to 256. const bytesPerRowAligned = Math.ceil(bytesPerRow / 256) * 256; const size = bytesPerRowAligned * height; @@ -75,9 +78,14 @@ export class Readback_WebGPU extends ResourceBase_WebGPU implements Readback { this.device.device.queue.submit([commandEncoder.finish()]); - // FIXME: read from buffer - // return this.readBuffer(buffer, size, dst, dstOffset, length, texture.pixelFormat); - return null; + return this.readBuffer( + buffer, + 0, + dst.byteLength === size ? dst : null, + dstOffset, + size, + texture.pixelFormat, + ); } readBuffer( diff --git a/packages/g-plugin-webgpu-device/src/platform/RenderPass.ts b/packages/g-plugin-webgpu-device/src/platform/RenderPass.ts index b345641f1..ded9da5c8 100644 --- a/packages/g-plugin-webgpu-device/src/platform/RenderPass.ts +++ b/packages/g-plugin-webgpu-device/src/platform/RenderPass.ts @@ -4,7 +4,6 @@ import { RenderPass, RenderPassDescriptor, RenderPipeline, - TransparentWhite, } from '@antv/g-plugin-device-renderer'; import { assert, @@ -107,7 +106,6 @@ export class RenderPass_WebGPU implements RenderPass { dstAttachment.loadOp = 'load'; } else { dstAttachment.loadOp = 'clear'; - console.log(clearColor, TransparentWhite); dstAttachment.clearValue = clearColor; } dstAttachment.storeOp = descriptor.colorStore[i] ? 'store' : 'discard'; diff --git a/packages/g-plugin-webgpu-device/src/platform/Texture.ts b/packages/g-plugin-webgpu-device/src/platform/Texture.ts index 354033206..ca7641002 100644 --- a/packages/g-plugin-webgpu-device/src/platform/Texture.ts +++ b/packages/g-plugin-webgpu-device/src/platform/Texture.ts @@ -8,7 +8,7 @@ import { ResourceType } from '@antv/g-plugin-device-renderer'; import type { IDevice_WebGPU, TextureShared_WebGPU } from './interfaces'; import { ResourceBase_WebGPU } from './ResourceBase'; -// @see https://toji.github.io/webgpu-best-practices/img-textures.html +// @see https://toji.dev/webgpu-best-practices/img-textures export class Texture_WebGPU extends ResourceBase_WebGPU @@ -56,8 +56,38 @@ export class Texture_WebGPU ); } - setImageData(data: TexImageSource, level: number) { - // TODO: https://www.w3.org/TR/webgpu/#image-copies + setImageData(data: TexImageSource | ArrayBufferView[], level: number) { + // @see https://www.w3.org/TR/webgpu/#image-copies + // @see https://www.w3.org/TR/webgpu/#dom-gpuqueue-copyexternalimagetotexture + // const isArray = Array.isArray(data); + // if (!isArray) { + // // if (this.gpuTexture) { + // // this.gpuTexture.destroy(); + // // } + // const textureDescriptor: GPUTextureDescriptor = { + // // Unlike in WebGL, the size of our texture must be set at texture creation time. + // // This means we have to wait until the image is loaded to create the texture, since we won't + // // know the size until then. + // size: { width: data.width, height: data.height }, + // format: 'rgba8unorm', + // usage: + // GPUTextureUsage.TEXTURE_BINDING | + // GPUTextureUsage.COPY_DST | + // GPUTextureUsage.RENDER_ATTACHMENT, + // }; + // const texture = this.device.device.createTexture(textureDescriptor); + // this.gpuTexture = texture; + // this.gpuTextureView = texture.createView(); + // this.width = data.width; + // this.height = data.height; + // this.device.device.queue.copyExternalImageToTexture( + // { source: data }, + // { texture }, + // textureDescriptor.size, + // ); + // } else { + // // TODO: support ArrayBufferView[] + // } } destroy() { diff --git a/packages/g-plugin-webgpu-device/src/platform/interfaces.ts b/packages/g-plugin-webgpu-device/src/platform/interfaces.ts index e6a441af4..61c189f0e 100644 --- a/packages/g-plugin-webgpu-device/src/platform/interfaces.ts +++ b/packages/g-plugin-webgpu-device/src/platform/interfaces.ts @@ -9,7 +9,9 @@ import type { Device, BindingLayoutSamplerDescriptor, BindingLayoutDescriptor, + Buffer, } from '@antv/g-plugin-device-renderer'; +import { BufferDescriptor } from '@antv/g-plugin-device-renderer'; export interface TextureSharedDescriptor { dimension: TextureDimension; @@ -46,6 +48,7 @@ export interface IDevice_WebGPU extends Device { device: GPUDevice; getFallbackSampler: (samplerEntry: BindingLayoutSamplerDescriptor) => Sampler; getFallbackTexture: (samplerEntry: BindingLayoutSamplerDescriptor) => Texture; + createBuffer: (descriptor: BufferDescriptor) => Buffer; createTextureShared: ( descriptor: TextureSharedDescriptor, texture: TextureShared_WebGPU, diff --git a/packages/g-plugin-yoga/CHANGELOG.md b/packages/g-plugin-yoga/CHANGELOG.md index 188f5f569..db2596ddc 100644 --- a/packages/g-plugin-yoga/CHANGELOG.md +++ b/packages/g-plugin-yoga/CHANGELOG.md @@ -1,5 +1,13 @@ # @antv/g-plugin-yoga +## 1.9.2 + +### Patch Changes + +- Updated dependencies [0eb5142d] +- Updated dependencies [71990540] + - @antv/g-lite@1.2.2 + ## 1.9.1 ### Patch Changes diff --git a/packages/g-plugin-yoga/package.json b/packages/g-plugin-yoga/package.json index cfdb546fa..54941606f 100644 --- a/packages/g-plugin-yoga/package.json +++ b/packages/g-plugin-yoga/package.json @@ -1,6 +1,6 @@ { "name": "@antv/g-plugin-yoga", - "version": "1.9.1", + "version": "1.9.2", "description": "A G plugin for Yoga layout engine", "keywords": [ "antv", diff --git a/packages/g-plugin-zdog-canvas-renderer/CHANGELOG.md b/packages/g-plugin-zdog-canvas-renderer/CHANGELOG.md index 5bb699cf4..758623df7 100644 --- a/packages/g-plugin-zdog-canvas-renderer/CHANGELOG.md +++ b/packages/g-plugin-zdog-canvas-renderer/CHANGELOG.md @@ -1,5 +1,16 @@ # @antv/g-plugin-zdog-canvas-renderer +## 1.2.2 + +### Patch Changes + +- 0eb5142d: Avoid overriding defXY when parsing path +- 71990540: Make picking process async for WebGL2 & WebGPU implementations +- Updated dependencies [0eb5142d] +- Updated dependencies [71990540] + - @antv/g-lite@1.2.2 + - @antv/g-canvas@1.11.2 + ## 1.2.1 ### Patch Changes diff --git a/packages/g-plugin-zdog-canvas-renderer/package.json b/packages/g-plugin-zdog-canvas-renderer/package.json index ea1597e12..66b7d9b66 100644 --- a/packages/g-plugin-zdog-canvas-renderer/package.json +++ b/packages/g-plugin-zdog-canvas-renderer/package.json @@ -1,6 +1,6 @@ { "name": "@antv/g-plugin-zdog-canvas-renderer", - "version": "1.2.1", + "version": "1.2.2", "description": "A G plugin of renderer implementation with Zdog", "keywords": [ "antv", diff --git a/packages/g-plugin-zdog-canvas-renderer/src/ZdogRendererPlugin.ts b/packages/g-plugin-zdog-canvas-renderer/src/ZdogRendererPlugin.ts index 2702c6400..c218f0c35 100644 --- a/packages/g-plugin-zdog-canvas-renderer/src/ZdogRendererPlugin.ts +++ b/packages/g-plugin-zdog-canvas-renderer/src/ZdogRendererPlugin.ts @@ -18,26 +18,14 @@ export class ZdogRendererPlugin implements RenderingPlugin { config.renderer.getConfig().enableDirtyCheck = false; config.renderer.getConfig().enableDirtyRectangleRendering = false; - const context = contextService.getContext(); - // // @ts-ignore - // context.illo = new Illustration({ - // element: contextService.getDomElement() as HTMLCanvasElement, - // dragRotate: false, - // }); - // @ts-ignore - // this.illo = context.illo; - + const context = contextService.getContext() as { scene: Anchor }; this.scene = new Anchor(); - // @ts-ignore context.scene = this.scene; }); renderingService.hooks.endFrame.tap(ZdogRendererPlugin.tag, () => { const context = contextService.getContext() as CanvasRenderingContext2D; this.scene.renderGraphCanvas(context); - - // @see https://zzz.dog/api#illustration-updaterendergraph - this.scene.updateGraph(); }); renderingService.hooks.destroy.tap(ZdogRendererPlugin.tag, () => {}); diff --git a/packages/g-plugin-zdog-canvas-renderer/src/renderers/Circle.ts b/packages/g-plugin-zdog-canvas-renderer/src/renderers/Circle.ts index 2d862465b..a54a11c10 100644 --- a/packages/g-plugin-zdog-canvas-renderer/src/renderers/Circle.ts +++ b/packages/g-plugin-zdog-canvas-renderer/src/renderers/Circle.ts @@ -1,29 +1,28 @@ import type { CanvasRenderer } from '@antv/g-canvas'; import type { DisplayObject, ParsedCircleStyleProps } from '@antv/g-lite'; -import { Ellipse } from 'zdog'; +import { Anchor, Ellipse } from 'zdog'; export class CircleRenderer implements CanvasRenderer.StyleRenderer { render( - context: CanvasRenderingContext2D, + context: CanvasRenderingContext2D & { scene: Anchor }, parsedStyle: ParsedCircleStyleProps, object: DisplayObject, ) { const { r, lineWidth, fill } = parsedStyle as ParsedCircleStyleProps; - const c = new Ellipse({ - // @ts-ignore + new Ellipse({ addTo: context.scene, diameter: 2 * r, stroke: lineWidth, color: fill.toString(), translate: { - x: 200, - y: 200, + x: 0, + y: 0, z: 40, }, }); - // @ts-ignore - console.log(c, context.scene); + // @see https://zzz.dog/api#illustration-updaterendergraph + context.scene.updateGraph(); } } diff --git a/packages/g-plugin-zdog-svg-renderer/CHANGELOG.md b/packages/g-plugin-zdog-svg-renderer/CHANGELOG.md index 804cd586f..67741d8b5 100644 --- a/packages/g-plugin-zdog-svg-renderer/CHANGELOG.md +++ b/packages/g-plugin-zdog-svg-renderer/CHANGELOG.md @@ -1,5 +1,15 @@ # @antv/g-plugin-zdog-svg-renderer +## 1.2.2 + +### Patch Changes + +- Updated dependencies [0eb5142d] +- Updated dependencies [71990540] + - @antv/g-lite@1.2.2 + - @antv/g-plugin-svg-renderer@1.10.2 + - @antv/g-svg@1.10.2 + ## 1.2.1 ### Patch Changes diff --git a/packages/g-plugin-zdog-svg-renderer/package.json b/packages/g-plugin-zdog-svg-renderer/package.json index 69af0f329..44e994c71 100644 --- a/packages/g-plugin-zdog-svg-renderer/package.json +++ b/packages/g-plugin-zdog-svg-renderer/package.json @@ -1,6 +1,6 @@ { "name": "@antv/g-plugin-zdog-svg-renderer", - "version": "1.2.1", + "version": "1.2.2", "description": "A G plugin of renderer implementation with Zdog", "keywords": [ "antv", diff --git a/packages/g-svg/CHANGELOG.md b/packages/g-svg/CHANGELOG.md index 9c235b7eb..d25a9bb6a 100644 --- a/packages/g-svg/CHANGELOG.md +++ b/packages/g-svg/CHANGELOG.md @@ -1,5 +1,16 @@ # @antv/g-svg +## 1.10.2 + +### Patch Changes + +- Updated dependencies [0eb5142d] +- Updated dependencies [71990540] + - @antv/g-lite@1.2.2 + - @antv/g-plugin-dom-interaction@1.9.2 + - @antv/g-plugin-svg-picker@1.9.2 + - @antv/g-plugin-svg-renderer@1.10.2 + ## 1.10.1 ### Patch Changes diff --git a/packages/g-svg/package.json b/packages/g-svg/package.json index a8c3d5dbc..f0d86e2ed 100644 --- a/packages/g-svg/package.json +++ b/packages/g-svg/package.json @@ -1,6 +1,6 @@ { "name": "@antv/g-svg", - "version": "1.10.1", + "version": "1.10.2", "description": "A renderer implemented by SVG", "keywords": [ "antv", diff --git a/packages/g-web-animations-api/CHANGELOG.md b/packages/g-web-animations-api/CHANGELOG.md index d473c4dbd..072544068 100644 --- a/packages/g-web-animations-api/CHANGELOG.md +++ b/packages/g-web-animations-api/CHANGELOG.md @@ -1,5 +1,13 @@ # @antv/g-web-animations-api +## 1.2.2 + +### Patch Changes + +- Updated dependencies [0eb5142d] +- Updated dependencies [71990540] + - @antv/g-lite@1.2.2 + ## 1.2.1 ### Patch Changes diff --git a/packages/g-web-animations-api/package.json b/packages/g-web-animations-api/package.json index cc9439b90..53a76c737 100644 --- a/packages/g-web-animations-api/package.json +++ b/packages/g-web-animations-api/package.json @@ -1,6 +1,6 @@ { "name": "@antv/g-web-animations-api", - "version": "1.2.1", + "version": "1.2.2", "description": "A simple implementation of Web Animations API.", "keywords": [ "antv", diff --git a/packages/g-web-components/CHANGELOG.md b/packages/g-web-components/CHANGELOG.md index dece3c61d..2f5e3e232 100644 --- a/packages/g-web-components/CHANGELOG.md +++ b/packages/g-web-components/CHANGELOG.md @@ -1,5 +1,15 @@ # @antv/g-web-components +## 1.9.2 + +### Patch Changes + +- Updated dependencies [0eb5142d] +- Updated dependencies [71990540] + - @antv/g-lite@1.2.2 + - @antv/g-webgl@1.9.2 + - @antv/g-canvas@1.11.2 + ## 1.9.1 ### Patch Changes diff --git a/packages/g-web-components/package.json b/packages/g-web-components/package.json index 0ca51b99d..1a3f5f7a6 100644 --- a/packages/g-web-components/package.json +++ b/packages/g-web-components/package.json @@ -1,6 +1,6 @@ { "name": "@antv/g-web-components", - "version": "1.9.1", + "version": "1.9.2", "description": "A declarative usage for G implemented with WebComponents", "keywords": [ "antv", diff --git a/packages/g-webgl/CHANGELOG.md b/packages/g-webgl/CHANGELOG.md index b8833b2ba..94ebf4e75 100644 --- a/packages/g-webgl/CHANGELOG.md +++ b/packages/g-webgl/CHANGELOG.md @@ -1,5 +1,18 @@ # @antv/g-webgl +## 1.9.2 + +### Patch Changes + +- Updated dependencies [0eb5142d] +- Updated dependencies [71990540] + - @antv/g-plugin-device-renderer@1.9.2 + - @antv/g-plugin-webgl-device@1.9.2 + - @antv/g-lite@1.2.2 + - @antv/g-plugin-dom-interaction@1.9.2 + - @antv/g-plugin-html-renderer@1.9.2 + - @antv/g-plugin-image-loader@1.3.2 + ## 1.9.1 ### Patch Changes diff --git a/packages/g-webgl/package.json b/packages/g-webgl/package.json index abcf30fd6..00f27a560 100644 --- a/packages/g-webgl/package.json +++ b/packages/g-webgl/package.json @@ -1,6 +1,6 @@ { "name": "@antv/g-webgl", - "version": "1.9.1", + "version": "1.9.2", "description": "A renderer implemented by WebGL1/2", "keywords": [ "antv", diff --git a/packages/g-webgpu/CHANGELOG.md b/packages/g-webgpu/CHANGELOG.md index c414ba503..6c6796fde 100644 --- a/packages/g-webgpu/CHANGELOG.md +++ b/packages/g-webgpu/CHANGELOG.md @@ -1,5 +1,20 @@ # @antv/g-webgpu +## 1.9.2 + +### Patch Changes + +- 0eb5142d: Avoid overriding defXY when parsing path +- 71990540: Make picking process async for WebGL2 & WebGPU implementations +- Updated dependencies [0eb5142d] +- Updated dependencies [71990540] + - @antv/g-plugin-device-renderer@1.9.2 + - @antv/g-plugin-webgpu-device@1.9.2 + - @antv/g-lite@1.2.2 + - @antv/g-plugin-dom-interaction@1.9.2 + - @antv/g-plugin-html-renderer@1.9.2 + - @antv/g-plugin-image-loader@1.3.2 + ## 1.9.1 ### Patch Changes diff --git a/packages/g-webgpu/package.json b/packages/g-webgpu/package.json index 47ace800b..01e99cd5d 100644 --- a/packages/g-webgpu/package.json +++ b/packages/g-webgpu/package.json @@ -1,6 +1,6 @@ { "name": "@antv/g-webgpu", - "version": "1.9.1", + "version": "1.9.2", "description": "A renderer implemented by WebGPU", "keywords": [ "antv", diff --git a/packages/g-webgpu/src/index.ts b/packages/g-webgpu/src/index.ts index 63b557ee0..47dd5cd39 100644 --- a/packages/g-webgpu/src/index.ts +++ b/packages/g-webgpu/src/index.ts @@ -1,4 +1,4 @@ -import type { RendererConfig } from '@antv/g-lite'; +import { ClipSpaceNearZ, RendererConfig } from '@antv/g-lite'; import { AbstractRenderer } from '@antv/g-lite'; import * as DeviceRenderer from '@antv/g-plugin-device-renderer'; import * as DomInteraction from '@antv/g-plugin-dom-interaction'; @@ -15,6 +15,8 @@ interface WebGPURendererConfig extends RendererConfig { } export class Renderer extends AbstractRenderer { + clipSpaceNearZ = ClipSpaceNearZ.ZERO; + constructor(config?: Partial) { super(config); diff --git a/packages/g/CHANGELOG.md b/packages/g/CHANGELOG.md index 88d5f16f4..d520eedeb 100644 --- a/packages/g/CHANGELOG.md +++ b/packages/g/CHANGELOG.md @@ -1,5 +1,16 @@ # @antv/g +## 5.18.3 + +### Patch Changes + +- Updated dependencies [0eb5142d] +- Updated dependencies [71990540] + - @antv/g-lite@1.2.2 + - @antv/g-camera-api@1.2.2 + - @antv/g-dom-mutation-observer-api@1.2.2 + - @antv/g-web-animations-api@1.2.2 + ## 5.18.2 ### Patch Changes diff --git a/packages/g/package.json b/packages/g/package.json index d14353868..35245c1c4 100644 --- a/packages/g/package.json +++ b/packages/g/package.json @@ -1,6 +1,6 @@ { "name": "@antv/g", - "version": "5.18.2", + "version": "5.18.3", "description": "A core module for rendering engine implements DOM API.", "keywords": [ "antv", diff --git a/packages/react-g/CHANGELOG.md b/packages/react-g/CHANGELOG.md index 53276c206..13afc553a 100644 --- a/packages/react-g/CHANGELOG.md +++ b/packages/react-g/CHANGELOG.md @@ -1,5 +1,11 @@ # @antv/react-g +## 1.10.3 + +### Patch Changes + +- @antv/g@5.18.3 + ## 1.10.2 ### Patch Changes diff --git a/packages/react-g/package.json b/packages/react-g/package.json index f57149f84..e1e1f4b7c 100644 --- a/packages/react-g/package.json +++ b/packages/react-g/package.json @@ -1,6 +1,6 @@ { "name": "@antv/react-g", - "version": "1.10.2", + "version": "1.10.3", "description": "react render for @antv/g", "keywords": [ "react", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index e84efb239..99e5ec980 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -812,6 +812,9 @@ importers: '@antv/g-lite': specifier: workspace:* version: link:../g-lite + gl-matrix: + specifier: ^3.4.3 + version: 3.4.3 tslib: specifier: ^2.5.3 version: 2.5.3 @@ -1153,14 +1156,14 @@ importers: site: dependencies: '@antv/g-components': - specifier: ^1.9.0 + specifier: ^1.9.1 version: link:../packages/g-components - '@antv/g-plugin-dragndrop': - specifier: ^1.8.0 - version: link:../packages/g-plugin-dragndrop - '@antv/g-svg': - specifier: ^1.10.0 - version: link:../packages/g-svg + '@antv/g-mobile-webgl': + specifier: ^0.9.1 + version: link:../packages/g-mobile-webgl + '@antv/g-plugin-image-loader': + specifier: ^1.3.1 + version: link:../packages/g-plugin-image-loader '@antv/g6': specifier: ^4.5.2 version: 4.5.2 @@ -1549,12 +1552,12 @@ packages: tslib: 2.5.3 dev: false - /@antv/g-camera-api@1.0.40(@antv/g-lite@1.0.70): + /@antv/g-camera-api@1.0.40(@antv/g-lite@1.2.1): resolution: {integrity: sha512-GhhNdrPlT+Pw9RtBqMsBEQxrXhbR8nbva4WxJ381/o4gTdSzF+DBEt4uND3u5mv910HeC2iNbq+8itQhMFvlTw==} peerDependencies: '@antv/g-lite': ^1.0.0 dependencies: - '@antv/g-lite': 1.0.70 + '@antv/g-lite': 1.2.1 '@antv/util': 3.3.1(gl-matrix@3.4.3) gl-matrix: 3.4.3 dev: false @@ -1571,38 +1574,37 @@ packages: tslib: 2.5.3 dev: false - /@antv/g-css-layout-api@1.0.38(@antv/g-lite@1.0.70): + /@antv/g-css-layout-api@1.0.38(@antv/g-lite@1.2.1): resolution: {integrity: sha512-2KFNXOXVN20hVVFSyDiShLdFF1Bnc2whPDNQpfUgWlwlBTeUDx3Bd1tnNEuPg6MDQkV4luPE/1rEe8o6fOE3zg==} peerDependencies: '@antv/g-lite': ^1.0.0 dependencies: - '@antv/g-lite': 1.0.70 + '@antv/g-lite': 1.2.1 dev: false - /@antv/g-css-typed-om-api@1.0.38(@antv/g-lite@1.0.70): + /@antv/g-css-typed-om-api@1.0.38(@antv/g-lite@1.2.1): resolution: {integrity: sha512-eDLGxlzMyoJGdbORHeajC23JNXV3TjVInegFZdiZdYmS4jNBQzK/8Y7HKdlelfGTJZs4m19i5diHCSyQebNJoQ==} peerDependencies: '@antv/g-lite': ^1.0.0 dependencies: - '@antv/g-lite': 1.0.70 + '@antv/g-lite': 1.2.1 dev: false - /@antv/g-dom-mutation-observer-api@1.0.38(@antv/g-lite@1.0.70): + /@antv/g-dom-mutation-observer-api@1.0.38(@antv/g-lite@1.2.1): resolution: {integrity: sha512-RIuXxTh5cFZz6OWc0D3n0ExlCEqBO/s5EQmLRB7QQTCBjrhBTqvJT7AV8Bp6reeBkCLyZ8eBjwIjc2LX9iWFnw==} peerDependencies: '@antv/g-lite': ^1.0.0 dependencies: - '@antv/g-lite': 1.0.70 + '@antv/g-lite': 1.2.1 dev: false - /@antv/g-lite@1.0.70: - resolution: {integrity: sha512-/ACSlRJXzC84+szMMKeV9AbvuJclnSMCdSyghqMVzeuYr5YE6mtWwLk+dOWAHgX/F0nJCpjQkIvcMdXGqakLzw==} + /@antv/g-lite@1.2.1: + resolution: {integrity: sha512-NxSqvhK62fvm+r/SPM1CP0HdUl2mJarV6mM/l77paCgFaEMpU+1veWdF97N1cUQ8QFOmgaodr5aiZBz0rkn8ag==} dependencies: - '@antv/g-math': 1.7.49 + '@antv/g-math': 2.0.1 '@antv/util': 3.3.1(gl-matrix@3.4.3) - '@types/offscreencanvas': 2019.6.4 d3-color: 1.4.0 - eventemitter3: 4.0.7 + eventemitter3: 5.0.1 gl-matrix: 3.4.3 rbush: 3.0.1 tslib: 2.5.3 @@ -1615,36 +1617,33 @@ packages: gl-matrix: 3.4.3 dev: false - /@antv/g-math@1.7.49: - resolution: {integrity: sha512-6eVtmtkmPAjqQrg1TZ6MICtHmBUv2jCDbgRpHl3VmX48KPPOaBlbkZlhh0ZEAEMN1ex075W8kYr/+xDHnhCvKg==} + /@antv/g-math@2.0.1: + resolution: {integrity: sha512-Y1DREalYzUMaglD0m6V9s9UxsseXgSmwNA3l9zDHRH1CXDLcvtmrku+DQM9oCgPtbPWV43AdyAYoNT3WLyL/WA==} dependencies: + '@antv/util': 3.3.1(gl-matrix@3.4.3) gl-matrix: 3.4.3 tslib: 2.5.3 dev: false - /@antv/g-plugin-device-renderer@1.7.70(@antv/g-lite@packages+g-lite): - resolution: {integrity: sha512-S7SbGqo9G2z3voBuOBMfTaiNkjTcBWxpVjIyMJ/R3CMqXuLtXC2DMi0VGtte2iAfcFyF2V4S56Y/kAklii7I8A==} - peerDependencies: - '@antv/g-lite': ^1.0.0 + /@antv/g-plugin-device-renderer@1.9.1: + resolution: {integrity: sha512-Q+/6TKqZOPDkIragpIdzSVPfXEZ72SM0LzBT7K5Hu5ttDL6yFNGACKdhJjdbEhG32ycY6sI8qLLX5aVbrOehVg==} dependencies: - '@antv/g-lite': link:packages/g-lite - '@antv/g-plugin-image-loader': 1.1.54(@antv/g-lite@packages+g-lite)(gl-matrix@3.4.3) - '@antv/g-shader-components': 1.7.55 + '@antv/g-lite': 1.2.1 + '@antv/g-math': 2.0.1 + '@antv/g-plugin-image-loader': 1.3.1 + '@antv/g-shader-components': 1.8.1 '@antv/util': 3.3.1(gl-matrix@3.4.3) - '@types/offscreencanvas': 2019.6.4 '@webgpu/types': 0.1.33 earcut: 2.2.3 - eventemitter3: 4.0.7 + eventemitter3: 5.0.1 gl-matrix: 3.4.3 tslib: 2.5.3 dev: false - /@antv/g-plugin-dom-interaction@1.7.52(@antv/g-lite@packages+g-lite): - resolution: {integrity: sha512-ZJgzI2CCfqzORsF3LkZkcmpDXzQbZGMVGTnz5CT26/cuBxVARutNjDN/YaUvtdgfG71Rngc5aIHfhO8A1FX7gw==} - peerDependencies: - '@antv/g-lite': ^1.0.0 + /@antv/g-plugin-dom-interaction@1.9.1: + resolution: {integrity: sha512-wtXIeQwZFm6Ij0HL0B5ZZtbnI4WNMCu8mw5Zl0jlq3RRtyHP/PYYd+3R3QQ5bePpZbPr4qns0sD0EqD4hUDgTg==} dependencies: - '@antv/g-lite': link:packages/g-lite + '@antv/g-lite': 1.2.1 tslib: 2.5.3 dev: false @@ -1659,37 +1658,32 @@ packages: tslib: 2.5.3 dev: false - /@antv/g-plugin-html-renderer@1.7.56(@antv/g-lite@packages+g-lite): - resolution: {integrity: sha512-8EqM3KxHdHmXLhvDWEWSmoBMTkydLiJAgc5nHHXknpCJUQ5SpsATBftnqKi51jPWo8Pm933sQoWSF0tZG/zC1A==} - peerDependencies: - '@antv/g-lite': ^1.0.0 + /@antv/g-plugin-html-renderer@1.9.1: + resolution: {integrity: sha512-bk94rLrQ2wclVt2aghWytTr8Ur9a0ImMcf2V2vmoatjD1+/k+EtsF230RcoflVk9MGr4Cn0LqFXVIiPSmckYHw==} dependencies: - '@antv/g-lite': link:packages/g-lite + '@antv/g-lite': 1.2.1 '@antv/util': 3.3.1(gl-matrix@3.4.3) gl-matrix: 3.4.3 tslib: 2.5.3 dev: false - /@antv/g-plugin-image-loader@1.1.54(@antv/g-lite@packages+g-lite)(gl-matrix@3.4.3): - resolution: {integrity: sha512-3udyGozFpE4mjsLOxegikYNNfb0RpHmSbvrZj5psTX4UVFB3V2eopKoRF2JYa3kUjnRzLJ3sDh0przr2K01tvg==} - peerDependencies: - '@antv/g-lite': ^1.0.0 + /@antv/g-plugin-image-loader@1.3.1: + resolution: {integrity: sha512-IdrlWjN6vBWjoqSu58ZbeL3Ta8q+Eq+686dMa0yCMCRnVlmym/mcW2JzCCA+IUcaCM39UEiDmyinJs8Ic04X9A==} dependencies: - '@antv/g-lite': link:packages/g-lite + '@antv/g-lite': 1.2.1 '@antv/util': 3.3.1(gl-matrix@3.4.3) + gl-matrix: 3.4.3 tslib: 2.5.3 - transitivePeerDependencies: - - gl-matrix dev: false - /@antv/g-plugin-webgl-device@1.7.54(@antv/g-lite@packages+g-lite)(@antv/g-plugin-device-renderer@1.7.70)(gl-matrix@3.4.3): + /@antv/g-plugin-webgl-device@1.7.54(@antv/g-lite@packages+g-lite)(@antv/g-plugin-device-renderer@1.9.1)(gl-matrix@3.4.3): resolution: {integrity: sha512-1Bnf+eb5HcK7plBYSBAKQDc+KWW0VZ3paFv8rEfJCnp7nTt4kHH2j9wdjwHztft4eOaxdRH1hdV1Aom05sahqg==} peerDependencies: '@antv/g-lite': ^1.0.0 '@antv/g-plugin-device-renderer': ^1.0.0 dependencies: '@antv/g-lite': link:packages/g-lite - '@antv/g-plugin-device-renderer': 1.7.70(@antv/g-lite@packages+g-lite) + '@antv/g-plugin-device-renderer': 1.9.1 '@antv/util': 3.3.1(gl-matrix@3.4.3) eventemitter3: 4.0.7 tslib: 2.5.3 @@ -1697,8 +1691,8 @@ packages: - gl-matrix dev: false - /@antv/g-shader-components@1.7.55: - resolution: {integrity: sha512-EV7L6yKw/qnQa+xKZiRyGC7ec4OTkrpIhJRsP2A1SHI4LA6q5ptJpR8xEjkc0Hcv4r0MluY6ECV74GDQwQXgeA==} + /@antv/g-shader-components@1.8.1: + resolution: {integrity: sha512-HzJPafrwhK6Qhjt3LSCYNL/YQOblCsQuUVFDlNXgUSrM20GwJ4kVhMxGxZ1Obo5d05DJ3siiSevFUf+iVmSWLA==} dev: false /@antv/g-svg@0.5.7: @@ -1711,12 +1705,12 @@ packages: tslib: 2.5.3 dev: false - /@antv/g-web-animations-api@1.0.39(@antv/g-lite@1.0.70)(gl-matrix@3.4.3): + /@antv/g-web-animations-api@1.0.39(@antv/g-lite@1.2.1)(gl-matrix@3.4.3): resolution: {integrity: sha512-0QXVzjk8kKrVokxHLLphkJsMPvbhLgcQN8/eVUdPaj+A0Yf6Cpg/hquYaGBBuqzwoMVB0ROUsIvwXgRtoXQONA==} peerDependencies: '@antv/g-lite': ^1.0.0 dependencies: - '@antv/g-lite': 1.0.70 + '@antv/g-lite': 1.2.1 '@antv/util': 3.3.1(gl-matrix@3.4.3) transitivePeerDependencies: - gl-matrix @@ -1728,11 +1722,11 @@ packages: '@antv/g-lite': ^1.0.0 dependencies: '@antv/g-lite': link:packages/g-lite - '@antv/g-plugin-device-renderer': 1.7.70(@antv/g-lite@packages+g-lite) - '@antv/g-plugin-dom-interaction': 1.7.52(@antv/g-lite@packages+g-lite) - '@antv/g-plugin-html-renderer': 1.7.56(@antv/g-lite@packages+g-lite) - '@antv/g-plugin-image-loader': 1.1.54(@antv/g-lite@packages+g-lite)(gl-matrix@3.4.3) - '@antv/g-plugin-webgl-device': 1.7.54(@antv/g-lite@packages+g-lite)(@antv/g-plugin-device-renderer@1.7.70)(gl-matrix@3.4.3) + '@antv/g-plugin-device-renderer': 1.9.1 + '@antv/g-plugin-dom-interaction': 1.9.1 + '@antv/g-plugin-html-renderer': 1.9.1 + '@antv/g-plugin-image-loader': 1.3.1 + '@antv/g-plugin-webgl-device': 1.7.54(@antv/g-lite@packages+g-lite)(@antv/g-plugin-device-renderer@1.9.1)(gl-matrix@3.4.3) '@antv/util': 3.3.1(gl-matrix@3.4.3) transitivePeerDependencies: - gl-matrix @@ -1853,12 +1847,12 @@ packages: /@antv/g@5.16.33(gl-matrix@3.4.3): resolution: {integrity: sha512-11F82JsrXeJZTZSREiaPhnILkzoHqajkebA4fkPQ4XXjpoAcpIEow//NF8LbJOr3c1hogTyDh+aofwFeY+JnMw==} dependencies: - '@antv/g-camera-api': 1.0.40(@antv/g-lite@1.0.70) - '@antv/g-css-layout-api': 1.0.38(@antv/g-lite@1.0.70) - '@antv/g-css-typed-om-api': 1.0.38(@antv/g-lite@1.0.70) - '@antv/g-dom-mutation-observer-api': 1.0.38(@antv/g-lite@1.0.70) - '@antv/g-lite': 1.0.70 - '@antv/g-web-animations-api': 1.0.39(@antv/g-lite@1.0.70)(gl-matrix@3.4.3) + '@antv/g-camera-api': 1.0.40(@antv/g-lite@1.2.1) + '@antv/g-css-layout-api': 1.0.38(@antv/g-lite@1.2.1) + '@antv/g-css-typed-om-api': 1.0.38(@antv/g-lite@1.2.1) + '@antv/g-dom-mutation-observer-api': 1.0.38(@antv/g-lite@1.2.1) + '@antv/g-lite': 1.2.1 + '@antv/g-web-animations-api': 1.0.39(@antv/g-lite@1.2.1)(gl-matrix@3.4.3) transitivePeerDependencies: - gl-matrix dev: false diff --git a/site/.dumi/global.ts b/site/.dumi/global.ts index 2e66fad5c..73e683162 100644 --- a/site/.dumi/global.ts +++ b/site/.dumi/global.ts @@ -17,6 +17,7 @@ if (window) { (window as any).d3Force3d = require('d3-force-3d'); (window as any).d3SvgAnnotation = require('d3-svg-annotation'); (window as any).plot = require('@observablehq/plot'); + (window as any).glMatrix = require('gl-matrix'); // core (window as any).g = require('@antv/g'); (window as any).gLite = require('@antv/g-lite'); diff --git a/site/.dumirc.ts b/site/.dumirc.ts index c4f6df817..f7636b75d 100644 --- a/site/.dumirc.ts +++ b/site/.dumirc.ts @@ -431,4 +431,12 @@ export default defineConfig({ copy: ['static'], jsMinifier: 'terser', mfsu: false, + analytics: { + // google analytics 的 key (GA 4) + // ga_v2: 'G-abcdefg', + // 若你在使用 GA v1 旧版本,请使用 `ga` 来配置 + ga_v2: 'G-3L8SSDC4X6', + // 百度统计的 key + // baidu: 'baidu_tongji_key', + }, }); diff --git a/site/docs/api/renderer/webgl.en.md b/site/docs/api/renderer/webgl.en.md index 97cd14cd4..0ceb992ac 100644 --- a/site/docs/api/renderer/webgl.en.md +++ b/site/docs/api/renderer/webgl.en.md @@ -55,6 +55,42 @@ const webglRenderer = new WebGLRenderer({ }); ``` +### onContextLost + +The `webglcontextlost` event of the WebGL API is fired if the user agent detects that the drawing buffer associated with a WebGLRenderingContext object has been lost. + + + +```js +const webglRenderer = new WebGLRenderer({ + onContextLost: (e: Event) => {}, +}); +``` + +### onContextRestored + +The `webglcontextrestored` event of the WebGL API is fired if the user agent restores the drawing buffer for a WebGLRenderingContext object. + + + +```js +const webglRenderer = new WebGLRenderer({ + onContextRestored: (e: Event) => {}, +}); +``` + +### onContextCreationError + +The `webglcontextcreationerror` event of the WebGL API is fired if the user agent is unable to create a WebGLRenderingContext context. + + + +```js +const webglRenderer = new WebGLRenderer({ + onContextCreationError: (e: Event) => {}, +}); +``` + ## Built-in plug-ins The renderer has the following plug-ins built in. diff --git a/site/docs/api/renderer/webgl.zh.md b/site/docs/api/renderer/webgl.zh.md index 04d6a630b..7639fa981 100644 --- a/site/docs/api/renderer/webgl.zh.md +++ b/site/docs/api/renderer/webgl.zh.md @@ -55,6 +55,42 @@ const webglRenderer = new WebGLRenderer({ }); ``` +### onContextLost + +如果浏览器检测到与 [WebGLRenderingContext](https://developer.mozilla.org/en-US/Web/API/WebGLRenderingContext) 对象关联的图形缓冲区已丢失,则会触发 WebGL API 中的 `webglcontextlost` 事件,此时 `onContextLost` 回调函数会被触发: + + + +```js +const webglRenderer = new WebGLRenderer({ + onContextLost: (e: Event) => {}, +}); +``` + +### onContextRestored + +当 [WebGLRenderingContext](https://developer.mozilla.org/en-US/Web/API/WebGLRenderingContext) 恢复时,会触发 `webglcontextrestored` 事件,此时 `onContextRestored` 回调函数会被触发: + + + +```js +const webglRenderer = new WebGLRenderer({ + onContextRestored: (e: Event) => {}, +}); +``` + +### onContextCreationError + +当 [WebGLRenderingContext](https://developer.mozilla.org/en-US/Web/API/WebGLRenderingContext) 创建失败时,会触发 `webglcontextcreationerror` 事件,此时 `onContextCreationError` 回调函数会被触发: + + + +```js +const webglRenderer = new WebGLRenderer({ + onContextCreationError: (e: Event) => {}, +}); +``` + ## 内置插件 该渲染器内置了以下插件: diff --git a/site/docs/api/renderer/webgpu.en.md b/site/docs/api/renderer/webgpu.en.md index a066ef946..5bb94cd19 100644 --- a/site/docs/api/renderer/webgpu.en.md +++ b/site/docs/api/renderer/webgpu.en.md @@ -13,7 +13,7 @@ The following pre-requisites need to be met. ### Feature Detection -When using it, you need to determine whether the current environment supports WebGPU, the following feature detection code from https://web.dev/gpu/#feature-detection. +When using it, you need to determine whether the current environment supports WebGPU, the following feature detection code from . ```js if ('gpu' in navigator) { @@ -39,7 +39,9 @@ After installing `@antv/g-webgpu` you can get the renderer from. import { Canvas } from '@antv/g'; import { Renderer } from '@antv/g-webgpu'; -const webgpuRenderer = new Renderer(); +const webgpuRenderer = new Renderer({ + shaderCompilerPath: '/glsl_wgsl_compiler_bg.wasm', +}); const canvas = new Canvas({ container: 'container', @@ -60,7 +62,34 @@ const canvas = new Canvas({ The renderer is available from the `G.WebGPU` namespace under. ```js -const webgpuRenderer = new window.G.WebGPU.Renderer(); +const webgpuRenderer = new window.G.WebGPU.Renderer({ + shaderCompilerPath: '/glsl_wgsl_compiler_bg.wasm', +}); +``` + +## Initial Configuration + +### shaderCompilerPath + +Since our shader is written in GLSL 300, it needs to be translated to WGSL in order to run in WebGPU. For this step we use naga, which is compiled into WASM to run in the browser, so it needs to be loaded at runtime: + +```js +const webgpuRenderer = new WebGPURenderer({ + shaderCompilerPath: '/glsl_wgsl_compiler_bg.wasm', +}); +``` + +### onContextLost + +Like WebGL, WebGPU applications may experience context loss during runtime, and this callback function will be triggered. + + + +```js +const webgpuRenderer = new WebGPURenderer({ + shaderCompilerPath: '/glsl_wgsl_compiler_bg.wasm', + onContextLost: () => {}, +}); ``` ## Built-in plug-ins diff --git a/site/docs/api/renderer/webgpu.zh.md b/site/docs/api/renderer/webgpu.zh.md index 3ae1226bd..3e4284631 100644 --- a/site/docs/api/renderer/webgpu.zh.md +++ b/site/docs/api/renderer/webgpu.zh.md @@ -13,7 +13,7 @@ order: 3 ### 特性检测 -在使用时需要判断当前环境是否支持 WebGPU,下面特性检测代码来自:https://web.dev/gpu/#feature-detection: +在使用时需要判断当前环境是否支持 WebGPU,下面特性检测代码来自:: ```js if ('gpu' in navigator) { @@ -39,7 +39,9 @@ if ('gpu' in navigator) { import { Canvas } from '@antv/g'; import { Renderer } from '@antv/g-webgpu'; -const webgpuRenderer = new Renderer(); +const webgpuRenderer = new Renderer({ + shaderCompilerPath: '/glsl_wgsl_compiler_bg.wasm', +}); const canvas = new Canvas({ container: 'container', @@ -60,7 +62,34 @@ const canvas = new Canvas({ 从 `G.WebGPU` 命名空间下可以获取渲染器: ```js -const webgpuRenderer = new window.G.WebGPU.Renderer(); +const webgpuRenderer = new window.G.WebGPU.Renderer({ + shaderCompilerPath: '/glsl_wgsl_compiler_bg.wasm', +}); +``` + +## 初始化配置 + +### shaderCompilerPath + +由于我们的 Shader 使用 GLSL 300 编写,因此需要转译到 WGSL 才能在 WebGPU 中运行。这一步我们使用了 naga,编译成 WASM 后便可以在浏览器运行,因此需要在运行时加载它: + +```js +const webgpuRenderer = new WebGPURenderer({ + shaderCompilerPath: '/glsl_wgsl_compiler_bg.wasm', +}); +``` + +### onContextLost + +和 WebGL 一样,WebGPU 应用在运行过程中也有可能出现上下文丢失的情况,此时会触发该回调函数。 + + + +```js +const webgpuRenderer = new WebGPURenderer({ + shaderCompilerPath: '/glsl_wgsl_compiler_bg.wasm', + onContextLost: () => {}, +}); ``` ## 内置插件 diff --git a/site/examples/3d/3d-basic/demo/webgpu.js b/site/examples/3d/3d-basic/demo/webgpu.js index 10d42d9ad..4bbc30c94 100644 --- a/site/examples/3d/3d-basic/demo/webgpu.js +++ b/site/examples/3d/3d-basic/demo/webgpu.js @@ -1,4 +1,13 @@ -import { Canvas, CanvasEvent, Circle } from '@antv/g'; +import { + Canvas, + CanvasEvent, + Circle, + Ellipse, + Rect, + Image, + Line, + Path, +} from '@antv/g'; import { Renderer as WebGPURenderer } from '@antv/g-webgpu'; import Stats from 'stats.js'; @@ -18,28 +27,76 @@ const canvas = new Canvas({ const circle = new Circle({ style: { - x: 250, - y: 250, - r: 250, + cx: 100, + cy: 100, + r: 50, fill: 'green', cursor: 'pointer', }, }); -// const icon = new Image({ -// style: { -// x: 200, -// y: 200, -// z: 0, -// width: 200, -// height: 200, -// src: 'https://gw.alipayobjects.com/mdn/rms_6ae20b/afts/img/A*N4ZMS7gHsUIAAAAAAAAAAABkARQnAQ', -// isBillboard: true, -// }, -// }); +const ellipse = new Ellipse({ + style: { + cx: 200, + cy: 100, + rx: 100, + ry: 50, + fill: 'red', + }, +}); + +const rect = new Rect({ + style: { + x: 300, + y: 100, + width: 100, + height: 50, + fill: 'blue', + stroke: 'yellow', + lineWidth: 2, + }, +}); + +const line = new Line({ + style: { + x1: 200, + y1: 100, + x2: 400, + y2: 100, + stroke: '#1890FF', + lineWidth: 2, + }, +}); + +const path = new Path({ + style: { + transform: 'translate(200, 100) scale(10)', + d: 'M2 4C0.8954304997175604 3.9999999991219815 -1.3527075029566811e-16 4.895430499717561 0 6C0 6 0 9.9375 0 12C1.3527075029566811e-16 13.10456950028244 0.8954304997175604 14.00000000087802 2 14C8 14 10.25 14 14 14C15.104569499040734 13.99999999912198 16 13.104569499040734 16 12C16 9 16 7.875 16 6C16 4.895430500959266 15.104569499040734 4.0000000008780185 14 4C13.414 4 13.194249999999998 4 12.828 4C12.297610373455704 3.9998867247945213 11.788985462367364 3.7890987493850155 11.414 3.414C11 3 10.84475 2.8447500000000003 10.586 2.5860000000000003C10.211014537632636 2.210901250614985 9.702389626544296 2.0001132752054787 9.172 2.0000000000000004C8 2.0000000000000004 7.560500000000001 2.0000000000000004 6.828000000000001 2.0000000000000004C6.297610373455706 2.0001132752054787 5.788985462367367 2.210901250614985 5.4140000000000015 2.5860000000000003C5.000000000000002 3 4.844750000000001 3.1552499999999997 4.586000000000001 3.414C4.211014537632636 3.7890987493850155 3.7023896265442966 3.9998867247945213 3.1720000000000015 4C2.5860000000000016 4 2.3662500000000017 4 2.0000000000000018 4C2.000000000000001 4 2.000000000000001 4 2 4M10.5 8.5C10.5 6.575499102701247 8.416666666666666 5.372686041889527 6.75 6.334936490538903C5.976497308103742 6.781518477924107 5.5 7.606836025229591 5.5 8.5C5.5 10.424500897298753 7.583333333333334 11.627313958110474 9.25 10.665063509461097C10.023502691896258 10.218481522075892 10.5 9.39316397477041 10.5 8.5C10.5 8.5 10.5 8.5 10.5 8.5M2.5 6C2.1150998205402494 6.000000000305956 1.874537208444147 5.583333333830511 2.0669872979090567 5.2500000003442C2.1563036954051213 5.095299461648009 2.321367204761929 4.999999999858005 2.5 5C2.8849001794597506 5.000000000305956 3.125462791688336 5.416666667163845 2.933012701693495 5.7500000003442C2.8436963042354777 5.904700538406512 2.6786327946700927 5.999999999858005 2.5 6C2.5 6 2.5 6 2.5 6M11.5 8.5C11.5 11.194301256218253 8.583333333333334 12.878239541354663 6.250000000000001 11.531088913245537C5.167096231345241 10.90587413090625 4.5 9.750429564678573 4.5 8.5C4.5 5.805698743781747 7.416666666666667 4.121760458645338 9.75 5.468911086754464C10.832903768654761 6.094125869093751 11.5 7.249570435321427 11.5 8.5C11.5 8.5 11.5 8.5 11.5 8.5', + lineWidth: 1, + lineJoin: 'round', + stroke: '#54BECC', + cursor: 'pointer', + }, +}); + +const image = new Image({ + style: { + x: 200, + y: 200, + z: 0, + width: 200, + height: 200, + src: 'https://gw.alipayobjects.com/mdn/rms_6ae20b/afts/img/A*N4ZMS7gHsUIAAAAAAAAAAABkARQnAQ', + }, +}); canvas.addEventListener(CanvasEvent.READY, () => { canvas.appendChild(circle); + canvas.appendChild(ellipse); + canvas.appendChild(rect); + canvas.appendChild(line); + canvas.appendChild(path); + canvas.appendChild(image); }); // stats diff --git a/site/examples/animation/animation-basic/demo/current-time.js b/site/examples/animation/animation-basic/demo/current-time.js index 8d586c009..3dc105e60 100644 --- a/site/examples/animation/animation-basic/demo/current-time.js +++ b/site/examples/animation/animation-basic/demo/current-time.js @@ -20,7 +20,9 @@ const canvaskitRenderer = new CanvaskitRenderer({ }, ], }); -const webgpuRenderer = new WebGPURenderer(); +const webgpuRenderer = new WebGPURenderer({ + shaderCompilerPath: '/glsl_wgsl_compiler_bg.wasm', +}); // create a canvas const canvas = new Canvas({ diff --git a/site/examples/animation/animation-basic/demo/delay.js b/site/examples/animation/animation-basic/demo/delay.js index 2cc764bd9..041ccfee3 100644 --- a/site/examples/animation/animation-basic/demo/delay.js +++ b/site/examples/animation/animation-basic/demo/delay.js @@ -20,7 +20,9 @@ const canvaskitRenderer = new CanvaskitRenderer({ }, ], }); -const webgpuRenderer = new WebGPURenderer(); +const webgpuRenderer = new WebGPURenderer({ + shaderCompilerPath: '/glsl_wgsl_compiler_bg.wasm', +}); // create a canvas const canvas = new Canvas({ diff --git a/site/examples/animation/animation-basic/demo/easing.js b/site/examples/animation/animation-basic/demo/easing.js index 24a98ef2e..a9e3fb58e 100644 --- a/site/examples/animation/animation-basic/demo/easing.js +++ b/site/examples/animation/animation-basic/demo/easing.js @@ -24,7 +24,9 @@ const canvaskitRenderer = new CanvaskitRenderer({ }, ], }); -const webgpuRenderer = new WebGPURenderer(); +const webgpuRenderer = new WebGPURenderer({ + shaderCompilerPath: '/glsl_wgsl_compiler_bg.wasm', +}); // create a canvas const canvas = new Canvas({ diff --git a/site/examples/animation/animation-basic/demo/lifecycle.js b/site/examples/animation/animation-basic/demo/lifecycle.js index a92e2838e..05bdb1fc1 100644 --- a/site/examples/animation/animation-basic/demo/lifecycle.js +++ b/site/examples/animation/animation-basic/demo/lifecycle.js @@ -24,7 +24,9 @@ const canvaskitRenderer = new CanvaskitRenderer({ }, ], }); -const webgpuRenderer = new WebGPURenderer(); +const webgpuRenderer = new WebGPURenderer({ + shaderCompilerPath: '/glsl_wgsl_compiler_bg.wasm', +}); // create a canvas const canvas = new Canvas({ diff --git a/site/examples/animation/animation-basic/demo/multiple-attributes.js b/site/examples/animation/animation-basic/demo/multiple-attributes.js index e4c983b16..70312c1e1 100644 --- a/site/examples/animation/animation-basic/demo/multiple-attributes.js +++ b/site/examples/animation/animation-basic/demo/multiple-attributes.js @@ -24,7 +24,9 @@ const canvaskitRenderer = new CanvaskitRenderer({ }, ], }); -const webgpuRenderer = new WebGPURenderer(); +const webgpuRenderer = new WebGPURenderer({ + shaderCompilerPath: '/glsl_wgsl_compiler_bg.wasm', +}); // create a canvas const canvas = new Canvas({ diff --git a/site/examples/animation/animation-basic/demo/onframe.js b/site/examples/animation/animation-basic/demo/onframe.js index bc0c3a8ee..5263abe49 100644 --- a/site/examples/animation/animation-basic/demo/onframe.js +++ b/site/examples/animation/animation-basic/demo/onframe.js @@ -20,7 +20,9 @@ const canvaskitRenderer = new CanvaskitRenderer({ }, ], }); -const webgpuRenderer = new WebGPURenderer(); +const webgpuRenderer = new WebGPURenderer({ + shaderCompilerPath: '/glsl_wgsl_compiler_bg.wasm', +}); // create a canvas const canvas = new Canvas({ diff --git a/site/examples/animation/animation-basic/demo/opacity.js b/site/examples/animation/animation-basic/demo/opacity.js index 9d2f73d72..ccb6a23c6 100644 --- a/site/examples/animation/animation-basic/demo/opacity.js +++ b/site/examples/animation/animation-basic/demo/opacity.js @@ -20,7 +20,9 @@ const canvaskitRenderer = new CanvaskitRenderer({ }, ], }); -const webgpuRenderer = new WebGPURenderer(); +const webgpuRenderer = new WebGPURenderer({ + shaderCompilerPath: '/glsl_wgsl_compiler_bg.wasm', +}); // create a canvas const canvas = new Canvas({ diff --git a/site/examples/animation/animation-basic/demo/sequence.js b/site/examples/animation/animation-basic/demo/sequence.js index d29983039..a7b65ca91 100644 --- a/site/examples/animation/animation-basic/demo/sequence.js +++ b/site/examples/animation/animation-basic/demo/sequence.js @@ -20,7 +20,9 @@ const canvaskitRenderer = new CanvaskitRenderer({ }, ], }); -const webgpuRenderer = new WebGPURenderer(); +const webgpuRenderer = new WebGPURenderer({ + shaderCompilerPath: '/glsl_wgsl_compiler_bg.wasm', +}); // create a canvas const canvas = new Canvas({ diff --git a/site/examples/animation/animation-basic/demo/visibility.js b/site/examples/animation/animation-basic/demo/visibility.js index fdfbdde7b..4321d139d 100644 --- a/site/examples/animation/animation-basic/demo/visibility.js +++ b/site/examples/animation/animation-basic/demo/visibility.js @@ -20,7 +20,9 @@ const canvaskitRenderer = new CanvaskitRenderer({ }, ], }); -const webgpuRenderer = new WebGPURenderer(); +const webgpuRenderer = new WebGPURenderer({ + shaderCompilerPath: '/glsl_wgsl_compiler_bg.wasm', +}); // create a canvas const canvas = new Canvas({ diff --git a/site/examples/animation/animation-effects/demo/animations.js b/site/examples/animation/animation-effects/demo/animations.js index 87e772ea4..951330413 100644 --- a/site/examples/animation/animation-effects/demo/animations.js +++ b/site/examples/animation/animation-effects/demo/animations.js @@ -20,7 +20,9 @@ const canvaskitRenderer = new CanvaskitRenderer({ }, ], }); -const webgpuRenderer = new WebGPURenderer(); +const webgpuRenderer = new WebGPURenderer({ + shaderCompilerPath: '/glsl_wgsl_compiler_bg.wasm', +}); // create a canvas const canvas = new Canvas({ diff --git a/site/examples/animation/animation-effects/demo/line-dash.js b/site/examples/animation/animation-effects/demo/line-dash.js index c7f3d526a..8496b16af 100644 --- a/site/examples/animation/animation-effects/demo/line-dash.js +++ b/site/examples/animation/animation-effects/demo/line-dash.js @@ -20,7 +20,9 @@ const canvaskitRenderer = new CanvaskitRenderer({ }, ], }); -const webgpuRenderer = new WebGPURenderer(); +const webgpuRenderer = new WebGPURenderer({ + shaderCompilerPath: '/glsl_wgsl_compiler_bg.wasm', +}); // create a canvas const canvas = new Canvas({ diff --git a/site/examples/animation/animation-effects/demo/marching-ants.js b/site/examples/animation/animation-effects/demo/marching-ants.js index b286806a8..fa7ddd879 100644 --- a/site/examples/animation/animation-effects/demo/marching-ants.js +++ b/site/examples/animation/animation-effects/demo/marching-ants.js @@ -20,7 +20,9 @@ const canvaskitRenderer = new CanvaskitRenderer({ }, ], }); -const webgpuRenderer = new WebGPURenderer(); +const webgpuRenderer = new WebGPURenderer({ + shaderCompilerPath: '/glsl_wgsl_compiler_bg.wasm', +}); // create a canvas const canvas = new Canvas({ diff --git a/site/examples/animation/animation-effects/demo/multiple-animations-per-element.js b/site/examples/animation/animation-effects/demo/multiple-animations-per-element.js index 3f0639cb5..9eab3d18e 100644 --- a/site/examples/animation/animation-effects/demo/multiple-animations-per-element.js +++ b/site/examples/animation/animation-effects/demo/multiple-animations-per-element.js @@ -24,7 +24,9 @@ const canvaskitRenderer = new CanvaskitRenderer({ }, ], }); -const webgpuRenderer = new WebGPURenderer(); +const webgpuRenderer = new WebGPURenderer({ + shaderCompilerPath: '/glsl_wgsl_compiler_bg.wasm', +}); // create a canvas const canvas = new Canvas({ diff --git a/site/examples/animation/animation-effects/demo/offset-path.js b/site/examples/animation/animation-effects/demo/offset-path.js index dc50fd198..483775ea3 100644 --- a/site/examples/animation/animation-effects/demo/offset-path.js +++ b/site/examples/animation/animation-effects/demo/offset-path.js @@ -24,7 +24,9 @@ const canvaskitRenderer = new CanvaskitRenderer({ }, ], }); -const webgpuRenderer = new WebGPURenderer(); +const webgpuRenderer = new WebGPURenderer({ + shaderCompilerPath: '/glsl_wgsl_compiler_bg.wasm', +}); // create a canvas const canvas = new Canvas({ diff --git a/site/examples/animation/morph/demo/convert-to-path.js b/site/examples/animation/morph/demo/convert-to-path.js index 8890c1a91..aac9c1c6c 100644 --- a/site/examples/animation/morph/demo/convert-to-path.js +++ b/site/examples/animation/morph/demo/convert-to-path.js @@ -31,7 +31,9 @@ const canvaskitRenderer = new CanvaskitRenderer({ }, ], }); -const webgpuRenderer = new WebGPURenderer(); +const webgpuRenderer = new WebGPURenderer({ + shaderCompilerPath: '/glsl_wgsl_compiler_bg.wasm', +}); // create a canvas const canvas = new Canvas({ diff --git a/site/examples/animation/morph/demo/issue.js b/site/examples/animation/morph/demo/issue.js index d1db28e93..c0581abb2 100644 --- a/site/examples/animation/morph/demo/issue.js +++ b/site/examples/animation/morph/demo/issue.js @@ -22,7 +22,9 @@ const canvaskitRenderer = new CanvaskitRenderer({ }, ], }); -const webgpuRenderer = new WebGPURenderer(); +const webgpuRenderer = new WebGPURenderer({ + shaderCompilerPath: '/glsl_wgsl_compiler_bg.wasm', +}); // create a canvas const canvas = new Canvas({ diff --git a/site/examples/animation/morph/demo/morph.js b/site/examples/animation/morph/demo/morph.js index 22b1a64a8..7424304b7 100644 --- a/site/examples/animation/morph/demo/morph.js +++ b/site/examples/animation/morph/demo/morph.js @@ -30,7 +30,9 @@ const canvaskitRenderer = new CanvaskitRenderer({ }, ], }); -const webgpuRenderer = new WebGPURenderer(); +const webgpuRenderer = new WebGPURenderer({ + shaderCompilerPath: '/glsl_wgsl_compiler_bg.wasm', +}); // create a canvas const canvas = new Canvas({ diff --git a/site/examples/camera/camera-action/demo/action.js b/site/examples/camera/camera-action/demo/action.js index dc62b01bd..b80f62678 100644 --- a/site/examples/camera/camera-action/demo/action.js +++ b/site/examples/camera/camera-action/demo/action.js @@ -20,7 +20,9 @@ const canvaskitRenderer = new CanvaskitRenderer({ }, ], }); -const webgpuRenderer = new WebGPURenderer(); +const webgpuRenderer = new WebGPURenderer({ + shaderCompilerPath: '/glsl_wgsl_compiler_bg.wasm', +}); // create a canvas const canvas = new Canvas({ diff --git a/site/examples/camera/camera-action/demo/zoom-by-point.js b/site/examples/camera/camera-action/demo/zoom-by-point.js index e2732cf9e..014911a7b 100644 --- a/site/examples/camera/camera-action/demo/zoom-by-point.js +++ b/site/examples/camera/camera-action/demo/zoom-by-point.js @@ -25,7 +25,9 @@ const canvaskitRenderer = new CanvaskitRenderer({ }, ], }); -const webgpuRenderer = new WebGPURenderer(); +const webgpuRenderer = new WebGPURenderer({ + shaderCompilerPath: '/glsl_wgsl_compiler_bg.wasm', +}); // create a canvas const canvas = new Canvas({ @@ -124,7 +126,7 @@ rendererFolder 'webgpu', 'canvaskit', ]) - .onChange(async (rendererName) => { + .onChange((rendererName) => { let renderer; if (rendererName === 'canvas') { renderer = canvasRenderer; @@ -137,7 +139,7 @@ rendererFolder } else if (rendererName === 'canvaskit') { renderer = canvaskitRenderer; } - await canvas.setRenderer(renderer); + canvas.setRenderer(renderer); bindWheelHandler(); }); rendererFolder.open(); diff --git a/site/examples/camera/camera-animation/demo/landmark2.js b/site/examples/camera/camera-animation/demo/landmark2.js index 0d95cf182..85db899e3 100644 --- a/site/examples/camera/camera-animation/demo/landmark2.js +++ b/site/examples/camera/camera-animation/demo/landmark2.js @@ -20,7 +20,9 @@ const canvaskitRenderer = new CanvaskitRenderer({ }, ], }); -const webgpuRenderer = new WebGPURenderer(); +const webgpuRenderer = new WebGPURenderer({ + shaderCompilerPath: '/glsl_wgsl_compiler_bg.wasm', +}); // create a canvas const canvas = new Canvas({ diff --git a/site/examples/canvas/canvas-basic/demo/coordinates.js b/site/examples/canvas/canvas-basic/demo/coordinates.js index 13899b4f9..04a8c8435 100644 --- a/site/examples/canvas/canvas-basic/demo/coordinates.js +++ b/site/examples/canvas/canvas-basic/demo/coordinates.js @@ -22,7 +22,9 @@ const canvaskitRenderer = new CanvaskitRenderer({ }, ], }); -const webgpuRenderer = new WebGPURenderer(); +const webgpuRenderer = new WebGPURenderer({ + shaderCompilerPath: '/glsl_wgsl_compiler_bg.wasm', +}); // create a canvas const canvas = new Canvas({ diff --git a/site/examples/canvas/canvas-basic/demo/element-from-point.js b/site/examples/canvas/canvas-basic/demo/element-from-point.js index 5dff8248c..9898c70e7 100644 --- a/site/examples/canvas/canvas-basic/demo/element-from-point.js +++ b/site/examples/canvas/canvas-basic/demo/element-from-point.js @@ -29,7 +29,9 @@ const canvaskitRenderer = new CanvaskitRenderer({ }, ], }); -const webgpuRenderer = new WebGPURenderer(); +const webgpuRenderer = new WebGPURenderer({ + shaderCompilerPath: '/glsl_wgsl_compiler_bg.wasm', +}); // create a canvas const canvas = new Canvas({ diff --git a/site/examples/canvas/container/demo/supports-css-transform.js b/site/examples/canvas/container/demo/supports-css-transform.js index f868316c2..19c2a8a26 100644 --- a/site/examples/canvas/container/demo/supports-css-transform.js +++ b/site/examples/canvas/container/demo/supports-css-transform.js @@ -14,7 +14,9 @@ $wrapper.style.transform = 'scale(1.1)'; const canvasRenderer = new CanvasRenderer(); const svgRenderer = new SVGRenderer(); const webglRenderer = new WebGLRenderer(); -const webgpuRenderer = new WebGPURenderer(); +const webgpuRenderer = new WebGPURenderer({ + shaderCompilerPath: '/glsl_wgsl_compiler_bg.wasm', +}); const canvaskitRenderer = new CanvaskitRenderer({ wasmDir: '/', }); diff --git a/site/examples/ecosystem/d3/demo/d3-annotation.js b/site/examples/ecosystem/d3/demo/d3-annotation.js index 9408cb602..319eb1b7b 100644 --- a/site/examples/ecosystem/d3/demo/d3-annotation.js +++ b/site/examples/ecosystem/d3/demo/d3-annotation.js @@ -33,7 +33,9 @@ const canvaskitRenderer = new CanvaskitRenderer({ }, ], }); -const webgpuRenderer = new WebGPURenderer(); +const webgpuRenderer = new WebGPURenderer({ + shaderCompilerPath: '/glsl_wgsl_compiler_bg.wasm', +}); const cssSelectPlugin = new PluginCSSSelect(); diff --git a/site/examples/ecosystem/d3/demo/d3-barchart.js b/site/examples/ecosystem/d3/demo/d3-barchart.js index ad0c011e8..f2b7094fb 100644 --- a/site/examples/ecosystem/d3/demo/d3-barchart.js +++ b/site/examples/ecosystem/d3/demo/d3-barchart.js @@ -20,7 +20,9 @@ import Stats from 'stats.js'; const canvasRenderer = new CanvasRenderer(); const svgRenderer = new SVGRenderer(); const webglRenderer = new WebGLRenderer(); -const webgpuRenderer = new WebGPURenderer(); +const webgpuRenderer = new WebGPURenderer({ + shaderCompilerPath: '/glsl_wgsl_compiler_bg.wasm', +}); const canvaskitRenderer = new CanvaskitRenderer({ wasmDir: '/', fonts: [ diff --git a/site/examples/ecosystem/d3/demo/d3-force-directed-graph.js b/site/examples/ecosystem/d3/demo/d3-force-directed-graph.js index 0c71212cf..18a8a3caa 100644 --- a/site/examples/ecosystem/d3/demo/d3-force-directed-graph.js +++ b/site/examples/ecosystem/d3/demo/d3-force-directed-graph.js @@ -17,7 +17,9 @@ import Stats from 'stats.js'; const canvasRenderer = new CanvasRenderer(); const svgRenderer = new SVGRenderer(); const webglRenderer = new WebGLRenderer(); -const webgpuRenderer = new WebGPURenderer(); +const webgpuRenderer = new WebGPURenderer({ + shaderCompilerPath: '/glsl_wgsl_compiler_bg.wasm', +}); const canvaskitRenderer = new CanvaskitRenderer({ wasmDir: '/', fonts: [ diff --git a/site/examples/ecosystem/d3/demo/d3-geo-polygon.js b/site/examples/ecosystem/d3/demo/d3-geo-polygon.js index d5038aa51..d74e13545 100644 --- a/site/examples/ecosystem/d3/demo/d3-geo-polygon.js +++ b/site/examples/ecosystem/d3/demo/d3-geo-polygon.js @@ -49,7 +49,9 @@ import Stats from 'stats.js'; const canvasRenderer = new CanvasRenderer(); const svgRenderer = new SVGRenderer(); const webglRenderer = new WebGLRenderer(); - const webgpuRenderer = new WebGPURenderer(); + const webgpuRenderer = new WebGPURenderer({ + shaderCompilerPath: '/glsl_wgsl_compiler_bg.wasm', + }); const canvaskitRenderer = new CanvaskitRenderer({ wasmDir: '/', fonts: [ diff --git a/site/examples/ecosystem/d3/demo/d3-geo.js b/site/examples/ecosystem/d3/demo/d3-geo.js index 8573fbaa7..f5e1e8869 100644 --- a/site/examples/ecosystem/d3/demo/d3-geo.js +++ b/site/examples/ecosystem/d3/demo/d3-geo.js @@ -145,7 +145,9 @@ function zoom( canvasRenderer.registerPlugin(new PluginRoughCanvasRenderer()); const svgRenderer = new SVGRenderer(); const webglRenderer = new WebGLRenderer(); - const webgpuRenderer = new WebGPURenderer(); + const webgpuRenderer = new WebGPURenderer({ + shaderCompilerPath: '/glsl_wgsl_compiler_bg.wasm', + }); const canvaskitRenderer = new CanvaskitRenderer({ wasmDir: '/', fonts: [ diff --git a/site/examples/ecosystem/d3/demo/d3-linechart.js b/site/examples/ecosystem/d3/demo/d3-linechart.js index fa55e1694..86637b012 100644 --- a/site/examples/ecosystem/d3/demo/d3-linechart.js +++ b/site/examples/ecosystem/d3/demo/d3-linechart.js @@ -20,7 +20,9 @@ import Stats from 'stats.js'; const canvasRenderer = new CanvasRenderer(); const svgRenderer = new SVGRenderer(); const webglRenderer = new WebGLRenderer(); -const webgpuRenderer = new WebGPURenderer(); +const webgpuRenderer = new WebGPURenderer({ + shaderCompilerPath: '/glsl_wgsl_compiler_bg.wasm', +}); const canvaskitRenderer = new CanvaskitRenderer({ wasmDir: '/', fonts: [ diff --git a/site/examples/ecosystem/d3/demo/d3-piechart.js b/site/examples/ecosystem/d3/demo/d3-piechart.js index 65664d7b3..562fd22e0 100644 --- a/site/examples/ecosystem/d3/demo/d3-piechart.js +++ b/site/examples/ecosystem/d3/demo/d3-piechart.js @@ -20,7 +20,9 @@ import Stats from 'stats.js'; const canvasRenderer = new CanvasRenderer(); const svgRenderer = new SVGRenderer(); const webglRenderer = new WebGLRenderer(); -const webgpuRenderer = new WebGPURenderer(); +const webgpuRenderer = new WebGPURenderer({ + shaderCompilerPath: '/glsl_wgsl_compiler_bg.wasm', +}); const canvaskitRenderer = new CanvaskitRenderer({ wasmDir: '/', fonts: [ diff --git a/site/examples/ecosystem/d3/demo/d3-scatterplot.js b/site/examples/ecosystem/d3/demo/d3-scatterplot.js index bca2668d6..40af40519 100644 --- a/site/examples/ecosystem/d3/demo/d3-scatterplot.js +++ b/site/examples/ecosystem/d3/demo/d3-scatterplot.js @@ -20,7 +20,9 @@ import Stats from 'stats.js'; const canvasRenderer = new CanvasRenderer(); const svgRenderer = new SVGRenderer(); const webglRenderer = new WebGLRenderer(); -const webgpuRenderer = new WebGPURenderer(); +const webgpuRenderer = new WebGPURenderer({ + shaderCompilerPath: '/glsl_wgsl_compiler_bg.wasm', +}); const canvaskitRenderer = new CanvaskitRenderer({ wasmDir: '/', fonts: [ diff --git a/site/examples/ecosystem/image-exporter/demo/image-exporter.js b/site/examples/ecosystem/image-exporter/demo/image-exporter.js index eb8340e78..33e43b7b3 100644 --- a/site/examples/ecosystem/image-exporter/demo/image-exporter.js +++ b/site/examples/ecosystem/image-exporter/demo/image-exporter.js @@ -23,7 +23,9 @@ import Stats from 'stats.js'; const canvasRenderer = new CanvasRenderer(); const svgRenderer = new SVGRenderer(); const webglRenderer = new WebGLRenderer(); -const webgpuRenderer = new WebGPURenderer(); +const webgpuRenderer = new WebGPURenderer({ + shaderCompilerPath: '/glsl_wgsl_compiler_bg.wasm', +}); const canvaskitRenderer = new CanvaskitRenderer({ wasmDir: '/', fonts: [ diff --git a/site/examples/ecosystem/lite/demo/lite.js b/site/examples/ecosystem/lite/demo/lite.js index a3763a6f2..24fe7429d 100644 --- a/site/examples/ecosystem/lite/demo/lite.js +++ b/site/examples/ecosystem/lite/demo/lite.js @@ -20,7 +20,9 @@ import Stats from 'stats.js'; const canvasRenderer = new CanvasRenderer(); const svgRenderer = new SVGRenderer(); const webglRenderer = new WebGLRenderer(); -const webgpuRenderer = new WebGPURenderer(); +const webgpuRenderer = new WebGPURenderer({ + shaderCompilerPath: '/glsl_wgsl_compiler_bg.wasm', +}); const canvaskitRenderer = new CanvaskitRenderer({ wasmDir: '/', fonts: [ diff --git a/site/examples/ecosystem/lottie/demo/ant.js b/site/examples/ecosystem/lottie/demo/ant.js index a3bcae28a..f64c2700b 100644 --- a/site/examples/ecosystem/lottie/demo/ant.js +++ b/site/examples/ecosystem/lottie/demo/ant.js @@ -17,7 +17,9 @@ import * as d3 from 'd3'; const canvasRenderer = new CanvasRenderer(); const svgRenderer = new SVGRenderer(); const webglRenderer = new WebGLRenderer(); -const webgpuRenderer = new WebGPURenderer(); +const webgpuRenderer = new WebGPURenderer({ + shaderCompilerPath: '/glsl_wgsl_compiler_bg.wasm', +}); const canvaskitRenderer = new CanvaskitRenderer({ wasmDir: '/', fonts: [ diff --git a/site/examples/ecosystem/lottie/demo/arrow.js b/site/examples/ecosystem/lottie/demo/arrow.js index f600b73af..ed2340320 100644 --- a/site/examples/ecosystem/lottie/demo/arrow.js +++ b/site/examples/ecosystem/lottie/demo/arrow.js @@ -17,7 +17,9 @@ import * as d3 from 'd3'; const canvasRenderer = new CanvasRenderer(); const svgRenderer = new SVGRenderer(); const webglRenderer = new WebGLRenderer(); -const webgpuRenderer = new WebGPURenderer(); +const webgpuRenderer = new WebGPURenderer({ + shaderCompilerPath: '/glsl_wgsl_compiler_bg.wasm', +}); const canvaskitRenderer = new CanvaskitRenderer({ wasmDir: '/', fonts: [ diff --git a/site/examples/ecosystem/lottie/demo/lottie-player-assets.js b/site/examples/ecosystem/lottie/demo/lottie-player-assets.js index aed451238..ae605854f 100644 --- a/site/examples/ecosystem/lottie/demo/lottie-player-assets.js +++ b/site/examples/ecosystem/lottie/demo/lottie-player-assets.js @@ -17,7 +17,9 @@ import * as d3 from 'd3'; const canvasRenderer = new CanvasRenderer(); const svgRenderer = new SVGRenderer(); const webglRenderer = new WebGLRenderer(); -const webgpuRenderer = new WebGPURenderer(); +const webgpuRenderer = new WebGPURenderer({ + shaderCompilerPath: '/glsl_wgsl_compiler_bg.wasm', +}); const canvaskitRenderer = new CanvaskitRenderer({ wasmDir: '/', fonts: [ diff --git a/site/examples/ecosystem/lottie/demo/lottie-player-basic-shapes.js b/site/examples/ecosystem/lottie/demo/lottie-player-basic-shapes.js index 3064819b9..9b77923c6 100644 --- a/site/examples/ecosystem/lottie/demo/lottie-player-basic-shapes.js +++ b/site/examples/ecosystem/lottie/demo/lottie-player-basic-shapes.js @@ -16,7 +16,9 @@ import Stats from 'stats.js'; const canvasRenderer = new CanvasRenderer(); const svgRenderer = new SVGRenderer(); const webglRenderer = new WebGLRenderer(); -const webgpuRenderer = new WebGPURenderer(); +const webgpuRenderer = new WebGPURenderer({ + shaderCompilerPath: '/glsl_wgsl_compiler_bg.wasm', +}); const canvaskitRenderer = new CanvaskitRenderer({ wasmDir: '/', fonts: [ diff --git a/site/examples/ecosystem/lottie/demo/lottie-player-transform.js b/site/examples/ecosystem/lottie/demo/lottie-player-transform.js index ab337cdb6..24c624740 100644 --- a/site/examples/ecosystem/lottie/demo/lottie-player-transform.js +++ b/site/examples/ecosystem/lottie/demo/lottie-player-transform.js @@ -17,7 +17,9 @@ import * as d3 from 'd3'; const canvasRenderer = new CanvasRenderer(); const svgRenderer = new SVGRenderer(); const webglRenderer = new WebGLRenderer(); -const webgpuRenderer = new WebGPURenderer(); +const webgpuRenderer = new WebGPURenderer({ + shaderCompilerPath: '/glsl_wgsl_compiler_bg.wasm', +}); const canvaskitRenderer = new CanvaskitRenderer({ wasmDir: '/', fonts: [ diff --git a/site/examples/ecosystem/lottie/demo/radar.js b/site/examples/ecosystem/lottie/demo/radar.js index f75091549..d0be6ea19 100644 --- a/site/examples/ecosystem/lottie/demo/radar.js +++ b/site/examples/ecosystem/lottie/demo/radar.js @@ -17,7 +17,9 @@ import * as d3 from 'd3'; const canvasRenderer = new CanvasRenderer(); const svgRenderer = new SVGRenderer(); const webglRenderer = new WebGLRenderer(); -const webgpuRenderer = new WebGPURenderer(); +const webgpuRenderer = new WebGPURenderer({ + shaderCompilerPath: '/glsl_wgsl_compiler_bg.wasm', +}); const canvaskitRenderer = new CanvaskitRenderer({ wasmDir: '/', fonts: [ diff --git a/site/examples/ecosystem/lottie/demo/spring.js b/site/examples/ecosystem/lottie/demo/spring.js index d75158e22..c671f01b0 100644 --- a/site/examples/ecosystem/lottie/demo/spring.js +++ b/site/examples/ecosystem/lottie/demo/spring.js @@ -17,7 +17,9 @@ import * as d3 from 'd3'; const canvasRenderer = new CanvasRenderer(); const svgRenderer = new SVGRenderer(); const webglRenderer = new WebGLRenderer(); -const webgpuRenderer = new WebGPURenderer(); +const webgpuRenderer = new WebGPURenderer({ + shaderCompilerPath: '/glsl_wgsl_compiler_bg.wasm', +}); const canvaskitRenderer = new CanvaskitRenderer({ wasmDir: '/', fonts: [ diff --git a/site/examples/ecosystem/lottie/demo/use-animations.js b/site/examples/ecosystem/lottie/demo/use-animations.js index 0db77867e..36ea4d672 100644 --- a/site/examples/ecosystem/lottie/demo/use-animations.js +++ b/site/examples/ecosystem/lottie/demo/use-animations.js @@ -17,7 +17,9 @@ import * as d3 from 'd3'; const canvasRenderer = new CanvasRenderer(); const svgRenderer = new SVGRenderer(); const webglRenderer = new WebGLRenderer(); -const webgpuRenderer = new WebGPURenderer(); +const webgpuRenderer = new WebGPURenderer({ + shaderCompilerPath: '/glsl_wgsl_compiler_bg.wasm', +}); const canvaskitRenderer = new CanvaskitRenderer({ wasmDir: '/', fonts: [ diff --git a/site/examples/ecosystem/observable-plot/demo/dot.js b/site/examples/ecosystem/observable-plot/demo/dot.js index efb60dc98..d51e6a9d3 100644 --- a/site/examples/ecosystem/observable-plot/demo/dot.js +++ b/site/examples/ecosystem/observable-plot/demo/dot.js @@ -12,7 +12,9 @@ import * as Plot from '@observablehq/plot'; const canvasRenderer = new CanvasRenderer(); const svgRenderer = new SVGRenderer(); const webglRenderer = new WebGLRenderer(); -const webgpuRenderer = new WebGPURenderer(); +const webgpuRenderer = new WebGPURenderer({ + shaderCompilerPath: '/glsl_wgsl_compiler_bg.wasm', +}); const canvaskitRenderer = new CanvaskitRenderer({ wasmDir: '/', fonts: [ diff --git a/site/examples/event/dragndrop/demo/drag.js b/site/examples/event/dragndrop/demo/drag.js index acbc0f63a..303ff3d60 100644 --- a/site/examples/event/dragndrop/demo/drag.js +++ b/site/examples/event/dragndrop/demo/drag.js @@ -25,7 +25,9 @@ const canvaskitRenderer = new CanvaskitRenderer({ }, ], }); -const webgpuRenderer = new WebGPURenderer(); +const webgpuRenderer = new WebGPURenderer({ + shaderCompilerPath: '/glsl_wgsl_compiler_bg.wasm', +}); // create a canvas const canvas = new Canvas({ diff --git a/site/examples/event/dragndrop/demo/interact.js b/site/examples/event/dragndrop/demo/interact.js index 9f4275e3c..81addeded 100644 --- a/site/examples/event/dragndrop/demo/interact.js +++ b/site/examples/event/dragndrop/demo/interact.js @@ -27,7 +27,9 @@ const canvaskitRenderer = new CanvaskitRenderer({ }, ], }); -const webgpuRenderer = new WebGPURenderer(); +const webgpuRenderer = new WebGPURenderer({ + shaderCompilerPath: '/glsl_wgsl_compiler_bg.wasm', +}); // register css select plugin canvasRenderer.registerPlugin(new Plugin()); diff --git a/site/examples/event/event-others/demo/builtin.js b/site/examples/event/event-others/demo/builtin.js index 7d6fcb81e..f1cb8147b 100644 --- a/site/examples/event/event-others/demo/builtin.js +++ b/site/examples/event/event-others/demo/builtin.js @@ -20,7 +20,9 @@ const canvaskitRenderer = new CanvaskitRenderer({ }, ], }); -const webgpuRenderer = new WebGPURenderer(); +const webgpuRenderer = new WebGPURenderer({ + shaderCompilerPath: '/glsl_wgsl_compiler_bg.wasm', +}); // create a canvas const canvas = new Canvas({ diff --git a/site/examples/event/event-others/demo/custom.js b/site/examples/event/event-others/demo/custom.js index 757437d01..aa6aa11e3 100644 --- a/site/examples/event/event-others/demo/custom.js +++ b/site/examples/event/event-others/demo/custom.js @@ -23,7 +23,9 @@ const canvaskitRenderer = new CanvaskitRenderer({ }, ], }); -const webgpuRenderer = new WebGPURenderer(); +const webgpuRenderer = new WebGPURenderer({ + shaderCompilerPath: '/glsl_wgsl_compiler_bg.wasm', +}); // create a canvas const canvas = new Canvas({ diff --git a/site/examples/event/event-others/demo/delegate.js b/site/examples/event/event-others/demo/delegate.js index c51dfa435..916f7e7b8 100644 --- a/site/examples/event/event-others/demo/delegate.js +++ b/site/examples/event/event-others/demo/delegate.js @@ -28,7 +28,9 @@ const canvaskitRenderer = new CanvaskitRenderer({ }, ], }); -const webgpuRenderer = new WebGPURenderer(); +const webgpuRenderer = new WebGPURenderer({ + shaderCompilerPath: '/glsl_wgsl_compiler_bg.wasm', +}); // create a canvas const canvas = new Canvas({ diff --git a/site/examples/event/event-others/demo/deprecated-delegate.js b/site/examples/event/event-others/demo/deprecated-delegate.js index 9768616c6..896d83a11 100644 --- a/site/examples/event/event-others/demo/deprecated-delegate.js +++ b/site/examples/event/event-others/demo/deprecated-delegate.js @@ -28,7 +28,9 @@ const canvaskitRenderer = new CanvaskitRenderer({ }, ], }); -const webgpuRenderer = new WebGPURenderer(); +const webgpuRenderer = new WebGPURenderer({ + shaderCompilerPath: '/glsl_wgsl_compiler_bg.wasm', +}); // create a canvas const canvas = new Canvas({ diff --git a/site/examples/event/event-others/demo/mutation-observer.js b/site/examples/event/event-others/demo/mutation-observer.js index 95d7a19c5..bde2d94b9 100644 --- a/site/examples/event/event-others/demo/mutation-observer.js +++ b/site/examples/event/event-others/demo/mutation-observer.js @@ -20,7 +20,9 @@ const canvaskitRenderer = new CanvaskitRenderer({ }, ], }); -const webgpuRenderer = new WebGPURenderer(); +const webgpuRenderer = new WebGPURenderer({ + shaderCompilerPath: '/glsl_wgsl_compiler_bg.wasm', +}); // create a canvas const canvas = new Canvas({ diff --git a/site/examples/event/event-others/demo/touch.js b/site/examples/event/event-others/demo/touch.js index 71022fd0d..5865dd092 100644 --- a/site/examples/event/event-others/demo/touch.js +++ b/site/examples/event/event-others/demo/touch.js @@ -20,7 +20,9 @@ const canvaskitRenderer = new CanvaskitRenderer({ }, ], }); -const webgpuRenderer = new WebGPURenderer(); +const webgpuRenderer = new WebGPURenderer({ + shaderCompilerPath: '/glsl_wgsl_compiler_bg.wasm', +}); // create a canvas const canvas = new Canvas({ diff --git a/site/examples/event/gesture/demo/hammer.js b/site/examples/event/gesture/demo/hammer.js index bde5834c5..45ed8ec85 100644 --- a/site/examples/event/gesture/demo/hammer.js +++ b/site/examples/event/gesture/demo/hammer.js @@ -21,7 +21,9 @@ const canvaskitRenderer = new CanvaskitRenderer({ }, ], }); -const webgpuRenderer = new WebGPURenderer(); +const webgpuRenderer = new WebGPURenderer({ + shaderCompilerPath: '/glsl_wgsl_compiler_bg.wasm', +}); // create a canvas const canvas = new Canvas({ diff --git a/site/examples/event/picking/demo/circle.js b/site/examples/event/picking/demo/circle.js index 8568d84b7..f9af48356 100644 --- a/site/examples/event/picking/demo/circle.js +++ b/site/examples/event/picking/demo/circle.js @@ -20,7 +20,9 @@ const canvaskitRenderer = new CanvaskitRenderer({ }, ], }); -const webgpuRenderer = new WebGPURenderer(); +const webgpuRenderer = new WebGPURenderer({ + shaderCompilerPath: '/glsl_wgsl_compiler_bg.wasm', +}); // create a canvas const canvas = new Canvas({ diff --git a/site/examples/event/picking/demo/shapes.js b/site/examples/event/picking/demo/shapes.js index c109cce84..a6ca27fd2 100644 --- a/site/examples/event/picking/demo/shapes.js +++ b/site/examples/event/picking/demo/shapes.js @@ -23,7 +23,9 @@ import Stats from 'stats.js'; const canvasRenderer = new CanvasRenderer(); const svgRenderer = new SVGRenderer(); const webglRenderer = new WebGLRenderer(); -const webgpuRenderer = new WebGPURenderer(); +const webgpuRenderer = new WebGPURenderer({ + shaderCompilerPath: '/glsl_wgsl_compiler_bg.wasm', +}); const canvaskitRenderer = new CanvaskitRenderer({ wasmDir: '/', fonts: [ diff --git a/site/examples/gpgpu/basic-algorithm/demo/add-2-vectors-webgl.js b/site/examples/gpgpu/basic-algorithm/demo/add-2-vectors-webgl.js deleted file mode 100644 index 96b41ba0e..000000000 --- a/site/examples/gpgpu/basic-algorithm/demo/add-2-vectors-webgl.js +++ /dev/null @@ -1,90 +0,0 @@ -import { Canvas, CanvasEvent } from '@antv/g'; -import { Kernel, Plugin } from '@antv/g-plugin-gpgpu'; -import { DeviceRenderer, Renderer } from '@antv/g-webgl'; - -const { BufferUsage } = DeviceRenderer; - -const CANVAS_SIZE = 1; -const $canvas = document.createElement('canvas'); - -// use WebGPU -const renderer = new Renderer(); -renderer.registerPlugin(new Plugin()); - -// create a canvas -const canvas = new Canvas({ - canvas: $canvas, - width: CANVAS_SIZE, - height: CANVAS_SIZE, - renderer, -}); - -canvas.addEventListener(CanvasEvent.READY, () => { - const plugin = renderer.getPlugin('device-renderer'); - const device = plugin.getDevice(); - - const kernel = new Kernel(device, { - bundle: { - shaders: { - WGSL: '', - GLSL450: - '\n\n\nbool gWebGPUDebug = false;\nvec4 gWebGPUDebugOutput = vec4(0.0);\n\nivec3 globalInvocationID = ivec3(gl_GlobalInvocationID);\nivec3 workGroupSize = ivec3(gl_WorkGroupSize);\nivec3 workGroupID = ivec3(gl_WorkGroupID);\nivec3 localInvocationID = ivec3(gl_LocalInvocationID);\nivec3 numWorkGroups = ivec3(gl_NumWorkGroups);\nint localInvocationIndex = int(gl_LocalInvocationIndex);\n\n\nlayout(std430, set = 0, binding = 0) buffer GWebGPUBuffer0 {\n float vectorA[];\n} gWebGPUBuffer0;\n\nlayout(std430, set = 0, binding = 1) buffer readonly GWebGPUBuffer1 {\n float vectorB[];\n} gWebGPUBuffer1;\n\n\n\nlayout (\n local_size_x = 8,\n local_size_y = 1,\n local_size_z = 1\n) in;\n\n\nfloat sum(float a, float b) {return a + b;}\nvoid main() {float a = gWebGPUBuffer0.vectorA[globalInvocationID.x];\nfloat b = gWebGPUBuffer1.vectorB[globalInvocationID.x];\ngWebGPUBuffer0.vectorA[globalInvocationID.x] = sum(a, b);}\n', - GLSL100: - '#ifdef GL_FRAGMENT_PRECISION_HIGH\n precision highp float;\n#else\n precision mediump float;\n#endif\n\n\nfloat epsilon = 0.00001;\nvec2 addrTranslation_1Dto2D(float address1D, vec2 texSize) {\n vec2 conv_const = vec2(1.0 / texSize.x, 1.0 / (texSize.x * texSize.y));\n vec2 normAddr2D = float(address1D) * conv_const;\n return vec2(fract(normAddr2D.x + epsilon), normAddr2D.y);\n}\n\nvoid barrier() {}\n \n\nuniform vec2 u_OutputTextureSize;\nuniform int u_OutputTexelCount;\nvarying vec2 v_TexCoord;\n\nbool gWebGPUDebug = false;\nvec4 gWebGPUDebugOutput = vec4(0.0);\n\n\nuniform sampler2D vectorA;\nuniform vec2 vectorASize;\nfloat getDatavectorA(vec2 address2D) {\n return float(texture2D(vectorA, address2D).r);\n}\nfloat getDatavectorA(float address1D) {\n return getDatavectorA(addrTranslation_1Dto2D(address1D, vectorASize));\n}\nfloat getDatavectorA(int address1D) {\n return getDatavectorA(float(address1D));\n}\nuniform sampler2D vectorB;\nuniform vec2 vectorBSize;\nfloat getDatavectorB(vec2 address2D) {\n return float(texture2D(vectorB, address2D).r);\n}\nfloat getDatavectorB(float address1D) {\n return getDatavectorB(addrTranslation_1Dto2D(address1D, vectorBSize));\n}\nfloat getDatavectorB(int address1D) {\n return getDatavectorB(float(address1D));\n}\nfloat sum(float a, float b) {\nivec3 workGroupSize = ivec3(1, 1, 1);\nivec3 numWorkGroups = ivec3(1, 1, 1); \nint globalInvocationIndex = int(floor(v_TexCoord.x * u_OutputTextureSize.x))\n + int(floor(v_TexCoord.y * u_OutputTextureSize.y)) * int(u_OutputTextureSize.x);\nint workGroupIDLength = globalInvocationIndex / (workGroupSize.x * workGroupSize.y * workGroupSize.z);\nivec3 workGroupID = ivec3(workGroupIDLength / numWorkGroups.y / numWorkGroups.z, workGroupIDLength / numWorkGroups.x / numWorkGroups.z, workGroupIDLength / numWorkGroups.x / numWorkGroups.y);\nint localInvocationIDZ = globalInvocationIndex / (workGroupSize.x * workGroupSize.y);\nint localInvocationIDY = (globalInvocationIndex - localInvocationIDZ * workGroupSize.x * workGroupSize.y) / workGroupSize.x;\nint localInvocationIDX = globalInvocationIndex - localInvocationIDZ * workGroupSize.x * workGroupSize.y - localInvocationIDY * workGroupSize.x;\nivec3 localInvocationID = ivec3(localInvocationIDX, localInvocationIDY, localInvocationIDZ);\nivec3 globalInvocationID = workGroupID * workGroupSize + localInvocationID;\nint localInvocationIndex = localInvocationID.z * workGroupSize.x * workGroupSize.y\n + localInvocationID.y * workGroupSize.x + localInvocationID.x;\nreturn a + b;}\nvoid main() {\nivec3 workGroupSize = ivec3(1, 1, 1);\nivec3 numWorkGroups = ivec3(1, 1, 1); \nint globalInvocationIndex = int(floor(v_TexCoord.x * u_OutputTextureSize.x))\n + int(floor(v_TexCoord.y * u_OutputTextureSize.y)) * int(u_OutputTextureSize.x);\nint workGroupIDLength = globalInvocationIndex / (workGroupSize.x * workGroupSize.y * workGroupSize.z);\nivec3 workGroupID = ivec3(workGroupIDLength / numWorkGroups.y / numWorkGroups.z, workGroupIDLength / numWorkGroups.x / numWorkGroups.z, workGroupIDLength / numWorkGroups.x / numWorkGroups.y);\nint localInvocationIDZ = globalInvocationIndex / (workGroupSize.x * workGroupSize.y);\nint localInvocationIDY = (globalInvocationIndex - localInvocationIDZ * workGroupSize.x * workGroupSize.y) / workGroupSize.x;\nint localInvocationIDX = globalInvocationIndex - localInvocationIDZ * workGroupSize.x * workGroupSize.y - localInvocationIDY * workGroupSize.x;\nivec3 localInvocationID = ivec3(localInvocationIDX, localInvocationIDY, localInvocationIDZ);\nivec3 globalInvocationID = workGroupID * workGroupSize + localInvocationID;\nint localInvocationIndex = localInvocationID.z * workGroupSize.x * workGroupSize.y\n + localInvocationID.y * workGroupSize.x + localInvocationID.x;\nfloat a = getDatavectorA(globalInvocationID.x);\nfloat b = getDatavectorB(globalInvocationID.x);\ngl_FragColor = vec4(sum(a, b));if (gWebGPUDebug) {\n gl_FragColor = gWebGPUDebugOutput;\n}}\n', - }, - context: { - name: '', - dispatch: [1, 1, 1], - threadGroupSize: [1, 1, 1], - maxIteration: 1, - defines: [], - uniforms: [ - { - name: 'vectorA', - type: 'Float[]', - storageClass: 'StorageBuffer', - readonly: false, - writeonly: false, - size: [1, 1], - }, - { - name: 'vectorB', - type: 'Float[]', - storageClass: 'StorageBuffer', - readonly: true, - writeonly: false, - size: [1, 1], - }, - ], - globalDeclarations: [], - output: { - name: 'vectorA', - size: [1, 1], - length: 1, - }, - needPingpong: true, - }, - }, - }); - - const inputBuffer = device.createBuffer({ - usage: BufferUsage.STORAGE | BufferUsage.COPY_SRC, - viewOrSize: new Int32Array([1, 2, 3, 4]), - }); - const outputBuffer = device.createBuffer({ - usage: BufferUsage.STORAGE | BufferUsage.COPY_SRC, - viewOrSize: new Int32Array([1, 2, 3, 4]), - }); - const readback = device.createReadback(); - - kernel.setBinding(0, inputBuffer); - kernel.setBinding(1, outputBuffer); - - kernel.dispatch(1, 1); - - (async () => { - const output = await readback.readBuffer(outputBuffer); - - console.log(output); - })(); -}); diff --git a/site/examples/gpgpu/basic-algorithm/demo/meta.json b/site/examples/gpgpu/basic-algorithm/demo/meta.json index b8aad8b88..5cc4645bd 100644 --- a/site/examples/gpgpu/basic-algorithm/demo/meta.json +++ b/site/examples/gpgpu/basic-algorithm/demo/meta.json @@ -11,13 +11,6 @@ "en": "Add 2 vectors" } }, - { - "filename": "add-2-vectors-webgl.js", - "title": { - "zh": "向量相加 WebGL", - "en": "Add 2 vectors" - } - }, { "filename": "matrix-multiplication.js", "title": { diff --git a/site/examples/perf/basic/demo/circle-animation.js b/site/examples/perf/animation/demo/circle.js similarity index 100% rename from site/examples/perf/basic/demo/circle-animation.js rename to site/examples/perf/animation/demo/circle.js diff --git a/site/examples/perf/basic/demo/group-move.js b/site/examples/perf/animation/demo/group-move.js similarity index 100% rename from site/examples/perf/basic/demo/group-move.js rename to site/examples/perf/animation/demo/group-move.js diff --git a/site/examples/perf/animation/demo/meta.json b/site/examples/perf/animation/demo/meta.json new file mode 100644 index 000000000..8b75d97cc --- /dev/null +++ b/site/examples/perf/animation/demo/meta.json @@ -0,0 +1,32 @@ +{ + "demos": [ + { + "filename": "circle.js", + "title": { + "zh": "Circle", + "en": "Circle" + } + }, + { + "filename": "path.js", + "title": { + "zh": "Path", + "en": "Path" + } + }, + { + "filename": "group-move.js", + "title": { + "zh": "频繁移动 Group", + "en": "Move groups" + } + }, + { + "filename": "redraw.js", + "title": { + "zh": "移动大量节点", + "en": "Move nodes" + } + } + ] +} diff --git a/site/examples/perf/basic/demo/path-animation.js b/site/examples/perf/animation/demo/path.js similarity index 100% rename from site/examples/perf/basic/demo/path-animation.js rename to site/examples/perf/animation/demo/path.js diff --git a/site/examples/perf/basic/demo/redraw.js b/site/examples/perf/animation/demo/redraw.js similarity index 100% rename from site/examples/perf/basic/demo/redraw.js rename to site/examples/perf/animation/demo/redraw.js diff --git a/site/examples/perf/animation/index.en.md b/site/examples/perf/animation/index.en.md new file mode 100644 index 000000000..485ebfb8e --- /dev/null +++ b/site/examples/perf/animation/index.en.md @@ -0,0 +1,4 @@ +--- +title: Performance of animation +order: 4 +--- diff --git a/site/examples/perf/animation/index.zh.md b/site/examples/perf/animation/index.zh.md new file mode 100644 index 000000000..2b68c961c --- /dev/null +++ b/site/examples/perf/animation/index.zh.md @@ -0,0 +1,4 @@ +--- +title: 动画性能 +order: 4 +--- diff --git a/site/examples/perf/basic/demo/culling.js b/site/examples/perf/basic/demo/culling.js index 349e4b06a..46194b098 100644 --- a/site/examples/perf/basic/demo/culling.js +++ b/site/examples/perf/basic/demo/culling.js @@ -20,7 +20,9 @@ const canvaskitRenderer = new CanvaskitRenderer({ }, ], }); -const webgpuRenderer = new WebGPURenderer(); +const webgpuRenderer = new WebGPURenderer({ + shaderCompilerPath: '/glsl_wgsl_compiler_bg.wasm', +}); // create a canvas const canvas = new Canvas({ diff --git a/site/examples/perf/basic/demo/disable-css.js b/site/examples/perf/basic/demo/disable-css.js index 5cb90c63f..3a75546f2 100644 --- a/site/examples/perf/basic/demo/disable-css.js +++ b/site/examples/perf/basic/demo/disable-css.js @@ -34,7 +34,9 @@ const canvaskitRenderer = new CanvaskitRenderer({ }, ], }); -const webgpuRenderer = new WebGPURenderer(); +const webgpuRenderer = new WebGPURenderer({ + shaderCompilerPath: '/glsl_wgsl_compiler_bg.wasm', +}); // create a canvas const canvas = new Canvas({ diff --git a/site/examples/perf/basic/demo/fcp.js b/site/examples/perf/basic/demo/fcp.js deleted file mode 100644 index c334a9e13..000000000 --- a/site/examples/perf/basic/demo/fcp.js +++ /dev/null @@ -1,74 +0,0 @@ -import { Canvas, CanvasEvent, Path } from '@antv/g'; -import { Renderer as CanvasRenderer } from '@antv/g-canvas'; -import Stats from 'stats.js'; - -const canvasRenderer = new CanvasRenderer(); - -// create a canvas -const canvas = new Canvas({ - container: 'container', - width: 600, - height: 500, - renderer: canvasRenderer, -}); - -function draw(nodesNum) { - function inner() { - for (let i = 0; i < nodesNum; i++) { - const x = Math.random() * 600; - const y = Math.random() * 500; - const path = canvas.appendChild( - new Path({ - attrs: { - fill: '#C6E5FF', - stroke: '#5B8FF9', - // path: [ - // ['M', 54.4462133232839 + x, -6.41757177038063 + y], - // ['L', 61.3765714868427 + x, 6.41757177038063 + y], - // ['M', 61.3765714868427 + x, 6.41757177038063 + y], - // ['L', 61.54285370420826 + x, 0.5852759906612777 + y], - // ['M', 61.3765714868427 + x, 6.41757177038063 + y], - // ['L', 56.4087962879037 + x, 3.3574192560847824 + y], - // ], - path: `M${54.4462133232839 + x},${-6.41757177038063 + y} L${ - 61.3765714868427 + x - },${6.41757177038063 + y} M${61.3765714868427 + x},${ - 6.41757177038063 + y - } L${61.54285370420826 + x},${0.5852759906612777 + y}M${ - 61.3765714868427 + x - },${6.41757177038063 + y}L${56.4087962879037 + x},${ - 3.3574192560847824 + y - }`, - }, - }), - ); - // path.animate([{ fillOpacity: 0 }, { fillOpacity: 1 }]); - } - } - - inner(); - inner(); - inner(); - inner(); - inner(); -} - -canvas.addEventListener(CanvasEvent.READY, () => { - let nodesNum = 10000; - draw(nodesNum); -}); - -// stats -const stats = new Stats(); -stats.showPanel(0); -const $stats = stats.dom; -$stats.style.position = 'absolute'; -$stats.style.left = '0px'; -$stats.style.top = '0px'; -const $wrapper = document.getElementById('container'); -$wrapper.appendChild($stats); -canvas.addEventListener(CanvasEvent.AFTER_RENDER, () => { - if (stats) { - stats.update(); - } -}); diff --git a/site/examples/perf/basic/demo/meta.json b/site/examples/perf/basic/demo/meta.json index 99c9dcf2b..65e33e99d 100644 --- a/site/examples/perf/basic/demo/meta.json +++ b/site/examples/perf/basic/demo/meta.json @@ -1,26 +1,5 @@ { "demos": [ - { - "filename": "canvas-circle-path.js", - "title": { - "zh": "g-canvas 渲染 Circle 和 Path", - "en": "Render Circle & Path with g-canvas" - } - }, - { - "filename": "webgl-circle-path.js", - "title": { - "zh": "g-webgl 渲染 Circle 和 Path", - "en": "Render Circle & Path with g-webgl" - } - }, - { - "filename": "vs-g4.0.js", - "title": { - "zh": "与 G 4.0 对比", - "en": "Compared with G 4.0" - } - }, { "filename": "culling.js", "title": { @@ -28,64 +7,6 @@ "en": "Viewport culling" } }, - { - "filename": "canvas-dirty-rectangle.js", - "title": { - "zh": "脏矩形渲染(Canvas)", - "en": "Rendering with dirty rectangle(Canvas)" - } - }, - { - "filename": "redraw.js", - "title": { - "zh": "移动大量节点", - "en": "Move nodes" - } - }, - { - "filename": "group-move.js", - "title": { - "zh": "频繁移动 Group", - "en": "Move groups" - } - }, - { - "filename": "nodes-8k.js", - "title": { - "zh": "8k 节点", - "en": "8k nodes" - }, - "screenshot": "https://gw.alipayobjects.com/mdn/rms_6ae20b/afts/img/A*D-57RohPWVgAAAAAAAAAAAAAARQnAQ" - }, - { - "filename": "nodes-5w.js", - "title": { - "zh": "5.5w 节点", - "en": "5.5w nodes" - }, - "screenshot": "https://gw.alipayobjects.com/mdn/rms_6ae20b/afts/img/A*dwS2Rb3mq5IAAAAAAAAAAAAAARQnAQ" - }, - { - "filename": "images.js", - "title": { - "zh": "大量图片", - "en": "Instanced Image" - } - }, - { - "filename": "texts.js", - "title": { - "zh": "大量文本", - "en": "Instanced Text" - } - }, - { - "filename": "rects.js", - "title": { - "zh": "大量矩形", - "en": "Instanced Rect" - } - }, { "filename": "disable-css.js", "title": { diff --git a/site/examples/perf/basic/index.en.md b/site/examples/perf/basic/index.en.md index 7dbc65ef6..75edb8a7b 100644 --- a/site/examples/perf/basic/index.en.md +++ b/site/examples/perf/basic/index.en.md @@ -1,4 +1,4 @@ --- -title: Performance -order: 1 +title: Performance tips +order: 5 --- diff --git a/site/examples/perf/basic/index.zh.md b/site/examples/perf/basic/index.zh.md index 6ae5b4f88..5227b83a3 100644 --- a/site/examples/perf/basic/index.zh.md +++ b/site/examples/perf/basic/index.zh.md @@ -1,4 +1,4 @@ --- -title: 性能 -order: 2 +title: 常见问题 +order: 5 --- diff --git a/site/examples/perf/basic/demo/canvas-circle-path.js b/site/examples/perf/canvas/demo/canvas-circle-path.js similarity index 100% rename from site/examples/perf/basic/demo/canvas-circle-path.js rename to site/examples/perf/canvas/demo/canvas-circle-path.js diff --git a/site/examples/perf/basic/demo/canvas-dirty-rectangle.js b/site/examples/perf/canvas/demo/canvas-dirty-rectangle.js similarity index 97% rename from site/examples/perf/basic/demo/canvas-dirty-rectangle.js rename to site/examples/perf/canvas/demo/canvas-dirty-rectangle.js index 18ed5c41f..3e831f534 100644 --- a/site/examples/perf/basic/demo/canvas-dirty-rectangle.js +++ b/site/examples/perf/canvas/demo/canvas-dirty-rectangle.js @@ -22,7 +22,9 @@ const canvaskitRenderer = new CanvaskitRenderer({ }, ], }); -const webgpuRenderer = new WebGPURenderer(); +const webgpuRenderer = new WebGPURenderer({ + shaderCompilerPath: '/glsl_wgsl_compiler_bg.wasm', +}); // create a canvas const canvas = new Canvas({ diff --git a/site/examples/perf/canvas/demo/meta.json b/site/examples/perf/canvas/demo/meta.json new file mode 100644 index 000000000..941c8c132 --- /dev/null +++ b/site/examples/perf/canvas/demo/meta.json @@ -0,0 +1,25 @@ +{ + "demos": [ + { + "filename": "canvas-circle-path.js", + "title": { + "zh": "g-canvas 渲染 Circle 和 Path", + "en": "Render Circle & Path with g-canvas" + } + }, + { + "filename": "canvas-dirty-rectangle.js", + "title": { + "zh": "脏矩形渲染(Canvas)", + "en": "Rendering with dirty rectangle(Canvas)" + } + }, + { + "filename": "vs-g4.0.js", + "title": { + "zh": "与 G 4.0 对比", + "en": "Compared with G 4.0" + } + } + ] +} diff --git a/site/examples/perf/basic/demo/vs-g4.0.js b/site/examples/perf/canvas/demo/vs-g4.0.js similarity index 96% rename from site/examples/perf/basic/demo/vs-g4.0.js rename to site/examples/perf/canvas/demo/vs-g4.0.js index 20c6e9bb6..5e166a3c3 100644 --- a/site/examples/perf/basic/demo/vs-g4.0.js +++ b/site/examples/perf/canvas/demo/vs-g4.0.js @@ -24,7 +24,9 @@ const canvaskitRenderer = new CanvaskitRenderer({ }, ], }); -const webgpuRenderer = new WebGPURenderer(); +const webgpuRenderer = new WebGPURenderer({ + shaderCompilerPath: '/glsl_wgsl_compiler_bg.wasm', +}); // create a canvas const canvas = new Canvas({ diff --git a/site/examples/perf/canvas/index.en.md b/site/examples/perf/canvas/index.en.md new file mode 100644 index 000000000..f32da385c --- /dev/null +++ b/site/examples/perf/canvas/index.en.md @@ -0,0 +1,4 @@ +--- +title: Performance of Canvas +order: 2 +--- diff --git a/site/examples/perf/canvas/index.zh.md b/site/examples/perf/canvas/index.zh.md new file mode 100644 index 000000000..b4d055948 --- /dev/null +++ b/site/examples/perf/canvas/index.zh.md @@ -0,0 +1,4 @@ +--- +title: Canvas 性能 +order: 2 +--- diff --git a/site/examples/perf/basic/demo/webgl-circle-path.js b/site/examples/perf/webgl/demo/circle-path.js similarity index 87% rename from site/examples/perf/basic/demo/webgl-circle-path.js rename to site/examples/perf/webgl/demo/circle-path.js index 71e4eebbd..b7bf161ff 100644 --- a/site/examples/perf/basic/demo/webgl-circle-path.js +++ b/site/examples/perf/webgl/demo/circle-path.js @@ -35,17 +35,6 @@ canvas.addEventListener(CanvasEvent.READY, () => { lineWidth: 0.3, }, }), - // new Line({ - // attrs: { - // x1: x, - // y1: y, - // x2: x + Math.random() * 100, - // y2: y + Math.random() * 50, - // lineWidth: 1, - // stroke: '#000', - // lineWidth: 0.3, - // }, - // }), ); } let nodesNum = 1589; diff --git a/site/examples/perf/basic/demo/images.js b/site/examples/perf/webgl/demo/images.js similarity index 74% rename from site/examples/perf/basic/demo/images.js rename to site/examples/perf/webgl/demo/images.js index deff5795f..8bd8830d6 100644 --- a/site/examples/perf/basic/demo/images.js +++ b/site/examples/perf/webgl/demo/images.js @@ -1,26 +1,14 @@ import { Canvas, CanvasEvent, Image } from '@antv/g'; -import { Renderer as CanvasRenderer } from '@antv/g-canvas'; -import { Renderer as CanvaskitRenderer } from '@antv/g-canvaskit'; -import { Renderer as SVGRenderer } from '@antv/g-svg'; import { Renderer as WebGLRenderer } from '@antv/g-webgl'; import { Renderer as WebGPURenderer } from '@antv/g-webgpu'; import * as lil from 'lil-gui'; import Stats from 'stats.js'; // create a renderer -const canvasRenderer = new CanvasRenderer(); const webglRenderer = new WebGLRenderer(); -const svgRenderer = new SVGRenderer(); -const canvaskitRenderer = new CanvaskitRenderer({ - wasmDir: '/', - fonts: [ - { - name: 'sans-serif', - url: 'https://mdn.alipayobjects.com/huamei_qa8qxu/afts/file/A*064aSK2LUPEAAAAAAAAAAAAADmJ7AQ/NotoSansCJKsc-VF.ttf', - }, - ], +const webgpuRenderer = new WebGPURenderer({ + shaderCompilerPath: '/glsl_wgsl_compiler_bg.wasm', }); -const webgpuRenderer = new WebGPURenderer(); // create a canvas const canvas = new Canvas({ @@ -107,25 +95,13 @@ const rendererConfig = { renderer: 'webgl', }; rendererFolder - .add(rendererConfig, 'renderer', [ - 'canvas', - 'svg', - 'webgl', - 'webgpu', - 'canvaskit', - ]) + .add(rendererConfig, 'renderer', ['webgl', 'webgpu']) .onChange((rendererName) => { let renderer; - if (rendererName === 'canvas') { - renderer = canvasRenderer; - } else if (rendererName === 'svg') { - renderer = svgRenderer; - } else if (rendererName === 'webgl') { + if (rendererName === 'webgl') { renderer = webglRenderer; } else if (rendererName === 'webgpu') { renderer = webgpuRenderer; - } else if (rendererName === 'canvaskit') { - renderer = canvaskitRenderer; } canvas.setRenderer(renderer); }); diff --git a/site/examples/perf/webgl/demo/meta.json b/site/examples/perf/webgl/demo/meta.json new file mode 100644 index 000000000..3925240ec --- /dev/null +++ b/site/examples/perf/webgl/demo/meta.json @@ -0,0 +1,66 @@ +{ + "demos": [ + { + "filename": "texts.js", + "title": { + "zh": "大量文本", + "en": "Instanced Text" + }, + "screenshot": "https://mdn.alipayobjects.com/huamei_qa8qxu/afts/img/A*utrOS5D0-d8AAAAAAAAAAAAADmJ7AQ/original" + }, + { + "filename": "rects.js", + "title": { + "zh": "大量矩形", + "en": "Instanced Rect" + }, + "screenshot": "https://mdn.alipayobjects.com/huamei_qa8qxu/afts/img/A*sQH_T5LdKdcAAAAAAAAAAAAADmJ7AQ/original" + }, + { + "filename": "images.js", + "title": { + "zh": "大量图片", + "en": "Instanced Image" + }, + "screenshot": "https://mdn.alipayobjects.com/huamei_qa8qxu/afts/img/A*qvDhTaGQXl0AAAAAAAAAAAAADmJ7AQ/original" + }, + { + "filename": "one-command-curve.js", + "title": { + "zh": "包含一条曲线命令的 Path", + "en": "Instanced Simple Path(one-command curve)" + } + }, + { + "filename": "circle-path.js", + "title": { + "zh": "大量 Circle Path 和 Text", + "en": "Render Circle, Path and Text" + } + }, + { + "filename": "nodes-8k.js", + "title": { + "zh": "包含 8k 节点的图", + "en": "A large graph with 8k nodes" + }, + "screenshot": "https://gw.alipayobjects.com/mdn/rms_6ae20b/afts/img/A*D-57RohPWVgAAAAAAAAAAAAAARQnAQ" + }, + { + "filename": "nodes-8k-curve-edges.js", + "title": { + "zh": "包含 8k 节点的图,使用曲线边", + "en": "A large graph with 8k nodes" + }, + "screenshot": "https://mdn.alipayobjects.com/huamei_qa8qxu/afts/img/A*PTs5R43dHGIAAAAAAAAAAAAADmJ7AQ/original" + }, + { + "filename": "nodes-5w.js", + "title": { + "zh": "包含 5.5w 节点的图", + "en": "A large graph with 5.5w nodes" + }, + "screenshot": "https://gw.alipayobjects.com/mdn/rms_6ae20b/afts/img/A*dwS2Rb3mq5IAAAAAAAAAAAAAARQnAQ" + } + ] +} diff --git a/site/examples/perf/basic/demo/nodes-5w.js b/site/examples/perf/webgl/demo/nodes-5w.js similarity index 83% rename from site/examples/perf/basic/demo/nodes-5w.js rename to site/examples/perf/webgl/demo/nodes-5w.js index d6041cc97..9a4c3048b 100644 --- a/site/examples/perf/basic/demo/nodes-5w.js +++ b/site/examples/perf/webgl/demo/nodes-5w.js @@ -1,7 +1,4 @@ import { Canvas, CanvasEvent, Circle, Line } from '@antv/g'; -import { Renderer as CanvasRenderer } from '@antv/g-canvas'; -import { Renderer as CanvaskitRenderer } from '@antv/g-canvaskit'; -import { Renderer as SVGRenderer } from '@antv/g-svg'; import { Renderer as WebGLRenderer } from '@antv/g-webgl'; import { Renderer as WebGPURenderer } from '@antv/g-webgpu'; import Hammer from 'hammerjs'; @@ -11,19 +8,10 @@ import Stats from 'stats.js'; // ported from G6 @see https://g6.antv.vision/zh/examples/performance/perf#moreData // create a renderer -const canvasRenderer = new CanvasRenderer(); const webglRenderer = new WebGLRenderer(); -const svgRenderer = new SVGRenderer(); -const canvaskitRenderer = new CanvaskitRenderer({ - wasmDir: '/', - fonts: [ - { - name: 'sans-serif', - url: 'https://mdn.alipayobjects.com/huamei_qa8qxu/afts/file/A*064aSK2LUPEAAAAAAAAAAAAADmJ7AQ/NotoSansCJKsc-VF.ttf', - }, - ], +const webgpuRenderer = new WebGPURenderer({ + shaderCompilerPath: '/glsl_wgsl_compiler_bg.wasm', }); -const webgpuRenderer = new WebGPURenderer(); // create a canvas const canvas = new Canvas({ @@ -166,15 +154,15 @@ const rendererConfig = { renderer: 'webgl', }; rendererFolder - .add(rendererConfig, 'renderer', ['canvas', 'webgl', 'svg']) - .onChange(async (renderer) => { - await canvas.setRenderer( - renderer === 'canvas' - ? canvasRenderer - : renderer === 'webgl' - ? webglRenderer - : svgRenderer, - ); + .add(rendererConfig, 'renderer', ['webgl', 'webgpu']) + .onChange((rendererName) => { + let renderer; + if (rendererName === 'webgl') { + renderer = webglRenderer; + } else if (rendererName === 'webgpu') { + renderer = webgpuRenderer; + } + canvas.setRenderer(renderer); bindWheelHandler(); }); rendererFolder.open(); diff --git a/site/examples/perf/webgl/demo/nodes-8k-curve-edges.js b/site/examples/perf/webgl/demo/nodes-8k-curve-edges.js new file mode 100644 index 000000000..e97c8ceaa --- /dev/null +++ b/site/examples/perf/webgl/demo/nodes-8k-curve-edges.js @@ -0,0 +1,232 @@ +import { Canvas, CanvasEvent, Circle, Path, Text, runtime } from '@antv/g'; +import { Renderer as WebGLRenderer } from '@antv/g-webgl'; +import { Renderer as WebGPURenderer } from '@antv/g-webgpu'; +import { vec2 } from 'gl-matrix'; +import Hammer from 'hammerjs'; +import * as lil from 'lil-gui'; +import Stats from 'stats.js'; + +runtime.enableCSSParsing = false; + +// create a renderer +const webglRenderer = new WebGLRenderer(); +const webgpuRenderer = new WebGPURenderer({ + shaderCompilerPath: '/glsl_wgsl_compiler_bg.wasm', +}); + +// create a canvas +const canvas = new Canvas({ + container: 'container', + width: 600, + height: 500, + renderer: webglRenderer, +}); + +// ported from G6 @see https://g6.antv.vision/zh/examples/performance/perf#eva + +const mapNodeSize = (nodes, propertyName, visualRange) => { + let minp = 9999999999; + let maxp = -9999999999; + nodes.forEach((node) => { + node[propertyName] = Math.pow(node[propertyName], 1 / 3); + minp = node[propertyName] < minp ? node[propertyName] : minp; + maxp = node[propertyName] > maxp ? node[propertyName] : maxp; + }); + const rangepLength = maxp - minp; + const rangevLength = visualRange[1] - visualRange[0]; + nodes.forEach((node) => { + node.size = + ((node[propertyName] - minp) / rangepLength) * rangevLength + + visualRange[0]; + }); +}; + +const getControlPoint = (startPoint, endPoint, percent, offset) => { + const point = { + x: (1 - percent) * startPoint.x + percent * endPoint.x, + y: (1 - percent) * startPoint.y + percent * endPoint.y, + }; + + let tangent = [0, 0]; + vec2.normalize(tangent, [ + endPoint.x - startPoint.x, + endPoint.y - startPoint.y, + ]); + + if (!tangent || (!tangent[0] && !tangent[1])) { + tangent = [0, 0]; + } + const perpendicular = [-tangent[1] * offset, tangent[0] * offset]; // 垂直向量 + point.x += perpendicular[0]; + point.y += perpendicular[1]; + return point; +}; + +(async () => { + const [_, data] = await Promise.all([ + canvas.ready, + fetch( + 'https://gw.alipayobjects.com/os/basement_prod/0b9730ff-0850-46ff-84d0-1d4afecd43e6.json', + ).then((res) => res.json()), + ]); + + data.nodes.forEach((node) => { + node.label = node.olabel; + node.degree = 0; + data.edges.forEach((edge) => { + if (edge.source === node.id || edge.target === node.id) { + node.degree++; + } + }); + }); + mapNodeSize(data.nodes, 'degree', [1, 15]); + + /** + * Draw edges + */ + data.edges.forEach(({ startPoint, endPoint }) => { + const cp = getControlPoint( + { x: startPoint.x * 10, y: startPoint.y * 10 }, + { x: endPoint.x * 10, y: endPoint.y * 10 }, + 0.5, + 50, + ); + const path = new Path({ + style: { + d: [ + ['M', startPoint.x * 10, startPoint.y * 10], + ['Q', cp.x, cp.y, endPoint.x * 10, endPoint.y * 10], + ], + stroke: '#1890FF', + lineWidth: 3, + }, + }); + + canvas.appendChild(path); + path.addEventListener('mouseenter', (e) => { + path.style.stroke = 'red'; + }); + + path.addEventListener('mouseleave', (e) => { + path.style.stroke = '#1890FF'; + }); + }); + + /** + * Draw nodes + */ + data.nodes.forEach(({ size, x, y, label }) => { + const circle = new Circle({ + style: { + cx: x * 10, + cy: y * 10, + fill: '#C6E5FF', + stroke: '#5B8FF9', + r: size * 10, + lineWidth: 1, + batchKey: 'node', // merge all circles into a single batch + }, + }); + canvas.appendChild(circle); + + const text = new Text({ + style: { + text: label, + fontSize: 12, + fontFamily: 'sans-serif', + fill: '#1890FF', + }, + }); + circle.appendChild(text); + + circle.addEventListener('mouseenter', (e) => { + circle.style.fill = '#2FC25B'; + text.style.fill = 'red'; + }); + + circle.addEventListener('mouseleave', (e) => { + circle.style.fill = '#C6E5FF'; + text.style.fill = '#1890FF'; + }); + }); +})(); + +// stats +const stats = new Stats(); +stats.showPanel(0); +const $stats = stats.dom; +$stats.style.position = 'absolute'; +$stats.style.left = '0px'; +$stats.style.top = '0px'; +const $wrapper = document.getElementById('container'); +$wrapper.appendChild($stats); + +const camera = canvas.getCamera(); +camera.pan(1000, 800); +camera.setZoom(0.05); +canvas.addEventListener(CanvasEvent.AFTER_RENDER, () => { + if (stats) { + stats.update(); + } + // console.log(canvas.getStats()); + + // manipulate camera instead of the root of canvas + camera.rotate(0, 0, 0.1); +}); + +// handle mouse wheel event +const bindWheelHandler = () => { + // update Camera's zoom + // @see https://github.com/mrdoob/three.js/blob/master/examples/jsm/controls/OrbitControls.js + const minZoom = 0; + const maxZoom = Infinity; + canvas + .getContextService() + .getDomElement() // g-canvas/webgl 为 ,g-svg 为 + .addEventListener( + 'wheel', + (e) => { + e.preventDefault(); + let zoom; + if (e.deltaY < 0) { + zoom = Math.max(minZoom, Math.min(maxZoom, camera.getZoom() / 0.95)); + } else { + zoom = Math.max(minZoom, Math.min(maxZoom, camera.getZoom() * 0.95)); + } + camera.setZoom(zoom); + }, + { passive: false }, + ); +}; + +// use hammer.js +const hammer = new Hammer(canvas); +hammer.on('pan', (ev) => { + camera.pan( + -ev.deltaX / Math.pow(2, camera.getZoom()), + -ev.deltaY / Math.pow(2, camera.getZoom()), + ); +}); + +bindWheelHandler(); + +// GUI +const gui = new lil.GUI({ autoPlace: false }); +$wrapper.appendChild(gui.domElement); +const rendererFolder = gui.addFolder('renderer'); +const rendererConfig = { + renderer: 'webgl', +}; +rendererFolder + .add(rendererConfig, 'renderer', ['webgl', 'webgpu']) + .onChange((rendererName) => { + let renderer; + if (rendererName === 'webgl') { + renderer = webglRenderer; + } else if (rendererName === 'webgpu') { + renderer = webgpuRenderer; + } + canvas.setRenderer(renderer); + bindWheelHandler(); + }); +rendererFolder.open(); diff --git a/site/examples/perf/basic/demo/nodes-8k.js b/site/examples/perf/webgl/demo/nodes-8k.js similarity index 72% rename from site/examples/perf/basic/demo/nodes-8k.js rename to site/examples/perf/webgl/demo/nodes-8k.js index 1fc643a9b..916eb1724 100644 --- a/site/examples/perf/basic/demo/nodes-8k.js +++ b/site/examples/perf/webgl/demo/nodes-8k.js @@ -1,15 +1,4 @@ -import { - Canvas, - CanvasEvent, - Circle, - Line, - Image, - Text, - runtime, -} from '@antv/g'; -import { Renderer as CanvasRenderer } from '@antv/g-canvas'; -import { Renderer as CanvaskitRenderer } from '@antv/g-canvaskit'; -import { Renderer as SVGRenderer } from '@antv/g-svg'; +import { Canvas, CanvasEvent, Circle, Line, Text, runtime } from '@antv/g'; import { Renderer as WebGLRenderer } from '@antv/g-webgl'; import { Renderer as WebGPURenderer } from '@antv/g-webgpu'; import Hammer from 'hammerjs'; @@ -19,23 +8,9 @@ import Stats from 'stats.js'; runtime.enableCSSParsing = false; // create a renderer -// enable culling for canvas & svg renderer -const canvasRenderer = new CanvasRenderer({ - enableCulling: true, -}); -const svgRenderer = new SVGRenderer({ - enableCulling: true, -}); const webglRenderer = new WebGLRenderer(); -const webgpuRenderer = new WebGPURenderer(); -const canvaskitRenderer = new CanvaskitRenderer({ - wasmDir: '/', - fonts: [ - { - name: 'sans-serif', - url: 'https://mdn.alipayobjects.com/huamei_qa8qxu/afts/file/A*064aSK2LUPEAAAAAAAAAAAAADmJ7AQ/NotoSansCJKsc-VF.ttf', - }, - ], +const webgpuRenderer = new WebGPURenderer({ + shaderCompilerPath: '/glsl_wgsl_compiler_bg.wasm', }); // create a canvas @@ -129,42 +104,14 @@ const mapNodeSize = (nodes, propertyName, visualRange) => { }); circle.appendChild(text); - let c1; circle.addEventListener('mouseenter', (e) => { circle.style.fill = '#2FC25B'; text.style.fill = 'red'; - - c1 = new Circle({ - style: { - cx: 100, - cy: 100, - r: 1000, - fill: '#2FC25B', - zIndex: -1, - }, - }); - - // c1 = new Image({ - // style: { - // x: 100, - // y: 100, - // width: 1000, - // height: 1000, - // src: 'https://gw.alipayobjects.com/mdn/rms_6ae20b/afts/img/A*N4ZMS7gHsUIAAAAAAAAAAABkARQnAQ', - // zIndex: -1, - // }, - // }); - canvas.appendChild(c1); }); circle.addEventListener('mouseleave', (e) => { circle.style.fill = '#C6E5FF'; text.style.fill = '#1890FF'; - - if (c1) { - canvas.removeChild(c1); - c1 = undefined; - } }); }); })(); @@ -236,27 +183,15 @@ const rendererConfig = { renderer: 'webgl', }; rendererFolder - .add(rendererConfig, 'renderer', [ - 'canvas', - 'svg', - 'webgl', - 'webgpu', - 'canvaskit', - ]) - .onChange(async (rendererName) => { + .add(rendererConfig, 'renderer', ['webgl', 'webgpu']) + .onChange((rendererName) => { let renderer; - if (rendererName === 'canvas') { - renderer = canvasRenderer; - } else if (rendererName === 'svg') { - renderer = svgRenderer; - } else if (rendererName === 'webgl') { + if (rendererName === 'webgl') { renderer = webglRenderer; } else if (rendererName === 'webgpu') { renderer = webgpuRenderer; - } else if (rendererName === 'canvaskit') { - renderer = canvaskitRenderer; } - await canvas.setRenderer(renderer); + canvas.setRenderer(renderer); bindWheelHandler(); }); rendererFolder.open(); diff --git a/site/examples/perf/webgl/demo/one-command-curve.js b/site/examples/perf/webgl/demo/one-command-curve.js new file mode 100644 index 000000000..ea74d0477 --- /dev/null +++ b/site/examples/perf/webgl/demo/one-command-curve.js @@ -0,0 +1,156 @@ +import { Canvas, CanvasEvent, Path } from '@antv/g'; +import { Renderer as WebGLRenderer } from '@antv/g-webgl'; +import * as lil from 'lil-gui'; +import Stats from 'stats.js'; +import { vec2 } from 'gl-matrix'; + +const getControlPoint = (startPoint, endPoint, percent, offset) => { + const point = { + x: (1 - percent) * startPoint.x + percent * endPoint.x, + y: (1 - percent) * startPoint.y + percent * endPoint.y, + }; + + let tangent = [0, 0]; + vec2.normalize(tangent, [ + endPoint.x - startPoint.x, + endPoint.y - startPoint.y, + ]); + + if (!tangent || (!tangent[0] && !tangent[1])) { + tangent = [0, 0]; + } + const perpendicular = [-tangent[1] * offset, tangent[0] * offset]; // 垂直向量 + point.x += perpendicular[0]; + point.y += perpendicular[1]; + return point; +}; + +// create a renderer +const webglRenderer = new WebGLRenderer(); + +// create a canvas +const canvas = new Canvas({ + container: 'container', + width: 600, + height: 500, + renderer: webglRenderer, +}); + +for (let i = 0; i < 5000; i++) { + const p1 = { x: Math.random() * 600 * 2, y: Math.random() * 500 * 2 }; + const p2 = { x: Math.random() * 600 * 2, y: Math.random() * 500 * 2 }; + const cp = getControlPoint(p1, p2, 0.5, 30); + const path = new Path({ + style: { + lineWidth: 1, + lineDash: [10, 10], + stroke: '#54BECC', + d: [ + ['M', p1.x, p1.y], + ['Q', cp.x, cp.y, p2.x, p2.y], + ], + }, + }); + canvas.appendChild(path); + + path.addEventListener('mouseenter', () => { + path.style.stroke = 'red'; + }); + path.addEventListener('mouseleave', () => { + path.style.stroke = '#54BECC'; + }); +} + +for (let i = 0; i < 5000; i++) { + const p1 = { x: Math.random() * 600 * 2, y: Math.random() * 500 * 2 }; + const p2 = { x: Math.random() * 600 * 2, y: Math.random() * 500 * 2 }; + const cp1 = getControlPoint(p1, p2, 0.2, 30); + const cp2 = getControlPoint(p1, p2, 0.8, 30); + const path = new Path({ + style: { + lineWidth: 1, + stroke: '#54BECC', + d: [ + ['M', p1.x, p1.y], + ['C', cp1.x, cp1.y, cp2.x, cp2.y, p2.x, p2.y], + ], + }, + }); + canvas.appendChild(path); + path.addEventListener('mouseenter', () => { + path.style.stroke = 'red'; + }); + path.addEventListener('mouseleave', () => { + path.style.stroke = '#54BECC'; + }); +} +// stats +const stats = new Stats(); +stats.showPanel(0); +const $stats = stats.dom; +$stats.style.position = 'absolute'; +$stats.style.left = '0px'; +$stats.style.top = '0px'; +const $wrapper = document.getElementById('container'); +$wrapper.appendChild($stats); + +const camera = canvas.getCamera(); +canvas.addEventListener(CanvasEvent.AFTER_RENDER, () => { + if (stats) { + stats.update(); + } + + // manipulate camera instead of the root of canvas + camera.rotate(0, 0, 1); +}); + +// update Camera's zoom +// @see https://github.com/mrdoob/three.js/blob/master/examples/jsm/controls/OrbitControls.js +const minZoom = 0; +const maxZoom = Infinity; +canvas + .getContextService() + .getDomElement() // g-canvas/webgl 为 ,g-svg 为 + .addEventListener( + 'wheel', + (e) => { + e.preventDefault(); + let zoom; + if (e.deltaY < 0) { + zoom = Math.max(minZoom, Math.min(maxZoom, camera.getZoom() / 0.95)); + } else { + zoom = Math.max(minZoom, Math.min(maxZoom, camera.getZoom() * 0.95)); + } + camera.setZoom(zoom); + }, + { passive: false }, + ); + +// GUI +const gui = new lil.GUI({ autoPlace: false }); +$wrapper.appendChild(gui.domElement); + +const transformFolder = gui.addFolder('style'); +const transformConfig = { + lineWidth: 1, + lineDash: 10, + lineDashOffset: 0, +}; +transformFolder + .add(transformConfig, 'lineWidth', 0, 20) + .onChange((lineWidth) => { + const paths = canvas.document.querySelectorAll('path'); + paths.forEach((path) => { + path.style.lineWidth = lineWidth; + }); + }); +transformFolder.add(transformConfig, 'lineDash', 0, 50).onChange((dash) => { + const paths = canvas.document.querySelectorAll('path'); + paths[0].style.lineDash = [dash, dash]; +}); +transformFolder + .add(transformConfig, 'lineDashOffset', 0, 50) + .onChange((lineDashOffset) => { + const paths = canvas.document.querySelectorAll('path'); + paths[0].style.lineDashOffset = lineDashOffset; + }); diff --git a/site/examples/perf/basic/demo/rects.js b/site/examples/perf/webgl/demo/rects.js similarity index 69% rename from site/examples/perf/basic/demo/rects.js rename to site/examples/perf/webgl/demo/rects.js index 8256d9e5e..0a676685d 100644 --- a/site/examples/perf/basic/demo/rects.js +++ b/site/examples/perf/webgl/demo/rects.js @@ -1,26 +1,14 @@ import { Canvas, CanvasEvent, Rect } from '@antv/g'; -import { Renderer as CanvasRenderer } from '@antv/g-canvas'; -import { Renderer as CanvaskitRenderer } from '@antv/g-canvaskit'; -import { Renderer as SVGRenderer } from '@antv/g-svg'; import { Renderer as WebGLRenderer } from '@antv/g-webgl'; import { Renderer as WebGPURenderer } from '@antv/g-webgpu'; import * as lil from 'lil-gui'; import Stats from 'stats.js'; // create a renderer -const canvasRenderer = new CanvasRenderer(); const webglRenderer = new WebGLRenderer(); -const svgRenderer = new SVGRenderer(); -const canvaskitRenderer = new CanvaskitRenderer({ - wasmDir: '/', - fonts: [ - { - name: 'sans-serif', - url: 'https://mdn.alipayobjects.com/huamei_qa8qxu/afts/file/A*064aSK2LUPEAAAAAAAAAAAAADmJ7AQ/NotoSansCJKsc-VF.ttf', - }, - ], +const webgpuRenderer = new WebGPURenderer({ + shaderCompilerPath: '/glsl_wgsl_compiler_bg.wasm', }); -const webgpuRenderer = new WebGPURenderer(); // create a canvas const canvas = new Canvas({ @@ -31,14 +19,16 @@ const canvas = new Canvas({ }); canvas.addEventListener(CanvasEvent.READY, () => { - for (let i = 0; i < 20; i++) { + for (let i = 0; i < 5000; i++) { const rect = new Rect({ style: { x: Math.random() * 600, y: Math.random() * 500, width: Math.random() * 100, height: Math.random() * 100, - fill: 'red', + fill: '#C6E5FF', + stroke: '#5B8FF9', + lineWidth: 1, }, }); canvas.appendChild(rect); @@ -95,25 +85,13 @@ const rendererConfig = { renderer: 'webgl', }; rendererFolder - .add(rendererConfig, 'renderer', [ - 'canvas', - 'svg', - 'webgl', - 'webgpu', - 'canvaskit', - ]) + .add(rendererConfig, 'renderer', ['webgl', 'webgpu']) .onChange((rendererName) => { let renderer; - if (rendererName === 'canvas') { - renderer = canvasRenderer; - } else if (rendererName === 'svg') { - renderer = svgRenderer; - } else if (rendererName === 'webgl') { + if (rendererName === 'webgl') { renderer = webglRenderer; } else if (rendererName === 'webgpu') { renderer = webgpuRenderer; - } else if (rendererName === 'canvaskit') { - renderer = canvaskitRenderer; } canvas.setRenderer(renderer); }); diff --git a/site/examples/perf/basic/demo/texts.js b/site/examples/perf/webgl/demo/texts.js similarity index 70% rename from site/examples/perf/basic/demo/texts.js rename to site/examples/perf/webgl/demo/texts.js index d07ad3520..9fa83df0e 100644 --- a/site/examples/perf/basic/demo/texts.js +++ b/site/examples/perf/webgl/demo/texts.js @@ -1,26 +1,14 @@ import { Canvas, CanvasEvent, Text } from '@antv/g'; -import { Renderer as CanvasRenderer } from '@antv/g-canvas'; -import { Renderer as CanvaskitRenderer } from '@antv/g-canvaskit'; -import { Renderer as SVGRenderer } from '@antv/g-svg'; import { Renderer as WebGLRenderer } from '@antv/g-webgl'; import { Renderer as WebGPURenderer } from '@antv/g-webgpu'; import * as lil from 'lil-gui'; import Stats from 'stats.js'; // create a renderer -const canvasRenderer = new CanvasRenderer(); const webglRenderer = new WebGLRenderer(); -const svgRenderer = new SVGRenderer(); -const canvaskitRenderer = new CanvaskitRenderer({ - wasmDir: '/', - fonts: [ - { - name: 'sans-serif', - url: 'https://mdn.alipayobjects.com/huamei_qa8qxu/afts/file/A*064aSK2LUPEAAAAAAAAAAAAADmJ7AQ/NotoSansCJKsc-VF.ttf', - }, - ], +const webgpuRenderer = new WebGPURenderer({ + shaderCompilerPath: '/glsl_wgsl_compiler_bg.wasm', }); -const webgpuRenderer = new WebGPURenderer(); // create a canvas const canvas = new Canvas({ @@ -31,7 +19,8 @@ const canvas = new Canvas({ }); canvas.addEventListener(CanvasEvent.READY, () => { - for (let i = 0; i < 100; i++) { + // Different fontSize + for (let i = 0; i < 50; i++) { const text = new Text({ style: { x: Math.random() * 600, @@ -44,6 +33,21 @@ canvas.addEventListener(CanvasEvent.READY, () => { }); canvas.appendChild(text); } + + // Different content but with the same fontsize. + for (let i = 0; i < 5000; i++) { + const text = new Text({ + style: { + x: Math.random() * 600, + y: Math.random() * 500, + fontFamily: 'PingFang SC', + text: '测试文本' + i, + fontSize: 6, + fill: 'green', + }, + }); + canvas.appendChild(text); + } }); // stats @@ -96,25 +100,13 @@ const rendererConfig = { renderer: 'webgl', }; rendererFolder - .add(rendererConfig, 'renderer', [ - 'canvas', - 'svg', - 'webgl', - 'webgpu', - 'canvaskit', - ]) + .add(rendererConfig, 'renderer', ['webgl', 'webgpu']) .onChange((rendererName) => { let renderer; - if (rendererName === 'canvas') { - renderer = canvasRenderer; - } else if (rendererName === 'svg') { - renderer = svgRenderer; - } else if (rendererName === 'webgl') { + if (rendererName === 'webgl') { renderer = webglRenderer; } else if (rendererName === 'webgpu') { renderer = webgpuRenderer; - } else if (rendererName === 'canvaskit') { - renderer = canvaskitRenderer; } canvas.setRenderer(renderer); }); diff --git a/site/examples/perf/webgl/index.en.md b/site/examples/perf/webgl/index.en.md new file mode 100644 index 000000000..4791686c2 --- /dev/null +++ b/site/examples/perf/webgl/index.en.md @@ -0,0 +1,4 @@ +--- +title: Performance of WebGL +order: 1 +--- diff --git a/site/examples/perf/webgl/index.zh.md b/site/examples/perf/webgl/index.zh.md new file mode 100644 index 000000000..fc8f5db60 --- /dev/null +++ b/site/examples/perf/webgl/index.zh.md @@ -0,0 +1,4 @@ +--- +title: WebGL 性能 +order: 1 +--- diff --git a/site/examples/plugins/a11y/demo/a11y-keyboard-navigation.js b/site/examples/plugins/a11y/demo/a11y-keyboard-navigation.js index bc224433d..eda107199 100644 --- a/site/examples/plugins/a11y/demo/a11y-keyboard-navigation.js +++ b/site/examples/plugins/a11y/demo/a11y-keyboard-navigation.js @@ -21,7 +21,9 @@ import Stats from 'stats.js'; const canvasRenderer = new CanvasRenderer(); const svgRenderer = new SVGRenderer(); const webglRenderer = new WebGLRenderer(); -const webgpuRenderer = new WebGPURenderer(); +const webgpuRenderer = new WebGPURenderer({ + shaderCompilerPath: '/glsl_wgsl_compiler_bg.wasm', +}); const canvaskitRenderer = new CanvaskitRenderer({ wasmDir: '/', fonts: [ diff --git a/site/examples/plugins/a11y/demo/a11y-text-extractor.js b/site/examples/plugins/a11y/demo/a11y-text-extractor.js index aeb67a9a9..c990263b5 100644 --- a/site/examples/plugins/a11y/demo/a11y-text-extractor.js +++ b/site/examples/plugins/a11y/demo/a11y-text-extractor.js @@ -21,7 +21,9 @@ import Stats from 'stats.js'; const canvasRenderer = new CanvasRenderer(); const svgRenderer = new SVGRenderer(); const webglRenderer = new WebGLRenderer(); -const webgpuRenderer = new WebGPURenderer(); +const webgpuRenderer = new WebGPURenderer({ + shaderCompilerPath: '/glsl_wgsl_compiler_bg.wasm', +}); const canvaskitRenderer = new CanvaskitRenderer({ wasmDir: '/', fonts: [ diff --git a/site/examples/plugins/annotation/demo/annotation.js b/site/examples/plugins/annotation/demo/annotation.js index e092c976c..6bbd66bdc 100644 --- a/site/examples/plugins/annotation/demo/annotation.js +++ b/site/examples/plugins/annotation/demo/annotation.js @@ -23,7 +23,9 @@ import Stats from 'stats.js'; const canvasRenderer = new CanvasRenderer(); const svgRenderer = new SVGRenderer(); const webglRenderer = new WebGLRenderer(); -const webgpuRenderer = new WebGPURenderer(); +const webgpuRenderer = new WebGPURenderer({ + shaderCompilerPath: '/glsl_wgsl_compiler_bg.wasm', +}); const canvaskitRenderer = new CanvaskitRenderer({ wasmDir: '/', fonts: [ diff --git a/site/examples/plugins/annotation/demo/selectable-image.js b/site/examples/plugins/annotation/demo/selectable-image.js index b3f6ec6f8..2bf1cb7fb 100644 --- a/site/examples/plugins/annotation/demo/selectable-image.js +++ b/site/examples/plugins/annotation/demo/selectable-image.js @@ -13,7 +13,9 @@ import Stats from 'stats.js'; const canvasRenderer = new CanvasRenderer(); const svgRenderer = new SVGRenderer(); const webglRenderer = new WebGLRenderer(); -const webgpuRenderer = new WebGPURenderer(); +const webgpuRenderer = new WebGPURenderer({ + shaderCompilerPath: '/glsl_wgsl_compiler_bg.wasm', +}); const canvaskitRenderer = new CanvaskitRenderer({ wasmDir: '/', fonts: [ diff --git a/site/examples/plugins/dragndrop/demo/dragndrop.js b/site/examples/plugins/dragndrop/demo/dragndrop.js index 7cc2e8983..69fd2d52f 100644 --- a/site/examples/plugins/dragndrop/demo/dragndrop.js +++ b/site/examples/plugins/dragndrop/demo/dragndrop.js @@ -58,7 +58,7 @@ canvas.addEventListener(CanvasEvent.READY, () => { y: 100, width: 200, height: 100, - src: 'https://en.js.cx/clipart/soccer-gate.svg', + src: 'https://mdn.alipayobjects.com/huamei_qa8qxu/afts/img/A*wLJaQ4EuUSYAAAAAAAAAAAAADmJ7AQ/original', }, }); @@ -69,7 +69,7 @@ canvas.addEventListener(CanvasEvent.READY, () => { y: 200, width: 100, height: 100, - src: 'https://en.js.cx/clipart/ball.svg', + src: 'https://mdn.alipayobjects.com/huamei_qa8qxu/afts/img/A*StLOQqlKYr0AAAAAAAAAAAAADmJ7AQ/original', cursor: 'pointer', }, }); diff --git a/site/examples/plugins/physics-engine/demo/physx.js b/site/examples/plugins/physics-engine/demo/physx.js index 16a5fdaad..a4f2f5a8d 100644 --- a/site/examples/plugins/physics-engine/demo/physx.js +++ b/site/examples/plugins/physics-engine/demo/physx.js @@ -25,6 +25,10 @@ const canvas = new Canvas({ renderer, }); +// adjust camera's position +const camera = canvas.getCamera(); +camera.setPerspective(0.1, 5000, 45, 600 / 500); + (async () => { await canvas.ready; const plugin = renderer.getPlugin('device-renderer'); @@ -34,11 +38,13 @@ const canvas = new Canvas({ ); const planeGeometry = new CubeGeometry(device, { - width: 200, - height: 200, - depth: 200, + width: 500, + height: 20, + depth: 500, + }); + const planeMaterial = new MeshBasicMaterial(device, { + wireframe: true, }); - const planeMaterial = new MeshBasicMaterial(device); const plane = new Mesh({ style: { fill: '#1890FF', @@ -47,16 +53,26 @@ const canvas = new Canvas({ rigid: 'static', }, }); + plane.setPosition(300, 400, 0); canvas.appendChild(plane); - plane.setPosition(300, 250, 0); + + const plane2 = new Mesh({ + style: { + fill: '#1890FF', + geometry: planeGeometry, + material: planeMaterial, + rigid: 'static', + }, + }); + plane2.setPosition(300, 100, 0); + canvas.appendChild(plane2); const cubeGeometry = new CubeGeometry(device, { - width: 200, - height: 200, - depth: 200, + width: 100, + height: 100, + depth: 100, }); const basicMaterial = new MeshBasicMaterial(device, { - // wireframe: true, map, }); @@ -68,9 +84,7 @@ const canvas = new Canvas({ rigid: 'dynamic', }, }); - - cube.setPosition(300, 250, 0); - + cube.setPosition(300, -50, 0); canvas.appendChild(cube); // stats diff --git a/site/examples/plugins/yoga/demo/yoga-container.js b/site/examples/plugins/yoga/demo/yoga-container.js index 0a94e64f0..d3026be2a 100644 --- a/site/examples/plugins/yoga/demo/yoga-container.js +++ b/site/examples/plugins/yoga/demo/yoga-container.js @@ -20,7 +20,9 @@ const canvaskitRenderer = new CanvaskitRenderer({ }, ], }); -const webgpuRenderer = new WebGPURenderer(); +const webgpuRenderer = new WebGPURenderer({ + shaderCompilerPath: '/glsl_wgsl_compiler_bg.wasm', +}); const plugin = new PluginYoga(); diff --git a/site/examples/plugins/zdog/demo/zdog.js b/site/examples/plugins/zdog/demo/zdog.js index 439162259..1a706c4ff 100644 --- a/site/examples/plugins/zdog/demo/zdog.js +++ b/site/examples/plugins/zdog/demo/zdog.js @@ -17,7 +17,7 @@ const canvas = new Canvas({ container: 'container', width: 600, height: 500, - renderer: svgRenderer, + renderer: canvasRenderer, }); canvas.addEventListener(CanvasEvent.READY, () => { diff --git a/site/examples/scenegraph/basic/demo/boxmodel.js b/site/examples/scenegraph/basic/demo/boxmodel.js index 30185075d..1eba040dc 100644 --- a/site/examples/scenegraph/basic/demo/boxmodel.js +++ b/site/examples/scenegraph/basic/demo/boxmodel.js @@ -30,7 +30,9 @@ const canvaskitRenderer = new CanvaskitRenderer({ }, ], }); -const webgpuRenderer = new WebGPURenderer(); +const webgpuRenderer = new WebGPURenderer({ + shaderCompilerPath: '/glsl_wgsl_compiler_bg.wasm', +}); // create a canvas const canvas = new Canvas({ diff --git a/site/examples/scenegraph/basic/demo/change-z-index.js b/site/examples/scenegraph/basic/demo/change-z-index.js index bd57c9188..91a7db8f3 100644 --- a/site/examples/scenegraph/basic/demo/change-z-index.js +++ b/site/examples/scenegraph/basic/demo/change-z-index.js @@ -11,7 +11,9 @@ import Stats from 'stats.js'; const canvasRenderer = new CanvasRenderer(); const svgRenderer = new SVGRenderer(); const webglRenderer = new WebGLRenderer(); -const webgpuRenderer = new WebGPURenderer(); +const webgpuRenderer = new WebGPURenderer({ + shaderCompilerPath: '/glsl_wgsl_compiler_bg.wasm', +}); const canvaskitRenderer = new CanvaskitRenderer({ wasmDir: '/', fonts: [ diff --git a/site/examples/scenegraph/basic/demo/hierarchy.js b/site/examples/scenegraph/basic/demo/hierarchy.js index 7325360ec..30d5d2899 100644 --- a/site/examples/scenegraph/basic/demo/hierarchy.js +++ b/site/examples/scenegraph/basic/demo/hierarchy.js @@ -34,7 +34,9 @@ const canvaskitRenderer = new CanvaskitRenderer({ }, ], }); -const webgpuRenderer = new WebGPURenderer(); +const webgpuRenderer = new WebGPURenderer({ + shaderCompilerPath: '/glsl_wgsl_compiler_bg.wasm', +}); // create a canvas const canvas = new Canvas({ diff --git a/site/examples/scenegraph/basic/demo/origin.js b/site/examples/scenegraph/basic/demo/origin.js index 4f5a548bb..8e9b7894e 100644 --- a/site/examples/scenegraph/basic/demo/origin.js +++ b/site/examples/scenegraph/basic/demo/origin.js @@ -28,7 +28,9 @@ const canvaskitRenderer = new CanvaskitRenderer({ }, ], }); -const webgpuRenderer = new WebGPURenderer(); +const webgpuRenderer = new WebGPURenderer({ + shaderCompilerPath: '/glsl_wgsl_compiler_bg.wasm', +}); // create a canvas const canvas = new Canvas({ diff --git a/site/examples/scenegraph/basic/demo/transform.js b/site/examples/scenegraph/basic/demo/transform.js index 002781920..3536f7b4b 100644 --- a/site/examples/scenegraph/basic/demo/transform.js +++ b/site/examples/scenegraph/basic/demo/transform.js @@ -20,7 +20,9 @@ const canvaskitRenderer = new CanvaskitRenderer({ }, ], }); -const webgpuRenderer = new WebGPURenderer(); +const webgpuRenderer = new WebGPURenderer({ + shaderCompilerPath: '/glsl_wgsl_compiler_bg.wasm', +}); // create a canvas const canvas = new Canvas({ diff --git a/site/examples/scenegraph/basic/demo/visibility.js b/site/examples/scenegraph/basic/demo/visibility.js index 252449913..e3660d52c 100644 --- a/site/examples/scenegraph/basic/demo/visibility.js +++ b/site/examples/scenegraph/basic/demo/visibility.js @@ -34,7 +34,9 @@ const canvaskitRenderer = new CanvaskitRenderer({ }, ], }); -const webgpuRenderer = new WebGPURenderer(); +const webgpuRenderer = new WebGPURenderer({ + shaderCompilerPath: '/glsl_wgsl_compiler_bg.wasm', +}); // create a canvas const canvas = new Canvas({ diff --git a/site/examples/scenegraph/basic/demo/z-index.js b/site/examples/scenegraph/basic/demo/z-index.js index d875bd905..679ae3d00 100644 --- a/site/examples/scenegraph/basic/demo/z-index.js +++ b/site/examples/scenegraph/basic/demo/z-index.js @@ -24,7 +24,9 @@ const canvaskitRenderer = new CanvaskitRenderer({ }, ], }); -const webgpuRenderer = new WebGPURenderer(); +const webgpuRenderer = new WebGPURenderer({ + shaderCompilerPath: '/glsl_wgsl_compiler_bg.wasm', +}); // create a canvas const canvas = new Canvas({ diff --git a/site/examples/shape/circle/demo/circle.js b/site/examples/shape/circle/demo/circle.js index ee7326bc6..aa9998c2a 100644 --- a/site/examples/shape/circle/demo/circle.js +++ b/site/examples/shape/circle/demo/circle.js @@ -11,7 +11,9 @@ import Stats from 'stats.js'; const canvasRenderer = new CanvasRenderer(); const svgRenderer = new SVGRenderer(); const webglRenderer = new WebGLRenderer(); -const webgpuRenderer = new WebGPURenderer(); +const webgpuRenderer = new WebGPURenderer({ + shaderCompilerPath: '/glsl_wgsl_compiler_bg.wasm', +}); const canvaskitRenderer = new CanvaskitRenderer({ wasmDir: '/', fonts: [ diff --git a/site/examples/shape/circle/demo/filter.js b/site/examples/shape/circle/demo/filter.js index 926e29e5d..cc7b47160 100644 --- a/site/examples/shape/circle/demo/filter.js +++ b/site/examples/shape/circle/demo/filter.js @@ -22,7 +22,9 @@ const canvaskitRenderer = new CanvaskitRenderer({ }, ], }); -const webgpuRenderer = new WebGPURenderer(); +const webgpuRenderer = new WebGPURenderer({ + shaderCompilerPath: '/glsl_wgsl_compiler_bg.wasm', +}); // create a canvas const canvas = new Canvas({ diff --git a/site/examples/shape/circle/demo/gradient.js b/site/examples/shape/circle/demo/gradient.js index e2d725152..15678a83d 100644 --- a/site/examples/shape/circle/demo/gradient.js +++ b/site/examples/shape/circle/demo/gradient.js @@ -29,7 +29,9 @@ const canvaskitRenderer = new CanvaskitRenderer({ }, ], }); -const webgpuRenderer = new WebGPURenderer(); +const webgpuRenderer = new WebGPURenderer({ + shaderCompilerPath: '/glsl_wgsl_compiler_bg.wasm', +}); // create a canvas const canvas = new Canvas({ diff --git a/site/examples/shape/custom-element/demo/arrow.js b/site/examples/shape/custom-element/demo/arrow.js index ee36492ab..fbbfd077b 100644 --- a/site/examples/shape/custom-element/demo/arrow.js +++ b/site/examples/shape/custom-element/demo/arrow.js @@ -25,7 +25,9 @@ const svgRenderer = new SVGRenderer(); const canvaskitRenderer = new CanvaskitRenderer({ wasmDir: '/', }); -const webgpuRenderer = new WebGPURenderer(); +const webgpuRenderer = new WebGPURenderer({ + shaderCompilerPath: '/glsl_wgsl_compiler_bg.wasm', +}); canvasRenderer.registerPlugin(new Plugin()); diff --git a/site/examples/shape/custom-element/demo/custom-element.js b/site/examples/shape/custom-element/demo/custom-element.js index 43325e312..4903a98c6 100644 --- a/site/examples/shape/custom-element/demo/custom-element.js +++ b/site/examples/shape/custom-element/demo/custom-element.js @@ -17,7 +17,9 @@ import Stats from 'stats.js'; const canvasRenderer = new CanvasRenderer(); const svgRenderer = new SVGRenderer(); const webglRenderer = new WebGLRenderer(); -const webgpuRenderer = new WebGPURenderer(); +const webgpuRenderer = new WebGPURenderer({ + shaderCompilerPath: '/glsl_wgsl_compiler_bg.wasm', +}); // create a canvas const canvas = new Canvas({ diff --git a/site/examples/shape/ellipse/demo/ellipse.js b/site/examples/shape/ellipse/demo/ellipse.js index 447393ff4..2d0b98ac8 100644 --- a/site/examples/shape/ellipse/demo/ellipse.js +++ b/site/examples/shape/ellipse/demo/ellipse.js @@ -24,7 +24,9 @@ const canvaskitRenderer = new CanvaskitRenderer({ }, ], }); -const webgpuRenderer = new WebGPURenderer(); +const webgpuRenderer = new WebGPURenderer({ + shaderCompilerPath: '/glsl_wgsl_compiler_bg.wasm', +}); // create a canvas const canvas = new Canvas({ diff --git a/site/examples/shape/html/demo/html.js b/site/examples/shape/html/demo/html.js index 3ebb86165..a2edd7a3f 100644 --- a/site/examples/shape/html/demo/html.js +++ b/site/examples/shape/html/demo/html.js @@ -32,7 +32,9 @@ const canvaskitRenderer = new CanvaskitRenderer({ }, ], }); -const webgpuRenderer = new WebGPURenderer(); +const webgpuRenderer = new WebGPURenderer({ + shaderCompilerPath: '/glsl_wgsl_compiler_bg.wasm', +}); // create a canvas const canvas = new Canvas({ diff --git a/site/examples/shape/image/demo/image.js b/site/examples/shape/image/demo/image.js index ba4088f70..9c8c8d2b1 100644 --- a/site/examples/shape/image/demo/image.js +++ b/site/examples/shape/image/demo/image.js @@ -24,7 +24,9 @@ const canvaskitRenderer = new CanvaskitRenderer({ }, ], }); -const webgpuRenderer = new WebGPURenderer(); +const webgpuRenderer = new WebGPURenderer({ + shaderCompilerPath: '/glsl_wgsl_compiler_bg.wasm', +}); // create a canvas const canvas = new Canvas({ diff --git a/site/examples/shape/line/demo/line.js b/site/examples/shape/line/demo/line.js index be304d6f6..207a02efb 100644 --- a/site/examples/shape/line/demo/line.js +++ b/site/examples/shape/line/demo/line.js @@ -24,7 +24,9 @@ const canvaskitRenderer = new CanvaskitRenderer({ }, ], }); -const webgpuRenderer = new WebGPURenderer(); +const webgpuRenderer = new WebGPURenderer({ + shaderCompilerPath: '/glsl_wgsl_compiler_bg.wasm', +}); // create a canvas const canvas = new Canvas({ diff --git a/site/examples/shape/path/demo/a-command.js b/site/examples/shape/path/demo/a-command.js index 471da73b5..68c5b20e2 100644 --- a/site/examples/shape/path/demo/a-command.js +++ b/site/examples/shape/path/demo/a-command.js @@ -13,7 +13,9 @@ const svgRenderer = new SVGRenderer(); const canvaskitRenderer = new CanvaskitRenderer({ wasmDir: '/', }); -const webgpuRenderer = new WebGPURenderer(); +const webgpuRenderer = new WebGPURenderer({ + shaderCompilerPath: '/glsl_wgsl_compiler_bg.wasm', +}); const canvas = new Canvas({ container: 'container', diff --git a/site/examples/shape/path/demo/get-point.js b/site/examples/shape/path/demo/get-point.js index c91c81774..5cd0d35f7 100644 --- a/site/examples/shape/path/demo/get-point.js +++ b/site/examples/shape/path/demo/get-point.js @@ -13,7 +13,9 @@ const svgRenderer = new SVGRenderer(); const canvaskitRenderer = new CanvaskitRenderer({ wasmDir: '/', }); -const webgpuRenderer = new WebGPURenderer(); +const webgpuRenderer = new WebGPURenderer({ + shaderCompilerPath: '/glsl_wgsl_compiler_bg.wasm', +}); const canvas = new Canvas({ container: 'container', diff --git a/site/examples/shape/path/demo/group.js b/site/examples/shape/path/demo/group.js index 858a227c7..b8cdd456b 100644 --- a/site/examples/shape/path/demo/group.js +++ b/site/examples/shape/path/demo/group.js @@ -13,7 +13,9 @@ const svgRenderer = new SVGRenderer(); const canvaskitRenderer = new CanvaskitRenderer({ wasmDir: '/', }); -const webgpuRenderer = new WebGPURenderer(); +const webgpuRenderer = new WebGPURenderer({ + shaderCompilerPath: '/glsl_wgsl_compiler_bg.wasm', +}); const canvas = new Canvas({ container: 'container', diff --git a/site/examples/shape/path/demo/l-command.js b/site/examples/shape/path/demo/l-command.js index 5033261df..083fb59e0 100644 --- a/site/examples/shape/path/demo/l-command.js +++ b/site/examples/shape/path/demo/l-command.js @@ -14,7 +14,9 @@ const svgRenderer = new SVGRenderer(); const canvaskitRenderer = new CanvaskitRenderer({ wasmDir: '/', }); -const webgpuRenderer = new WebGPURenderer(); +const webgpuRenderer = new WebGPURenderer({ + shaderCompilerPath: '/glsl_wgsl_compiler_bg.wasm', +}); const canvas = new Canvas({ container: 'container', diff --git a/site/examples/shape/path/demo/marker.js b/site/examples/shape/path/demo/marker.js index 83071e23d..c689a5e3c 100644 --- a/site/examples/shape/path/demo/marker.js +++ b/site/examples/shape/path/demo/marker.js @@ -13,7 +13,9 @@ const svgRenderer = new SVGRenderer(); const canvaskitRenderer = new CanvaskitRenderer({ wasmDir: '/', }); -const webgpuRenderer = new WebGPURenderer(); +const webgpuRenderer = new WebGPURenderer({ + shaderCompilerPath: '/glsl_wgsl_compiler_bg.wasm', +}); const canvas = new Canvas({ container: 'container', diff --git a/site/examples/shape/path/demo/multi-segments.js b/site/examples/shape/path/demo/multi-segments.js index 05b855bdb..5331435c2 100644 --- a/site/examples/shape/path/demo/multi-segments.js +++ b/site/examples/shape/path/demo/multi-segments.js @@ -13,7 +13,9 @@ const svgRenderer = new SVGRenderer(); const canvaskitRenderer = new CanvaskitRenderer({ wasmDir: '/', }); -const webgpuRenderer = new WebGPURenderer(); +const webgpuRenderer = new WebGPURenderer({ + shaderCompilerPath: '/glsl_wgsl_compiler_bg.wasm', +}); const canvas = new Canvas({ container: 'container', diff --git a/site/examples/shape/path/demo/path.js b/site/examples/shape/path/demo/path.js index 8a8e0072e..2f4ae1176 100644 --- a/site/examples/shape/path/demo/path.js +++ b/site/examples/shape/path/demo/path.js @@ -14,7 +14,9 @@ const svgRenderer = new SVGRenderer(); const canvaskitRenderer = new CanvaskitRenderer({ wasmDir: '/', }); -const webgpuRenderer = new WebGPURenderer(); +const webgpuRenderer = new WebGPURenderer({ + shaderCompilerPath: '/glsl_wgsl_compiler_bg.wasm', +}); const canvas = new Canvas({ container: 'container', diff --git a/site/examples/shape/path/demo/picking.js b/site/examples/shape/path/demo/picking.js index de4681daa..e1dcbf531 100644 --- a/site/examples/shape/path/demo/picking.js +++ b/site/examples/shape/path/demo/picking.js @@ -13,7 +13,9 @@ const svgRenderer = new SVGRenderer(); const canvaskitRenderer = new CanvaskitRenderer({ wasmDir: '/', }); -const webgpuRenderer = new WebGPURenderer(); +const webgpuRenderer = new WebGPURenderer({ + shaderCompilerPath: '/glsl_wgsl_compiler_bg.wasm', +}); const canvas = new Canvas({ container: 'container', diff --git a/site/examples/shape/polygon/demo/fillrule.js b/site/examples/shape/polygon/demo/fillrule.js index 1011fb73a..298763156 100644 --- a/site/examples/shape/polygon/demo/fillrule.js +++ b/site/examples/shape/polygon/demo/fillrule.js @@ -24,7 +24,9 @@ const canvaskitRenderer = new CanvaskitRenderer({ }, ], }); -const webgpuRenderer = new WebGPURenderer(); +const webgpuRenderer = new WebGPURenderer({ + shaderCompilerPath: '/glsl_wgsl_compiler_bg.wasm', +}); // create a canvas const canvas = new Canvas({ diff --git a/site/examples/shape/polygon/demo/marker.js b/site/examples/shape/polygon/demo/marker.js index 6120d0574..6e7da3bf7 100644 --- a/site/examples/shape/polygon/demo/marker.js +++ b/site/examples/shape/polygon/demo/marker.js @@ -24,7 +24,9 @@ const canvaskitRenderer = new CanvaskitRenderer({ }, ], }); -const webgpuRenderer = new WebGPURenderer(); +const webgpuRenderer = new WebGPURenderer({ + shaderCompilerPath: '/glsl_wgsl_compiler_bg.wasm', +}); // create a canvas const canvas = new Canvas({ diff --git a/site/examples/shape/polygon/demo/polygon.js b/site/examples/shape/polygon/demo/polygon.js index c5b620b05..2e581b81d 100644 --- a/site/examples/shape/polygon/demo/polygon.js +++ b/site/examples/shape/polygon/demo/polygon.js @@ -24,7 +24,9 @@ const canvaskitRenderer = new CanvaskitRenderer({ }, ], }); -const webgpuRenderer = new WebGPURenderer(); +const webgpuRenderer = new WebGPURenderer({ + shaderCompilerPath: '/glsl_wgsl_compiler_bg.wasm', +}); // create a canvas const canvas = new Canvas({ diff --git a/site/examples/shape/polyline/demo/marker.js b/site/examples/shape/polyline/demo/marker.js index 0eed6ecfa..3fe288a8b 100644 --- a/site/examples/shape/polyline/demo/marker.js +++ b/site/examples/shape/polyline/demo/marker.js @@ -24,7 +24,9 @@ const canvaskitRenderer = new CanvaskitRenderer({ }, ], }); -const webgpuRenderer = new WebGPURenderer(); +const webgpuRenderer = new WebGPURenderer({ + shaderCompilerPath: '/glsl_wgsl_compiler_bg.wasm', +}); // create a canvas const canvas = new Canvas({ diff --git a/site/examples/shape/polyline/demo/polyline.js b/site/examples/shape/polyline/demo/polyline.js index 0c80a6c8c..1fc8a8926 100644 --- a/site/examples/shape/polyline/demo/polyline.js +++ b/site/examples/shape/polyline/demo/polyline.js @@ -24,7 +24,9 @@ const canvaskitRenderer = new CanvaskitRenderer({ }, ], }); -const webgpuRenderer = new WebGPURenderer(); +const webgpuRenderer = new WebGPURenderer({ + shaderCompilerPath: '/glsl_wgsl_compiler_bg.wasm', +}); // create a canvas const canvas = new Canvas({ diff --git a/site/examples/shape/rect/demo/rect.js b/site/examples/shape/rect/demo/rect.js index f07e5504d..df592f28e 100644 --- a/site/examples/shape/rect/demo/rect.js +++ b/site/examples/shape/rect/demo/rect.js @@ -24,7 +24,9 @@ const canvaskitRenderer = new CanvaskitRenderer({ }, ], }); -const webgpuRenderer = new WebGPURenderer(); +const webgpuRenderer = new WebGPURenderer({ + shaderCompilerPath: '/glsl_wgsl_compiler_bg.wasm', +}); // create a canvas const canvas = new Canvas({ diff --git a/site/examples/shape/text/demo/d3-word-cloud.js b/site/examples/shape/text/demo/d3-word-cloud.js index 0bf2e4991..9dc96654d 100644 --- a/site/examples/shape/text/demo/d3-word-cloud.js +++ b/site/examples/shape/text/demo/d3-word-cloud.js @@ -35,7 +35,9 @@ const canvaskitRenderer = new CanvaskitRenderer({ }, ], }); -const webgpuRenderer = new WebGPURenderer(); +const webgpuRenderer = new WebGPURenderer({ + shaderCompilerPath: '/glsl_wgsl_compiler_bg.wasm', +}); // create a canvas const canvas = new Canvas({ diff --git a/site/examples/shape/text/demo/text-baseline.js b/site/examples/shape/text/demo/text-baseline.js index 29a6ec073..ad0542778 100644 --- a/site/examples/shape/text/demo/text-baseline.js +++ b/site/examples/shape/text/demo/text-baseline.js @@ -22,7 +22,9 @@ const canvaskitRenderer = new CanvaskitRenderer({ }, ], }); -const webgpuRenderer = new WebGPURenderer(); +const webgpuRenderer = new WebGPURenderer({ + shaderCompilerPath: '/glsl_wgsl_compiler_bg.wasm', +}); // create a canvas const canvas = new Canvas({ diff --git a/site/examples/shape/text/demo/text-overflow.js b/site/examples/shape/text/demo/text-overflow.js index 576454fbd..a67bafe5d 100644 --- a/site/examples/shape/text/demo/text-overflow.js +++ b/site/examples/shape/text/demo/text-overflow.js @@ -20,7 +20,9 @@ const canvaskitRenderer = new CanvaskitRenderer({ }, ], }); -const webgpuRenderer = new WebGPURenderer(); +const webgpuRenderer = new WebGPURenderer({ + shaderCompilerPath: '/glsl_wgsl_compiler_bg.wasm', +}); // create a canvas const canvas = new Canvas({ diff --git a/site/examples/shape/text/demo/text.js b/site/examples/shape/text/demo/text.js index f9e5103a2..5904dde05 100644 --- a/site/examples/shape/text/demo/text.js +++ b/site/examples/shape/text/demo/text.js @@ -20,7 +20,9 @@ const canvaskitRenderer = new CanvaskitRenderer({ }, ], }); -const webgpuRenderer = new WebGPURenderer(); +const webgpuRenderer = new WebGPURenderer({ + shaderCompilerPath: '/glsl_wgsl_compiler_bg.wasm', +}); // create a canvas const canvas = new Canvas({ diff --git a/site/examples/shape/text/demo/web-font-loader.js b/site/examples/shape/text/demo/web-font-loader.js index 0b90339ff..8f8ca096d 100644 --- a/site/examples/shape/text/demo/web-font-loader.js +++ b/site/examples/shape/text/demo/web-font-loader.js @@ -21,7 +21,9 @@ const canvaskitRenderer = new CanvaskitRenderer({ }, ], }); -const webgpuRenderer = new WebGPURenderer(); +const webgpuRenderer = new WebGPURenderer({ + shaderCompilerPath: '/glsl_wgsl_compiler_bg.wasm', +}); // create a canvas const canvas = new Canvas({ diff --git a/site/examples/style/basic/demo/color.js b/site/examples/style/basic/demo/color.js index 644d8f938..04c5d6b36 100644 --- a/site/examples/style/basic/demo/color.js +++ b/site/examples/style/basic/demo/color.js @@ -25,7 +25,9 @@ const canvaskitRenderer = new CanvaskitRenderer({ }, ], }); -const webgpuRenderer = new WebGPURenderer(); +const webgpuRenderer = new WebGPURenderer({ + shaderCompilerPath: '/glsl_wgsl_compiler_bg.wasm', +}); // create a canvas const canvas = new Canvas({ diff --git a/site/examples/style/basic/demo/custom-property.js b/site/examples/style/basic/demo/custom-property.js index 43325e312..4903a98c6 100644 --- a/site/examples/style/basic/demo/custom-property.js +++ b/site/examples/style/basic/demo/custom-property.js @@ -17,7 +17,9 @@ import Stats from 'stats.js'; const canvasRenderer = new CanvasRenderer(); const svgRenderer = new SVGRenderer(); const webglRenderer = new WebGLRenderer(); -const webgpuRenderer = new WebGPURenderer(); +const webgpuRenderer = new WebGPURenderer({ + shaderCompilerPath: '/glsl_wgsl_compiler_bg.wasm', +}); // create a canvas const canvas = new Canvas({ diff --git a/site/examples/style/basic/demo/inheritance.js b/site/examples/style/basic/demo/inheritance.js index b6661707f..6bcdba3da 100644 --- a/site/examples/style/basic/demo/inheritance.js +++ b/site/examples/style/basic/demo/inheritance.js @@ -25,7 +25,9 @@ const canvaskitRenderer = new CanvaskitRenderer({ }, ], }); -const webgpuRenderer = new WebGPURenderer(); +const webgpuRenderer = new WebGPURenderer({ + shaderCompilerPath: '/glsl_wgsl_compiler_bg.wasm', +}); // create a canvas const canvas = new Canvas({ diff --git a/site/examples/style/basic/demo/length.js b/site/examples/style/basic/demo/length.js index 555bd638f..fd12f3e83 100644 --- a/site/examples/style/basic/demo/length.js +++ b/site/examples/style/basic/demo/length.js @@ -27,7 +27,9 @@ const canvaskitRenderer = new CanvaskitRenderer({ }, ], }); -const webgpuRenderer = new WebGPURenderer(); +const webgpuRenderer = new WebGPURenderer({ + shaderCompilerPath: '/glsl_wgsl_compiler_bg.wasm', +}); // create a canvas const canvas = new Canvas({ diff --git a/site/examples/style/basic/demo/paint.js b/site/examples/style/basic/demo/paint.js index bdbb06562..e411038be 100644 --- a/site/examples/style/basic/demo/paint.js +++ b/site/examples/style/basic/demo/paint.js @@ -25,7 +25,9 @@ const canvaskitRenderer = new CanvaskitRenderer({ }, ], }); -const webgpuRenderer = new WebGPURenderer(); +const webgpuRenderer = new WebGPURenderer({ + shaderCompilerPath: '/glsl_wgsl_compiler_bg.wasm', +}); // create a canvas const canvas = new Canvas({ diff --git a/site/examples/style/clip-path/demo/clip.js b/site/examples/style/clip-path/demo/clip.js index 761c9ac7c..9c6d8465e 100644 --- a/site/examples/style/clip-path/demo/clip.js +++ b/site/examples/style/clip-path/demo/clip.js @@ -20,7 +20,9 @@ const canvaskitRenderer = new CanvaskitRenderer({ }, ], }); -const webgpuRenderer = new WebGPURenderer(); +const webgpuRenderer = new WebGPURenderer({ + shaderCompilerPath: '/glsl_wgsl_compiler_bg.wasm', +}); // in user space const clipPathCircle = new Circle({ diff --git a/site/examples/style/gradient/demo/gradient.js b/site/examples/style/gradient/demo/gradient.js index bfc978e7d..32de8d1a1 100644 --- a/site/examples/style/gradient/demo/gradient.js +++ b/site/examples/style/gradient/demo/gradient.js @@ -22,7 +22,9 @@ import Stats from 'stats.js'; const canvasRenderer = new CanvasRenderer(); const svgRenderer = new SVGRenderer(); const webglRenderer = new WebGLRenderer(); -const webgpuRenderer = new WebGPURenderer(); +const webgpuRenderer = new WebGPURenderer({ + shaderCompilerPath: '/glsl_wgsl_compiler_bg.wasm', +}); const canvaskitRenderer = new CanvaskitRenderer({ wasmDir: '/', }); diff --git a/site/examples/style/gradient/demo/inner-shadow.js b/site/examples/style/gradient/demo/inner-shadow.js index 21af97435..26e3dc56c 100644 --- a/site/examples/style/gradient/demo/inner-shadow.js +++ b/site/examples/style/gradient/demo/inner-shadow.js @@ -11,7 +11,9 @@ import Stats from 'stats.js'; const canvasRenderer = new CanvasRenderer(); const svgRenderer = new SVGRenderer(); const webglRenderer = new WebGLRenderer(); -const webgpuRenderer = new WebGPURenderer(); +const webgpuRenderer = new WebGPURenderer({ + shaderCompilerPath: '/glsl_wgsl_compiler_bg.wasm', +}); const canvaskitRenderer = new CanvaskitRenderer({ wasmDir: '/', }); diff --git a/site/examples/style/pattern/demo/dots.js b/site/examples/style/pattern/demo/dots.js index 801bf0d5e..cb5aeb384 100644 --- a/site/examples/style/pattern/demo/dots.js +++ b/site/examples/style/pattern/demo/dots.js @@ -15,7 +15,9 @@ import { dots } from '@antv/g-pattern'; const canvasRenderer = new CanvasRenderer(); const svgRenderer = new SVGRenderer(); const webglRenderer = new WebGLRenderer(); -const webgpuRenderer = new WebGPURenderer(); +const webgpuRenderer = new WebGPURenderer({ + shaderCompilerPath: '/glsl_wgsl_compiler_bg.wasm', +}); const canvaskitRenderer = new CanvaskitRenderer({ wasmDir: '/', fonts: [ diff --git a/site/examples/style/pattern/demo/lines.js b/site/examples/style/pattern/demo/lines.js index 0d45ad573..5950772e9 100644 --- a/site/examples/style/pattern/demo/lines.js +++ b/site/examples/style/pattern/demo/lines.js @@ -15,7 +15,9 @@ import { lines } from '@antv/g-pattern'; const canvasRenderer = new CanvasRenderer(); const svgRenderer = new SVGRenderer(); const webglRenderer = new WebGLRenderer(); -const webgpuRenderer = new WebGPURenderer(); +const webgpuRenderer = new WebGPURenderer({ + shaderCompilerPath: '/glsl_wgsl_compiler_bg.wasm', +}); const canvaskitRenderer = new CanvaskitRenderer({ wasmDir: '/', fonts: [ diff --git a/site/examples/style/pattern/demo/pattern.js b/site/examples/style/pattern/demo/pattern.js index c292daf54..406a34c4c 100644 --- a/site/examples/style/pattern/demo/pattern.js +++ b/site/examples/style/pattern/demo/pattern.js @@ -22,7 +22,9 @@ import Stats from 'stats.js'; const canvasRenderer = new CanvasRenderer(); const svgRenderer = new SVGRenderer(); const webglRenderer = new WebGLRenderer(); -const webgpuRenderer = new WebGPURenderer(); +const webgpuRenderer = new WebGPURenderer({ + shaderCompilerPath: '/glsl_wgsl_compiler_bg.wasm', +}); const canvaskitRenderer = new CanvaskitRenderer({ wasmDir: '/', }); diff --git a/site/examples/style/pattern/demo/piechart.js b/site/examples/style/pattern/demo/piechart.js index 88f59da00..b77121b3e 100644 --- a/site/examples/style/pattern/demo/piechart.js +++ b/site/examples/style/pattern/demo/piechart.js @@ -21,7 +21,9 @@ import { lines } from '@antv/g-pattern'; const canvasRenderer = new CanvasRenderer(); const svgRenderer = new SVGRenderer(); const webglRenderer = new WebGLRenderer(); -const webgpuRenderer = new WebGPURenderer(); +const webgpuRenderer = new WebGPURenderer({ + shaderCompilerPath: '/glsl_wgsl_compiler_bg.wasm', +}); const canvaskitRenderer = new CanvaskitRenderer({ wasmDir: '/', fonts: [ @@ -45,7 +47,6 @@ const canvas = new Canvas({ }); const data = [38024.7, 209484.6, 6201.2, 17741.9, 24377.7]; -const total = d3.sum(data); const colors = ['#e8c1a0', '#f47560', '#f1e15b', '#e8a838', '#61cdbb']; const width = 600; const sectorArc = d3 diff --git a/site/examples/style/pattern/demo/rect.js b/site/examples/style/pattern/demo/rect.js index 7503e168c..0c3696689 100644 --- a/site/examples/style/pattern/demo/rect.js +++ b/site/examples/style/pattern/demo/rect.js @@ -11,7 +11,9 @@ import Stats from 'stats.js'; const canvasRenderer = new CanvasRenderer(); const svgRenderer = new SVGRenderer(); const webglRenderer = new WebGLRenderer(); -const webgpuRenderer = new WebGPURenderer(); +const webgpuRenderer = new WebGPURenderer({ + shaderCompilerPath: '/glsl_wgsl_compiler_bg.wasm', +}); const canvaskitRenderer = new CanvaskitRenderer({ wasmDir: '/', }); diff --git a/site/examples/style/pattern/demo/squares.js b/site/examples/style/pattern/demo/squares.js index f4583a81e..674f81da0 100644 --- a/site/examples/style/pattern/demo/squares.js +++ b/site/examples/style/pattern/demo/squares.js @@ -15,7 +15,9 @@ import { squares } from '@antv/g-pattern'; const canvasRenderer = new CanvasRenderer(); const svgRenderer = new SVGRenderer(); const webglRenderer = new WebGLRenderer(); -const webgpuRenderer = new WebGPURenderer(); +const webgpuRenderer = new WebGPURenderer({ + shaderCompilerPath: '/glsl_wgsl_compiler_bg.wasm', +}); const canvaskitRenderer = new CanvaskitRenderer({ wasmDir: '/', fonts: [ diff --git a/site/package.json b/site/package.json index 6030c9449..58037bf6f 100644 --- a/site/package.json +++ b/site/package.json @@ -24,9 +24,9 @@ "start": "npm run site:dev" }, "dependencies": { - "@antv/g-components": "^1.9.0", - "@antv/g-plugin-dragndrop": "^1.8.0", - "@antv/g-svg": "^1.10.0", + "@antv/g-components": "^1.9.1", + "@antv/g-mobile-webgl": "^0.9.1", + "@antv/g-plugin-image-loader": "^1.3.1", "@antv/g6": "^4.5.2", "@antv/react-g": "^1.8.79", "@antv/util": "^3.3.1",