我正在尝试实现以下具有挑战性的效果:我想将白色“窗帘”向下移动以露出红色框。(注意:在下面的截图中,窗帘是白色的,背景是灰色的)
问题出在视图层次结构中。
为了让盒子隐藏在初始位置,它必须放在窗帘后面,但为了在最终位置显示,它必须在窗帘的顶部。
我怎样才能“作弊”,让它看起来像窗帘真的用流畅的动画揭示了盒子?
谢谢!
我正在尝试实现以下具有挑战性的效果:我想将白色“窗帘”向下移动以露出红色框。(注意:在下面的截图中,窗帘是白色的,背景是灰色的)
问题出在视图层次结构中。
为了让盒子隐藏在初始位置,它必须放在窗帘后面,但为了在最终位置显示,它必须在窗帘的顶部。
我怎样才能“作弊”,让它看起来像窗帘真的用流畅的动画揭示了盒子?
谢谢!
您需要 2 张图像和一个蒙版。您完全模糊的灰色区域和带有白色背景的框。窗帘的图像只是底部边缘的蒙版。这样它就可以绘制窗帘的底部边缘,而不会抹掉灰色的重叠区域。
在顶部设置一个起始位置,每帧:只绘制/复制幕布的大小,通过幕布复制对应的红框区域。将起始位置向下移动一个扫描线并等待下一帧。重复直到完成。
本质上,没有白色的幕布,只有包含盒子白色背景的“隐藏”图像的显示。根据您的绘图方式,您的蒙版图像可能是另一个具有 Alpha 通道的图像。
编辑:根据要求,一些示例代码。但是,很可能您用来在屏幕上获取图形的任何内容都已经具有带有遮罩的绘制例程,并且您最好使用它。这个片段未经测试,但应该提供逻辑并且几乎可以在任何地方工作。我不熟悉 iOS,不知道您的图像像素是什么格式,24 位、32 位等,并使用“PixelType”作为替代。
这也假设带有黑色背景的白色窗帘边缘在绘画程序中制作为 8 位图像,黑色为零,白色为其他任何颜色。它应该与其他两个图像的宽度相同,并且仅与窗帘边缘所需的高度一样高。
struct Mask
{
char *mData; // set this to the image data of your 8 bit mask
int mWidth; // width in pixels, should be the same as your 2 images
int mHeight; // height in pixels of the mask
};
int iRevealPos = 0; // increment each frame value until box is revealed.
// Hopefully, your pixel type is a basic type like byte, short or int.
void Reveal(PixelType *foreground, PixelType *background, Mask *mask)
{
int height = (iRevealPos < mask->mHeight) ? iRevealPos : mask->mHeight; // account for initial slide in
PixelType *src = background + (iRevealPos * mask->mWidth); // background box at current reveal position
PixelType *dst = foreground + (iRevealPos * mask->mWidth); // matching foreground screen position
int count = mask->mWidth * height;
char *filter = mask->mData;
if ((iRevealPos < mask->mHeight)) // adjust for initial slide in
filter += (mask->mHeight - iRevealPos) * mask->mWidth;
while (count--)
{
if (*filter++) // not black?
*dst++ = *src++; // copy the box image
else // skip this pixel
{
src++;
dst++;
}
}
// if you create your mask with a solid white line at the top, you don't need this
if (iRevealPos > mask->mHeight) // fixup, so the mask doesn't leave a trail
{
src = background + ((iRevealPos-1) * mask->mWidth);
dst = foreground + ((iRevealPos-1) * mask->mWidth);
count = mask->mWidth;
while (count--)
*dst++ = *src++;
}
iRevealPos++; // bump position for next time
}
如果您使用白色实线或 2 在顶部创建遮罩,则不需要第二个循环来修复遮罩留下的任何痕迹。我还允许窗帘在开始时滑入而不是完全弹出。这是未经测试的,所以我可能对此错误进行了调整。