中文字幕日韩精品一区二区免费_精品一区二区三区国产精品无卡在_国精品无码专区一区二区三区_国产αv三级中文在线

漸進(jìn)式動畫解決方案

2022-06-16    分類: 解決方案

今天聊的內(nèi)容是淘寶虛擬互動實(shí)驗(yàn)室的@渚薰大神 在2017年06月在北京GMTC大會上分享的一個(gè)主題。未能親臨聽到相關(guān)的精彩分享,但還算是有幸的,在內(nèi)部聽到@渚薰大神 的分享。個(gè)人對Web動畫這方面的課程非常的感興趣,而且現(xiàn)在和團(tuán)隊(duì)一直在致力于手淘互動動效相關(guān)的研究。經(jīng)歷了從Gif、視頻到CSS Animation的零至一的過程,并且致力于JavaScript驅(qū)動的動效開發(fā),以及現(xiàn)在致力于研究的數(shù)據(jù)化驅(qū)動的動效。這樣的一個(gè)過程是幸福的,而且也是具有挑戰(zhàn)力的。我想很多喜歡動畫的同學(xué)也對這樣的一個(gè)課程會感興趣,所以接下來,我們根據(jù)@渚薰大神分享的PPT的思路來聊聊漸進(jìn)式動畫解決方案。

PWA


最早聽到PWA(Progressive Web Apps)這樣的一個(gè)概念是2016年在上海Qcon的分享會上聽到@黃弦 大大的分享,但我們今天要聊的并不是Progressive Web APPs,而是其變身Progressive Web Animation。我們把其稱為漸進(jìn)式動畫。那問題來了,什么才是漸進(jìn)式動畫呢?這是值得每位愛好動畫的同學(xué)去思考的?為了更好的闡述自己對漸進(jìn)式動畫的理解,將分幾個(gè)方向來介紹:

重新認(rèn)識動畫

如何操作動畫

如何管理動畫

如何制作動畫

重新思考動畫

接下來一一聊聊。

重新認(rèn)識動畫

要重新認(rèn)識動畫,那么其中有兩個(gè)非常重要的概念:動效和插值。

動效

動效是源于電影動效。動效是錄音學(xué)范疇,簡言之,指各種動作的聲音效果,又被稱為擬聲。比如武打片里,骨折的聲音是芹菜制造的,下雨的聲音是由洗臉的聲音制造的。

看上并不是我們所要說的動效,這并不要緊。如果需要和我們的實(shí)際工作中緊密聯(lián)合在一起,我們的Web也可以有音效,特別是早期的Flash,各種的配合音效,得到與眾不同的效果。隨著CSS和HTML以及JavaScript相關(guān)技術(shù)不斷的革新,同時(shí)各種特性能得到眾多現(xiàn)代瀏覽器的支持?,F(xiàn)在的Web展示形式也不斷的變化,不管是Web頁面或者說APP應(yīng)用,都會或多或少的添加一些動效效果。

俗話說得好,顏值不夠,動效來湊,Web動效已經(jīng)不僅僅是Web設(shè)計(jì)的潤滑劑了,它的功能更多的體現(xiàn)在交互邏輯、視覺渲染和創(chuàng)新實(shí)踐上,上能引人注目,下能潛移默化。對于Web開發(fā)人員而言,更喜歡把這些動效稱之為Web動畫。為了接地氣,后面也將稱之為動畫。

迪士尼動畫大師乃特維克的畢生經(jīng)驗(yàn)對Web動畫濃縮成一句話:

動畫的一切皆在于時(shí)間點(diǎn)和空間幅度!

事實(shí)上,動效設(shè)計(jì)和做動畫是一脈相通的,我們不要做寫實(shí)主義的動畫,而是要通過時(shí)間點(diǎn)和空間幅度的設(shè)置為用戶建立運(yùn)動的可信度。這樣描述感覺有點(diǎn)繞。其實(shí)我們可以這樣來描述動畫的概念:

動畫是指由許多幀靜止的畫面,以一定的速度(比如每秒16張)連續(xù)播放時(shí),肉眼因視覺殘象產(chǎn)生錯(cuò)覺,而誤以為畫面活動的作品。為了得到活動的畫面,第個(gè)畫面之間都會有細(xì)微的改變。

其實(shí)我更喜歡說動畫就是以時(shí)間置換空間。比如下圖:


