我正在使用的SVG通过feGaussianBlur过滤器有一个投影.
阴影本身正确显示,但在顶部和底部边缘被切除.
像这样:
有问题的SVG是:
<?xml version="1.0" standalone="no" ?>
<!DOCTYPE svg
PUBLIC '-//W3C//DTD SVG 1.1//EN'
'http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd'>
<svg height="600" version="1.1" width="700" xml:space="preserve" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<defs/>
<filter id="SVGID_0">
<feGaussianBlur in="SourceGraphic" stdDeviation="6.6"/>
<feOffset dx="0" dy="0"/>
<feMerge>
<feMergeNode/>
<feMergeNode in="SourceGraphic"/>
</feMerge>
</filter>
<path d="M 0 83 Q 0 83 0 83 Q 0 83 6 79.5 Q 12 76 17 71 Q 22 66 30.5 57.5 Q 39 49 54 36 Q 69 23 82.5 16.5 Q 96 10 120 4.5 Q 144 -1 170.5 …
Run Code Online (Sandbox Code Playgroud) 我试图在SVG中找到一种从另一种形状中减去一种形状的方法,在中间创建一个洞或在它的侧面咬一口.有点像剪切路径,但我不想显示交叉点,而是要显示交叉点之外的其中一个部分.一个解决方案涉及使用Adobe Flex,但我不知道如何正确实现它.我知道有一种方法可以使用布尔路径操作在Inkscape中执行此操作,但我希望保持圆形元素的方式,而不是将它们更改为路径元素.
<defs>
<subtractPath id="hole">
<circle r="50" cx="100" cy="100" />
</subtractPath>
</defs>
<circle id="donut" r="100" cx="100" cy="100" subtract-path="url(#hole)" />
Run Code Online (Sandbox Code Playgroud) 显然,微软已经改变了2018年末发布的Windows更新1809的剪辑方式.在更新之前,GetClipBox()
返回窗口的完整客户端矩形,即使它(部分)在屏幕外.更新后,相同的函数返回一个剪切的矩形,仅包含仍在屏幕上的部分.这导致不为屏幕外区域更新设备上下文内容,这阻止我从这些窗口截取屏幕截图.
问题是:我可以以某种方式操纵裁剪区域吗?
我研究了一下,似乎最终剪辑区域受窗口区域,更新矩形和系统区域的影响 - 据我所知,"全局剪辑区域".我用GetWindowRgn()
和检查了窗口区域,并且GetRgnBox()
都返回了Windows 1809和旧版本的相同值.GetUpdateRect()
也返回完整的客户端矩形,因此也不是问题.我也试图挂钩BeginPaint()
方法,看看是否做了更改PAINTSTRUCT.rcPaint
,没有成功.
所以我剩下的就是尝试调整系统区域,或者有时称为可见区域.但是,我不知道是否以及如何做到这一点.MSDN表明它不是,但我想也许有人确实想要一个解决方案!?
编辑:为了使这更清楚,我不认为裁剪是由应用程序本身完成的,因为相同应用程序版本的屏幕截图在Windows 1809之前工作,并且不适用于更新的Windows版本.相反,Windows本身似乎会剪切任何屏幕外表面.
EDIT2:这是获取屏幕截图的最小工作代码示例.
// Get the client size.
RECT crect;
GetClientRect(hwnd, &crect);
int width = crect.right - crect.left;
int height = crect.bottom - crect.top;
// Create DC and Bitmap.
HDC windowDC = GetDC(hwnd);
HDC memoryDC = CreateCompatibleDC(windowDC);
BITMAPINFO bitmapInfo;
ZeroMemory(&bitmapInfo, sizeof(BITMAPINFO));
bitmapInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bitmapInfo.bmiHeader.biWidth = width;
bitmapInfo.bmiHeader.biHeight = -height;
bitmapInfo.bmiHeader.biPlanes = 1;
bitmapInfo.bmiHeader.biBitCount = 32; …
Run Code Online (Sandbox Code Playgroud) 当我将文本添加到标签时,文本的adjustsFontSizeToFitWidth
设置YES
不再垂直居中,最终剪切标签框底部的文本.对于大量文本,它最终会从标签的底部消失.
如果您添加较少的文本会发生这种情况:
这是我所期望的剪裁(即字体大小没有缩小,文字在标签中垂直居中,并在顶部和底部剪裁.
这是重现的代码:
- (void)loadView {
[super loadView];
self.view.backgroundColor = [UIColor blueColor];
testLabel = [[UILabel alloc] init];
testLabel.font = [UIFont boldSystemFontOfSize:172];
testLabel.textColor = [UIColor blackColor];
testLabel.adjustsFontSizeToFitWidth = YES;
testLabel.numberOfLines = 1;
testLabel.frame = CGRectMake(50, 50, 300, 100);
testLabel.text = @"123";
[self.view addSubview:testLabel];
}
Run Code Online (Sandbox Code Playgroud)
这会发生吗?如何使我的标签垂直居中,而不管标签中的字符数是多少.
我想知道是否可以将视图剪切到Bezier路径.我的意思是我希望能够仅在封闭的贝塞尔路径内的区域中看到视图.原因是我有一个不规则形状的轮廓,我想逐渐用从上到下的纯色填充形状.如果我能够使某个视图仅在路径中可见,那么我可以简单地创建一个我想要的颜色的UIView,然后根据需要更改其框架的y坐标,有效地填充形状.如果有人对如何实现这一点有任何更好的想法,将不胜感激.对于记录,形状的填充将与用户手指的y值匹配,因此它不能是连续动画.谢谢.
更新(很长一段时间后):
我尝试了你的答案,Rob,除了一件事,它的效果很好.我的目的是在掩模保持在屏幕上的相同位置时移动视图被遮罩.这样我就可以给人一种被视图"填满"面具的印象.问题在于,根据你的答案编写的代码,当我移动视图时,掩码随之移动.我明白这是可以预料到的,因为我所做的就是将它作为视图的掩码添加,因此如果它与之相关联的东西移动,它将会移动.我尝试添加掩码作为superview的子层,以便它保持放置,但这有非常奇怪的结果.这是我的代码:
self.test = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 200, 200)];
self.test.backgroundColor = [UIColor greenColor];
[self.view addSubview:self.test];
UIBezierPath *myClippingPath = [UIBezierPath bezierPath];
[myClippingPath moveToPoint:CGPointMake(100, 100)];
[myClippingPath addCurveToPoint:CGPointMake(200, 200) controlPoint1:CGPointMake(self.screenWidth, 0) controlPoint2:CGPointMake(self.screenWidth, 50)];
[myClippingPath closePath];
CAShapeLayer *mask = [CAShapeLayer layer];
mask.path = myClippingPath.CGPath;
self.test.layer.mask = mask;
CGRect firstFrame = self.test.frame;
firstFrame.origin.x += 100;
[UIView animateWithDuration:3 animations:^{
self.test.frame = firstFrame;
}];
Run Code Online (Sandbox Code Playgroud)
谢谢你的帮助.
我需要在OpenGL ES 2.0中的剪切平面下剪切几百个对象,并且会欣赏那些对这个OpenGL子集更有经验的人的想法.
在OpenGL ES 1.x中有glClipPlane.在桌面上,您在着色器中有glClipPlane或gl_ClipDistance.这两者都不适用于OpenGL ES 2.0.似乎这种功能完全消失了2.0.
似乎唯一的方法是:A)在片段着色器中运行平面方程,或者B)编写一个非常复杂的顶点着色器,如果它们位于平面后面,则将它们定位在平面上.
(a)与glClipPlane相比会很慢,因为在顶点着色器之后和片段着色器之前进行"常规"剪辑,每个片段仍然必须被部分处理和丢弃.
(B)很难在着色器之间进行兼容,因为我们不能丢弃顶点,我们必须将它们与平面对齐并调整那些"切割"的属性.如果不在纹理中发送所有顶点并对其进行采样,则无法在着色器中的顶点之间进行插值,这将非常昂贵.通常,无论如何都可能无法正确地插入数据.
我还想过将近平面与剪切平面对齐,这将是一种有效的解决方案.
在渲染整个场景并检查深度失败后绘制平面也不起作用(除非您看起来接近垂直于平面).
对单个对象起作用的是将平面绘制到深度缓冲区,然后使用glDepthFunc(GL_GREATER)渲染对象,但正如预期的那样,当其中一个对象位于另一个对象后面时,它不起作用.我试图建立在这个概念的基础上,但最终得到了与阴影卷非常相似的东西,同样昂贵.
那我错过了什么?你会如何在OpenGL ES 2.0中进行平面剪裁?
通常,<clipPath>
元素会隐藏夹子路径以外的所有内容.为了达到相反的效果 - 即从图像中"剪切"某些东西 - 我想在clipPath和clip-rule="evenodd"
属性中使用两个路径.基本上,我想"修剪"剪辑路径.
但它不起作用.它显示区域"ORed":
<clipPath clip-rule="evenodd" id="imageclippath" clipPathUnits = "objectBoundingBox">
<rect clip-rule="evenodd" x="0.3" y="0.3" height="0.6" width="6" />
<rect clip-rule="evenodd" x="0" y="0" height="0.5" width="0.5" />
</clipPath>
<rect clip-path="url(#imageclippath)" x="0" y="0" height="500" width="500" fill="red"/>
Run Code Online (Sandbox Code Playgroud)
编辑:
我的问题是AFAIK <mask>
在iOS WebKit中不起作用.
我在另一个绝对定位的div中有一个绝对定位的div.子div内容远大于父级可以包含的内容.这是设计的.我需要将子div从其父级中溢出.除了IE 8之外的所有其他浏览器都会这样做(IE 7看起来还不错,不确定)在IE8中,剪切了父节点之外的部分.它就在那里,但只是不可见,因为IE开发人员工具可以验证.我尝试了z-index,尝试明确设置溢出:可见,根本没有运气.
更新:我发现问题是由父div中定义的过滤器引起的,如下所示:
-ms-filter: "progid:DXImageTransform.Microsoft.gradient(startColorstr=#66C6DEA2,endColorstr=#66C6DEA2)";
Run Code Online (Sandbox Code Playgroud)
任何人都知道如何解决这个问题?
我正在创建一个NSView
具有圆角的子类.此视图是一个容器,其他子视图将添加到其中.我试图获得圆角NSView
以夹住所有子视图的角落,但我无法得到它.
- (void)drawRect:(NSRect)dirtyRect {
NSRect rect = [self bounds];
NSBezierPath *path = [NSBezierPath bezierPathWithRoundedRect:rect xRadius:self.radius yRadius:self.radius];
[path addClip];
[[NSColor redColor] set];
NSRectFill(dirtyRect);
[super drawRect:dirtyRect];
}
Run Code Online (Sandbox Code Playgroud)
红色就是例如.如果我在矩形中添加子视图,则角落不会被剪裁:
我怎样才能做到这一点?