标题: 用自已方法实现一个自已版本的Cover Flow效果
zizhang
注册会员
Rank: 2



UID 93364
精华 3
积分 189
帖子 38
阅读权限 20
注册 2009-10-29
状态 离线
发表于 2010-2-3 11:29  资料  个人空间  短消息  加为好友 
用自已方法实现一个自已版本的Cover Flow效果

从透视效果应用到实现一个转动,(用动画的方式来表现一个程序中的转动),再发展成一个cover flow效果,方法简单,源代码有空发上来。原理是有时我们搬运物体,采用在手上传递的方法,人转身把东西传给旁边的人,然后脱手,再转回身体,从而人不走动,和东西在人的手里向前移动。倒影好象是一张张画面立在一个有很光洁的平面上,影子向下引伸,这可不是效果反射reflection,因为它是与水平线完全对称的,不适合用在立体感的图形中。必须向下引伸,倒影逐渐变虚。可见javafx功能非常之强大!代码简单。

[ 本帖最后由 zizhang 于 2010-2-3 16:55 编辑 ]



 附件: 您所在的用户组无法下载或查看附件
本帖最近评分记录
longaiting   2010-2-10 15:04  威望  +10   不错
galf   2010-2-3 11:47  威望  +10   
顶部
[广告]
zizhang
注册会员
Rank: 2



UID 93364
精华 3
积分 189
帖子 38
阅读权限 20
注册 2009-10-29
状态 离线
发表于 2010-2-5 10:28  资料  个人空间  短消息  加为好友 
用PerspectiveTransform玩出转动效果!

原则是要有3D透视效果,关键是物体具有纵深感,符合远小近大,大的部分接近观测点。

a, 如果有一张图片绕着它的y中心轴做转动,a.jpg是这张图片处于左边部分向你转来,而右边的部分正向你离去,

它的规律是左上角和左下角它的y坐标的特点是相反而行,大者更大,小者更小,如果y值的增量是dh,则必然是左上

角的y值减去这个增量dh,而它左下角的y值加上这个增量dh.而右上角和右下角的y坐标是相向而行,大者变小,小

者变大,则必然是右上角的y值加上这个增量dh,而它左下角的y值减去这个增量dh.所有顶点的x值在没转时离它的y

中心轴的距离最大,其它时刻介于最大和零之间,转过90时为零, dw>0, dh>0.

b, 见图b.jpg是处于没转动时的情况,所有顶点的x,y坐标增量都为零,dh=0, dw=0,

c,见图c.jpg则是这张图片处于左边部分向你离去,而右边的部分正向你转来,情况同a正好相反, dw>0, dh<0.   

在类Positioner创建的对象后,当你设定dw=0,dh=0,就是图b.jpg,当你取dw=30,dh=30则是a.jpg,当你设置dw=30,dh=

-30则是c.jpg,三种位置正好是cover flow effect中的三种位置,当你变化dw,和dh的值在时间线Timeline中时,图

片间的变化是平滑的变化的,再加水平移动,最后产生组合变动,这个问题解决了,接下来将是一马平川。

import javafx.scene.CustomNode;
import javafx.scene.Group;
import javafx.scene.Node;
import javafx.scene.effect.PerspectiveTransform;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;

public class Positioner extends CustomNode {
    package var offsetX:Number;
    package var offsetY:Number;
    package var image:Image;
    package var dw:Number;
    package var dh:Number;

    override function create():Node {
        Group {
            translateX: bind offsetX
            translateY: offsetY
            content:[
                Group {
                    effecterspectiveTransform {
                           ulx: bind dw
                           uly: bind -dh
                           urx: bind 200 - dw
                           ury: bind dh
                           lrx: bind 200 - dw
                           lry: bind 200 - dh
                           llx: bind dw
                           lly: bind 200 + dh
                    }
                    content: [
                        ImageView {
                            x:0 y:0
                            image: bind image
                        }

                    ]
                }
            ]
        }
    }
}

var xoffset:Number = 25;
var yoffset:Number = 50;
var dw:Number;
var dh:Number;

Stage {
   
    scene: Scene {
        width: 250
        height:500
        content: [
            Rectangle {
                x: 0, y: 0
                width: 250, height: 500
            },
            Rectangle {
                x: xoffset, y: yoffset
                width: 200, height: 200
                fill: null
                stroke: Color.WHITE
            },
            Positioner {
                offsetX: xoffset
                offsetY: yoffset
                dw: dw
                dh: dh
                image: bind Image { url: "{__DIR__}img3.jpg" }
                    
            }
               
        ]
    }
}




 附件: 您所在的用户组无法下载或查看附件
