成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

SVG 立方體內(nèi)嵌路徑拼接

姘存按 / 2251人閱讀

摘要:第一部分是正方體部分,第二部分是中的路徑動(dòng)畫了,第三部分則是交互旋轉(zhuǎn)。然后在立方體元素上添加鼠標(biāo)點(diǎn)擊事件事件,在回調(diào)函數(shù)中做處理內(nèi)容?;卣{(diào)函數(shù)中先記錄下來(lái)鼠標(biāo)點(diǎn)擊的位置。

1.前言

我使用了jquery編寫交互的旋轉(zhuǎn),因?yàn)槌鯇W(xué)所以不太承受,還請(qǐng)見諒。樣式我是寫stylus編碼,自動(dòng)生成css。

2.正文

先放上一張效果圖

我將其分成三部分。第一部分是正方體部分(SVG),第二部分是svg中的路徑動(dòng)畫了(animateMotion + jQuery),第三部分則是交互旋轉(zhuǎn)(jQuery)。

1.正方體

做一個(gè)正方體

我的思路是用六塊svg正方形畫板通過(guò)css屬性旋轉(zhuǎn)和平移來(lái)構(gòu)成正方體。

html代碼:

stylus代碼

html
    margin 0
    padding 0
    height 100%
    width 100%
    body
        height 100%
        width 100%
        .page
            .state
                height 300px
                width 300px
                position absolute
                top 50%
                left 50%
                transform translate(-50%,-50%)//修正位置
                .container
                    transform-style preserve-3d
                    position relative
                    height 300px
                    width 300px
                    transform rotateX(0deg) rotateY(0deg)
                    svg
                        position absolute
                        height 300px
                        width 300px
                        stroke-width 5px
                        stroke brown
                        fill transparent //填充用透明
                        .rect
                            height 300px
                            width 300px
                    .top
                        transform rotateX(90deg) translateZ(150px)
                    .bottom 
                        transform rotateX(-90deg) translateZ(150px)
                    .left
                        transform rotateY(-90deg) translateZ(150px)
                    .right
                        transform rotateY(90deg) translateZ(150px)
                    .front
                        transform rotateY(0deg) translateZ(150px)
                    .behind
                        transform rotateY(180deg) translateZ(150px)

通常有兩種方式來(lái)構(gòu)建一個(gè)立方體
第一種:先平移再旋轉(zhuǎn)。優(yōu)點(diǎn)是不許太強(qiáng)的空間構(gòu)造能力,寫起來(lái)比較簡(jiǎn)單。缺點(diǎn)就是:代碼數(shù)會(huì)多一些,需要在平移后設(shè)置旋轉(zhuǎn)基點(diǎn)。替換一下樣式就行。

.top 
    fill blue 
    transform-origin: bottom 
    transform translateY(-200px) rotateX(90deg)
.bottom 
    fill red 
    transform-origin:top 
    transform translateY(200px) rotateX(-90deg)
.left 
    fill green 
    transform-origin: right 
    transform translateX(-200px) rotateY(-90deg)
.right 
    fill black 
    transform-origin: left 
    transform translateX(200px) rotateY(90deg)
.front 
    fill grey
    transform translateZ()
.behind 
    fill pink 
    transform translateZ(-200px)

第二種:先旋轉(zhuǎn)再平移。這個(gè)的特點(diǎn)就是與上面的相反了。(我使用的是這種)
兩種生成立方體的原理看下圖
第一種

第二種

以上就是兩種構(gòu)建立方體的方法大致原理了

2.路徑動(dòng)畫

路徑動(dòng)畫我是通過(guò)在相鄰兩個(gè)面上一個(gè)動(dòng)畫結(jié)束的位置和下一個(gè)動(dòng)畫起始位置重合,
下一個(gè)動(dòng)畫起始的延時(shí)設(shè)置為之前所有動(dòng)畫的動(dòng)畫時(shí)間,做到視覺認(rèn)為路線是連接起來(lái)的。
先上代碼:

路徑動(dòng)畫是有animateMotion元素做的所以可以不是直線,只是為了方便設(shè)計(jì),我吧path路徑設(shè)計(jì)成了直線
有興趣的可以自己設(shè)計(jì)一下。
路徑是我用 Method Draw 畫的 editor.method.ac/

接下來(lái)就是重點(diǎn)的路徑控制了