圖形A狀態(tài)(一個(gè)正方形)經(jīng)過時(shí)間的變換到了圖形B的狀態(tài)(一個(gè)圓形)。從正方形變成圓形這樣的一個(gè)過程就是一個(gè)動畫效果(動效)。當(dāng)然為了制作這樣的一個(gè)動畫,會添加控制動畫的一些手段,比如控制持續(xù)時(shí)間、延遲時(shí)間、緩動函數(shù)、動畫次數(shù)和方向之類的等。當(dāng)然根據(jù)不同的制作動畫的方式,這些控制動畫的參數(shù)或者說手段吧,其方法不一樣。這里暫且不深入的介紹。

剛才也說過了,這樣的一個(gè)過程就是一個(gè)動畫效果,專業(yè)一點(diǎn)稱之為Motion Effect。而這個(gè)Motion Effect又受眾多因素的影響。同樣拿上面的示例來說,正方形是一下子變成圓形呢還是慢慢的變形圓形呢?又是經(jīng)過多少時(shí)間才變成圓形呢?這一切的一切都會影響到。而其中有一個(gè)較好的方案就是在運(yùn)動的過程中將插值引進(jìn)來。

插值

這里所說的插值其實(shí)是指線性插值。線性插值是數(shù)學(xué)、計(jì)算機(jī)圖形學(xué)等領(lǐng)域廣泛的一種簡單插值方法。在平常實(shí)際運(yùn)用當(dāng)中,把插值稱之為lerp,簡單而言:

lerp是兩點(diǎn)之間的線性插值的別稱。

同樣的回到面的示例,正方形狀態(tài)A是一個(gè)點(diǎn),圓形狀態(tài)B是一個(gè)點(diǎn)。如果我們把狀態(tài)A稱為0點(diǎn),把狀態(tài)B稱為1點(diǎn)。那么在這個(gè)過程中我們可以有很多個(gè)值,比如0.1、0.2....9之類,比如下圖所示:


從0至1這樣的一個(gè)過程就是一個(gè)插值過程。用到圖形變化中來,比如正方形是四個(gè)點(diǎn)連起的圖形,那么變成圓形,這個(gè)點(diǎn)數(shù)越多這個(gè)圓就越圓,比如16、32、64、128等等,也可以說點(diǎn)數(shù)越多,越趨向于圓。而這個(gè)程,我們使用插值原理來計(jì)算,效果會更佳。比如下面兩個(gè)圖:


一個(gè)高級動畫或者動畫藝術(shù)家都手繪的關(guān)鍵幀定義的一個(gè)動畫。不管你是怎么一個(gè)高級的動畫設(shè)計(jì)師,手繪總是有所限制的,如果我們換成插值來繪制:


插值能增加很多中間幀,讓動效變得更為絲滑。

上面演示的是幀之間的插值,事實(shí)上我們除了這個(gè)之外,還有顏色的插值,圖形插值等等。這里想要表達(dá)的觀點(diǎn)是:插值能讓動效變得更為絲滑。有關(guān)于插值方面的相關(guān)介紹,可以閱讀:

線性插值

理解動畫中的線性插值

如何操作動畫

操作一個(gè)動畫,其實(shí)具有兩個(gè)過程,其一制作動畫的場景,其二拼接動畫場景。把它們結(jié)合起來就是操作一個(gè)動畫。那么操作一個(gè)動畫,就目前的技術(shù)常見的有:

CSS Animation

SVG Animation

JavaScript-Driven Animation

我想大家最早接觸動畫的控制方式應(yīng)該類似于jQuery的.animate():

$( "#clickme" ).click(function() {

$( "#book" ).animate({

opacity: 0.25,

left: "+=50",

height: "toggle"

}, 5000, function() {

// Animation complete.

});

});

對于這種制作動畫的方式不做過多的評介。但隨著CSS技術(shù)的發(fā)展,使用純CSS就可以很好的實(shí)現(xiàn)Animation。在CSS中主要是使用@keyframes和animation-*屬性來控制動畫。CSS Animation雖然實(shí)現(xiàn)一個(gè)動效較為容易,成本也較低,但對于一些復(fù)雜的動畫場景,他就變得非常的雞肋。除此之外,這兩年SVG Animation也越來越多在實(shí)際場景中使用。

