mirror of
https://github.com/niklasvh/html2canvas.git
synced 2023-08-10 21:13:10 +03:00
Implement visibility css prop
This commit is contained in:
parent
f278ba4f22
commit
f2b8c16c2c
@ -48,8 +48,10 @@ export default class CanvasRenderer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
renderNode(container: NodeContainer) {
|
renderNode(container: NodeContainer) {
|
||||||
this.renderNodeBackgroundAndBorders(container);
|
if (container.isVisible()) {
|
||||||
this.renderNodeContent(container);
|
this.renderNodeBackgroundAndBorders(container);
|
||||||
|
this.renderNodeContent(container);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
renderNodeContent(container: NodeContainer) {
|
renderNodeContent(container: NodeContainer) {
|
||||||
@ -242,69 +244,71 @@ export default class CanvasRenderer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
renderStack(stack: StackingContext) {
|
renderStack(stack: StackingContext) {
|
||||||
this.ctx.globalAlpha = stack.getOpacity();
|
if (stack.container.isVisible()) {
|
||||||
const transform = stack.container.style.transform;
|
this.ctx.globalAlpha = stack.getOpacity();
|
||||||
if (transform !== null) {
|
const transform = stack.container.style.transform;
|
||||||
this.ctx.save();
|
if (transform !== null) {
|
||||||
this.ctx.translate(
|
this.ctx.save();
|
||||||
stack.container.bounds.left + transform.transformOrigin[0].value,
|
this.ctx.translate(
|
||||||
stack.container.bounds.top + transform.transformOrigin[1].value
|
stack.container.bounds.left + transform.transformOrigin[0].value,
|
||||||
);
|
stack.container.bounds.top + transform.transformOrigin[1].value
|
||||||
this.ctx.transform(
|
);
|
||||||
transform.transform[0],
|
this.ctx.transform(
|
||||||
transform.transform[1],
|
transform.transform[0],
|
||||||
transform.transform[2],
|
transform.transform[1],
|
||||||
transform.transform[3],
|
transform.transform[2],
|
||||||
transform.transform[4],
|
transform.transform[3],
|
||||||
transform.transform[5]
|
transform.transform[4],
|
||||||
);
|
transform.transform[5]
|
||||||
this.ctx.translate(
|
);
|
||||||
-(stack.container.bounds.left + transform.transformOrigin[0].value),
|
this.ctx.translate(
|
||||||
-(stack.container.bounds.top + transform.transformOrigin[1].value)
|
-(stack.container.bounds.left + transform.transformOrigin[0].value),
|
||||||
);
|
-(stack.container.bounds.top + transform.transformOrigin[1].value)
|
||||||
}
|
);
|
||||||
const [
|
}
|
||||||
negativeZIndex,
|
const [
|
||||||
zeroOrAutoZIndexOrTransformedOrOpacity,
|
negativeZIndex,
|
||||||
positiveZIndex,
|
zeroOrAutoZIndexOrTransformedOrOpacity,
|
||||||
nonPositionedFloats,
|
positiveZIndex,
|
||||||
nonPositionedInlineLevel
|
nonPositionedFloats,
|
||||||
] = splitStackingContexts(stack);
|
nonPositionedInlineLevel
|
||||||
const [inlineLevel, nonInlineLevel] = splitDescendants(stack);
|
] = splitStackingContexts(stack);
|
||||||
|
const [inlineLevel, nonInlineLevel] = splitDescendants(stack);
|
||||||
|
|
||||||
// https://www.w3.org/TR/css-position-3/#painting-order
|
// https://www.w3.org/TR/css-position-3/#painting-order
|
||||||
// 1. the background and borders of the element forming the stacking context.
|
// 1. the background and borders of the element forming the stacking context.
|
||||||
this.renderNodeBackgroundAndBorders(stack.container);
|
this.renderNodeBackgroundAndBorders(stack.container);
|
||||||
// 2. the child stacking contexts with negative stack levels (most negative first).
|
// 2. the child stacking contexts with negative stack levels (most negative first).
|
||||||
negativeZIndex.sort(sortByZIndex).forEach(this.renderStack, this);
|
negativeZIndex.sort(sortByZIndex).forEach(this.renderStack, this);
|
||||||
// 3. For all its in-flow, non-positioned, block-level descendants in tree order:
|
// 3. For all its in-flow, non-positioned, block-level descendants in tree order:
|
||||||
this.renderNodeContent(stack.container);
|
this.renderNodeContent(stack.container);
|
||||||
nonInlineLevel.forEach(this.renderNode, this);
|
nonInlineLevel.forEach(this.renderNode, this);
|
||||||
// 4. All non-positioned floating descendants, in tree order. For each one of these,
|
// 4. All non-positioned floating descendants, in tree order. For each one of these,
|
||||||
// treat the element as if it created a new stacking context, but any positioned descendants and descendants
|
// treat the element as if it created a new stacking context, but any positioned descendants and descendants
|
||||||
// which actually create a new stacking context should be considered part of the parent stacking context,
|
// which actually create a new stacking context should be considered part of the parent stacking context,
|
||||||
// not this new one.
|
// not this new one.
|
||||||
nonPositionedFloats.forEach(this.renderStack, this);
|
nonPositionedFloats.forEach(this.renderStack, this);
|
||||||
// 5. the in-flow, inline-level, non-positioned descendants, including inline tables and inline blocks.
|
// 5. the in-flow, inline-level, non-positioned descendants, including inline tables and inline blocks.
|
||||||
nonPositionedInlineLevel.forEach(this.renderStack, this);
|
nonPositionedInlineLevel.forEach(this.renderStack, this);
|
||||||
inlineLevel.forEach(this.renderNode, this);
|
inlineLevel.forEach(this.renderNode, this);
|
||||||
// 6. All positioned, opacity or transform descendants, in tree order that fall into the following categories:
|
// 6. All positioned, opacity or transform descendants, in tree order that fall into the following categories:
|
||||||
// All positioned descendants with 'z-index: auto' or 'z-index: 0', in tree order.
|
// All positioned descendants with 'z-index: auto' or 'z-index: 0', in tree order.
|
||||||
// For those with 'z-index: auto', treat the element as if it created a new stacking context,
|
// For those with 'z-index: auto', treat the element as if it created a new stacking context,
|
||||||
// but any positioned descendants and descendants which actually create a new stacking context should be
|
// but any positioned descendants and descendants which actually create a new stacking context should be
|
||||||
// considered part of the parent stacking context, not this new one. For those with 'z-index: 0',
|
// considered part of the parent stacking context, not this new one. For those with 'z-index: 0',
|
||||||
// treat the stacking context generated atomically.
|
// treat the stacking context generated atomically.
|
||||||
//
|
//
|
||||||
// All opacity descendants with opacity less than 1
|
// All opacity descendants with opacity less than 1
|
||||||
//
|
//
|
||||||
// All transform descendants with transform other than none
|
// All transform descendants with transform other than none
|
||||||
zeroOrAutoZIndexOrTransformedOrOpacity.forEach(this.renderStack, this);
|
zeroOrAutoZIndexOrTransformedOrOpacity.forEach(this.renderStack, this);
|
||||||
// 7. Stacking contexts formed by positioned descendants with z-indices greater than or equal to 1 in z-index
|
// 7. Stacking contexts formed by positioned descendants with z-indices greater than or equal to 1 in z-index
|
||||||
// order (smallest first) then tree order.
|
// order (smallest first) then tree order.
|
||||||
positiveZIndex.sort(sortByZIndex).forEach(this.renderStack, this);
|
positiveZIndex.sort(sortByZIndex).forEach(this.renderStack, this);
|
||||||
|
|
||||||
if (transform !== null) {
|
if (transform !== null) {
|
||||||
this.ctx.restore();
|
this.ctx.restore();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -13,6 +13,7 @@ import type {Position} from './parsing/position';
|
|||||||
import type {TextTransform} from './parsing/textTransform';
|
import type {TextTransform} from './parsing/textTransform';
|
||||||
import type {TextDecoration} from './parsing/textDecoration';
|
import type {TextDecoration} from './parsing/textDecoration';
|
||||||
import type {Transform} from './parsing/transform';
|
import type {Transform} from './parsing/transform';
|
||||||
|
import type {Visibility} from './parsing/visibility';
|
||||||
import type {zIndex} from './parsing/zIndex';
|
import type {zIndex} from './parsing/zIndex';
|
||||||
|
|
||||||
import type {Bounds, BoundCurves, Path} from './Bounds';
|
import type {Bounds, BoundCurves, Path} from './Bounds';
|
||||||
@ -36,6 +37,7 @@ import {parsePosition, POSITION} from './parsing/position';
|
|||||||
import {parseTextDecoration} from './parsing/textDecoration';
|
import {parseTextDecoration} from './parsing/textDecoration';
|
||||||
import {parseTextTransform} from './parsing/textTransform';
|
import {parseTextTransform} from './parsing/textTransform';
|
||||||
import {parseTransform} from './parsing/transform';
|
import {parseTransform} from './parsing/transform';
|
||||||
|
import {parseVisibility, VISIBILITY} from './parsing/visibility';
|
||||||
import {parseZIndex} from './parsing/zIndex';
|
import {parseZIndex} from './parsing/zIndex';
|
||||||
|
|
||||||
import {parseBounds, parseBoundCurves, calculatePaddingBoxPath} from './Bounds';
|
import {parseBounds, parseBoundCurves, calculatePaddingBoxPath} from './Bounds';
|
||||||
@ -56,6 +58,7 @@ type StyleDeclaration = {
|
|||||||
textDecoration: TextDecoration,
|
textDecoration: TextDecoration,
|
||||||
textTransform: TextTransform,
|
textTransform: TextTransform,
|
||||||
transform: Transform,
|
transform: Transform,
|
||||||
|
visibility: Visibility,
|
||||||
zIndex: zIndex
|
zIndex: zIndex
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -90,6 +93,7 @@ export default class NodeContainer {
|
|||||||
textDecoration: parseTextDecoration(style),
|
textDecoration: parseTextDecoration(style),
|
||||||
textTransform: parseTextTransform(style.textTransform),
|
textTransform: parseTextTransform(style.textTransform),
|
||||||
transform: parseTransform(style),
|
transform: parseTransform(style),
|
||||||
|
visibility: parseVisibility(style.visibility),
|
||||||
zIndex: parseZIndex(style.zIndex)
|
zIndex: parseZIndex(style.zIndex)
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -127,7 +131,11 @@ export default class NodeContainer {
|
|||||||
return this.isRootElement() && !this.isFloating() && !this.isAbsolutelyPositioned();
|
return this.isRootElement() && !this.isFloating() && !this.isAbsolutelyPositioned();
|
||||||
}
|
}
|
||||||
isVisible(): boolean {
|
isVisible(): boolean {
|
||||||
return !contains(this.style.display, DISPLAY.NONE) && this.style.opacity > 0;
|
return (
|
||||||
|
!contains(this.style.display, DISPLAY.NONE) &&
|
||||||
|
this.style.opacity > 0 &&
|
||||||
|
this.style.visibility === VISIBILITY.VISIBLE
|
||||||
|
);
|
||||||
}
|
}
|
||||||
isAbsolutelyPositioned(): boolean {
|
isAbsolutelyPositioned(): boolean {
|
||||||
return this.style.position !== POSITION.STATIC && this.style.position !== POSITION.RELATIVE;
|
return this.style.position !== POSITION.STATIC && this.style.position !== POSITION.RELATIVE;
|
||||||
|
22
src/parsing/visibility.js
Normal file
22
src/parsing/visibility.js
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
/* @flow */
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
export const VISIBILITY = {
|
||||||
|
VISIBLE: 0,
|
||||||
|
HIDDEN: 1,
|
||||||
|
COLLAPSE: 2
|
||||||
|
};
|
||||||
|
|
||||||
|
export type Visibility = $Values<typeof VISIBILITY>;
|
||||||
|
|
||||||
|
export const parseVisibility = (visibility: string): Visibility => {
|
||||||
|
switch (visibility) {
|
||||||
|
case 'hidden':
|
||||||
|
return VISIBILITY.HIDDEN;
|
||||||
|
case 'collapse':
|
||||||
|
return VISIBILITY.COLLAPSE;
|
||||||
|
case 'visible':
|
||||||
|
default:
|
||||||
|
return VISIBILITY.VISIBLE;
|
||||||
|
}
|
||||||
|
};
|
@ -1,24 +1,30 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<title>Visible elements tests</title>
|
<title>Visible elements tests</title>
|
||||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||||
<script type="text/javascript" src="../test.js"></script>
|
<script type="text/javascript" src="../test.js"></script>
|
||||||
<style>
|
<style>
|
||||||
div{
|
div{
|
||||||
border:2px solid black;
|
border:2px solid black;
|
||||||
}
|
}
|
||||||
</style>
|
.none {
|
||||||
|
display:none
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<h1>Display:none and visible:hidden tests</h1>
|
<div>
|
||||||
<div>This should be visible </div>
|
<h1>Display:none and visible:hidden tests</h1>
|
||||||
<div style="display:none">display:none, This should be <b>hidden</b></div>
|
<div>This should be visible </div>
|
||||||
<div style="visibility:hidden">visibility:hidden, This should be <b>hidden</b></div>
|
<div class="none">display:none, This should be <b>hidden</b></div>
|
||||||
<hr />
|
<div style="visibility:hidden">visibility:hidden, This should be <b>hidden</b></div>
|
||||||
<div style="display:none">display:none, This should be <b>hidden</b></div>
|
<hr />
|
||||||
<div style="visibility:hidden">visibility:hidden, This should be <b>hidden</b></div>
|
<div class="none">display:none, This should be <b>hidden</b></div>
|
||||||
|
<div style="visibility:hidden">visibility:hidden, This should be <b>hidden</b></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
</body>
|
|
||||||
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user