顶部
[广告]
zizhang
注册会员
Rank: 2



UID 93364
精华 3
积分 189
帖子 38
阅读权限 20
注册 2009-10-29
状态 离线
发表于 2010-2-20 10:54  资料  个人空间  短消息  加为好友 
package javafxapplication26;

import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.image.Image;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.animation.Timeline;
import javafx.animation.KeyFrame;
import javafx.animation.Interpolator;
import javafx.scene.Group;
import java.lang.Math.*;
import javafx.scene.paint.RadialGradient;
import javafx.scene.paint.Stop;
/**
* @author Administrator
*/
var yoffset = 65;
var dist = 50;
var dx = 0;
var dw:Number = 50;
var dh:Number = 20;
var dh2:Number = 0;
var dh2_target1:Number;
var dh2_target2:Number;
var dh2_target3:Number;
var index = 13;
var images:Image[] = [];
var isRight:Boolean = true;
var count = 0;
var target:Integer;
var g:Group;
for (i in[1..14]) insert Image { url: "{__DIR__}images/img{i}.jpg" } into images;

var tl:Timeline;

function makeMove():Void {

    tl = Timeline {
        repeatCount: bind count
            keyFrames : [
            at(0s) {
                dx => 0 tween Interpolator.EASEIN;
                dw => 50 tween Interpolator.EASEIN;
                dh => 20 tween Interpolator.EASEIN;
                dh2 => dh2_target1 tween Interpolator.EASEIN;
            }
            at(10s) {
                dx => target/3 tween Interpolator.EASEIN;
                dw => 17 tween Interpolator.EASEIN;
                dh => 7 tween Interpolator.EASEIN;
                dh2 => dh2_target2 tween Interpolator.EASEIN
            }
            at(20s) {
                dx => target tween Interpolator.EASEIN;
                dw => 0 tween Interpolator.EASEIN;
                dh => 0 tween Interpolator.EASEIN;
                dh2 => dh2_target3 tween Interpolator.EASEIN;
            }
            KeyFrame {
                time : 21s
                action: function () {
                    if(isRight) index --
                    else index ++;

                    dx = 0;
                    dw = 50;
                    dh = 20;
                    dh2 = dh2_target1;
                    Id = 0;
                    
                }

            }
        ]
    };
    tl.play();
}

var Id:Integer;

function actionPerformed(id:String):Void{
    if(Id == -1 or tl.running) return;
    Id = Integer.parseInt(id);

    if(Id>4) {
       isRight = true;
       target = dist;
       dh2_target1 = 0;
       dh2_target2 = 30;
       dh2_target3 = 20;
    } else if(Id<4) {
       isRight = false;
       target = -dist;
       dh2_target1 = 20;
       dh2_target2 = 30;
       dh2_target3 = 0;
    }

    count = abs(Id-4);
    Id = -1;

    makeMove();
}

Stage {
    title: "Cover Flow 效果"
    scene: Scene {
        width: 700
        height:340
        content: [
            Rectangle {
                x: 0, y: 0
                width: 700, height: 340
                fill: RadialGradient {
                        centerX: 350
                        centerY: 170
                        radius: 180
                        proportional: false
                        stops: [
                            Stop {
                                color : Color.web("#141aa2")
                                offset: 0.0
                            },
                            Stop {
                                color : Color.web("#06012a")
                                offset: 1.0
                            },

                        ]
                }
                stroke: null
            },
            g = Group {
                clip: Rectangle {
                    x: 50, y: -30
                    width: 12*dist, height: 350
                }
                translateY: yoffset
                content: [
                    for (i in [8..6 step -1])
                        Positioner {
                            Id: "{i}"
                            offsetX: bind (7 - i)*dist + dx
                            image: bind images[index-i]
                            action: actionPerformed
                        },

                    Positioner {
                        Id: "5"
                        offsetX: bind if(isRight) 2*dist + 3*dx else 2*dist + dx
                        image: bind images[index-5]
                        dw: bind if(isRight) dw else 50
                        dh: bind if(isRight) dh else 20

                        action: actionPerformed
                    },
                    Positioner {
                        Id: "4"
                        offsetX: bind  5*dist + 3*dx
                        image: bind images[index-4]
                        dw: bind if(isRight) 3*(50 - dw) else 50 - dw
                        dh: bind if(isRight) dh2 else 20 - dh
                    },
                    Positioner {
                        Id: "3"
                        offsetX: bind if(isRight) 8*dist + dx else 8*dist + 3*dx
                        image: bind images[index-3]
                        dw: bind if(isRight) 150 else 3*dw
                        dh: bind if(isRight) 20 else dh2

                        action: actionPerformed
                    },
                    for (i in [2..0 step -1])
                        Positioner {
                            Id: "{i}"
                            offsetX: bind (11 - i)*dist + dx
                            image: bind images[index-i]
                            dw: 150
                            action: actionPerformed
                        },


                ]
            }
        ]
    }
}
g.content[4..] = reverse g.content[4..];