$(document).ready(function () {
    const animate = document.getElementsByTagName("animateMotion");
    // 0 frontY 1 frontX 2 behindY 3 behindX 4 leftX 5 rightX 6 topY 7 bottomY
    var frontY = animate[0], frontX = animate[1],
        behindY = animate[2], behindX = animate[3],
        leftX = animate[4], rightX = animate[5],
        topY = animate[6], bottomY = animate[7];
    // Y面球體運(yùn)動(dòng)
    (() => {
        //先執(zhí)行一次
        frontY.beginElement();
        setTimeout(() => {
            bottomY.beginElement();
        }, 3000);
        setTimeout(() => {
            behindY.beginElement();
        }, 6000);
        setTimeout(() => {
            topY.beginElement();
        }, 9000);
        // 循環(huán)執(zhí)行動(dòng)畫
        var time = setInterval(() => {
            frontY.beginElement();
            setTimeout(() => {
                bottomY.beginElement();
            }, 3000);
            setTimeout(() => {
                behindY.beginElement();
            }, 6000);
            setTimeout(() => {
                topY.beginElement();
            }, 9000);
        }, 12000);
    })();
    // X面球體運(yùn)動(dòng)
    (() => {
        //先執(zhí)行一次
        frontX.beginElement();
        setTimeout(() => {
            leftX.beginElement();
        }, 3000);
        setTimeout(() => {
            behindX.beginElement();
        }, 6000);
        setTimeout(() => {
            rightX.beginElement();
        }, 9000);
        // 循環(huán)執(zhí)行動(dòng)畫
        var time = setInterval(() => {
            frontX.beginElement();
            setTimeout(() => {
                leftX.beginElement();
            }, 3000);
            setTimeout(() => {
                behindX.beginElement();
            }, 6000);
            setTimeout(() => {
                rightX.beginElement();
            }, 9000);
        }, 12000);
    })();
})

我設(shè)置的是讓animateMotion元素的起始值begininfinite,在頁(yè)面加載完畢后動(dòng)畫不會(huì)自動(dòng)執(zhí)行。
我用jQuery來(lái)控制動(dòng)畫的執(zhí)行順序。

首先獲取每個(gè)動(dòng)畫元素const animate = document.getElementsByTagName("animateMotion");,之后將每個(gè)動(dòng)畫元素都標(biāo)記好。
接著使用計(jì)時(shí)器setIntervalsetTimeout計(jì)時(shí)器來(lái)控制動(dòng)畫。首先使用setInterval來(lái)控制動(dòng)畫循環(huán)執(zhí)行。接著在setInterval中用setTimeout設(shè)置動(dòng)畫執(zhí)行的順序,每個(gè)setTimeout計(jì)時(shí)器的延遲都為之前所有動(dòng)畫時(shí)間之和。模塊化的最好先設(shè)置一個(gè)動(dòng)畫對(duì)象數(shù)組,然后將動(dòng)畫順序加入數(shù)組。

最后附加兩個(gè)API

// svg指當(dāng)前svg DOM元素
// 暫停
svg.pauseAnimations();
// 重啟動(dòng)
svg.unpauseAnimations()

兩個(gè)API可已暫停當(dāng)前動(dòng)畫,關(guān)于詳情請(qǐng)看張?chǎng)涡翊罄械奈恼脉慰臻g

3.旋轉(zhuǎn)控制

旋轉(zhuǎn)控制是我還沒(méi)完善的地方,用戶體驗(yàn)不是十分好,還望大佬們幫我指出錯(cuò)誤。另一個(gè)旋轉(zhuǎn)方案過(guò)一兩天再添加上來(lái)。
代碼:

var X = 0;//記錄X軸旋轉(zhuǎn)過(guò)的角度
var Y = 0;//記錄Y軸旋轉(zhuǎn)過(guò)的角度
// 旋轉(zhuǎn)控制
$(".container").mousedown(function (event) {
    var mousedownX = event.clientX;
    var mousedownY = event.clientY;
    $("body").mousemove(function (event) {
        var mousemoveX = event.clientX;
        var mousemoveY = event.clientY;
        var scaleY = ((mousemoveX - mousedownX) / 200);
        var scaleX = ((mousemoveY - mousedownY) / 200);
        Y = ((Y + scaleY) % 360);
        X = ((X + scaleX) % 360);
        $(".container").animate({}, function () {
            $(".container").css({ "transform": `rotateX(${X}deg) rotateY(${Y}deg)` });
        })
    })
})
$("body").mouseup(function () {
    $("body").unbind("mousemove");
    $("body").unbind("mousedown");
})

