如何在Flutter中给“自定义路径”弧阴影?

时间:2020-09-07 00:19:21

标签: flutter

正如问题所说…………我需要在自定义涂料绘制的圆弧上添加阴影。我像这样尝试了我们的drawShadow()方法:

Path a = Path()..arcTo(Rect.fromCircle(center: center, radius: pieRadius), -(pi / 2) + val1 + val3 + val4 ,val2, false);
canvas.drawCircle(center,pieRadius/* * 0.4*/, outerArc);
canvas.drawPath(a, innerArc1);
    canvas.drawShadow(a, Colors.black, 3, true);

但这会导致这样的阴影:

enter image description here

但是我想要阴影均匀地围绕弧线,就像Container的boxShadow属性一样。

enter image description here

以这种方式(蓝色标记和弧之间的区域应该在阴影下)。

在此先感谢您的帮助。

1 个答案:

答案 0 :(得分:1)

我遇到了同样的问题。经过一些实验,我发现最好的解决方案是绘制两条弧线,一条用于弧线本身,另一条用于阴影下方。阴影弧有一个小的偏移量,可以有自己的油漆,带有 package com.bornander.sandbox; import com.badlogic.gdx.ApplicationAdapter; import com.badlogic.gdx.Gdx; import com.badlogic.gdx.Input; import com.badlogic.gdx.graphics.Color; import com.badlogic.gdx.graphics.GL20; import com.badlogic.gdx.graphics.OrthographicCamera; import com.badlogic.gdx.graphics.Texture; import com.badlogic.gdx.graphics.g2d.SpriteBatch; import com.badlogic.gdx.math.Intersector; import com.badlogic.gdx.math.Vector2; import com.badlogic.gdx.utils.Array; import java.util.Comparator; public class SandboxGame extends ApplicationAdapter { OrthographicCamera camera; SpriteBatch batch; Texture texture; CutTexture cutTexture; public static class CutTexture { public static class VertexAngle { public Vector2 v; public float a; } public static class CutHalf { public float[] vertices = new float[4 * 5]; public void translate(float x, float y) { for(int i = 0; i < vertices.length; i += 5) { vertices[i + 0] += x; vertices[i + 1] += y; } } } public Vector2 position = new Vector2(); public Vector2 driftDirection = new Vector2(); public float drift = 0.0f; public Texture source; public CutHalf halfA = new CutHalf(); public CutHalf halfB = new CutHalf(); public void cut(float angle) { Vector2 d = (new Vector2(1.0f, 0.0f)).rotate(angle); Vector2 c = new Vector2(0.5f, 0.5f); driftDirection.set(d).rotate(90.0f); Vector2 la = (new Vector2(d)).scl( 1.0f).add(c); Vector2 lb = (new Vector2(d)).scl(-1.0f).add(c); Vector2 tl = new Vector2(0, 1); Vector2 tr = new Vector2(1, 1); Vector2 bl = new Vector2(0, 0); Vector2 br = new Vector2(1, 0); Vector2 i1 = new Vector2(); Vector2 i2 = new Vector2(); if (Intersector.intersectSegments(c, la, tl, tr, i1) || Intersector.intersectSegments(c, lb, tl, tr, i1)) i2.set(1.0f - i1.x, 1.0f - i1.y); else { if (Intersector.intersectSegments(c, la, tl, bl, i1) || Intersector.intersectSegments(c, lb, tl, bl, i1)) i2.set(1.0f - i1.x, 1.0f - i1.y); } Vector2[] vertexList = new Vector2[] { tl, tr, bl, br, i1, i2 }; Array<VertexAngle> vas = new Array<>(); for (Vector2 v : vertexList) { Vector2 vd = (new Vector2(v)).sub(c); float a = d.angle(vd); VertexAngle va = new VertexAngle(); va.v = v; va.a = a; vas.add(va); } vas.sort(new Comparator<VertexAngle>() { @Override public int compare(VertexAngle a, VertexAngle b) { return Float.compare(a.a, b.a); } }); Array<Vector2> nv = new Array<>(); for (VertexAngle va : vas) nv.add(va.v); int index = nv.indexOf(i1, true); int idx = 0; int lastIndex = 0; for(int j = 0; j < 4; ++j) { lastIndex = (index + j) % nv.size; Vector2 vertex = nv.get(lastIndex); float width = source.getWidth(); float height = source.getWidth(); float fx2 = position.x + width * vertex.x - width / 2.0f; float fy2 = position.y + height * vertex.y - height / 2.0f; halfA.vertices[idx++] = fx2; halfA.vertices[idx++] = fy2; halfA.vertices[idx++] = Color.WHITE_FLOAT_BITS; halfA.vertices[idx++] = vertex.x; halfA.vertices[idx++] = 1.0f - vertex.y; } idx = 0; for(int j = 0; j < 4; ++j) { Vector2 vertex = nv.get((lastIndex + j) % nv.size); float width = source.getWidth(); float height = source.getWidth(); float fx2 = position.x + width * vertex.x - width / 2.0f; float fy2 = position.y + height * vertex.y - height / 2.0f; halfB.vertices[idx++] = fx2; halfB.vertices[idx++] = fy2; halfB.vertices[idx++] = Color.WHITE_FLOAT_BITS; halfB.vertices[idx++] = vertex.x; halfB.vertices[idx++] = 1.0f - vertex.y; } } public void render(SpriteBatch batch) { float dx = driftDirection.x * drift; float dy = driftDirection.y * drift; halfA.translate(dx, dy); halfB.translate(-dx, -dy); batch.draw(source, halfA.vertices, 0, 20); batch.draw(source, halfB.vertices, 0, 20); halfA.translate(-dx, -dy); halfB.translate(dx, dy); } } @Override public void create () { float aspectRatio = (float)Gdx.graphics.getHeight()/(float)Gdx.graphics.getWidth(); camera = new OrthographicCamera(800, 800 * aspectRatio); camera.position.set(camera.viewportWidth / 2.0f, camera.viewportHeight / 2.0f, 0.0f); batch = new SpriteBatch(); texture = new Texture(Gdx.files.internal("badlogic.jpg")); Gdx.gl.glCullFace(0); cutTexture = new CutTexture(); cutTexture.position.set(camera.viewportWidth / 2.0f, camera.viewportHeight / 2.0f); cutTexture.source = texture; cutTexture.cut(0); } float[] cutAngles = new float[] { 0.0f, -22.5f, -45.0f, -12.0f, -75.0f, -90.0f}; int ai = 0; @Override public void render () { if (Gdx.input.isKeyJustPressed(Input.Keys.SPACE)) { cutTexture.drift = 0.0f; cutTexture.cut(cutAngles[(ai++) % cutAngles.length]); } cutTexture.drift -= 64.0f * Gdx.graphics.getDeltaTime(); Gdx.gl.glClearColor(0.6f, 0.6f, 1.0f, 1); Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT); Gdx.gl.glCullFace(GL20.GL_NONE); camera.update(); batch.setProjectionMatrix(camera.combined); batch.begin(); cutTexture.render(batch); batch.end(); } }

MaskFilter.blur