国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

JS仿《阿麗塔》中依德醫(yī)生的旋轉(zhuǎn)縮放控件 — DEMO篇

douzifly / 707人閱讀

摘要:前言前些天看了阿麗塔感嘆酷炫特效的同時(shí),不得不說(shuō)這個(gè)片子灰常之熱血重新點(diǎn)燃了我糞斗的基情有那么幾個(gè)瞬間仿佛自己回到了,下面進(jìn)入正題在依德醫(yī)生剛撿回阿麗塔的那一段,有木有發(fā)現(xiàn)醫(yī)生家的設(shè)備都很有意思比如那個(gè)人皮縫紉機(jī),其靈活程度堪比織網(wǎng)的蜘蛛說(shuō)

前言

前些天看了《阿麗塔》
感嘆酷炫特效的同時(shí),不得不說(shuō)這個(gè)片子灰常之熱血!
重新點(diǎn)燃了我糞斗的基情!!
有那么幾個(gè)瞬間仿佛自己回到了……

OK,下面進(jìn)入正題
在依德醫(yī)生剛撿回阿麗塔的那一段,有木有發(fā)現(xiàn)醫(yī)生家的設(shè)備都很有意思~
比如那個(gè)人皮縫紉機(jī),其靈活程度堪比織網(wǎng)ing的蜘蛛
說(shuō)到蜘蛛,就想起了西游記里的蜘蛛精。今年下半年……

…………
…………
除了人皮縫紉機(jī),當(dāng)時(shí)還注意到他們屏幕的一個(gè)交互很有趣——

沒(méi)錯(cuò),今天的主角出場(chǎng)了
就是用JS做一個(gè)類似的旋轉(zhuǎn)縮放控件
先來(lái)看一哈最終效果,鐺鐺:


貌似手感不錯(cuò)?可以點(diǎn)此搶先體驗(yàn)(此版本僅限PC端玩家)

正文

本篇首先開(kāi)發(fā)一個(gè)demo試試水,暫時(shí)用鼠標(biāo)代替手指

實(shí)現(xiàn)思路如下:

畫一個(gè)彩色圓環(huán)

監(jiān)聽(tīng)鼠標(biāo)移動(dòng)事件(保證只能作用在圓環(huán)上)

實(shí)時(shí)計(jì)算鼠標(biāo)當(dāng)前的角度(相對(duì)于圓心)

對(duì)比當(dāng)前角度和上一次角度,確定每一幀的旋轉(zhuǎn)方向和距離,根據(jù)變化的角度值旋轉(zhuǎn)圓環(huán)

縮放操作外部dom

1. 畫圓環(huán)

這里使用大圓套小圓組成圓環(huán):大圓設(shè)置一個(gè)漸變背景色,小圓為純白色
為啥子不只用一個(gè)圓,然后設(shè)置border屬性捏?
因?yàn)槲也幌矚g
因?yàn)閎order不能設(shè)置漸變色
當(dāng)然還有另一個(gè)作用:阻止事件(詳見(jiàn)下文)

萬(wàn)事俱備,開(kāi)始裝逼
目標(biāo)是把圓環(huán)用絕對(duì)定位放到左上角,而且內(nèi)圓要適中大小
所以分別設(shè)置圓心和大小圓的半徑為:

var CENTER = { x: 150, y: 150 }, BIG_RADIUS = 150, SMALL_RADIUS = 70

創(chuàng)建div表示兩個(gè)圓

var bigCircle = document.createElement("div")
var smallCircle = document.createElement("div")
document.body.appendChild(bigCircle)
document.body.appendChild(smallCircle)

封裝一個(gè)函數(shù)方便給大小圓添加樣式
參數(shù):center圓心、radius半徑、bg背景、isMove是否運(yùn)動(dòng)(使用CSS3的變化和旋轉(zhuǎn),每0.16秒運(yùn)動(dòng)一次,即60幀)

function setCircleClass(center, radius, bg, isMove) {
    this.style.position = "absolute"
    this.style.left = center.x - radius + "px"
    this.style.top = center.y - radius + "px"
    this.style.width = radius * 2 + "px"
    this.style.height = radius * 2 + "px"
    this.style.borderRadius = "50%"
    this.style.zIndex = 66666
    this.style.background = bg
    isMove && (this.style.transition = "transform linear .016s")
}

調(diào)用函數(shù)添加樣式

setCircleClass.apply(bigCircle, [CENTER, BIG_RADIUS, "linear-gradient(skyblue, darkorange)", true])
setCircleClass.apply(smallCircle, [CENTER, SMALL_RADIUS, "#FFF", false])

顏色有點(diǎn)瓜皮:

2. 監(jiān)聽(tīng)鼠標(biāo)事件

監(jiān)聽(tīng)大圓的mousemove事件,同時(shí)小圓阻止事件傳播