不過,這里需要特別提出的是JavaScript-Driven Animation,也就是JavaScript驅(qū)動動畫。最簡單的就是W3C規(guī)范提供的Web Animation API簡稱為WAAPI。其原理非常類似于CSS Animation,具有@keyframes的概念,也具有類似于animation-*屬性樣的方法,用于控制動畫。同時(shí)還提供了對應(yīng)的Timeline的概念,而Timeline又是動畫中一個(gè)至關(guān)重要的一個(gè)概念,稍后或多或少會介紹一些。

雖然有了WAAPI,可以使用原生的JavaScript制作動畫,但還是有一些功能性的限制,而且實(shí)現(xiàn)方式,制作流程等等,都有待于改善。但對于Web社區(qū)而言,這一切都不是問題。因?yàn)楹芏嚅_發(fā)者,都會針對于自己的業(yè)務(wù),或者說自己的需求,在某一方面做出優(yōu)秀的成績,并且分享給社區(qū)。正因?yàn)槿绱?,社區(qū)中有很多使用JavaScript來驅(qū)動動畫的庫,比如:GreenSock、CreateJS、Anime和Motion等:


不管是哪種制作動畫的JavaScript庫或者說工具都有各自的利弊。只能說選擇最適合自己的,俗話說:

站在巨人的肩膀上,看得比別人更遠(yuǎn)些。(If I have been able to see further, it was only because I stood on the shoulders of giants.)

除了上述制作動畫之外,我們還可以采用Canvas和WebGL。特別是WebGL,在當(dāng)今算是一個(gè)熱門的話題,國內(nèi)外很多團(tuán)隊(duì)都在研究這方面的技術(shù),其中最具代表性的作品就是ThreeJS。

制作動畫另一個(gè)不可避免的問題,那就是動畫的性能問題。這是一個(gè)很深的、很復(fù)雜的話題。不過我們可以借助一些其他的工具幫助我們在底層做一些變化,比如采用GPU來渲染:

GPU.JS:使用JavaScript給GPU加速

PixiJS:一個(gè)HTML5引擎,也是最靈活的2D WebGL渲染器

除了借助工具之外,我們也可以在自己的代碼層面做一些優(yōu)化,比如使用requestAnimationFrame這個(gè)API:

const raf = requestAnimationFrame;

const running = [];

const idle = [];

export const add = tick => running.push(tick);

export const remove = id => (running[id] = idle[id] = undefined);

export const run = () => raf(function tok() {

raf(tok);

running.forEach(t => t());

});

export const pause = id => (idle[id] = running[id]) && (running[id] = undefined);

export const resume = id => (running[id] = idle[id]) && (idle[id] = undefined);

有關(guān)于這方面的介紹大家可以閱讀下面幾篇文章:

requestAnimationFrame for Smart Animating

requestAnimationFrame API: now with sub-millisecond precision

Using requestAnimationFrame

Animating with javascript: from setInterval to requestAnimationFrame

CSS3動畫那么強(qiáng),requestAnimationFrame還有毛線用?

requestAnimationFrame

使用requestAnimationFrame更好的實(shí)現(xiàn)javascript動畫

requestAnimationFrame 性能更好

以前在站上也整理了一些優(yōu)化動畫性能的相關(guān)文章,對這方面感興趣的同學(xué)可以閱讀下面的文章:

使用瀏覽器開發(fā)者工具檢測CSS動畫性能

CSS Animation性能優(yōu)化

高性能的動畫

使用CSS3實(shí)現(xiàn)60FPS動畫

使用 FLIP 來提高 Web 動畫的性能

CSS動畫之硬件加速

如何管理動畫

制作出來動畫,我們可以將整體的動畫細(xì)分出來,那么怎么管理動畫變得就很重要了。我常常喜歡把動畫比喻成一場舞臺劇,整個(gè)劇會有演員,演員什么時(shí)候出場之類的。而控制演員出場順序和時(shí)間之類的由導(dǎo)演來負(fù)責(zé)?;氐轿覀兊膭赢嬛衼?,我們可以把整個(gè)動畫當(dāng)作一個(gè)舞臺劇(一個(gè)故事),故事中有很多個(gè)片段(也就是我們的動畫分場景),而串起整個(gè)動畫是由時(shí)間軸來控制,常常稱之為Timeline。

比如:


正如上圖所示,這里有三輛小汽車向右行駛的動效,那么藍(lán)、黃、紅怎么出現(xiàn),就由時(shí)間軸來控制了。而整個(gè)過程,它其實(shí)也是一個(gè)流式的過程。有接觸過Flash的同學(xué)應(yīng)該知道。在Flash中有兩種動畫方式:

流式動畫

交互式動畫

所謂流式動畫,就是像電影那樣按既定順序一直播放,不會停,也不會發(fā)生改變的動畫。你在電視上看到的所有動畫片都可以說是流式動畫。流式動畫最顯著的特點(diǎn)就是你無法對流式動畫施加影響,比如你無法期待單擊流式動畫中的某個(gè)器物(動畫元素)而指望因此而發(fā)生什么事情??傊?,流式動畫中所有的一切都是注定的,有一種宿命的感覺。盡管流式動畫的能力有限,但不可否認(rèn),流式動畫的應(yīng)用還是非常廣泛的。

說到這里,大家可能會想到,我們CSS Animation。眾所周知,一旦我們定制好了一個(gè)CSS Animation,我們是無法通過一些事情讓動畫中的某些動畫元素做其他的事情。這也是令我們頭痛的地方之一。比如我們做一個(gè)互動的動畫,希望動畫播放到一定的位置,彈一個(gè)彈框出來,告訴用戶你可以領(lǐng)起紅包了。

除了流式動畫,還有一種交互式動畫。所謂交互式動畫,簡單地說就是動畫隨時(shí)準(zhǔn)備因你的命令或某些事件的出現(xiàn)而發(fā)生變化。例如,當(dāng)你用鼠標(biāo)點(diǎn)擊動畫中一只小狗的頭時(shí),它會高興地沖你搖尾巴。在這里,鼠標(biāo)的單擊就是一個(gè)命令(或者說是一個(gè)事件),而小狗搖尾巴就是對這個(gè)命令(或說事件)的響應(yīng),整個(gè)過程就可以被看作是一次交互。

到目前為止,僅使用CSS Animation,或者后面將提到的一些制作動畫的IDE或軟件,他們做出來的動畫都是流式動畫,只能通過時(shí)間軸來控制動畫,整個(gè)動畫中沒有任何可交互性而言,這對于大多數(shù)業(yè)務(wù)場景是無法達(dá)到需求方的要求。但對于JavaScript驅(qū)動的動畫而言,我們的交互行為就要豐富的多,比如SVG Animation,Canvas Animation等。

感覺有點(diǎn)跑題了,這一節(jié)我們要說的是管理動畫,其實(shí)除了管理動畫中的交互行為之外,更為重要的是管理動畫的播放。前面也提到過了,不管是CSS Animation動畫,還是JavaScript驅(qū)動的動畫,都是通過Timeline來管理。只不過JavaScript更具優(yōu)勢。來看兩個(gè)小場景。

先來看CSS Animation中的Timeline,如下圖所示:


上圖演示的是一個(gè)紅包火山的動畫場景(喜歡手淘的同學(xué),應(yīng)該在去年的雙十一看到過這樣的動畫),在這個(gè)動畫中我們包括了火山升起(valcaoRising)、火焰柱噴發(fā)(expulsion)、巖漿流動(flow)和紅包噴發(fā)(blowout)。在這個(gè)動畫中,我們要人工的去計(jì)算動畫的延遲時(shí)間(animation-delay)和持續(xù)時(shí)間(animation-duration)。比如火山升起,我們花費(fèi)了1s,火焰柱噴發(fā)等火山升起才開始,這樣一來,其延遲時(shí)間為1s,并且持續(xù)了.4s,在此同時(shí)巖漿流動的效果也同時(shí)發(fā)生,也就是說巖漿流動的延遲時(shí)間也是1s,而其持續(xù)了2s,其實(shí)動畫進(jìn)行到1.4s時(shí),火焰柱噴發(fā)的動效是已經(jīng)停止了。除此之外,還有紅包噴發(fā)的一個(gè)動畫,而這個(gè)動畫是在火焰柱噴發(fā)結(jié)束的時(shí)候開始,這樣其延遲時(shí)間是1.4s,并且持續(xù)了15s。其實(shí)整個(gè)動效花了16.4s。

如果這樣做就能滿足業(yè)務(wù)方的需求,那是開發(fā)者的福音,但是要變動某個(gè)時(shí)間,比如火山升起需要持續(xù)2s,那么后續(xù)的三個(gè)動畫的時(shí)間都需要變更。而這個(gè)過程是一個(gè)痛苦的過程。

但在JavaScript驅(qū)動的動畫中,我們依舊是通過Timeline來管理動畫,但會變得輕松和靈活的多,比如下圖:


在JavaScript中,我們可以通過技術(shù)手段,將相關(guān)功能封裝成函數(shù),然后在動畫流中調(diào)用:

add(me) => (

playAt: () => number

) => assign(me, {playAt});

tick(elapsed) => queue.forEach(me => {

if (me.playAt() >= elapsed && !me.started)

me.start();

});

同樣拿上圖來說,如果我給火山升起通過playAt()來得到起始時(shí)間,并且函數(shù)能拿到其停止時(shí)間,并且在其停止的這個(gè)時(shí)候通知其他動畫什么時(shí)候開始播放。這樣我們控制動畫會變得輕松的多。哪怕是我們需要改變其中某一個(gè)或某兩個(gè)的時(shí)間,也可以很好的自動獲取。

() => me1.finished;

let fetched;

fetch(url).then(() => fetched = true);

() => fetched;

() => store.getState() === ‘BTN_CLICKED’;

() => me2.started && (me2.startAt + 500);

簡單點(diǎn)講,我們把動畫的控制、決定和管理都交互兩個(gè)函數(shù),比如playAt()和stopAt。比如下圖:


這樣是不是感覺爽得多了。

如何制作動畫

其實(shí)前面我們簡單的提到了如何制作動畫,比如通過CSS Animation、SVG Animation或者說JavaScript。但在這一節(jié),我們繼續(xù)來聊這個(gè)話題。在具體聊這個(gè)話題之前,咱們先來看一下開發(fā)者和設(shè)計(jì)者之間的合作關(guān)系。

早期的Gif動畫、視頻動畫或者說Flash動畫,這些可以說都不需要開發(fā)人員去做什么(這些都是流式動畫,無交互可言)。但隨著市場的變化或者說技術(shù)革新后,開發(fā)人員想嘗試著新的技術(shù)來實(shí)現(xiàn)動畫,并且在提供給業(yè)務(wù)方,這樣做多NB,跟老板說,這樣能節(jié)約多少成本。沒想到,這個(gè)時(shí)候自己挖了一個(gè)巨坑讓自己和自己的小伙伴跳進(jìn)坑中。

別的不說,咱先上一張圖:


可以說這是一個(gè)痛苦的過程,視覺設(shè)計(jì)師將想要的動效制作成視頻文件或者Gif文件以及可切圖的PSD文件給開發(fā)人員,然后開發(fā)人員將Gif動效或者說視頻演示的動畫轉(zhuǎn)成Web動畫。大家可能會問,這不是蛋疼?為什么需要制作視頻或Gif文件呢?提供一個(gè)PSD文件不就行了?其實(shí)視覺設(shè)計(jì)師也是這么認(rèn)為的。但話說回來,有多少開發(fā)人員能不看效果,通過視覺設(shè)計(jì)師或者說業(yè)務(wù)方的描述就能理解所需的動效呢?不知道你行不行,反正我經(jīng)歷之后告訴我,我是不行。

這樣的一個(gè)過程,其實(shí)也增加了設(shè)計(jì)師和開發(fā)者的溝通成本,也增加了設(shè)計(jì)師的工作量。特別是當(dāng)需求變更之后,設(shè)計(jì)師欲哭無淚。這個(gè)時(shí)候老板會說,成本、成本、效率、效率。設(shè)計(jì)師會說麻煩、麻煩。需求方會說,就這樣吧,其實(shí)離我需要的還是有差距的。

隨著時(shí)間變化,不管是自己的Boss還是需求方,都希望有所改變:動效能不能變得更絲滑一些、效果還原度能不能更接近一些、能不能更有一些創(chuàng)意和創(chuàng)新,能不能玩一些更有意思的...

開發(fā)人員心中千萬個(gè)草昵瑪就出來了。但活還是要繼續(xù)做的,只是換個(gè)方式做而以。這也是我和我們團(tuán)隊(duì)小伙伴近一年多來一直在研究的一個(gè)課程:可量化和數(shù)據(jù)驅(qū)動。


這個(gè)流程讓我們有了更多的變化。視覺設(shè)計(jì)師專業(yè)的做他的設(shè)計(jì),開發(fā)人員專業(yè)的做他的業(yè)務(wù)開發(fā)。為什么這樣說呢?因?yàn)閯有У霓D(zhuǎn)換我們通過工具或者軟件來實(shí)現(xiàn),然使用JavaScript的將業(yè)務(wù)插入到轉(zhuǎn)化后的動效中。

簡單講,我們的開發(fā)過程變成了這樣:


其實(shí)這樣的過程,并不是我們有的,最早的時(shí)候有些團(tuán)隊(duì)使用Animation CC設(shè)計(jì)動畫,然后直接轉(zhuǎn)換出Web動畫,它依賴于CreateJS這個(gè)庫。另外也有團(tuán)隊(duì)使用After Effects CC制作動畫,然后借助bodymovin將動畫轉(zhuǎn)出來。其中最具代表性的就是Airbnb的Lottie:


有關(guān)于這方面的DEMO,可以點(diǎn)擊這里查閱。

這是別人家的產(chǎn)品,也是巨人的肩膀。其實(shí)在Lottie和Bodymovin還沒有開源出來的時(shí)候,我們團(tuán)隊(duì)也有一個(gè)類似的產(chǎn)品,AFT(Animation Flow Tools)。AFT沒有開源,我不能聊得太多,簡單的說,AFT具有自己的渲染引擎、也可以借用別人的渲染引擎,比如Canvas、Weex之類。但其主要功能和特點(diǎn)是用來管理動畫,擴(kuò)展動畫。而且AFT也具有類似Lottie的特性,只不過我們的Player層是自己寫的。下面的示例就是使用AFT通過AE轉(zhuǎn)出來的一個(gè)動效,并且在實(shí)際項(xiàng)目中運(yùn)用的:


我們把這樣制作動畫稱之為可量化和數(shù)據(jù)驅(qū)動。主要原理其實(shí)在上面也提到過了。這里簡單的復(fù)述一下:

通過類似AE這樣的制作動畫的軟件,將動畫導(dǎo)出成一份JSON數(shù)據(jù),這份JSON數(shù)據(jù)將描述動畫。同時(shí)使用Player層結(jié)合DSL,將JSON數(shù)據(jù)和業(yè)務(wù)邏輯整合,完成帶有可交互的動畫。

雖然我們初步完成了這些樣的一個(gè)開發(fā)模式,但路還很長,我們也在不斷努力。希望有一天能讓她面世,與眾多動畫愛好者共享。

重新思考動畫

經(jīng)過這一系列的變化,并且隨著技術(shù)越來越先進(jìn)。我們有必要重新思考動畫。除了思考其制作過程和動畫效果之外,我們更多的時(shí)候去思考其中的模式和工程化相關(guān)的東西。

在我們的意識中,動畫就是設(shè)計(jì)師與開發(fā)者之間的故事。但有沒有想過,我們可以換一種模式:


上圖我不想用再多的語言來描述,因?yàn)檫@個(gè)過程我和我們的團(tuán)隊(duì)還在探討,等哪一天有了答案和大寫一起分享。在這里我們提出一個(gè)動畫工程師的職能,那么真正的動畫工程師應(yīng)該支承擔(dān)一些什么呢?又需要去思考些什么呢?我們一起來思考吧,我想有一天會有答案的。

總結(jié)

經(jīng)過一段從事動畫開發(fā)的體驗(yàn)和感受。我和我們的團(tuán)隊(duì)一直在探索一種好的模式,希望這種模式能幫助我們降低開發(fā)成本,提高開發(fā)效率,滿足更多需求。同時(shí)讓自己參與到創(chuàng)意當(dāng)中,或者在這些方面有一些創(chuàng)新。

本文名稱:漸進(jìn)式動畫解決方案
網(wǎng)頁地址:http://www.rwnh.cn/news32/167982.html

網(wǎng)站建設(shè)、網(wǎng)絡(luò)推廣公司-創(chuàng)新互聯(lián),是專注品牌與效果的網(wǎng)站制作,網(wǎng)絡(luò)營銷seo公司;服務(wù)項(xiàng)目有解決方案

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)

網(wǎng)站建設(shè)網(wǎng)站維護(hù)公司
阿勒泰市| 四平市| 通河县| 馆陶县| 滦平县| 延津县| 长丰县| 昌都县| 江永县| 若尔盖县| 镇沅| 丹江口市| 平罗县| 金秀| 漳平市| 惠安县| 榆林市| 乐平市| 延川县| 米林县| 南丰县| 罗平县| 墨江| 岳普湖县| 江油市| 望江县| 乐业县| 泰宁县| 浪卡子县| 阳信县| 池州市| 广水市| 五原县| 余干县| 博白县| 辽阳市| 金川县| 鄂尔多斯市| 牡丹江市| 台山市| 卫辉市|