首先設(shè)置兩個(gè)變量X,Y這是記錄這個(gè)立方體真正旋轉(zhuǎn)了多少角度。
然后在立方體.container元素上添加鼠標(biāo)點(diǎn)擊事件mousedown事件,在回調(diào)函數(shù)中做處理內(nèi)容?;卣{(diào)函數(shù)中先記錄下來(lái)鼠標(biāo)點(diǎn)擊的位置。
接著body上添加鼠標(biāo)移動(dòng)mousemove事件因?yàn)槲覀円苿?dòng)不能只在立方體上,移動(dòng)的范圍要擴(kuò)大到頁(yè)面上。接著在移動(dòng)事件中的回調(diào)函數(shù)做旋轉(zhuǎn)處理,首先記錄下來(lái)移動(dòng)后鼠標(biāo)的位置,計(jì)算出鼠標(biāo)移動(dòng)的距離然后除以一個(gè)數(shù)var scaleY = ((mousemoveX - mousedownX) / 200);注意其中的200沒(méi)有真正代表的意義,只是因?yàn)槭髽?biāo)移動(dòng)的距離數(shù)值相對(duì)于旋轉(zhuǎn)的角度來(lái)說(shuō)比較大,所以除以200減少它移動(dòng)的角度,可以隨意更改,其中鼠標(biāo)在X軸上移動(dòng)用戶需要的是圖形在以Y軸旋轉(zhuǎn)。接著我么要計(jì)算立方體真正對(duì)于初始旋轉(zhuǎn)了多少角度我們最好做一下范圍限制(取模運(yùn)算),Y = ((Y + scaleY) % 360);最后就是設(shè)置屬性了,先用$(".container").animate()讓旋轉(zhuǎn)用動(dòng)畫的形式來(lái)做成,然后設(shè)置旋轉(zhuǎn)角度$(".container").css({ "transform": rotateX(${X}deg) rotateY(${Y}deg) });css()方法來(lái)設(shè)置旋轉(zhuǎn)角度。

3.總結(jié)

最后將github庫(kù)放上來(lái)
github庫(kù)

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/103322.html

相關(guān)文章

  • 2017-10-19 前端日?qǐng)?bào)

    摘要:前端日?qǐng)?bào)精選源碼解析一組件的實(shí)現(xiàn)與掛載寫在的前端數(shù)據(jù)層不完全指北非時(shí)圓角邊框剪裁問(wèn)題專題之解讀排序源碼中的閉包再也不用擔(dān)心面試被問(wèn)什么是閉包了中文路由路由基礎(chǔ)入門實(shí)戰(zhàn)操作詳細(xì)指南前端學(xué)習(xí)教程用實(shí)現(xiàn)一門編程語(yǔ)言語(yǔ)言簡(jiǎn)介眾成翻譯第 2017-10-19 前端日?qǐng)?bào) 精選 React源碼解析(一):組件的實(shí)現(xiàn)與掛載寫在2017的前端數(shù)據(jù)層不完全指北Chrome opacity非1時(shí)border...

    v1 評(píng)論0 收藏0
  • 翻譯 | 編寫SVG的口袋指南(上)

    摘要:元素元素歸屬于容器和結(jié)構(gòu)元素,在文檔內(nèi)允許嵌套使用獨(dú)立的片段。如果包含葡萄的組被移動(dòng)到文檔的末尾,它將出現(xiàn)在西瓜的前面。例如,將葡萄的莖的路徑移動(dòng)到組的末尾將導(dǎo)致莖在頂部。 作者:DDU(滬江前端開發(fā)工程師)本文是原文翻譯,轉(zhuǎn)載請(qǐng)注明作者及出處。 簡(jiǎn)介 Scalable Vector Graphics (SVG)是在XML中描述二維圖形的語(yǔ)言。這些圖形由路徑,圖片和(或)文本組成,并能...

    Brenner 評(píng)論0 收藏0
  • 翻譯 | 編寫SVG的口袋指南(上)

    摘要:元素元素歸屬于容器和結(jié)構(gòu)元素,在文檔內(nèi)允許嵌套使用獨(dú)立的片段。如果包含葡萄的組被移動(dòng)到文檔的末尾,它將出現(xiàn)在西瓜的前面。例如,將葡萄的莖的路徑移動(dòng)到組的末尾將導(dǎo)致莖在頂部。 作者:DDU(滬江前端開發(fā)工程師)本文是原文翻譯,轉(zhuǎn)載請(qǐng)注明作者及出處。 簡(jiǎn)介 Scalable Vector Graphics (SVG)是在XML中描述二維圖形的語(yǔ)言。這些圖形由路徑,圖片和(或)文本組成,并能...

    linkFly 評(píng)論0 收藏0
  • 打造最美HTML5 3D機(jī)房(第二季)

    摘要:寫在前面的前面現(xiàn)在拍電影搞真人秀都流行拍續(xù)集,哥今天給大家?guī)?lái)的是打造最美機(jī)房的續(xù)集,哥的目標(biāo)是成為機(jī)房界的網(wǎng)紅。機(jī)柜標(biāo)簽機(jī)房中最重要的物理資源機(jī)柜是機(jī)房管理規(guī)劃監(jiān)控人員最關(guān)注的對(duì)象之一。 寫在前面的前面 現(xiàn)在拍電影、搞真人秀都流行拍續(xù)集,哥今天給大家?guī)?lái)的是打造最美3D機(jī)房的續(xù)集,哥的目標(biāo)是成為3D機(jī)房界的網(wǎng)紅。 -------------------------------我是這個(gè)...

    BetaRabbit 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<