import javafx.scene.CustomNode;
import javafx.scene.Group;
import javafx.scene.Node;
import javafx.scene.image.Image;
import javafx.scene.effect.PerspectiveTransform;
import javafx.scene.image.ImageView;
import javafx.scene.paint.Color;
import javafx.scene.paint.LinearGradient;
import javafx.scene.paint.Stop;
import javafx.scene.shape.Rectangle;
import javafx.scene.input.MouseEvent;
import javafx.scene.text.Text;
import javafx.scene.text.Font;

/**
* @author Administrator
*/

// place your code here
public class Positioner extends CustomNode {
    package var offsetX:Number;
    package var image:Image;
    package var dw:Number = 50;
    package var dh:Number = 20;
    package var sx:Number = 1;
    package var sy:Number = 1;
    package var Id:String;
    package var action:function(:String):Void;

    override function create():Node {
        Group {
            translateX: bind offsetX
            content:[
                Group {
                     effect: bind if(image == null) null else
                     PerspectiveTransform {
                           ulx:bind dw
                           uly:bind -dh
                           urx:bind 200 - dw
                           ury:bind dh
                           lrx:bind 200 - dw
                           lry:bind 400 - 3*dh
                           llx:bind dw
                           lly:bind 400 + 3*dh
                    }
                    content: bind if(image == null) null else [
                        ImageView {
                            x:0 y:0
                            image: bind image
                            onMouseReleased: function (e: MouseEvent): Void {
                                action(this.Id);
                            }
                        },
                        Text {
                            font : Font {
                                size: 14
                                name: "Times New Roman Bold"
                            }
                            x: 10, y: 30
                            content: "{Id}"
                        },
                        ImageView {
                            scaleY:-1.0
                            x:0 y:200
                            image: bind image
                        },
                        Rectangle {
                            x: 0, y: 200
                            width: 200, height: 200
                            fill:  LinearGradient {
                                startX : 0
                                startY : 0.0
                                endX : 0
                                endY : 1
                                stops: [
                                    Stop {
                                        color : Color.rgb(1, 2, 28, 0.5)
                                        offset: 0.0
                                    },
                                    Stop {
                                        color : Color.rgb(1, 2, 28, 0.87)
                                        offset: 0.25
                                    },
                                ]
                            }
                        }
                    ]
                }
            ]
        }
    }
}


顶部
[广告]
zizhang
注册会员
Rank: 2



UID 93364
精华 3
积分 189
帖子 38
阅读权限 20
注册 2009-10-29
状态 离线
发表于 2010-2-22 11:07  资料  个人空间  短消息  加为好友 

取两张图片,一张正面,另一张背面,通过鼠标的水平方向移动使图形翻转(绕y轴转动),看到它的背面,在手机方面有用武之地,同时可以更好理解转动。

package javafxapplication25;


import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.image.Image;
import javafx.scene.input.MouseEvent;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.scene.Group;
import javafx.scene.effect.PerspectiveTransform;
import javafx.scene.image.ImageView;
import javafx.scene.paint.LinearGradient;
import javafx.scene.paint.Stop;
import javafx.scene.CustomNode;
import javafx.scene.Node;
import javafx.scene.shape.Line;


var xoffset:Number = 25;
var yoffset:Number = 50;
var dw:Number = 0;
var dh:Number = 0;

var x0:Number;
var curDx:Number;
var preDx:Number = 0;

