Merge branch 'feature/slider' into 'master'

Feature/slider



See merge request !18
This commit is contained in:
pengfeizhou 2019-11-20 11:59:19 +08:00
commit 5814e79eb6
9 changed files with 505 additions and 55 deletions

View File

@ -5,4 +5,5 @@ export default [
'src/ScrollerDemo', 'src/ScrollerDemo',
'src/SliderDemo', 'src/SliderDemo',
'src/LayoutDemo', 'src/LayoutDemo',
'src/EffectsDemo',
] ]

367
demo/src/EffectsDemo.ts Normal file
View File

@ -0,0 +1,367 @@
import { Group, Panel, Text, text, gravity, Color, Stack, LayoutSpec, vlayout, hlayout, scroller, IVLayout, IHLayout, layoutConfig } from "doric";
import { colors } from "./colorutils";
function box(idx = 0) {
return (new Stack).also(it => {
it.width = it.height = 20
it.bgColor = colors[idx || 0]
})
}
function boxStr(str: string, idx = 0) {
return (new Text).also(it => {
it.width = it.height = 20
it.text = str
it.textColor = Color.parse('#ffffff')
it.bgColor = colors[idx || 0]
})
}
function label(str: string) {
return text({
text: str,
textSize: 16,
})
}
@Entry
class EffectsDemo extends Panel {
build(rootView: Group) {
scroller(
vlayout([
hlayout([
vlayout([
label("Origin view"),
box().apply({
width: 100,
height: 100
}),]).apply({
gravity: gravity().center(),
space: 10,
} as IVLayout),
vlayout([
label("Border"),
box().apply({
width: 100,
height: 100,
border: {
width: 5,
color: colors[3]
},
layoutConfig: layoutConfig().exactly().m({
left: 5,
right: 5,
bottom: 5,
})
}),]).apply({
gravity: gravity().center(),
space: 10,
} as IVLayout),
vlayout([
label("Corner"),
box().apply({
width: 100,
height: 100,
corners: 10,
layoutConfig: layoutConfig().exactly().m({
bottom: 10
})
}),]).apply({
gravity: gravity().center(),
space: 10,
} as IVLayout),
vlayout([
label("Shadow"),
box().apply({
width: 100,
height: 100,
shadow: {
opacity: 1,
color: colors[1],
offsetX: 3,
offsetY: 3,
radius: 5,
},
layoutConfig: layoutConfig().exactly().m({
bottom: 10
})
}),]).apply({
gravity: gravity().center(),
space: 10,
} as IVLayout),
]).apply({ space: 20 } as IHLayout),
hlayout([
vlayout([
label("Border,Corner"),
box().apply({
width: 100,
height: 100,
border: {
width: 5,
color: colors[3]
},
corners: 10,
layoutConfig: layoutConfig().exactly().m({
left: 5,
right: 5,
bottom: 5,
})
}),]).apply({
gravity: gravity().center(),
space: 10,
} as IVLayout),
vlayout([
label("Border,Shadow"),
box().apply({
width: 100,
height: 100,
border: {
width: 5,
color: colors[3]
},
shadow: {
opacity: 1,
color: colors[1],
offsetX: 3,
offsetY: 3,
radius: 5,
},
layoutConfig: layoutConfig().exactly().m({
bottom: 10
})
}),]).apply({
gravity: gravity().center(),
space: 10,
} as IVLayout),
vlayout([
label("Corner,Shadow"),
box().apply({
width: 100,
height: 100,
corners: 10,
shadow: {
opacity: 1,
color: colors[1],
offsetX: 3,
offsetY: 3,
radius: 5,
},
layoutConfig: layoutConfig().exactly().m({
bottom: 10
})
}),]).apply({
gravity: gravity().center(),
space: 10,
} as IVLayout),
vlayout([
label("Border,Corner,Shadow"),
box().apply({
width: 100,
height: 100,
border: {
width: 5,
color: colors[3]
},
corners: 10,
shadow: {
opacity: 1,
color: colors[1],
offsetX: 3,
offsetY: 3,
radius: 5,
},
layoutConfig: layoutConfig().exactly().m({
left: 5,
right: 5,
bottom: 5,
})
}),]).apply({
gravity: gravity().center(),
space: 10,
} as IVLayout),
]).apply({ space: 20 } as IHLayout),
hlayout([
vlayout([
label("Shadow"),
box().apply({
width: 100,
height: 100,
corners: 50,
shadow: {
opacity: 1,
color: colors[1],
offsetX: 0,
offsetY: 0,
radius: 10,
},
layoutConfig: layoutConfig().exactly().m({
left: 10,
right: 10,
bottom: 10,
})
}),]).apply({
gravity: gravity().center(),
space: 10,
} as IVLayout),
vlayout([
label("Shadow,offset"),
box().apply({
width: 100,
height: 100,
corners: 50,
shadow: {
opacity: 1,
color: colors[1],
offsetX: 5,
offsetY: 5,
radius: 5,
},
layoutConfig: layoutConfig().exactly().m({
left: 10,
right: 10,
bottom: 10,
})
}),]).apply({
gravity: gravity().center(),
space: 10,
} as IVLayout),
vlayout([
label("Shadow,opacity"),
box().apply({
width: 100,
height: 100,
corners: 50,
shadow: {
opacity: 0.5,
color: colors[1],
offsetX: 5,
offsetY: 5,
radius: 5,
},
layoutConfig: layoutConfig().exactly().m({
left: 10,
right: 10,
bottom: 10,
})
}),]).apply({
gravity: gravity().center(),
space: 10,
} as IVLayout),
vlayout([
label("Shadow,color"),
box().apply({
width: 100,
height: 100,
corners: 50,
shadow: {
opacity: 1,
color: colors[2],
offsetX: 5,
offsetY: 5,
radius: 5,
},
layoutConfig: layoutConfig().exactly().m({
left: 10,
right: 10,
bottom: 10,
})
}),]).apply({
gravity: gravity().center(),
space: 10,
} as IVLayout),
]).apply({ space: 20 } as IHLayout),
hlayout([
vlayout([
label("Corner round"),
box().apply({
width: 100,
height: 100,
corners: 50,
layoutConfig: layoutConfig().exactly().m({
left: 5,
right: 5,
bottom: 5,
})
}),]).apply({
gravity: gravity().center(),
space: 10,
} as IVLayout),
vlayout([
label("Corner left top"),
box().apply({
width: 100,
height: 100,
corners: {
leftTop: 50,
},
layoutConfig: layoutConfig().exactly().m({
left: 5,
right: 5,
bottom: 5,
})
}),]).apply({
gravity: gravity().center(),
space: 10,
} as IVLayout),
vlayout([
label("Corner right top"),
box().apply({
width: 100,
height: 100,
corners: {
rightTop: 50,
},
layoutConfig: layoutConfig().exactly().m({
left: 5,
right: 5,
bottom: 5,
})
}),]).apply({
gravity: gravity().center(),
space: 10,
} as IVLayout),
vlayout([
label("Corner left bottom"),
box().apply({
width: 100,
height: 100,
corners: {
leftBottom: 50,
},
layoutConfig: layoutConfig().exactly().m({
left: 5,
right: 5,
bottom: 5,
})
}),]).apply({
gravity: gravity().center(),
space: 10,
} as IVLayout),
vlayout([
label("Corner right bottom"),
box().apply({
width: 100,
height: 100,
corners: {
rightBottom: 50,
},
layoutConfig: layoutConfig().exactly().m({
left: 5,
right: 5,
bottom: 5,
})
}),]).apply({
gravity: gravity().center(),
space: 10,
} as IVLayout),
]).apply({ space: 20 } as IHLayout),
]).also(it => {
it.space = 20
}),
).also(it => {
it.layoutConfig = layoutConfig().wrap()
}).in(rootView)
}
}

