Difference between revisions of "Drop shadows"

From Wiki
Jump to navigation Jump to search
(new)
 
(better code)
Line 1: Line 1:
 +
< [[MetaPost]] | [[Overlays]] >
 +
 
So you’d like to have one of these nice drop shadows behind some object? Here’s a piece of code to play with:
 
So you’d like to have one of these nice drop shadows behind some object? Here’s a piece of code to play with:
  
 
<texcode>
 
<texcode>
 
\startuniqueMPgraphic{mpshadow}
 
\startuniqueMPgraphic{mpshadow}
% these values are good for small text boxes
+
% BodyFontSize should be the current font size of/in the frame
ox := 0 ; % offset x
+
mw := BodyFontSize/3;
oy := 0 ; % offset y
+
ox := -0.5 ; % offset x
bx := 10 ; % bleed x
+
oy := -0.5 ; % offset y
by := 0 ; % bleed y
+
bx := 1.5mw ; % bleed x (height of the shadow)
rx := 5 ; % corner radius x
+
by := 1.5mw ; % bleed y (width of the shadow)
ry := 5 ; % corner radius y
+
rx := 3mw ; % max. corner radius x
 +
ry := 2mw ; % max. corner radius y
 +
steps := 10 ; % number of shadow layers, 10 is a good value
 +
hue := 0.015 ; % 0.02 is a good value
 +
ycorr := 1mw ; % difference between overlay height and shadow height
  
for dx = 0 upto 10: % use more iterations for bigger boxes
+
for step = 1 upto steps:
dy := dx ;
+
 
xa := dx + ox - bx/2;
+
part := (step-1)/steps;
xb := \overlaywidth - dx + ox + bx/2;
+
xstep := bx * part ; % current part of bleed
ya := dy + oy - by/2;
+
ystep := by * part ;
yb := \overlayheight - dy + oy + by/2;
+
crx := (rx + rx*part)/2; % current radius
 +
cry := (ry + ry*part)/2;
 +
 
 +
% points of the rounded rectangle
 +
xa := -xstep + ox;
 +
xb := -xstep + ox + crx;
 +
xc := xstep + ox - crx + \overlaywidth;
 +
xd :=  xstep + ox       + \overlaywidth;
 +
ya := -ystep + ycorr + oy;
 +
yb := -ystep + ycorr + oy + cry;
 +
yc := ystep - ycorr + oy - cry + \overlayheight;
 +
yd :=  ystep - ycorr + oy       + \overlayheight;
 +
 
 +
fill (xb, ya)---
 +
(xc, ya)...
 +
(xd, yb)---
 +
(xd, yc)...
 +
(xc, yd)---
 +
(xb, yd)...
 +
(xa, yc)---
 +
(xa, yb)...cycle
 +
withcolor transparent(1, hue, black) ;
  
% rounded rectangle
 
fill (xa, ya + ry)---
 
(xa, yb - ry)..
 
(xa + rx, yb)---
 
(xb - rx, yb)..
 
(xb, yb - ry)---
 
(xb, ya + ry)..
 
(xb - rx, ya)---
 
(xa + rx, ya)..cycle
 
withcolor transparent(1, .04, black) ;
 
 
endfor;
 
endfor;
 +
 
setbounds currentpicture to OverlayBox ;
 
setbounds currentpicture to OverlayBox ;
 
\stopuniqueMPgraphic
 
\stopuniqueMPgraphic

Revision as of 21:33, 2 August 2019

< MetaPost | Overlays >

So you’d like to have one of these nice drop shadows behind some object? Here’s a piece of code to play with:

\startuniqueMPgraphic{mpshadow}
% BodyFontSize should be the current font size of/in the frame
mw := BodyFontSize/3;
ox := -0.5 ; % offset x
oy := -0.5 ; % offset y
bx := 1.5mw ; % bleed x (height of the shadow)
by := 1.5mw ; % bleed y (width of the shadow)
rx := 3mw ; % max. corner radius x
ry := 2mw ; % max. corner radius y
steps := 10 ; % number of shadow layers, 10 is a good value
hue := 0.015 ; % 0.02 is a good value
ycorr := 1mw ; % difference between overlay height and shadow height

for step = 1 upto steps:

	part := (step-1)/steps;
	xstep := bx * part ; % current part of bleed
	ystep := by * part ;
	crx := (rx + rx*part)/2; % current radius
	cry := (ry + ry*part)/2;

	% points of the rounded rectangle
	xa := -xstep + ox;
	xb := -xstep + ox + crx;
	xc :=  xstep + ox - crx + \overlaywidth;
	xd :=  xstep + ox       + \overlaywidth;
	ya := -ystep + ycorr + oy;
	yb := -ystep + ycorr + oy + cry;
	yc :=  ystep - ycorr + oy - cry + \overlayheight;
	yd :=  ystep - ycorr + oy       + \overlayheight;

	fill (xb, ya)---
	(xc, ya)...
	(xd, yb)---
	(xd, yc)...
	(xc, yd)---
	(xb, yd)...
	(xa, yc)---
	(xa, yb)...cycle
	withcolor transparent(1, hue, black) ;

endfor;

setbounds currentpicture to OverlayBox ;
\stopuniqueMPgraphic

\defineoverlay[shadow][\useMPgraphic{mpshadow}]

\inframed[frame=off,background=shadow,foregroundcolor=white]{\bfa This text box has a shadow.}