果圖
各位條子,大家下午好!
今天給大家帶來的是 逼真花瓣飄落前端特效源碼!
大家可以按照自己的意愿進行修改!
有想要文件版源碼的朋友,可以到我的HTML學習交流 581549454 !里面都是做前端開發的,拒絕賣課和廣告!純學習交流,每天會上傳一些優秀的作品和源碼,歡迎初學者和大神們。
好了,廢話不多說,上源碼
(function (lib, img, cjs) {
var p; // shortcut to reference prototypes
// library properties:
lib.properties={
width: 1920,
height: 885,
fps: 24,
color: "#FFFFFF",
manifest: [
{src:"images/florwe1.png", id:"florwe1"},
{src:"images/florwe10.png", id:"florwe10"},
{src:"images/florwe11.png", id:"florwe11"},
{src:"images/florwe12.png", id:"florwe12"},
{src:"images/florwe13.png", id:"florwe13"},
{src:"images/florwe14.png", id:"florwe14"},
{src:"images/florwe15.png", id:"florwe15"},
{src:"images/florwe16.png", id:"florwe16"},
{src:"images/florwe17.png", id:"florwe17"},
{src:"images/florwe18.png", id:"florwe18"},
{src:"images/florwe3.png", id:"florwe3"},
{src:"images/florwe4.png", id:"florwe4"},
{src:"images/florwe5.png", id:"florwe5"},
{src:"images/florwe6.png", id:"florwe6"},
{src:"images/florwe7.png", id:"florwe7"},
{src:"images/florwe8.png", id:"florwe8"},
{src:"images/florwe9.png", id:"florwe9"},
{src:"images/sflorwe2.png", id:"sflorwe2"}
]
};
// symbols:
(lib.florwe1=function() {
this.initialize(img.florwe1);
}).prototype=p=new cjs.Bitmap();
p.nominalBounds=new cjs.Rectangle(0,0,309,504);
(lib.florwe10=function() {
this.initialize(img.florwe10);
}).prototype=p=new cjs.Bitmap();
p.nominalBounds=new cjs.Rectangle(0,0,84,68);
(lib.florwe11=function() {
this.initialize(img.florwe11);
}).prototype=p=new cjs.Bitmap();
p.nominalBounds=new cjs.Rectangle(0,0,108,112);
(lib.florwe12=function() {
this.initialize(img.florwe12);
}).prototype=p=new cjs.Bitmap();
p.nominalBounds=new cjs.Rectangle(0,0,146,89);
(lib.florwe13=function() {
this.initialize(img.florwe13);
}).prototype=p=new cjs.Bitmap();
p.nominalBounds=new cjs.Rectangle(0,0,94,96);
(lib.florwe14=function() {
this.initialize(img.florwe14);
}).prototype=p=new cjs.Bitmap();
p.nominalBounds=new cjs.Rectangle(0,0,163,193);
(lib.florwe15=function() {
this.initialize(img.florwe15);
}).prototype=p=new cjs.Bitmap();
p.nominalBounds=new cjs.Rectangle(0,0,112,122);
(lib.florwe16=function() {
this.initialize(img.florwe16);
}).prototype=p=new cjs.Bitmap();
p.nominalBounds=new cjs.Rectangle(0,0,72,96);
(lib.florwe17=function() {
this.initialize(img.florwe17);
}).prototype=p=new cjs.Bitmap();
p.nominalBounds=new cjs.Rectangle(0,0,199,146);
(lib.florwe18=function() {
this.initialize(img.florwe18);
}).prototype=p=new cjs.Bitmap();
p.nominalBounds=new cjs.Rectangle(0,0,294,293);
(lib.florwe3=function() {
this.initialize(img.florwe3);
}).prototype=p=new cjs.Bitmap();
p.nominalBounds=new cjs.Rectangle(0,0,154,88);
(lib.florwe4=function() {
this.initialize(img.florwe4);
}).prototype=p=new cjs.Bitmap();
p.nominalBounds=new cjs.Rectangle(0,0,189,140);
(lib.florwe5=function() {
this.initialize(img.florwe5);
}).prototype=p=new cjs.Bitmap();
p.nominalBounds=new cjs.Rectangle(0,0,91,88);
(lib.florwe6=function() {
this.initialize(img.florwe6);
}).prototype=p=new cjs.Bitmap();
p.nominalBounds=new cjs.Rectangle(0,0,70,110);
(lib.florwe7=function() {
this.initialize(img.florwe7);
}).prototype=p=new cjs.Bitmap();
p.nominalBounds=new cjs.Rectangle(0,0,120,76);
(lib.florwe8=function() {
this.initialize(img.florwe8);
}).prototype=p=new cjs.Bitmap();
p.nominalBounds=new cjs.Rectangle(0,0,199,91);
(lib.florwe9=function() {
this.initialize(img.florwe9);
}).prototype=p=new cjs.Bitmap();
p.nominalBounds=new cjs.Rectangle(0,0,168,162);
(lib.sflorwe2=function() {
this.initialize(img.sflorwe2);
}).prototype=p=new cjs.Bitmap();
p.nominalBounds=new cjs.Rectangle(0,0,111,121);
(lib.補間10=function() {
this.initialize();
// 圖層 1
this.instance=new lib.florwe18();
this.instance.setTransform(-147,-146.5);
this.addChild(this.instance);
}).prototype=p=new cjs.Container();
p.nominalBounds=new cjs.Rectangle(-147,-146.5,294,293);
(lib.補間9=function() {
this.initialize();
// 圖層 1
this.instance=new lib.florwe18();
this.instance.setTransform(183.2,-97.6,1,1,107);
this.addChild(this.instance);
}).prototype=p=new cjs.Container();
p.nominalBounds=new cjs.Rectangle(-183.1,-183.4,366.3,366.9);
(lib.補間8=function() {
this.initialize();
// 圖層 1
this.instance=new lib.florwe8();
this.instance.setTransform(88.9,-63.8,1,1,119.8);
this.addChild(this.instance);
}).prototype=p=new cjs.Container();
p.nominalBounds=new cjs.Rectangle(-88.9,-108.9,177.8,217.9);
(lib.補間7=function() {
this.initialize();
// 圖層 1
this.instance=new lib.florwe8();
this.instance.setTransform(-106.9,23.2,1,1,-36.8);
this.addChild(this.instance);
}).prototype=p=new cjs.Container();
p.nominalBounds=new cjs.Rectangle(-106.9,-96,213.9,192.1);
(lib.補間6=function() {
this.initialize();
// 圖層 1
this.instance=new lib.florwe6();
this.instance.setTransform(-35,-55);
this.addChild(this.instance);
}).prototype=p=new cjs.Container();
p.nominalBounds=new cjs.Rectangle(-35,-55,70,110);
(lib.補間5=function() {
this.initialize();
// 圖層 1
this.instance=new lib.florwe6();
this.instance.setTransform(-35,-55);
this.addChild(this.instance);
}).prototype=p=new cjs.Container();
p.nominalBounds=new cjs.Rectangle(-35,-55,70,110);
(lib.補間4=function() {
this.initialize();
// 圖層 1
this.instance=new lib.florwe4();
this.instance.setTransform(-94.5,-70);
this.addChild(this.instance);
}).prototype=p=new cjs.Container();
p.nominalBounds=new cjs.Rectangle(-94.5,-70,189,140);
(lib.補間3=function() {
this.initialize();
// 圖層 1
this.instance=new lib.florwe4();
this.instance.setTransform(-94.5,-70);
this.addChild(this.instance);
}).prototype=p=new cjs.Container();
p.nominalBounds=new cjs.Rectangle(-94.5,-70,189,140);
(lib.補間1=function() {
this.initialize();
// 圖層 1
this.instance=new lib.florwe1();
this.instance.setTransform(-49.3,125.6,0.456,0.456,-127);
this.addChild(this.instance);
}).prototype=p=new cjs.Container();
p.nominalBounds=new cjs.Rectangle(-134.2,-125.5,268.6,251.1);
// stage content:
(lib.flower=function(mode,startPosition,loop) {
this.initialize(mode,startPosition,loop,{});
// 圖層 1
this.instance=new lib.補間1("synched",0);
this.instance.setTransform(2011.3,25.8);
this.timeline.addTween(cjs.Tween.get(this.instance).to({rotation:43,guide:{path:[2011.2,25.9,1968.7,57.5,1897.7,103.8,1755.9,196.5,1614,269.6,1415.4,372.3,1245.1,421.7,1032.3,483.5,876.4,458,865.1,456.2,854.5,454.2,788.5,441.4,748.4,420.7,723.8,408,709.6,392.7]}},17).to({scaleX:1,scaleY:1,rotation:88.5,guide:{path:[709.4,392.8,699.1,381.7,694.1,369.2,683.3,342.4,698,311.3,711.5,282.8,744.1,254.5,746.9,252.1,749.8,249.8]}},4).to({rotation:156.9,guide:{path:[749.7,249.8,778.7,225.9,816.5,206.6,857.7,185.5,899.2,175.1,942.7,164.2,976.4,167.7,979.1,167.9,981.7,168.3]}},3).to({scaleX:1,scaleY:1,rotation:273.4,guide:{path:[981.7,168.3,1014.5,173,1032.2,192,1051.6,212.9,1048.9,242.7,1046.6,266.9,1030,295.3]}},5).to({rotation:350.6,guide:{path:[1030,295.3,1027.2,300.2,1023.9,305.2,1002.1,338.3,964.2,373.1,926.2,407.8,876.7,440.1,865.7,447.3,854.3,454.2,848.1,458,841.9,461.6]}},5).to({rotation:382.2,guide:{path:[841.9,461.6,806.6,482.2,768.4,500,732.5,516.7,695.9,530.1]}},4).to({scaleX:1,scaleY:1,rotation:417.6,guide:{path:[695.9,530,671.2,539,646.3,546.5,508,587.6,388.1,574.1,370.2,566.2,343.9,553.9]}},9).to({scaleX:1,scaleY:1,rotation:430.2,guide:{path:[343.7,553.9,336.3,550.4,328.3,546.6,254.5,511.8,184.7,475.3,-38.8,358.3,-140.1,267.2]}},12).to({_off:true},1).wait(71));
// 圖層 3
this.instance_1=new lib.補間3("synched",0);
this.instance_1.setTransform(2088.5,108.5);
this.instance_1._off=true;
this.instance_2=new lib.補間4("synched",0);
this.instance_2.setTransform(-153.8,343.9);
this.timeline.addTween(cjs.Tween.get({}).to({state:[]}).to({state:[{t:this.instance_1}]},56).to({state:[{t:this.instance_1}]},28).to({state:[{t:this.instance_1}]},7).to({state:[{t:this.instance_1}]},8).to({state:[{t:this.instance_1}]},6).to({state:[{t:this.instance_2}]},10).to({state:[]},1).wait(15));
this.timeline.addTween(cjs.Tween.get(this.instance_1).wait(56).to({_off:false},0).to({rotation:51.7,guide:{path:[2088.5,108.7,2028.4,137,1934.7,178,1744.1,261.2,1570.1,327.1,1326.6,419.3,1151.2,463.2,932.1,518.1,832.4,494.1,783.2,482.2,744.5,464,702.8,444.3,673.2,417.2,668.1,412.5,663.4,407.7]}},28).to({scaleX:1,scaleY:1,rotation:184.6,guide:{path:[663.1,407.6,644.7,388.5,633.2,366.8,619.6,341.4,616.3,314.2,613.3,288.4,619.9,263.6,626.3,239.4,641.1,219.2,656,199,677.4,185.4,699.6,171.3,726.1,166.1,761.9,159.2,798.9,162.6]}},7).to({rotation:318.2,guide:{path:[798.8,162.7,816.3,164.3,834.1,168.2,887.1,180,922.7,207.4,959.7,235.9,962.5,270.4,965.5,308.7,924.1,344,892.8,370.8,873.4,385.7,843.1,409.2,812.9,427.7]}},8).to({scaleX:1,scaleY:1,rotation:333.9,guide:{path:[812.9,427.6,809.8,429.5,806.7,431.4,776.3,449.6,744.2,463.9,682.5,491.7,595.9,501.8,525.3,510.1,444.8,505.8]}},6).to({_off:true,scaleX:1,scaleY:1,rotation:360,x:-153.8,y:343.9},10).wait(16));
// 圖層 5
this.instance_3=new lib.補間5("synched",0);
this.instance_3.setTransform(2075.1,60.1,1,1,39.5);
this.instance_3._off=true;
this.instance_4=new lib.補間6("synched",0);
this.instance_4.setTransform(-167.3,456.4,1,1,100);
this.timeline.addTween(cjs.Tween.get({}).to({state:[]}).to({state:[{t:this.instance_3}]},41).to({state:[{t:this.instance_3}]},22).to({state:[{t:this.instance_3}]},1).to({state:[{t:this.instance_3}]},2).to({state:[{t:this.instance_3}]},3).to({state:[{t:this.instance_3}]},3).to({state:[{t:this.instance_4}]},28).to({state:[]},1).wait(30));
this.timeline.addTween(cjs.Tween.get(this.instance_3).wait(41).to({_off:false},0).to({rotation:66,guide:{path:[2075.1,60.2,2020.9,89.7,1939.2,132.3,1764.2,223.5,1606.3,297.8,1385.2,402.2,1229.5,458.6,1087.5,510,1006.4,519.1]}},22).to({rotation:-75,guide:{path:[1006.2,519.1,976.1,522.5,954.2,520.1,954,519.9,953.8,519.8]}},1).to({scaleX:1,scaleY:1,rotation:60.2,guide:{path:[953.7,519.8,946.5,515.4,936.4,508.4,927.2,502,919.1,495.7]}},2).to({scaleX:1,scaleY:1,rotation:97.6,guide:{path:[919.1,495.7,910.4,489,902.9,482.5]}},3).to({scaleX:1,scaleY:1,rotation:45,guide:{path:[902.9,482.4,901.5,481.2,900.1,480,892.6,482.7,883.5,485.5]}},3).to({_off:true,rotation:100,guide:{path:[883.5,485.6,855.8,494.2,814.2,504.2,703.9,530.6,582.1,542.3,411.4,558.8,242.1,543.4,30.5,524.2,-167.2,456.3]}},28).wait(31));
// 圖層 7
this.instance_5=new lib.補間7("synched",0);
this.instance_5.setTransform(2025.9,210.5);
this.instance_5._off=true;
this.instance_6=new lib.補間8("synched",0);
this.instance_6.setTransform(-328,350.1);
this.timeline.addTween(cjs.Tween.get({}).to({state:[]}).to({state:[{t:this.instance_5}]},9).to({state:[{t:this.instance_5}]},15).to({state:[{t:this.instance_5}]},24).to({state:[{t:this.instance_6}]},20).to({state:[]},3).wait(60));
this.timeline.addTween(cjs.Tween.get(this.instance_5).wait(9).to({_off:false},0).to({rotation:23.7,guide:{path:[2025.9,210.7,2013.8,219.9,1991.4,235.5,1945.6,267.2,1891.3,300.6,1717.8,407.5,1525.3,489.1,1479.4,508.5,1433.5,526]}},15).to({scaleX:1,scaleY:1,rotation:52,guide:{path:[1433.6,526,1209.9,611.3,986.7,650.5,675.6,705.2,381.5,666.9]}},24).to({_off:true,scaleX:1,scaleY:1,rotation:0,guide:{path:[381.3,666.9,357.6,663.8,334,660.1,17.7,610.6,-157.4,550.9,-297.7,503.1,-341.9,451,-373.5,413.8,-353.9,378.2,-347.7,367.1,-337.2,357.4,-332.6,353.7,-327.9,350]}},20).wait(63));
// 圖層 9
this.instance_7=new lib.補間9("synched",0);
this.instance_7.setTransform(2070.5,-77.3,0.617,0.617,0,0,0,0.3,-0.1);
this.instance_8=new lib.補間10("synched",0);
this.instance_8.setTransform(-188.6,225.3,1.715,1.715,150,0,0,-0.4,0.7);
this.timeline.addTween(cjs.Tween.get({}).to({state:[{t:this.instance_7}]}).to({state:[{t:this.instance_7}]},18).to({state:[{t:this.instance_7}]},22).to({state:[{t:this.instance_7}]},19).to({state:[{t:this.instance_8}]},11).to({state:[]},1).wait(60));
this.timeline.addTween(cjs.Tween.get(this.instance_7).to({regX:0,regY:0,scaleX:1,scaleY:1,rotation:78.6,guide:{path:[2070.4,-77.2,1968,-40.2,1805.8,10.6,1647.9,59.8,1495.3,101.7]}},18).to({regX:0.6,regY:-0.5,scaleX:1.22,scaleY:1.22,rotation:220.2,guide:{path:[1495.2,101.9,1330.8,146.8,1172.2,183.3,965.9,230.6,784,259.7]}},22).to({regX:0.3,regY:-0.1,scaleX:1.42,scaleY:1.42,rotation:385.7,guide:{path:[784,259.6,588.7,290.8,421.7,300.8,281.8,309.2,164.5,302.5]}},19).to({_off:true,regX:-0.4,regY:0.7,scaleX:1.72,scaleY:1.72,rotation:510,guide:{path:[164.2,302.6,-50.7,290.3,-189.3,227.1]}},11).wait(61));
// 圖層 1
this.instance_9=new lib.補間1("synched",0);
this.instance_9.setTransform(2011.3,191.8);
this.instance_9._off=true;
this.timeline.addTween(cjs.Tween.get(this.instance_9).wait(41).to({_off:false},0).to({rotation:148,guide:{path:[2011.2,191.9,1968.7,223.5,1897.7,269.8,1755.9,362.3,1614,435.6,1597.1,444.4,1580.4,452.7,1400.9,542.5,1245.1,587.7,1032.3,649.5,876.4,624,865.1,622.2,854.5,620.2,788.5,607.4,748.4,586.7,706.1,564.9,694.3,535.2,683.5,508.4,698.2,477.3,710.6,451.1,739.1,425.1]}},17).to({scaleX:1,scaleY:1,rotation:208.5,guide:{path:[738.9,425.2,741.4,422.8,744.1,420.5,774,394.7,813.9,373.9]}},4).to({rotation:268.5,guide:{path:[813.9,373.9,815.2,373.2,816.5,372.6,857.8,351.5,899.2,341.1,939.3,331,971.1,333.2]}},3).to({scaleX:1,scaleY:1,rotation:273.4,guide:{path:[971.1,333.2,973.8,333.4,976.4,333.7,995.3,335.6,1009.5,342.1]}},5).to({rotation:350.6,guide:{path:[1009.6,342,1023,348,1032.2,358,1049.4,376.4,1049.2,401.9]}},5).to({rotation:382.2,guide:{path:[1049.2,402,1049.2,405.3,1048.9,408.7,1046.2,437.1,1023.9,471.2,1002.1,504.3,964.2,539.1,944.7,556.9,922.1,574.1]}},4).to({scaleX:1,scaleY:1,rotation:417.6,guide:{path:[922.1,574.1,900.7,590.4,876.7,606.1,865.6,613.3,854.2,620.2,813.3,645,768.4,666,708.1,694.1,646.2,712.5,507.9,753.6,388.2,740.1,365.3,730.1,328.5,712.7,303,700.7,278.1,688.5]}},9).to({scaleX:1,scaleY:1,rotation:430.2,x:-140.2,y:429.1},12).to({_off:true},1).wait(30));
// 圖層 3
this.instance_10=new lib.補間3("synched",0);
this.instance_10.setTransform(2088.5,230.5);
this.instance_10._off=true;
this.instance_11=new lib.補間4("synched",0);
this.instance_11.setTransform(-153.8,343.9);
this.timeline.addTween(cjs.Tween.get({}).to({state:[]}).to({state:[{t:this.instance_10}]},27).to({state:[{t:this.instance_10}]},28).to({state:[{t:this.instance_10}]},7).to({state:[{t:this.instance_10}]},8).to({state:[{t:this.instance_10}]},6).to({state:[{t:this.instance_11}]},10).to({state:[]},1).wait(44));
this.timeline.addTween(cjs.Tween.get(this.instance_10).wait(27).to({_off:false},0).to({rotation:51.7,guide:{path:[2088.5,230.7,2028.4,259,1934.7,300,1744.1,383.2,1570.1,449.1,1326.6,541.3,1151.2,585.2,932.1,640.1,832.4,616.1,783.2,604.2,744.5,586,702.8,566.3,673.2,539.2,668.1,534.5,663.4,529.7]}},28).to({scaleX:1,scaleY:1,rotation:184.6,guide:{path:[663.1,529.6,644.7,510.5,633.2,488.8,619.6,463.4,616.3,436.2,613.3,410.4,619.9,385.6,626.3,361.4,641.1,341.2,656,320.8,677.4,307.2,699.6,293.1,726.1,287.9,761.9,281,798.9,284.4]}},7).to({rotation:318.2,guide:{path:[798.8,284.4,816.3,286,834.1,290,887.1,301.7,922.7,329.2,959.7,357.8,962.5,392.3,965.5,430.6,924.1,466,893.5,492.1,874.3,507]}},8).to({scaleX:1,scaleY:1,rotation:333.9,guide:{path:[874.4,507,873.9,507.3,873.5,507.7,840,533.5,806.8,553.4,776.4,571.6,744.3,585.9,682.5,613.7,595.9,623.8,522.1,632.5,437.4,627.4]}},6).to({_off:true,scaleX:1,scaleY:1,rotation:360,x:-153.8,y:343.9},10).wait(45));
// 圖層 5
this.instance_12=new lib.補間5("synched",0);
this.instance_12.setTransform(2165.1,94.1,1,1,39.5);
this.instance_12._off=true;
this.instance_13=new lib.補間6("synched",0);
this.instance_13.setTransform(-167.3,456.4,1,1,100);
this.timeline.addTween(cjs.Tween.get({}).to({state:[]}).to({state:[{t:this.instance_12}]},56).to({state:[{t:this.instance_12}]},22).to({state:[{t:this.instance_12}]},1).to({state:[{t:this.instance_12}]},2).to({state:[{t:this.instance_12}]},3).to({state:[{t:this.instance_12}]},3).to({state:[{t:this.instance_13}]},28).to({state:[]},1).wait(15));
this.timeline.addTween(cjs.Tween.get(this.instance_12).wait(56).to({_off:false},0).to({rotation:66,guide:{path:[2165.1,94.2,2110.9,123.7,2029.2,166.3,1854.2,257.5,1696.3,331.8,1475.2,436.2,1319.5,492.6,1124.9,563.1,1044.4,554.1,1037.1,549.6,1026.7,542.3,1013.4,533.1,1002.4,524.2]}},22).to({rotation:-75,guide:{path:[1002.2,524.3,995.8,519.1,990.2,514.1,975.5,519.3,955.2,525]}},1).to({scaleX:1,scaleY:1,rotation:60.2,guide:{path:[955.2,525,942.9,528.5,928.5,532.2]}},2).to({scaleX:1,scaleY:1,rotation:97.6,guide:{path:[928.4,532.2,922.4,533.7,916,535.3]}},3).to({scaleX:1,scaleY:1,rotation:45,guide:{path:[916,535.3,910.3,536.7,904.3,538.2,900.3,539.1,896.3,540]}},3).to({_off:true,rotation:100,x:-167.3,y:456.4},28).wait(16));
// 圖層 7
this.instance_14=new lib.補間7("synched",0);
this.instance_14.setTransform(2265.9,104.5);
this.instance_14._off=true;
this.instance_15=new lib.補間8("synched",0);
this.instance_15.setTransform(-88,244.1);
this.timeline.addTween(cjs.Tween.get({}).to({state:[]}).to({state:[{t:this.instance_14}]},69).to({state:[{t:this.instance_14}]},15).to({state:[{t:this.instance_14}]},24).to({state:[{t:this.instance_15}]},20).wait(3));
this.timeline.addTween(cjs.Tween.get(this.instance_14).wait(69).to({_off:false},0).to({rotation:23.7,guide:{path:[2265.9,104.7,2253.8,113.9,2231.4,129.5,2185.6,161.4,2131.3,194.8,1957.8,301.5,1765.3,383.1,1719.4,402.5,1673.5,420]}},15).to({scaleX:1,scaleY:1,rotation:52,guide:{path:[1673.6,420,1449.9,505.3,1226.7,544.5,915.4,599.2,621.5,560.9]}},24).to({_off:true,scaleX:1,scaleY:1,rotation:0,guide:{path:[621.3,560.9,597.6,557.8,574,554.1,257.7,504.6,82.6,444.9,-57.7,397.1,-101.9,345,-133.5,307.8,-113.9,272.4,-107.7,261.3,-97.2,251.6,-92.6,247.9,-87.9,244.2]}},20).wait(3));
// 圖層 9
this.instance_16=new lib.補間9("synched",0);
this.instance_16.setTransform(2040.5,58.7,0.617,0.617,0,0,0,0.3,-0.1);
this.instance_16._off=true;
this.instance_17=new lib.補間10("synched",0);
this.instance_17.setTransform(-218.6,362.3,0.499,0.498,150,0,0,-0.4,0.6);
this.timeline.addTween(cjs.Tween.get({}).to({state:[]}).to({state:[{t:this.instance_16}]},46).to({state:[{t:this.instance_16}]},18).to({state:[{t:this.instance_16}]},22).to({state:[{t:this.instance_16}]},19).to({state:[{t:this.instance_17}]},11).to({state:[]},1).wait(14));
this.timeline.addTween(cjs.Tween.get(this.instance_16).wait(46).to({_off:false},0).to({regX:0,regY:0,scaleX:0.58,scaleY:0.58,rotation:78.6,guide:{path:[2040.4,58.8,1938,95.8,1775.8,146.4,1617.9,195.8,1465.2,237.7]}},18).to({regX:0.6,regY:-0.5,scaleX:0.48,scaleY:0.48,rotation:220.2,guide:{path:[1465.2,237.8,1300.8,282.9,1142.2,319.3,936.2,366.6,754.6,395.6]}},22).to({regX:0.3,regY:-0.1,scaleX:0.51,scaleY:0.51,rotation:385.8,guide:{path:[754.6,395.5,559,426.8,391.7,436.8,251.6,445.2,134.2,438.5]}},19).to({_off:true,regX:-0.4,regY:0.6,scaleX:0.5,scaleY:0.5,rotation:510,guide:{path:[134,438.5,-80.5,426.2,-218.9,363.2]}},11).wait(15));
}).prototype=p=new cjs.MovieClip();
p.nominalBounds=new cjs.Rectangle(2837,252.1,306.3,341.8);
})(lib=lib||{}, images=images||{}, createjs=createjs||{});
var lib, images, createjs;
著元宇宙概念的火爆,3D 渲染相關的技術頻繁被提及,而 Three.js 是基于 WebGL 的 api 封裝的用于簡化 3D 場景的開發的框架, 是入門 3D 的不錯的抓手,今天我們就來入門下 Three.js。
我們基于 Three.js 來實現一個花瓣雨的效果。
Three.js 的基礎
Three.js 用于渲染一個 3D 的場景,里面會有很多物體,比如立方體、圓柱、圓環、圓錐等各種幾何體(以 Geometry 為后綴),比如點(Points)線(Line)面(Sprite)等基礎物體。這些所有的物體怎么管理呢?
用一個場景 Scene 來承載,所有的物體都會被添加到 Scene 里。
所以有這樣的 api:
const scene=new THREE.Scene();
scene.add(xxx);
scene.add(yyy);
當然,物體之間可以做分組 Group,組內的物體可以統一管理,之后再添加到 Scene 里。
const scene=new THREE.Scene();
const group=new THREE.Group();
group.add(xxx);
group.add(yyy);
scene.add(group);
這種場景、物體、分組的概念,在很多游戲引擎中也有類似的 api,大家都是這么來管理的。
可以添加到 Scene 中的物體,除了幾何體(Geometry)、點線面等,還有輔助工具,比如坐標系工具(AxisHelper)。其實這些工具也是用集合體、點線面封裝出來的,只不過是作為工具來臨時添加到 Scene 中。
const axisHelper=new THREE.AxisHelper(max);
scene.add(axisHelper)
有了場景和場景中的各種物體,怎么渲染出來呢?
調用 Renderer,這個類是專門負責渲染 Scene 中各種物體的。
但是還有個問題,三維的世界(scene)怎么渲染到二維的屏幕呢?
圖片
圖片
如圖,從一個點找個角度來看三維世界,或者從一個平面來平行的看三維世界,看到的就是二維的。
這兩種方式,第一種叫做透視、第二種叫做正交。
生成二維圖像,就像照相機的功能一樣,所以這種概念叫做 Camera。
在 Three.js 里面有 PerspectiveCamera (透視相機)和 OrthographicCamera(正交相機),分別對應上面兩種三維轉二維的方式。
這兩個 Camera 的參數還是挺多的,但是理解了也挺簡單:
new Three.PerspectiveCamera( fov, aspect, near, far )
new Three.OrthographicCamera( left, right, top, bottom, near, far )
先看透視相機的,它要看三維世界,那就要有一個最近和最遠兩個位置,然后從一個點看過去會有一個視野的角度,看到的畫面還有個寬高比。
這就是為什么 PerspectCamera 有 near、far、fov、aspect 這四個參數。
圖片
正交相機的參數也是差不多的意思,不過因為不是從一個點,看的,而是從一個面做的投影,那么就沒有角度的參數,而是有上下左右的四個面位置的參數。
圖片
正交相機的上下左右位置也不是隨便的,比例要和畫面的寬高比一樣,所以一般都是這么算:
const width=window.innerWidth;
const height=window.innerHeight;
//窗口寬高比
const k=width / height;
//三維場景的顯示的上下范圍
const s=200;
// 上下范圍 s 再乘以寬高比 k 就是左右的范圍,而遠近隨便設置一個數就行
const camera=new THREE.OrthographicCamera(-s * k, s * k, s, -s, 1, 1000);
上面的正交相機的參數里面,遠近可以設置為 1 和 1000,上下設置為 200,左右就可以根據寬高比算出來。這就是相機所看到的二維畫面的范圍。
有了場景 Scene 中的各種物體,有了照相機 Camera,就可以用渲染器 Renderer 渲染出畫面來了。
const renderer=new THREE.WebGLRenderer();
//設置渲染區域尺寸
renderer.setSize(width, height)
renderer.render(scene, camera)
不過,一般不會只渲染一幀,有動畫效果的話,會使用 requestAnimationFrame 的 api 一幀幀的不停渲染。
function render() {
renderer.render(scene, camera)
requestAnimationFrame(render)
}
render();
這就是 Three.js 的大概流程:Scene 中有幾何體Geometry、點線面、輔助工具等各種物體,物體還可以做分組,然后通過正交或者透視相機來設置看到的二維畫面,之后用 Renderer 渲染出來。有動畫效果的話,要用 requestAnimationFrame 來一幀幀的渲染。
下面我們來實現一下花瓣雨的效果。
花瓣雨實現
首先我們要創建場景 Scene 中的物體,也就是各種花瓣,這個需要顯示的是一個平面,可以用 Sprite。
Sprite 是精靈的意思,在 Three.js 中,它就是一個永遠面向相機的二維平面。
我們給 Sprite 貼上花瓣的紋理就可以了。
我們先準備一些花瓣的貼圖,類似這種:
圖片
圖片
花瓣的數量有很多,我們生成 400 個,加到花瓣分組里,然后添加到場景中:
const scene=new THREE.Scene();
/**
* 花瓣分組
*/
const petal=new THREE.Group();
function create() {
var texture1=new THREE.TextureLoader().load("img/h1.png");
var texture2=new THREE.TextureLoader().load("img/h2.png");
var texture3=new THREE.TextureLoader().load("img/h3.png");
var texture4=new THREE.TextureLoader().load("img/h4.png");
var texture5=new THREE.TextureLoader().load("img/h5.png");
var imageList=[texture1, texture2, texture3, texture4, texture5];
for (let i=0; i < 400; i++) {
var spriteMaterial=new THREE.SpriteMaterial({
map: imageList[Math.floor(Math.random() * imageList.length)],//設置精靈紋理貼圖
});
var sprite=new THREE.Sprite(spriteMaterial);
petal.add(sprite);
sprite.scale.set(40, 50, 1);
sprite.position.set(2000 * (Math.random() - 0.5), 2000 * Math.random(), 0)
}
scene.add(petal)
}
create();
400 個 Sprite 隨機貼上了不同的花瓣的紋理貼圖,然后設置了下放縮,之后隨機設置了一個在場景中的位置。
我們在 Scene 中加入坐標系輔助工具來看下坐標:
const axisHelper=new THREE.AxisHelper(1000);
scene.add(axisHelper)
圖片
紅色是 x 軸,向右是遞增的,綠色是 y 軸,向上是遞增的。z 軸我們暫時用不到。
所以,根據代碼,花瓣的 x 的范圍就是隨機的 -1000 到 1000,y 的范圍就是 0 到 2000。
然后,我們創建正交相機:
const width=window.innerWidth;
const height=window.innerHeight;
//窗口寬高比
const k=width / height;
//三維場景的顯示的上下范圍
const s=200;
const camera=new THREE.OrthographicCamera(-s * k, s * k, s, -s, 1, 1000);
設置下相機的位置和方向:
camera.position.set(0, 200, 500)
camera.lookAt(scene.position)
我們創建相機的時候指定了二維能顯示的范圍,相機在這個范圍內的哪個位置都行。
然后創建渲染器,設置下大小和背景顏色,把渲染到的 canvas 元素插入到 dom 中。
const renderer=new THREE.WebGLRenderer();
//設置渲染區域尺寸
renderer.setSize(width, height)
//設置背景顏色
renderer.setClearColor(0xFFFFFF, 1)
//body元素中插入canvas對象
document.body.appendChild(renderer.domElement)
之后就用 requestAnimation 不斷地一幀幀渲染就行了。
function render() {
petal.children.forEach(sprite=> {
sprite.position.y -=1;
sprite.position.x +=0.5;
if (sprite.position.y < -400) {
sprite.position.y=800;
}
if (sprite.position.x > 1000) {
sprite.position.x=-1000
}
});
renderer.render(scene, camera)
requestAnimationFrame(render)
}
每次重新渲染之前,我們修改下花瓣的位置,產生下落效果,如果超出了范圍,就移到上面去重新開始落,這樣就是不間斷的花瓣雨效果。
圖片
完整代碼如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>花瓣雨</title>
<style>
body {
margin: 0;
overflow: hidden;
}
</style>
<script src="js/three.min.js"></script>
</head>
<body>
<script>
const scene=new THREE.Scene();
/**
* 花瓣分組
*/
const petal=new THREE.Group();
const width=window.innerWidth;
const height=window.innerHeight;
//窗口寬高比
const k=width / height;
//三維場景的顯示的上下范圍
const s=200;
const camera=new THREE.OrthographicCamera(-s * k, s * k, s, -s, 1, 1000);
const renderer=new THREE.WebGLRenderer();
function create() {
//設置相機位置
camera.position.set(0, 200, 500)
camera.lookAt(scene.position)
//設置渲染區域尺寸
renderer.setSize(width, height)
//設置背景顏色
renderer.setClearColor(0xFFFFFF, 1)
//body元素中插入canvas對象
document.body.appendChild(renderer.domElement)
// const axisHelper=new THREE.AxisHelper(1000);
// scene.add(axisHelper)
var textureTree1=new THREE.TextureLoader().load("img/h1.png");
var textureTree2=new THREE.TextureLoader().load("img/h2.png");
var textureTree3=new THREE.TextureLoader().load("img/h3.png");
var textureTree4=new THREE.TextureLoader().load("img/h4.png");
var textureTree5=new THREE.TextureLoader().load("img/h5.png");
var imageList=[textureTree1, textureTree2, textureTree3, textureTree4, textureTree5];
for (let i=0; i < 400; i++) {
var spriteMaterial=new THREE.SpriteMaterial({
map: imageList[Math.floor(Math.random() * imageList.length)],//設置精靈紋理貼圖
});
var sprite=new THREE.Sprite(spriteMaterial);
petal.add(sprite);
sprite.scale.set(40, 50, 1);
sprite.position.set(2000 * (Math.random() - 0.5), 2000 * Math.random(), 0)
}
scene.add(petal)
}
function render() {
petal.children.forEach(sprite=> {
sprite.position.y -=1;
sprite.position.x +=0.5;
if (sprite.position.y < -400) {
sprite.position.y=800;
}
if (sprite.position.x > 1000) {
sprite.position.x=-1000
}
});
renderer.render(scene, camera)
requestAnimationFrame(render)
}
create()
render()
</script>
</body>
</html>
總結
Three.js 是為了簡化 3D 渲染的框架,它提供了場景 Scene 的 api,里面可以包含各種可渲染的物體:立方體、圓錐等各種幾何體 Geometry、點線面、坐標系等輔助工具。這些物體還可以通過 Group 分組來統一管理。
Sence 要渲染出來需要指定一個相機,分為從點去看的透視相機 PerspectiveCamera,從平面去投影的正交相機 OrthographicCamera。理解了它們的原理才能理解 Camera 的參數。
之后通過 Renderer 渲染出來,如果有動畫需要用 requestAnimationFrame 來一幀幀的渲染。
這是 Three.js 的大概渲染流程。
之后我們實現了一個花瓣雨的案例。用到了 Sprite 這種物體,它是一個永遠面向相機的平面,用來做這種效果很合適。
當然,Three.js 的東西還是比較多的,這篇文章只是入下門,后面我們會繼續深入,做更多的有意思的 3D 場景和效果。
*請認真填寫需求信息,我們會在24小時內與您取得聯系。