View File

@ -44,6 +44,7 @@ class ListPanel extends Panel {
text({ text({
textColor: Color.parse("#ffffff"), textColor: Color.parse("#ffffff"),
textSize: 20, textSize: 20,
text: "",
}).also(it => { }).also(it => {
counter = it counter = it
it.layoutConfig = { it.layoutConfig = {

View File

@ -1,53 +1,48 @@
import { Group, Panel, List, text, gravity, Color, Stack, LayoutSpec, list, NativeCall, listItem, log, vlayout, Gravity, hlayout, slider, slideItem } from "doric"; import { Group, Panel, List, text, gravity, Color, Stack, LayoutSpec, list, NativeCall, listItem, log, vlayout, Gravity, hlayout, slider, slideItem, image, layoutConfig } from "doric";
const colors = [ import { colors } from "./colorutils";
"#f0932b",
"#eb4d4b", const imageUrls = [
"#6ab04c", 'http://b.hiphotos.baidu.com/image/pic/item/908fa0ec08fa513db777cf78376d55fbb3fbd9b3.jpg',
"#e056fd", 'http://f.hiphotos.baidu.com/image/pic/item/0e2442a7d933c8956c0e8eeadb1373f08202002a.jpg',
"#686de0", 'http://f.hiphotos.baidu.com/image/pic/item/b151f8198618367aa7f3cc7424738bd4b31ce525.jpg',
"#30336b", 'http://b.hiphotos.baidu.com/image/pic/item/0eb30f2442a7d9337119f7dba74bd11372f001e0.jpg',
'http://calonye.com/wp-content/uploads/2015/08/0-wx_fmtgiftpwebpwxfrom5wx_lazy1-9.gif',
'http://hbimg.b0.upaiyun.com/ca29ea125b7f2d580f573e48eb594b1ef509757f34a08-m0hK45_fw658',
'https://misc.aotu.io/ONE-SUNDAY/SteamEngine.png',
] ]
@Entry @Entry
class SliderPanel extends Panel { class SliderPanel extends Panel {
build(rootView: Group): void { build(rootView: Group): void {
rootView.addChild(vlayout([ rootView.addChild(vlayout([
text({ text({
text: "SliderDemo", text: "Gallery",
layoutConfig: { layoutConfig: {
widthSpec: LayoutSpec.AT_MOST, widthSpec: LayoutSpec.AT_MOST,
heightSpec: LayoutSpec.EXACTLY, heightSpec: LayoutSpec.EXACTLY,
}, },
textSize: 30, textSize: 30,
textColor: Color.parse("#535c68"), textColor: Color.WHITE,
bgColor: Color.parse("#dff9fb"), bgColor: colors[1],
textAlignment: gravity().center(), textAlignment: gravity().center(),
height: 50, height: 50,
}), }),
slider({ slider({
itemCount: 100, itemCount: 100,
renderPage: (idx) => { renderPage: (idx) => {
return slideItem(text({ return slideItem(image({
layoutConfig: { imageUrl: imageUrls[idx % imageUrls.length],
widthSpec: LayoutSpec.AT_MOST, layoutConfig: layoutConfig().wrap().a(gravity().center()),
heightSpec: LayoutSpec.EXACTLY, })).also(it => {
alignment: gravity().center(),
},
text: `Page At Line ${idx}`,
textAlignment: gravity().center(),
textColor: Color.parse("#ffffff"),
textSize: 20,
height: 300,
bgColor: Color.parse(colors[idx % colors.length]),
}).also(it => {
let start = idx let start = idx
it.onClick = () => { it.onClick = () => {
it.bgColor = Color.parse(colors[++start % colors.length]) it.bgColor = (colors[++start % colors.length])
} }
})) })
}, },
layoutConfig: { layoutConfig: {
widthSpec: LayoutSpec.AT_MOST, widthSpec: LayoutSpec.AT_MOST,
heightSpec: LayoutSpec.WRAP_CONTENT, heightSpec: LayoutSpec.WRAP_CONTENT,
weight: 1,
}, },
}), }),
]).also(it => { ]).also(it => {

View File

@ -281,6 +281,14 @@ class SnakeView extends ViewHolder<SnakeModel> {
if (item === undefined) { if (item === undefined) {
item = new Stack item = new Stack
item.width = item.height = 10 item.width = item.height = 10
item.corners = 5
item.shadow = {
color: Color.GRAY,
opacity: 1,
radius: 3,
offsetX: 3,
offsetY: 3,
}
this.panel.addChild(item) this.panel.addChild(item)
} }
if (index === nodes.length - 1) { if (index === nodes.length - 1) {

14
demo/src/colorutils.ts Normal file
View File

@ -0,0 +1,14 @@
import { Color } from "doric";
export const colors = [
"#70a1ff",
"#7bed9f",
"#ff6b81",
"#a4b0be",
"#f0932b",
"#eb4d4b",
"#6ab04c",
"#e056fd",
"#686de0",
"#30336b",
].map(e => Color.parse(e))

View File

@ -147,20 +147,21 @@ - (void)blendView:(UIView *)view forPropName:(NSString *)name propValue:(id)prop
CGFloat rightTop = [(NSNumber *) dic[@"rightTop"] floatValue]; CGFloat rightTop = [(NSNumber *) dic[@"rightTop"] floatValue];
CGFloat rightBottom = [(NSNumber *) dic[@"rightBottom"] floatValue]; CGFloat rightBottom = [(NSNumber *) dic[@"rightBottom"] floatValue];
CGFloat leftBottom = [(NSNumber *) dic[@"leftBottom"] floatValue]; CGFloat leftBottom = [(NSNumber *) dic[@"leftBottom"] floatValue];
CALayer *mask = nil;
if (ABS(leftTop - rightTop) > CGFLOAT_MIN if (ABS(leftTop - rightTop) > CGFLOAT_MIN
|| ABS(leftTop - rightBottom) > CGFLOAT_MIN || ABS(leftTop - rightBottom) > CGFLOAT_MIN
|| ABS(leftTop - leftBottom) > CGFLOAT_MIN) { || ABS(leftTop - leftBottom) > CGFLOAT_MIN) {
view.layer.cornerRadius = 0; view.layer.cornerRadius = 0;
CAShapeLayer *shapeLayer = [CAShapeLayer layer]; dispatch_async(dispatch_get_main_queue(), ^{
CGPathRef path = DoricCreateRoundedRectPath(self.view.bounds, leftTop, rightTop, rightBottom, leftBottom); CAShapeLayer *shapeLayer = [CAShapeLayer layer];
shapeLayer.path = path; CGPathRef path = DoricCreateRoundedRectPath(self.view.bounds, leftTop, rightTop, rightBottom, leftBottom);
CGPathRelease(path); shapeLayer.path = path;
mask = shapeLayer; CGPathRelease(path);
view.layer.mask = shapeLayer;
});
} else { } else {
view.layer.cornerRadius = leftTop; view.layer.cornerRadius = leftTop;
view.layer.mask = nil;
} }
view.layer.mask = mask;
} }
} else if ([name isEqualToString:@"shadow"]) { } else if ([name isEqualToString:@"shadow"]) {
NSDictionary *dic = prop; NSDictionary *dic = prop;

View File

@ -13,18 +13,17 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
import { View, LayoutSpec } from './view' import { View, LayoutSpec, LayoutConfig } from './view'
import { Stack, HLayout, VLayout } from './layout' import { Stack, HLayout, VLayout } from './layout'
import { IText, IImage, Text, Image } from './widgets' import { IText, IImage, Text, Image } from './widgets'
import { IList, List } from './list' import { IList, List } from './list'
import { ISlider, Slider } from './slider' import { ISlider, Slider } from './slider'
import { Gravity } from '../util/gravity'
import { Modeling } from '../util/types'
export function text(config: IText) { export function text(config: IText) {
const ret = new Text const ret = new Text
ret.layoutConfig = { ret.layoutConfig = layoutConfig().wrap()
widthSpec: LayoutSpec.WRAP_CONTENT,
heightSpec: LayoutSpec.WRAP_CONTENT,
}
for (let key in config) { for (let key in config) {
Reflect.set(ret, key, Reflect.get(config, key, config), ret) Reflect.set(ret, key, Reflect.get(config, key, config), ret)
} }
@ -33,10 +32,7 @@ export function text(config: IText) {
export function image(config: IImage) { export function image(config: IImage) {
const ret = new Image const ret = new Image
ret.layoutConfig = { ret.layoutConfig = layoutConfig().wrap()
widthSpec: LayoutSpec.WRAP_CONTENT,
heightSpec: LayoutSpec.WRAP_CONTENT,
}
for (let key in config) { for (let key in config) {
Reflect.set(ret, key, Reflect.get(config, key, config), ret) Reflect.set(ret, key, Reflect.get(config, key, config), ret)
} }
@ -45,10 +41,7 @@ export function image(config: IImage) {
export function stack(views: View[]) { export function stack(views: View[]) {
const ret = new Stack const ret = new Stack
ret.layoutConfig = { ret.layoutConfig = layoutConfig().wrap()
widthSpec: LayoutSpec.WRAP_CONTENT,
heightSpec: LayoutSpec.WRAP_CONTENT,
}
for (let v of views) { for (let v of views) {
ret.addChild(v) ret.addChild(v)
} }
@ -57,10 +50,7 @@ export function stack(views: View[]) {
export function hlayout(views: View[]) { export function hlayout(views: View[]) {
const ret = new HLayout const ret = new HLayout
ret.layoutConfig = { ret.layoutConfig = layoutConfig().wrap()
widthSpec: LayoutSpec.WRAP_CONTENT,
heightSpec: LayoutSpec.WRAP_CONTENT,
}
for (let v of views) { for (let v of views) {
ret.addChild(v) ret.addChild(v)
} }
@ -69,10 +59,7 @@ export function hlayout(views: View[]) {
export function vlayout(views: View[]) { export function vlayout(views: View[]) {
const ret = new VLayout const ret = new VLayout
ret.layoutConfig = { ret.layoutConfig = layoutConfig().wrap()
widthSpec: LayoutSpec.WRAP_CONTENT,
heightSpec: LayoutSpec.WRAP_CONTENT,
}
for (let v of views) { for (let v of views) {
ret.addChild(v) ret.addChild(v)
} }
@ -94,3 +81,79 @@ export function slider(config: ISlider) {
} }
return ret return ret
} }
export class LayoutConfigImpl implements LayoutConfig, Modeling {
widthSpec?: LayoutSpec
heightSpec?: LayoutSpec
margin?: {
left?: number,
right?: number,
top?: number,
bottom?: number,
}
alignment?: Gravity
//Only affective in VLayout or HLayout
weight?: number
wrap() {
this.widthSpec = LayoutSpec.WRAP_CONTENT
this.heightSpec = LayoutSpec.WRAP_CONTENT
return this
}
atmost() {
this.widthSpec = LayoutSpec.AT_MOST
this.heightSpec = LayoutSpec.AT_MOST
return this
}
exactly() {
this.widthSpec = LayoutSpec.EXACTLY
this.heightSpec = LayoutSpec.EXACTLY
return this
}
w(w: LayoutSpec) {
this.widthSpec = w
return this
}
h(h: LayoutSpec) {
this.heightSpec = h
return this
}
m(m: {
left?: number,
right?: number,
top?: number,
bottom?: number,
}) {
this.margin = m
return this
}
a(a: Gravity) {
this.alignment = a
return this
}
wg(w: number) {
this.weight = w
return this
}
toModel() {
return {
widthSpec: this.widthSpec,
heightSpec: this.heightSpec,
margin: this.margin,
alignment: this.alignment ? this.alignment.toModel() : undefined,
weight: this.weight,
}
}
}
export function layoutConfig() {
return new LayoutConfigImpl
}

View File

@ -5,7 +5,7 @@ export function slideItem(item: View) {
return (new SlideItem).also((it) => { return (new SlideItem).also((it) => {
it.layoutConfig = { it.layoutConfig = {
widthSpec: LayoutSpec.AT_MOST, widthSpec: LayoutSpec.AT_MOST,
heightSpec: LayoutSpec.WRAP_CONTENT, heightSpec: LayoutSpec.AT_MOST,
} }
it.addChild(item) it.addChild(item)
}) })