bigCircle.addEventListener("mousemove", main)
smallCircle.addEventListener("mousemove", function(e) {
    e.stopPropagation()
})

創(chuàng)建大圓的監(jiān)聽(tīng)函數(shù)main
這里設(shè)置鼠標(biāo)左鍵按下時(shí)生效,順便寫一個(gè)打印語(yǔ)句

function main(e) {
    if(e.buttons === 1) {
        console.log("鼠標(biāo)在圓環(huán)移動(dòng)ing")
    }
}

3. 實(shí)時(shí)計(jì)算當(dāng)前角度

接下來(lái)就是重頭戲了,想要讓圓環(huán)跟隨鼠標(biāo)轉(zhuǎn)動(dòng),首先想到的絕壁是斜率
在監(jiān)聽(tīng)事件觸發(fā)時(shí),不停計(jì)算鼠標(biāo)位置和圓心兩點(diǎn)連線的斜率,通過(guò)對(duì)比本次的斜率和上一次斜率,即可得出圓環(huán)轉(zhuǎn)動(dòng)的方向
方向有了,還要計(jì)算圓環(huán)移動(dòng)的速度,然而斜率的變化并不是線性的,因此很難通過(guò)斜率的變化值來(lái)計(jì)算速度……
所以光有斜率是沒(méi)辦法解決問(wèn)題的,那么有木有其他線性變化的東西呢……
沒(méi)錯(cuò),就是角度了~!

記得Math對(duì)象有一些三角函數(shù)方法,速速去查

正在眼花繚亂之時(shí),突然眼角一閃,一個(gè)黑衣人從天而降,定睛一看,正是傳說(shuō)中的atan2函數(shù)
“騷年,你要找的人正是在下”

打量了一番,發(fā)現(xiàn)這哥們不僅長(zhǎng)得帥,而且手中還拿了一個(gè)神器:計(jì)算角度函數(shù)

function calcAngleDegrees(x, y) {
    return Math.atan2(y, x) * 180 / Math.PI
}

臥槽,簡(jiǎn)直是踏破鐵鞋,趕緊來(lái)戰(zhàn):

function main(e) {
    if(e.buttons === 1) {
        var angle = calcAngleDegrees((e.clientX - CENTER.x), (CENTER.y - e.clientY))
        console.log("角度:" + angle)
    }
}


如圖可以看到,角度的變化是從9點(diǎn)鐘方向的180度,順時(shí)針遞減360度,回到9點(diǎn)鐘方向
正符合我們后續(xù)的需求

“大師果然牛皮,不知您的一身好武功是如何修來(lái)的?”
atan2笑而不語(yǔ),一轉(zhuǎn)身便消失在了無(wú)盡的夜色中,只留下了無(wú)盡的疑問(wèn)……

既然如此,作為一個(gè)熱愛(ài)技術(shù)的搬磚工,我決定自己找出真相~


本小節(jié)終。

4. 根據(jù)角度計(jì)算方向和距離,旋轉(zhuǎn)圓環(huán)

有了角度值,下面就的問(wèn)題就引刃而解了

先創(chuàng)建一個(gè)函數(shù)用來(lái)旋轉(zhuǎn)圓環(huán),參數(shù):deg當(dāng)前圓環(huán)的角度

function rotate(deg) {
    this.style.webkitTransform = "rotate(" + deg + "deg)"
    this.style.mozTransform = "rotate(" + deg + "deg)"
    this.style.msTransform = "rotate(" + deg + "deg)"
    this.style.oTransform = "rotate(" + deg + "deg)"
    this.style.transform = "rotate(" + deg + "deg)"
}

創(chuàng)建變量:當(dāng)前圓環(huán)(大圓)角度值circleAngle、當(dāng)前鼠標(biāo)角度值mouseAngle、上一次鼠標(biāo)角度值lastMouseAngle

var circleAngle = 0, mouseAngle, lastMouseAngle

此處需初始化lastMouseAngle,這個(gè)操作看似簡(jiǎn)單,實(shí)則使用正確的姿勢(shì)可以避免一系列bug
這里研究出來(lái)比較好的方法就是在鼠標(biāo)移入圓環(huán)在圓環(huán)中按下鼠標(biāo)的時(shí)候賦值,感性趣的童鞋可以自行研究一下

bigCircle.addEventListener("mouseenter", init)
bigCircle.addEventListener("mousedown", init)

function init(e) {
    lastMouseAngle = calcAngleDegrees((e.clientX - CENTER.x), (CENTER.y - e.clientY))
}

初始化lastMouseAngle之后,mouseAngle - lastMouseAngle即為角度的增量

增量正負(fù)決定方向:正數(shù)為逆時(shí)針,負(fù)數(shù)為順時(shí)針
增量大小決定距離:絕對(duì)值即是圓環(huán)旋轉(zhuǎn)的角度