Stage {
    title: "reverse test"
    scene: Scene {
        width: 250
        height:500
        fill: Color.BLACK
        content: [
            Rectangle {
                x: xoffset, y: yoffset
                width: 200, height: 200
                fill: Color.BLACK

                onMousePressed: function (e: MouseEvent): Void {
                    x0 = e.x;
                }
                onMouseDragged: function (e: MouseEvent): Void {

                    curDx = preDx + e.x-x0;

                    if(curDx<=0) {
                        dw = 0;
                        dh = 0;
                    }
                    else if (curDx<=100) {
                        dh = 0.3*curDx;
                        dw = curDx;
                    }
                    else if (curDx<=200 ) {
                        dh = 0.3*(200-curDx);
                        dw = curDx;
                    }
                    else if (curDx>200) {
                        dw = 200;
                        dh = 0;
                    }
                }
                onMouseReleased: function (e: MouseEvent): Void {
                    preDx = curDx;
                }
            },
            Rectangle {
                x: xoffset, y: yoffset
                width: 200, height: 200
                fill: null
                stroke: Color.web("#888888")
                strokeWidth:2
            },
            Positioner {
                offsetX: xoffset
                offsetY: yoffset
                dw: bind dw
                dh: bind dh
                sx: bind if(dw<=100) 1 else -1
                image: bind if(dw<=100) Image { url: "{__DIR__}img3.jpg" }
                else Image { url: "{__DIR__}img13.jpg" }
            },
            Line {
                startX: 100 + xoffset, startY: yoffset-10
                endX: 100 + xoffset, endY: 400
                strokeWidth: 2
                stroke: Color.web("#880000")
            },
        ]
    }
}

class Positioner extends CustomNode {
    package var offsetX:Number;
    package var offsetY:Number;
    package var image:Image;
    package var dw:Number = 30;
    package var dh:Number = 20;
    package var sx:Number = 1;

    override function create():Node {
        Group {
            translateX: offsetX
            translateY: offsetY
            
            content:[
                Group {
                     effecterspectiveTransform {
                           ulx:bind dw
                           uly:bind -dh
                           urx:bind 200 - dw
                           ury:bind dh
                           lrx:bind 200 - dw
                           lry:bind 400 - 3*dh
                           llx:bind dw
                           lly:bind 400 + 3*dh
                    }
                    content: [
                        ImageView {
                            scaleX: bind sx
                            x:0 y:0
                            image: bind image
                        },
                        ImageView {
                            scaleX: bind sx
                            scaleY:-1.0
                            x:0 y:200
                            image: bind image
                        },
                        Rectangle {
                            x: 0, y: 200
                            width: 200, height: 200
                            fill:  LinearGradient {
                                startX : 0
                                startY : 0.0
                                endX : 0
                                endY : 1
                                stops: [
                                    Stop {
                                        color : Color.rgb(0, 0, 0, 0.6)
                                        offset: 0.0
                                    },
                                    Stop {
                                        color : Color.rgb(0, 0, 0, 0.87)
                                        offset: 0.4
                                    },
                                ]
                            }
                        }

                    ]
                }

            ]
        }
    }
}






[ 本帖最后由 zizhang 于 2010-3-2 11:40 编辑 ]



 附件: 您所在的用户组无法下载或查看附件
顶部
zizhang
注册会员
Rank: 2



UID 93364
精华 3
积分 189
帖子 38
阅读权限 20
注册 2009-10-29
状态 离线
发表于 2010-2-22 11:12  资料  个人空间  短消息  加为好友 

把天气预报作为载体,1是效果图,2是正在翻转时的正面图(今天的预报),3是正在翻转时的背面图(明天的预报),这是一个上面的具体应用.zip中是源程序。
如果有更快的电脑,或更快的编程语言效果更好。

结束!


[ 本帖最后由 zizhang 于 2010-3-2 11:29 编辑 ]



 附件: 您所在的用户组无法下载或查看附件
顶部
murderer1234
新手上路
Rank: 1



UID 99362
精华 0
积分 3
帖子 1
阅读权限 10
注册 2010-3-24
状态 离线
发表于 2010-3-24 13:56  资料  个人空间  短消息  加为好友 
正是我急需的,非常感谢楼主! :victory: :handshake :handshake :handshake :handshake :handshake

顶部
 



当前时区 GMT+8, 现在时间是 2010-9-9 15:53

    本论坛支付平台由支付宝提供
携手打造安全诚信的交易社区 Powered by Discuz! 5.5.0  © 2001-2007 Comsenz Inc.
Processed in 0.053579 second(s), 11 queries

清除 Cookies - 联系我们 - Unix体验中心 - Archiver