Closed PaulWoitaschek closed 9 years ago
The Play button is defined by this contant:
/**
* Play icon
*/
private static final float[][] VERTEX_PLAY = {
{1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f}, // x coordinates
{0.5f, 0.5f, 0.0f, 1.0f, 0.5f, 0.5f, 0.0f, 1.0f, 0.5f} // y coordinates
};
, where all of those points will be multiplied by drawable's size. Note, that VERTEX_PAUSE
, VERTEX_PLAY
and VERTEX_STOP
must have the same number of points.
Is it possible to convert a svg into such a path?
@Ph1b yes, I think so. At least, the easiest way would be to open this icon in a graphic editor and get its points manually. For example, look at this square: and the code:
private static final float[][] VERTEX_EXAMPLE = {
{0f, 1f, 1f, 0f}, // x coordinates
{0f, 0f, 1f, 1f} // y coordinates
};
Damn, I dont understand the coordinates. I guess the order matters?
I found this: http://www.professorcloud.com/svg-to-canvas/
Which gave me this output which I guess has the coordinates. But how can I match them to the matrix?
var draw = function(ctx) {
ctx.save();
ctx.beginPath();
ctx.moveTo(0,0);
ctx.lineTo(24,0);
ctx.lineTo(24,24);
ctx.lineTo(0,24);
ctx.closePath();
ctx.clip();
ctx.translate(0,0);
ctx.translate(0,0);
ctx.scale(1,1);
ctx.translate(0,0);
ctx.strokeStyle = 'rgba(0,0,0,0)';
ctx.lineCap = 'butt';
ctx.lineJoin = 'miter';
ctx.miterLimit = 4;
ctx.save();
ctx.beginPath();
ctx.moveTo(8,5);
ctx.lineTo(8,19);
ctx.lineTo(19,12);
ctx.closePath();
ctx.fill();
ctx.stroke();
ctx.restore();
ctx.restore();
};
@Ph1b right, the order matters. Maybe this code from TransformationDrawable
will help you:
protected TransformationDrawable(@NonNull float[][]... vertex) {
mVertex = vertex;
}
...
public void setTransformation(float progress) {
mProgress = progress;
Rect rect = getBounds();
final float size = Math.min(Math.min(
rect.right - rect.left,
rect.bottom - rect.top), mSize);
final float left = rect.left + (rect.right - rect.left - size) / 2;
final float top = rect.top + (rect.bottom - rect.top - size) / 2;
mPath.reset();
// Set initial point
mPath.moveTo(
left + calcTransformation(0, 0, progress, size),
top + calcTransformation(1, 0, progress, size));
// Add all other points
for (int i = 1; i < mVertex[0][0].length; i++) {
mPath.lineTo(
left + calcTransformation(0, i, progress, size),
top + calcTransformation(1, i, progress, size));
}
// Close the path (if needed)
mPath.close();
invalidateSelf();
}
private float calcTransformation(int type, int i, float progress, float size) {
float v0 = mVertex[mFromShape][type][i] * (1f - progress);
float v1 = mVertex[mToShape][type][i] * progress;
return (v0 + v1) * size;
}
Your code is pretty close to required format. I don't recommend simple copy-pasting, cause the animation will probably look ugly. You should think about the transformations. :+1:
Ah okay. Since play is a rectangle, it just has 3 points, because of:
ctx.moveTo(8,5);
ctx.lineTo(8,19);
ctx.lineTo(19,12);
it would be
private static final float[][] PLAY_MODI = {
{1f/8f, 1f/8f, 1f/19f}, // x coordinates
{1f/5f, 1f/ 19f, 1f/12f} // y coordinates
};
But thats much smaller than your play button.
Why is your play button not simply:
private static final float[][] VERTEX_PLAY = {
{0f, 0f, 1f}, // x coordinates
{0f, 1f, 0f} // y coordinates
};
@Ph1b
Note, that VERTEX_PAUSE, VERTEX_PLAY and VERTEX_STOP must have the same number of points.
, because each point is transforming into a corresponding point of another shape (for example, VERTEX_PLAY
-> VERTEX_PAUSE
)
Yeah now I got it, works flawless.
In case someone wants this with material icons: (directly fetched from source 1:1)
/**
* Pause icon
*/
private static final float[][] VERTEX_PAUSE = {
{10f / 24f, 6f / 24f, 6f / 24f, 10f / 24f, 10f / 24f, 14f / 24f, 14f / 24f, 18f / 24f, 18f / 24f},
{5f / 24f, 5f / 24f, 19f / 24f, 19f / 24f, 5f / 24f, 5f / 24f, 19f / 24f, 19f / 24f, 5f / 24f}
};
/**
* Play icon
*/
private static final float[][] VERTEX_PLAY = {
{19f / 24f, 19f / 24f, 8f / 24f, 8f / 24f, 19f / 24f, 19f / 24f, 8f / 24f, 8f / 24f, 19f / 24f},
{12f / 24f, 12f / 24f, 5f / 24f, 9f / 24f, 12f / 24f, 12f / 24f, 5f / 24f, 19f / 24f, 12f / 24f}
};
Thanks again!
@Ph1b I think that more correct points are:
/**
* Pause icon
*/
private static final float[][] VERTEX_PAUSE;
/**
* Play icon
*/
private static final float[][] VERTEX_PLAY;
/**
* Stop icon
*/
private static final float[][] VERTEX_STOP;
static {
float lef0 = 1f / 14f;
float lef1 = 5f / 14f;
float rig0 = 9f / 14f;
float rig1 = 13f / 14f;
VERTEX_PAUSE = new float[][] {
{lef1, lef0, lef0, lef1, lef1, rig0, rig0, rig1, rig1},
{0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f}
};
VERTEX_STOP = new float[][] {
{0.5f, lef0, lef0, 0.5f, 0.5f, 0.5f, 0.5f, rig1, rig1},
{lef0, lef0, rig1, rig1, lef0, lef0, rig1, rig1, lef0}
};
lef0 = 4f / 14f;
VERTEX_PLAY = new float[][] {
{1.0f, 1.0f, lef0, lef0, 1.0f, 1.0f, lef0, lef0, 1.0f},
{0.5f, 0.5f, 0.0f, 1.0f, 0.5f, 0.5f, 0.0f, 1.0f, 0.5f}
};
}
, but the result is not sharp enough, due to float coordinates and I won't include it in master
.
You can use:
/**
* Pause icon
*/
private static final float[][] VERTEX_PAUSE = {
{10f, 6f, 6f, 10f, 10f, 14f, 14f, 18f, 18f},
{5f, 5f, 19f, 19f, 5f, 5f, 19f, 19f, 5f}
};
/**
* Play icon
*/
private static final float[][] VERTEX_PLAY = {
{19f, 19f, 8f, 8f, 19f, 19f, 8f, 8f, 19f},
{12f, 12f, 5f, 9f, 12f, 12f, 5f, 19f, 12f}
};
And then:
private float calcTransformation(int type, int i, float progress, float size) {
float v0 = mVertex[mFromShape][type][i] * (1f - progress);
float v1 = mVertex[mToShape][type][i] * progress;
return (v0 + v1) * size / 24f;
}
Another question: How can I set the image immediately without animation? When I enter a screen I sometimes want to set an initial state without the hickup-animation caused by onResume()
Okay, got it. Passed a boolean that if true sets animator duration to 0, else to default value (300).
How can I customize the PlayPauseDrawable class? Its great, but its a bit weird bacause the play aligns left with the pause, so The play is a bit off-centered. How can the centering be archieved?
A nice thing would be to directly use the material svg paths like here: https://raw.githubusercontent.com/google/material-design-icons/master/av/svg/production/ic_play_arrow_24px.svg