由于順時(shí)針旋轉(zhuǎn)時(shí)增量為負(fù),且CSS里transform屬性為順時(shí)針旋轉(zhuǎn)增加角度
所以當(dāng)前圓環(huán)的角度計(jì)算公式為:circleAngle -= (mouseAngle - lastMouseAngle)

改造main函數(shù):

function main(e) {
    if(e.buttons === 1) {
        mouseAngle = calcAngleDegrees((e.clientX - CENTER.x), (CENTER.y - e.clientY))
        var changeMouseAngle = mouseAngle - lastMouseAngle
        circleAngle -= changeMouseAngle
        console.log("當(dāng)前角度:" + circleAngle)
        rotate.call(this, circleAngle)
        lastMouseAngle = mouseAngle
    }
}


可以看到已經(jīng)有了雛形,愉快地進(jìn)入下一步

5. 操作外部dom

想要操作外部dom,需要的是一個(gè)線性變化的值
用腳趾頭都能想到,當(dāng)前最合適的無(wú)疑就是當(dāng)前圓環(huán)角度circleAngle
然鵝仔細(xì)觀察上一張圖就會(huì)發(fā)現(xiàn),當(dāng)鼠標(biāo)每次移動(dòng)過(guò)9點(diǎn)鐘方向時(shí),圓環(huán)角度就會(huì)瞬間改變360度,回到初始值,并不能滿足當(dāng)前需求
此處做一波改造,判斷當(dāng)角度的變化值changeMouseAngle超過(guò)一定度數(shù)的時(shí)候,不執(zhí)行后面的操作
考慮到單身20年用戶的手速,暫時(shí)設(shè)置這個(gè)值為300

var MAX_CHANGE_ANGLE = 300
function main(e) {
    ...
    var changeMouseAngle = mouseAngle - lastMouseAngle
    if(Math.abs(changeMouseAngle) > MAX_CHANGE_ANGLE){
        return lastMouseAngle = mouseAngle
    }
    ...
}

這樣circleAngle就會(huì)呈線性變化了

接下來(lái)的事就是找一張阿麗塔的美圖了

.pic {
    width: 100px;
    margin: 100px auto;
    border-radius: 10px;
}
.pic img {
    width: 100%;
    border-radius: 10px;
}

最后寫一段縮放代碼:

var picDom = document.getElementsByClassName("pic")[0]

function controlPic(value) {
    this.style.width = 100 + 1 * value + "px"
}

function main(e) {
    ...
    controlPic.call(picDom, circleAngle)
    ...
}

大功告成!查看完整的代碼示例請(qǐng)戳這里,在線體驗(yàn)請(qǐng)戳這里

后記

從《阿麗塔》上映那天起就開(kāi)始醞釀這篇博客了,直到一個(gè)多月后的今天……

不多BB,下一篇博客將會(huì)在demo的基礎(chǔ)上封裝插件,有生之年見(jiàn)~

原文地址在此 ,歡迎來(lái)玩~

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

轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/109323.html

相關(guān)文章

  • JS仿阿麗依德醫(yī)生旋轉(zhuǎn)縮放控件DEMO

    摘要:前言前些天看了阿麗塔感嘆酷炫特效的同時(shí),不得不說(shuō)這個(gè)片子灰常之熱血重新點(diǎn)燃了我糞斗的基情有那么幾個(gè)瞬間仿佛自己回到了,下面進(jìn)入正題在依德醫(yī)生剛撿回阿麗塔的那一段,有木有發(fā)現(xiàn)醫(yī)生家的設(shè)備都很有意思比如那個(gè)人皮縫紉機(jī),其靈活程度堪比織網(wǎng)的蜘蛛說(shuō) 前言 前些天看了《阿麗塔》感嘆酷炫特效的同時(shí),不得不說(shuō)這個(gè)片子灰常之熱血!重新點(diǎn)燃了我糞斗的基情!!有那么幾個(gè)瞬間仿佛自己回到了…… showIm...

    liangzai_cool 評(píng)論0 收藏0
  • ReactNative仿《ONE》APP

    摘要:仿又來(lái)了又寫了一個(gè),別急呀,我可沒(méi)上次寫的代碼這是用寫的基本界面都已經(jīng)實(shí)現(xiàn),當(dāng)然了,有些地方圖省事搞不定追求速度寫的,就自然會(huì)導(dǎo)致退而求其次的實(shí)現(xiàn)方式代碼結(jié)構(gòu)可能不太規(guī)范清晰可能還有呢我不聽(tīng)我不聽(tīng)項(xiàng)目地址我的個(gè)人主頁(yè)盡管風(fēng)光無(wú)限幾乎對(duì)各大 仿《ONE》APP又來(lái)了! 又寫了一個(gè)《ONE》,別急呀,我可沒(méi)copy上次寫的代碼~ 這是用ReactNative寫的《ONE》 基本界面都已經(jīng)實(shí)...

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

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

0條評(píng)論

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