web: add AnimatePlugin

This commit is contained in:
pengfei.zhou 2021-04-16 17:19:02 +08:00 committed by osborn
parent 900bccb98a
commit d1cc17c7a0
7 changed files with 345 additions and 124 deletions

View File

@ -4550,57 +4550,67 @@ var doric_web = (function (exports, axios, sandbox) {
} }
configBorder() { configBorder() {
if (this.border) { if (this.border) {
this.view.style.borderStyle = "solid"; this.applyCSSStyle({
this.view.style.borderWidth = toPixelString(this.border.width); borderStyle: "solid",
this.view.style.borderColor = toRGBAString(this.border.color); borderWidth: toPixelString(this.border.width),
borderColor: toRGBAString(this.border.color),
});
} }
} }
configWidth() { configWidth() {
let width;
switch (this.layoutConfig.widthSpec) { switch (this.layoutConfig.widthSpec) {
case exports.LayoutSpec.WRAP_CONTENT: case exports.LayoutSpec.WRAP_CONTENT:
this.view.style.width = "max-content"; width = "max-content";
break; break;
case exports.LayoutSpec.AT_MOST: case exports.LayoutSpec.AT_MOST:
this.view.style.width = "100%"; width = "100%";
break; break;
case exports.LayoutSpec.EXACTLY: case exports.LayoutSpec.EXACTLY:
default: default:
this.view.style.width = toPixelString(this.frameWidth width = toPixelString(this.frameWidth
- this.paddingLeft - this.paddingRight - this.paddingLeft - this.paddingRight
- this.borderWidth * 2); - this.borderWidth * 2);
break; break;
} }
this.applyCSSStyle({ width });
} }
configHeight() { configHeight() {
let height;
switch (this.layoutConfig.heightSpec) { switch (this.layoutConfig.heightSpec) {
case exports.LayoutSpec.WRAP_CONTENT: case exports.LayoutSpec.WRAP_CONTENT:
this.view.style.height = "max-content"; height = "max-content";
break; break;
case exports.LayoutSpec.AT_MOST: case exports.LayoutSpec.AT_MOST:
this.view.style.height = "100%"; height = "100%";
break; break;
case exports.LayoutSpec.EXACTLY: case exports.LayoutSpec.EXACTLY:
default: default:
this.view.style.height = toPixelString(this.frameHeight height = toPixelString(this.frameHeight
- this.paddingTop - this.paddingBottom - this.paddingTop - this.paddingBottom
- this.borderWidth * 2); - this.borderWidth * 2);
break; break;
} }
this.applyCSSStyle({ height });
} }
configMargin() { configMargin() {
if (this.layoutConfig.margin) { if (this.layoutConfig.margin) {
this.view.style.marginLeft = toPixelString(this.layoutConfig.margin.left || 0); this.applyCSSStyle({
this.view.style.marginRight = toPixelString(this.layoutConfig.margin.right || 0); marginLeft: toPixelString(this.layoutConfig.margin.left || 0),
this.view.style.marginTop = toPixelString(this.layoutConfig.margin.top || 0); marginRight: toPixelString(this.layoutConfig.margin.right || 0),
this.view.style.marginBottom = toPixelString(this.layoutConfig.margin.bottom || 0); marginTop: toPixelString(this.layoutConfig.margin.top || 0),
marginBottom: toPixelString(this.layoutConfig.margin.bottom || 0),
});
} }
} }
configPadding() { configPadding() {
if (this.padding) { if (this.padding) {
this.view.style.paddingLeft = toPixelString(this.paddingLeft); this.applyCSSStyle({
this.view.style.paddingRight = toPixelString(this.paddingRight); paddingLeft: toPixelString(this.paddingLeft),
this.view.style.paddingTop = toPixelString(this.paddingTop); paddingRight: toPixelString(this.paddingRight),
this.view.style.paddingBottom = toPixelString(this.paddingBottom); paddingTop: toPixelString(this.paddingTop),
paddingBottom: toPixelString(this.paddingBottom),
});
} }
} }
layout() { layout() {
@ -4647,35 +4657,61 @@ var doric_web = (function (exports, axios, sandbox) {
break; break;
case 'corners': case 'corners':
if (typeof prop === 'object') { if (typeof prop === 'object') {
this.view.style.borderTopLeftRadius = toPixelString(prop.leftTop); this.applyCSSStyle({
this.view.style.borderTopRightRadius = toPixelString(prop.rightTop); borderTopLeftRadius: toPixelString(prop.leftTop),
this.view.style.borderBottomRightRadius = toPixelString(prop.rightBottom); borderTopRightRadius: toPixelString(prop.rightTop),
this.view.style.borderBottomLeftRadius = toPixelString(prop.leftBottom); borderBottomRightRadius: toPixelString(prop.rightBottom),
borderBottomLeftRadius: toPixelString(prop.leftBottom),
});
} }
else { else {
this.view.style.borderRadius = toPixelString(prop); this.applyCSSStyle({ borderRadius: toPixelString(prop) });
} }
break; break;
case 'shadow': case 'shadow':
const opacity = prop.opacity || 0; const opacity = prop.opacity || 0;
let boxShadow;
if (opacity > 0) { if (opacity > 0) {
const offsetX = prop.offsetX || 0; const offsetX = prop.offsetX || 0;
const offsetY = prop.offsetY || 0; const offsetY = prop.offsetY || 0;
const shadowColor = prop.color || 0xff000000; const shadowColor = prop.color || 0xff000000;
const shadowRadius = prop.radius; const shadowRadius = prop.radius;
const alpha = opacity * 255; const alpha = opacity * 255;
this.view.style.boxShadow = `${toPixelString(offsetX)} ${toPixelString(offsetY)} ${toPixelString(shadowRadius)} ${toRGBAString((shadowColor & 0xffffff) | ((alpha & 0xff) << 24))} `; boxShadow = `${toPixelString(offsetX)} ${toPixelString(offsetY)} ${toPixelString(shadowRadius)} ${toRGBAString((shadowColor & 0xffffff) | ((alpha & 0xff) << 24))} `;
} }
else { else {
this.view.style.boxShadow = ""; boxShadow = "";
} }
this.applyCSSStyle({
boxShadow,
});
break; break;
case 'alpha': case 'alpha':
this.view.style.opacity = `${prop}`; this.applyCSSStyle({
opacity: `${prop}`,
});
break; break;
case 'rotation': case 'rotation':
this.transform.rotation = prop; this.transform.rotation = prop;
break; break;
case 'rotationX':
this.transform.rotationX = prop;
break;
case 'rotationY':
this.transform.rotationY = prop;
break;
case 'scaleX':
this.transform.scaleX = prop;
break;
case 'scaleY':
this.transform.scaleY = prop;
break;
case 'translationX':
this.transform.translateX = prop;
break;
case 'translationY':
this.transform.translateY = prop;
break;
case 'pivotX': case 'pivotX':
if (this.transformOrigin) { if (this.transformOrigin) {
this.transformOrigin.x = prop; this.transformOrigin.x = prop;
@ -4699,12 +4735,9 @@ var doric_web = (function (exports, axios, sandbox) {
} }
break; break;
case 'hidden': case 'hidden':
if (prop === true) { this.applyCSSStyle({
this.view.style.display = "none"; display: prop === true ? "none" : this._originDisplay
} });
else {
this.view.style.display = this._originDisplay;
}
break; break;
default: default:
console.error(`Cannot blend prop for ${propName}`); console.error(`Cannot blend prop for ${propName}`);
@ -4712,7 +4745,7 @@ var doric_web = (function (exports, axios, sandbox) {
} }
} }
set backgroundColor(v) { set backgroundColor(v) {
this.view.style.backgroundColor = toRGBAString(v); this.applyCSSStyle({ backgroundColor: toRGBAString(v) });
} }
static create(context, type) { static create(context, type) {
const viewNodeClass = acquireViewNode(type); const viewNodeClass = acquireViewNode(type);
@ -4748,7 +4781,8 @@ var doric_web = (function (exports, axios, sandbox) {
return Reflect.apply(this.context.pureInvokeEntityMethod, this.context, argumentsList); return Reflect.apply(this.context.pureInvokeEntityMethod, this.context, argumentsList);
} }
updateTransform() { updateTransform() {
this.view.style.transform = Object.entries(this.transform).filter((e) => !!e[1]).map((e) => { this.applyCSSStyle({
transform: Object.entries(this.transform).filter((e) => !!e[1]).map((e) => {
const v = e[1] || 0; const v = e[1] || 0;
switch (e[0]) { switch (e[0]) {
case "translateX": case "translateX":
@ -4759,19 +4793,32 @@ var doric_web = (function (exports, axios, sandbox) {
return `scaleY(${v})`; return `scaleY(${v})`;
case "rotation": case "rotation":
return `rotate(${v / 2}turn)`; return `rotate(${v / 2}turn)`;
case "rotateX": case "rotationX":
return `rotateX(${v / 2}turn)`; return `rotateX(${v / 2}turn)`;
case "rotateY": case "rotationY":
return `rotateY(${v / 2}turn)`; return `rotateY(${v / 2}turn)`;
default: default:
console.error(`Do not support transform ${e[0]}`); console.error(`Do not support transform ${e[0]}`);
return ""; return "";
} }
}).join(" "); }).join(" ")
});
} }
updateTransformOrigin() { updateTransformOrigin() {
if (this.transformOrigin) { if (this.transformOrigin) {
this.view.style.transformOrigin = `${Math.round(this.transformOrigin.x * 100)}% ${Math.round(this.transformOrigin.y * 100)}%`; this.applyCSSStyle({
transformOrigin: `${Math.round(this.transformOrigin.x * 100)}% ${Math.round(this.transformOrigin.y * 100)}%`
});
}
}
applyCSSStyle(cssStyle) {
if (this.context.inAnimation()) {
this.context.addAnimation(this, cssStyle);
}
else {
for (let v in cssStyle) {
Reflect.set(this.view.style, v, cssStyle[v]);
}
} }
} }
/** ++++++++++call from doric ++++++++++*/ /** ++++++++++call from doric ++++++++++*/
@ -5164,28 +5211,33 @@ var doric_web = (function (exports, axios, sandbox) {
} }
configOffset() { configOffset() {
this.childNodes.forEach(e => { this.childNodes.forEach(e => {
e.view.style.position = "absolute"; const position = "absolute";
e.view.style.left = toPixelString(e.offsetX + this.paddingLeft); let left = toPixelString(e.offsetX + this.paddingLeft);
e.view.style.top = toPixelString(e.offsetY + this.paddingTop); let top = toPixelString(e.offsetY + this.paddingTop);
const gravity = e.layoutConfig.alignment; const gravity = e.layoutConfig.alignment;
if ((gravity & LEFT) === LEFT) { if ((gravity & LEFT) === LEFT) {
e.view.style.left = toPixelString(0); left = toPixelString(0);
} }
else if ((gravity & RIGHT) === RIGHT) { else if ((gravity & RIGHT) === RIGHT) {
e.view.style.left = toPixelString(this.view.offsetWidth - e.view.offsetWidth); left = toPixelString(this.view.offsetWidth - e.view.offsetWidth);
} }
else if ((gravity & CENTER_X) === CENTER_X) { else if ((gravity & CENTER_X) === CENTER_X) {
e.view.style.left = toPixelString(this.view.offsetWidth / 2 - e.view.offsetWidth / 2); left = toPixelString(this.view.offsetWidth / 2 - e.view.offsetWidth / 2);
} }
if ((gravity & TOP) === TOP) { if ((gravity & TOP) === TOP) {
e.view.style.top = toPixelString(0); top = toPixelString(0);
} }
else if ((gravity & BOTTOM) === BOTTOM) { else if ((gravity & BOTTOM) === BOTTOM) {
e.view.style.top = toPixelString(this.view.offsetHeight - e.view.offsetHeight); top = toPixelString(this.view.offsetHeight - e.view.offsetHeight);
} }
else if ((gravity & CENTER_Y) === CENTER_Y) { else if ((gravity & CENTER_Y) === CENTER_Y) {
e.view.style.top = toPixelString(this.view.offsetHeight / 2 - e.view.offsetHeight / 2); top = toPixelString(this.view.offsetHeight / 2 - e.view.offsetHeight / 2);
} }
e.applyCSSStyle({
position,
left,
top,
});
}); });
} }
} }
@ -6076,6 +6128,48 @@ var doric_web = (function (exports, axios, sandbox) {
} }
} }
class AnimatePlugin extends DoricPlugin {
submit() {
return Promise.resolve();
}
animateRender(args) {
var _a;
this.context.animationSet = [];
if (((_a = this.context.rootNode.viewId) === null || _a === void 0 ? void 0 : _a.length) > 0) {
const viewNode = this.context.targetViewNode(args.id);
viewNode === null || viewNode === void 0 ? void 0 : viewNode.blend(args.props);
viewNode === null || viewNode === void 0 ? void 0 : viewNode.onBlended();
}
else {
this.context.rootNode.viewId = args.id;
this.context.rootNode.blend(args.props);
this.context.rootNode.onBlended();
}
return new Promise(resolve => {
Promise.resolve().then(() => {
var _a;
Promise.all(((_a = this.context.animationSet) === null || _a === void 0 ? void 0 : _a.map(e => {
return new Promise(resolve => {
const animation = e.viewNode.view.animate([e.keyFrame], {
duration: args.duration,
fill: "forwards"
});
animation.onfinish = () => {
resolve(true);
};
});
})) || [])
.then(() => {
resolve(0);
})
.finally(() => {
this.context.animationSet = undefined;
});
});
});
}
}
const bundles = new Map; const bundles = new Map;
const plugins = new Map; const plugins = new Map;
const nodes = new Map; const nodes = new Map;
@ -6102,6 +6196,7 @@ var doric_web = (function (exports, axios, sandbox) {
registerPlugin('storage', StoragePlugin); registerPlugin('storage', StoragePlugin);
registerPlugin('navigator', NavigatorPlugin); registerPlugin('navigator', NavigatorPlugin);
registerPlugin('popover', PopoverPlugin); registerPlugin('popover', PopoverPlugin);
registerPlugin('animate', AnimatePlugin);
registerViewNode('Stack', DoricStackNode); registerViewNode('Stack', DoricStackNode);
registerViewNode('VLayout', DoricVLayoutNode); registerViewNode('VLayout', DoricVLayoutNode);
registerViewNode('HLayout', DoricHLayoutNode); registerViewNode('HLayout', DoricHLayoutNode);
@ -6309,6 +6404,16 @@ ${content}
build(frame) { build(frame) {
this.invokeEntityMethod("__build__", frame); this.invokeEntityMethod("__build__", frame);
} }
inAnimation() {
return !!this.animationSet;
}
addAnimation(viewNode, keyFrame) {
var _a;
(_a = this.animationSet) === null || _a === void 0 ? void 0 : _a.push({
viewNode,
keyFrame
});
}
teardown() { teardown() {
for (let plugin of this.pluginInstances.values()) { for (let plugin of this.pluginInstances.values()) {
plugin.onTearDown(); plugin.onTearDown();

File diff suppressed because one or more lines are too long

View File

@ -20,6 +20,7 @@ export class DoricContext {
pluginInstances: Map<string, DoricPlugin> = new Map pluginInstances: Map<string, DoricPlugin> = new Map
rootNode: DoricStackNode rootNode: DoricStackNode
headNodes: Map<string, Map<string, DoricViewNode>> = new Map headNodes: Map<string, Map<string, DoricViewNode>> = new Map
animationSet?: { viewNode: DoricViewNode, keyFrame: Partial<CSSStyleDeclaration> }[]
constructor(content: string) { constructor(content: string) {
createContext(this.contextId, content) createContext(this.contextId, content)
@ -84,6 +85,18 @@ export class DoricContext {
}) { }) {
this.invokeEntityMethod("__build__", frame) this.invokeEntityMethod("__build__", frame)
} }
inAnimation() {
return !!this.animationSet
}
addAnimation(viewNode: DoricViewNode, keyFrame: Partial<CSSStyleDeclaration>) {
this.animationSet?.push({
viewNode,
keyFrame
})
}
teardown() { teardown() {
for (let plugin of this.pluginInstances.values()) { for (let plugin of this.pluginInstances.values()) {
plugin.onTearDown() plugin.onTearDown()

View File

@ -15,6 +15,7 @@ import { DoricListItemNode } from "./shader/DoricListItemNode"
import { DoricListNode } from "./shader/DoricListNode" import { DoricListNode } from "./shader/DoricListNode"
import { DoricDraggableNode } from "./shader/DoricDraggableNode" import { DoricDraggableNode } from "./shader/DoricDraggableNode"
import { DoricRefreshableNode } from "./shader/DoricRefreshableNode" import { DoricRefreshableNode } from "./shader/DoricRefreshableNode"
import { AnimatePlugin } from "./plugins/AnimatePlugin"
const bundles: Map<string, string> = new Map const bundles: Map<string, string> = new Map
@ -54,6 +55,7 @@ registerPlugin('modal', ModalPlugin)
registerPlugin('storage', StoragePlugin) registerPlugin('storage', StoragePlugin)
registerPlugin('navigator', NavigatorPlugin) registerPlugin('navigator', NavigatorPlugin)
registerPlugin('popover', PopoverPlugin) registerPlugin('popover', PopoverPlugin)
registerPlugin('animate', AnimatePlugin)
registerViewNode('Stack', DoricStackNode) registerViewNode('Stack', DoricStackNode)
registerViewNode('VLayout', DoricVLayoutNode) registerViewNode('VLayout', DoricVLayoutNode)

View File

@ -0,0 +1,47 @@
import { DoricPlugin } from "../DoricPlugin";
export class AnimatePlugin extends DoricPlugin {
submit() {
return Promise.resolve()
}
animateRender(args: {
duration: number,
id: string,
props: any
}) {
this.context.animationSet = []
if (this.context.rootNode.viewId?.length > 0) {
const viewNode = this.context.targetViewNode(args.id)
viewNode?.blend(args.props)
viewNode?.onBlended()
} else {
this.context.rootNode.viewId = args.id
this.context.rootNode.blend(args.props)
this.context.rootNode.onBlended()
}
return new Promise(resolve => {
Promise.resolve().then(() => {
Promise.all(
this.context.animationSet?.map(e => {
return new Promise(resolve => {
const animation = e.viewNode.view.animate(
[e.keyFrame as Keyframe],
{
duration: args.duration,
fill: "forwards"
})
animation.onfinish = () => {
resolve(true)
}
})
}) || [])
.then(() => {
resolve(0)
})
.finally(() => {
this.context.animationSet = undefined
})
})
})
}
}

View File

@ -39,24 +39,29 @@ export class DoricStackNode extends DoricGroupViewNode {
configOffset() { configOffset() {
this.childNodes.forEach(e => { this.childNodes.forEach(e => {
e.view.style.position = "absolute" const position = "absolute"
e.view.style.left = toPixelString(e.offsetX + this.paddingLeft) let left = toPixelString(e.offsetX + this.paddingLeft)
e.view.style.top = toPixelString(e.offsetY + this.paddingTop) let top = toPixelString(e.offsetY + this.paddingTop)
const gravity = e.layoutConfig.alignment const gravity = e.layoutConfig.alignment
if ((gravity & LEFT) === LEFT) { if ((gravity & LEFT) === LEFT) {
e.view.style.left = toPixelString(0) left = toPixelString(0)
} else if ((gravity & RIGHT) === RIGHT) { } else if ((gravity & RIGHT) === RIGHT) {
e.view.style.left = toPixelString(this.view.offsetWidth - e.view.offsetWidth) left = toPixelString(this.view.offsetWidth - e.view.offsetWidth)
} else if ((gravity & CENTER_X) === CENTER_X) { } else if ((gravity & CENTER_X) === CENTER_X) {
e.view.style.left = toPixelString(this.view.offsetWidth / 2 - e.view.offsetWidth / 2) left = toPixelString(this.view.offsetWidth / 2 - e.view.offsetWidth / 2)
} }
if ((gravity & TOP) === TOP) { if ((gravity & TOP) === TOP) {
e.view.style.top = toPixelString(0) top = toPixelString(0)
} else if ((gravity & BOTTOM) === BOTTOM) { } else if ((gravity & BOTTOM) === BOTTOM) {
e.view.style.top = toPixelString(this.view.offsetHeight - e.view.offsetHeight) top = toPixelString(this.view.offsetHeight - e.view.offsetHeight)
} else if ((gravity & CENTER_Y) === CENTER_Y) { } else if ((gravity & CENTER_Y) === CENTER_Y) {
e.view.style.top = toPixelString(this.view.offsetHeight / 2 - e.view.offsetHeight / 2) top = toPixelString(this.view.offsetHeight / 2 - e.view.offsetHeight / 2)
} }
e.applyCSSStyle({
position,
left,
top,
})
}) })
} }
} }

View File

@ -172,64 +172,75 @@ export abstract class DoricViewNode {
configBorder() { configBorder() {
if (this.border) { if (this.border) {
this.view.style.borderStyle = "solid" this.applyCSSStyle({
this.view.style.borderWidth = toPixelString(this.border.width) borderStyle: "solid",
this.view.style.borderColor = toRGBAString(this.border.color) borderWidth: toPixelString(this.border.width),
borderColor: toRGBAString(this.border.color),
})
} }
} }
configWidth() { configWidth() {
let width: string
switch (this.layoutConfig.widthSpec) { switch (this.layoutConfig.widthSpec) {
case LayoutSpec.WRAP_CONTENT: case LayoutSpec.WRAP_CONTENT:
this.view.style.width = "max-content" width = "max-content"
break break
case LayoutSpec.AT_MOST: case LayoutSpec.AT_MOST:
this.view.style.width = "100%" width = "100%"
break break
case LayoutSpec.EXACTLY: case LayoutSpec.EXACTLY:
default: default:
this.view.style.width = toPixelString(this.frameWidth width = toPixelString(this.frameWidth
- this.paddingLeft - this.paddingRight - this.paddingLeft - this.paddingRight
- this.borderWidth * 2) - this.borderWidth * 2)
break break
} }
this.applyCSSStyle({ width })
} }
configHeight() { configHeight() {
let height
switch (this.layoutConfig.heightSpec) { switch (this.layoutConfig.heightSpec) {
case LayoutSpec.WRAP_CONTENT: case LayoutSpec.WRAP_CONTENT:
this.view.style.height = "max-content" height = "max-content"
break break
case LayoutSpec.AT_MOST: case LayoutSpec.AT_MOST:
this.view.style.height = "100%" height = "100%"
break break
case LayoutSpec.EXACTLY: case LayoutSpec.EXACTLY:
default: default:
this.view.style.height = toPixelString(this.frameHeight height = toPixelString(this.frameHeight
- this.paddingTop - this.paddingBottom - this.paddingTop - this.paddingBottom
- this.borderWidth * 2) - this.borderWidth * 2)
break break
} }
this.applyCSSStyle({ height })
} }
configMargin() { configMargin() {
if (this.layoutConfig.margin) { if (this.layoutConfig.margin) {
this.view.style.marginLeft = toPixelString(this.layoutConfig.margin.left || 0) this.applyCSSStyle({
this.view.style.marginRight = toPixelString(this.layoutConfig.margin.right || 0) marginLeft: toPixelString(this.layoutConfig.margin.left || 0),
this.view.style.marginTop = toPixelString(this.layoutConfig.margin.top || 0) marginRight: toPixelString(this.layoutConfig.margin.right || 0),
this.view.style.marginBottom = toPixelString(this.layoutConfig.margin.bottom || 0) marginTop: toPixelString(this.layoutConfig.margin.top || 0),
marginBottom: toPixelString(this.layoutConfig.margin.bottom || 0),
})
} }
} }
configPadding() { configPadding() {
if (this.padding) { if (this.padding) {
this.view.style.paddingLeft = toPixelString(this.paddingLeft) this.applyCSSStyle({
this.view.style.paddingRight = toPixelString(this.paddingRight) paddingLeft: toPixelString(this.paddingLeft),
this.view.style.paddingTop = toPixelString(this.paddingTop) paddingRight: toPixelString(this.paddingRight),
this.view.style.paddingBottom = toPixelString(this.paddingBottom) paddingTop: toPixelString(this.paddingTop),
paddingBottom: toPixelString(this.paddingBottom),
})
} }
} }
@ -278,33 +289,59 @@ export abstract class DoricViewNode {
break break
case 'corners': case 'corners':
if (typeof prop === 'object') { if (typeof prop === 'object') {
this.view.style.borderTopLeftRadius = toPixelString(prop.leftTop) this.applyCSSStyle({
this.view.style.borderTopRightRadius = toPixelString(prop.rightTop) borderTopLeftRadius: toPixelString(prop.leftTop),
this.view.style.borderBottomRightRadius = toPixelString(prop.rightBottom) borderTopRightRadius: toPixelString(prop.rightTop),
this.view.style.borderBottomLeftRadius = toPixelString(prop.leftBottom) borderBottomRightRadius: toPixelString(prop.rightBottom),
borderBottomLeftRadius: toPixelString(prop.leftBottom),
})
} else { } else {
this.view.style.borderRadius = toPixelString(prop) this.applyCSSStyle({ borderRadius: toPixelString(prop) })
} }
break break
case 'shadow': case 'shadow':
const opacity = prop.opacity || 0 const opacity = prop.opacity || 0
let boxShadow
if (opacity > 0) { if (opacity > 0) {
const offsetX = prop.offsetX || 0 const offsetX = prop.offsetX || 0
const offsetY = prop.offsetY || 0 const offsetY = prop.offsetY || 0
const shadowColor = prop.color || 0xff000000 const shadowColor = prop.color || 0xff000000
const shadowRadius = prop.radius const shadowRadius = prop.radius
const alpha = opacity * 255 const alpha = opacity * 255
this.view.style.boxShadow = `${toPixelString(offsetX)} ${toPixelString(offsetY)} ${toPixelString(shadowRadius)} ${toRGBAString((shadowColor & 0xffffff) | ((alpha & 0xff) << 24))} ` boxShadow = `${toPixelString(offsetX)} ${toPixelString(offsetY)} ${toPixelString(shadowRadius)} ${toRGBAString((shadowColor & 0xffffff) | ((alpha & 0xff) << 24))} `
} else { } else {
this.view.style.boxShadow = "" boxShadow = ""
} }
this.applyCSSStyle({
boxShadow,
})
break break
case 'alpha': case 'alpha':
this.view.style.opacity = `${prop}` this.applyCSSStyle({
opacity: `${prop}`,
})
break break
case 'rotation': case 'rotation':
this.transform.rotation = prop this.transform.rotation = prop
break break
case 'rotationX':
this.transform.rotationX = prop
break
case 'rotationY':
this.transform.rotationY = prop
break
case 'scaleX':
this.transform.scaleX = prop
break
case 'scaleY':
this.transform.scaleY = prop
break
case 'translationX':
this.transform.translateX = prop
break
case 'translationY':
this.transform.translateY = prop
break
case 'pivotX': case 'pivotX':
if (this.transformOrigin) { if (this.transformOrigin) {
this.transformOrigin.x = prop this.transformOrigin.x = prop
@ -326,11 +363,9 @@ export abstract class DoricViewNode {
} }
break break
case 'hidden': case 'hidden':
if (prop === true) { this.applyCSSStyle({
this.view.style.display = "none" display: prop === true ? "none" : this._originDisplay
} else { })
this.view.style.display = this._originDisplay
}
break break
default: default:
console.error(`Cannot blend prop for ${propName}`) console.error(`Cannot blend prop for ${propName}`)
@ -339,7 +374,7 @@ export abstract class DoricViewNode {
} }
set backgroundColor(v: number) { set backgroundColor(v: number) {
this.view.style.backgroundColor = toRGBAString(v) this.applyCSSStyle({ backgroundColor: toRGBAString(v) })
} }
static create(context: DoricContext, type: string) { static create(context: DoricContext, type: string) {
@ -381,7 +416,8 @@ export abstract class DoricViewNode {
updateTransform() { updateTransform() {
this.view.style.transform = Object.entries(this.transform).filter((e: [string, number?]) => !!e[1]).map((e: [string, number?]) => { this.applyCSSStyle({
transform: Object.entries(this.transform).filter((e: [string, number?]) => !!e[1]).map((e: [string, number?]) => {
const v = e[1] || 0 const v = e[1] || 0
switch (e[0]) { switch (e[0]) {
case "translateX": case "translateX":
@ -392,20 +428,33 @@ export abstract class DoricViewNode {
return `scaleY(${v})` return `scaleY(${v})`
case "rotation": case "rotation":
return `rotate(${v / 2}turn)` return `rotate(${v / 2}turn)`
case "rotateX": case "rotationX":
return `rotateX(${v / 2}turn)` return `rotateX(${v / 2}turn)`
case "rotateY": case "rotationY":
return `rotateY(${v / 2}turn)` return `rotateY(${v / 2}turn)`
default: default:
console.error(`Do not support transform ${e[0]}`) console.error(`Do not support transform ${e[0]}`)
return "" return ""
} }
}).join(" ") }).join(" ")
})
} }
updateTransformOrigin() { updateTransformOrigin() {
if (this.transformOrigin) { if (this.transformOrigin) {
this.view.style.transformOrigin = `${Math.round(this.transformOrigin.x * 100)}% ${Math.round(this.transformOrigin.y * 100)}%` this.applyCSSStyle({
transformOrigin: `${Math.round(this.transformOrigin.x * 100)}% ${Math.round(this.transformOrigin.y * 100)}%`
})
}
}
applyCSSStyle(cssStyle: Partial<CSSStyleDeclaration>) {
if (this.context.inAnimation()) {
this.context.addAnimation(this, cssStyle)
} else {
for (let v in cssStyle) {
Reflect.set(this.view.style, v, cssStyle[v])
}
} }
} }
/** ++++++++++call from doric ++++++++++*/ /** ++++++++++call from doric ++++++++++*/