Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537
html5 地理定位
html5 Geolocation API用于獲得用戶的地理位置
鑒于該特性可能侵犯用戶的隱私,除非用戶同意,否則用戶位置信息是不可用的
注意:Geolocation(地理定位)對于擁有GPS的設備,地理定位更加精確
Geolocation API的主要方法是gerCurrentPositon,它用來獲得用戶的位置
下面是一個簡答的地理定位實例,可返回用戶位置的經度和緯度:
var x=document.getElementById("demo");
function getLocation(){
if(navigator.geolocation){
navigator.geolocation.getCurrentLocation(showPositon);}
else{
x.innerHTML="該瀏覽器不支持獲取地理位置."}
}
function showPosition(position){
x.innerHTML="緯度:"+position.coords.latitude+
"<br>經度:"+position.coords.longitude;}
實例解析:
●檢測是否支持地理定位
●如果支持,則運行gerCurrentPosition()方法.如果不支持,則向用戶顯示一段信息
●如果getCurrentPostion()運行成功,則向參數showPosition中規定的函數返回一個coordinates對象
●showPosition()函數獲得并顯示經度和緯度
上面的例子是一個非常基礎的地理定位腳本,不含錯誤處理
你需要先熟悉JavaScript才能理解和使用API
如果gerCurrentPosition()運行成功,則getCurrentPosition()方法返回對象.始終返回latitude,longtitude以及accuracy屬性.如果可用,則會返回其他下面的屬性:
●coords.latitude:十進制數的緯度
●coords.longtitude:十進制的經度
●coords.accuracy:位置精度
●coords.altitude:海拔,海平面以上以米計
●coords.altitudeAccuracy:位置的海拔精度
●coords.heading:方向,從正北開始以度計
●coords.speed:速度,以米/每秒計
●timestamp:響應的日期/時間
二 html5 拖放
拖放(Drag和drop)是html5標準的組成部分
拖放是一種常見的特性,即抓取對象以后拖到另一個位置
在html5中,拖放是標準的一部分,任何元素都能夠拖放
★設置元素為可拖放
首先,為了使元素可拖動,需要把draggable屬性設置為true:
<img draggable="true">
★拖動什么-ondragstart和setData()
然后,規定當元素拖動時,會發生什么
dataTransfer.setData()方法,設置被拖數據的數據類型和值:
function drag(ev){
ev.dataTransfer.setData("Text",ev.target.id);}
在這個例子中,數據類型是"Text",值是可拖動元素的id("drag1")
★放到何處-ondragover
ondragover時間規定在何處放置被拖動的數據
默認地,無法將數據/元素放置到其他元素中,如果需要設置允許放置,我們必須阻止元素的默認處理方式.
這要通過調用ondragover時間的event.preventDefault()方法:
event.preventDefault()
★進行放置-ondrop
當放置被拖數據時,會發生drop事件
function drop(ev){
ev.preventDefault();
var data=ev.dataTransfer.getData("Text");
ev.target.appendChild(document.getElementById(data));}
三 html5 SVG
什么是SVG?
●SVG指可伸縮矢量圖形(Scalable Vector Graphics)
●SVG用于定義用于網絡的基于矢量的圖形
●SVG使用XML格式定義圖形
●SVG圖像在放大或改變尺寸的情況下其圖形質量不會損失
●SVG是萬維聯盟的標準
在html5中,你能夠直接將SVG元素嵌入html頁面中
要使用SVG繪制圖形,你首先需要創建一個<svg>標簽
<svg width="1000" height="1000"></svg>
要創建一個圓形,需要添加一個<circle>標簽
下面是SVG代碼:
<svg width="1000" height="1000">
<circle cx="100" cy="50" r="40" fill="red" />
</svg>
●cx和cy屬性定義圓點的x和y坐標.如果省略cx和cy,圓的中心會被設置為(0,0)
●r屬性定義圓的半徑
運行效果如下:
畫布坐標、屏幕坐標的概念
幾何變換:平移、縮放、旋轉
Canvas 中的所有幾何變換針對的不是繪制的圖形,而是針對畫布本身,也就是說,當移動、縮放、旋轉畫布之后,新的坐標系只對新的操作生效
參考:
示例代碼
const canvas = document.getElementById("canvas");
const context = convas.getContext("2d");
context.fillRect(100, 100, 50, 50);
Canvas的繪制和html的繪制是不一樣的,html的繪制是增量的,當變化時,只會重新繪制變化的部分,沒有變化的部分是不會重新繪制的,但是canvas不一樣,每次都是全量繪制的,如果一個canvas里有很多圖形,當改變一個圖形時,需要重新繪制所有圖形才可以(當然,可以用clearRect擦除部分區域,但一般很少這么用)。
了解canvas的繪制規則之后,就很容易發現性能問題,如果canvas上繪制了大量的圖形(成千上萬個),每次重繪就需要很長的時間,如果重繪的頻率很高,那么就會有性能問題
那么如何解決這個問題呢,目前有以下幾種方案
圖層的概念來自于PS,每一個圖層都是一個canvas,既然在一個canvas上繪制太多圖形會有性能問題,那么就分幾個圖層,每次僅重新繪制其中一個圖層,每個圖層的圖形都不會很多,那么即使重繪的頻率很高,也不會有性能問題。圖層的概念圖如下:
這里用背景顏色只是示意,實際上圖層都是透明
代碼實現
用一個父元素作為容器,把所有的元素設置成一樣的寬高并放在里面重疊。
<div class="container">
<canvas width="500" height="500"></canvas>
<canvas width="500" height="500"></canvas>
<canvas width="500" height="500"></canvas>
<canvas width="500" height="500"></canvas>
<canvas width="500" height="500"></canvas>
</div>
繪制是很耗性能的,如果每次都清空畫布然后重新畫一次,那么性能會消耗很大(即使分了幾個圖層),我們應區分“變”與“不變”的部分,只對“變”的部分重新渲染,“不變”的部分不渲染,將經常變化的部分抽離到臨時圖層,這樣僅需要渲染臨時圖層,臨時圖層有幾種實現思路,一種是使用操作圖層(俗稱高性能圖層),一種是使用隱藏圖層(不繪制到界面上的)
高性能圖層
一般高頻(實時響應鼠標、鍵盤等事件)的操作會放在高性能圖層,等操作完成之后,再將最終結果保存到其它圖層,比如繪制、拖拽、縮放一個(或一批)shape
隱藏圖層
有些圖層是不用給用戶看的,這些canvas僅存在于內存中,不會插入html的dom中,用完就銷毀,比如常見的canvas to image。
還有一種實現方式是離屏渲染(OffscreenCanvas),先在一個offCanvas操作,然后再將結果渲染到界面上(有點像虛擬dom操作),一般會結合webworker或webassembly
const canvas = document.createElement("canvas");
const context = canvas.getContext("2d");
// 繪制圖片,或其它操作
context.drawImage();
// 轉成base64圖片
convas.toDataUrl();
影響canvas性能的除了繪制頻率,還有一個重要的是像素點操作,一般圖像處理會涉及到大量的像素點操作,如果放在主線程計算,那么會卡住其它操作,造成頁面卡頓,特別影響用戶體驗,這些涉及大量計算的一般會單獨開個線程來操作,而在瀏覽器中有這個能力的就只有webworker了。
有了webworker可能還不夠,因為始終是在js上執行,js執行效率天生就比其它語言慢,所以一般的會使用webassembly,執行效率比js快很多,而且還能用到更豐富的圖像處理庫
如果還有更高的性能要求,那么普通的2d canvas可能就無法滿足了,這個時候可以使用webgl,性能更高(當然學習成本也更高),再結合wasm,就可以有無限想象力了,鼎鼎大名的figma就是用webgl + wasm(rust)實現的,另外google doc在線文檔也使用了webgl,飛書文檔將來也會替換成wegbl,基于瀏覽器的渲染始終有諸多限制,一般有能力的都會實現自己的渲染引擎。
假設canvas大小為(867,350)
圖片的大小為(768,576)
將上面這張圖片放到canvas中,圖片貼邊處理,也即圖片太大就縮小,圖片太小就放大。那么我們如何實現這種效果呢?
總結一下,總共分為幾步:
canvas的執行細節如下:
有時候,我們想閱讀頁面中某段精彩的內容,但由于頁面太長,用戶需要自己滾動頁面,查找起來非常麻煩 ,很容易讓人失去繼續往下閱讀的興趣。這樣體驗非常不好,所以我們可以想辦法 實現點擊某段文字或者圖片跳轉到頁面指定位置,方便用戶的閱讀。
這里作為錨點的標簽可以是任意元素。
<a href="#aa">跳轉到 id 為 aa 標記的錨點</a>
<p>-------------分隔線-------------</p>
<div id="aa">a</div>
這里作為錨點的標簽只能是 a 標簽。
<a href="#bb" >跳轉到 name 為 bb 的 a 標簽錨點</a>
<p>-------------分隔線-------------</p>
<a name="bb">name 為 bb 的 a 標簽的錨點</a>
<div id="abb">bbb</div>
注意:當以 ' a 標簽 name 屬性作為錨點 ' 和 ' 利用 id 為標記的錨點 ' 同時出現(即以 name 為錨點和以 id 為錨點名字相同時),會將后者作為錨點。
window.scrollTo 滾動到文檔中的某個坐標??商峁┗瑒有Ч?,想具體了解 scrollTo() 可以看看 MDN 中的介紹。
話不多說,看下面代碼
「html 部分」:
<a id="linkc">平滑滾動到 c</a>
<p>-------------分隔線-------------</p>
<div id="cc">c</div>
「js 部分」:
var linkc = document.querySelector('#linkc')
var cc = document.querySelector('#cc')
function to(toEl) {
// toEl 為指定跳轉到該位置的DOM節點
let bridge = toEl;
let body = document.body;
let height = 0;
// 計算該 DOM 節點到 body 頂部距離
do {
height += bridge.offsetTop;
bridge = bridge.offsetParent;
} while (bridge !== body)
// 滾動到指定位置
window.scrollTo({
top: height,
behavior: 'smooth'
})
}
linkc.addEventListener('click', function () {
to(cc)
});
Element.scrollIntoView() 方法讓當前的元素滾動到瀏覽器窗口的可視區域內。想具體了解 scrollIntoView() 可以看看 MDN 中的介紹。
下面也直接上代碼
「html 部分」:
<a onclick="goTo()">利用 scrollIntoView 跳轉到 d</a>
<p>-------------分隔線-------------</p>
<div id="dd">ddd</div>
「js 部分」:
var dd = document.querySelector('#dd')
function goTo(){
dd.scrollIntoView()
}
注意:此功能某些瀏覽器尚在開發中,請參考瀏覽器兼容性表格以得到在不同瀏覽器中適合使用的前綴。由于該功能對應的標準文檔可能被重新修訂,所以在未來版本的瀏覽器中該功能的語法和行為可能隨之改變。
下面為了方便看效果,把上面的代碼整理在一起。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
div {
width: 600px;
height: 300px;
background-color: pink;
}
</style>
</head>
<body>
<a href="#aa">跳轉到以 id 為 aa 標記的錨點 a</a>
<p>-------------分隔線-------------</p>
<a name="aa">hhh</a>
<div id="aa">aa</div>
<a href="#bb" >跳轉到 name 為 bb 的 a 標簽錨點</a>
<p>-------------分隔線-------------</p>
<a name="bb">name 為 bb 的 a 標簽的錨點</a>
<p>-------------分隔線-------------</p>
<div>bb</div>
<a id="linkc">平滑滾動到 c</a>
<p>-------------分隔線-------------</p>
<div id="cc">cc</div>
<a onclick="goTo()">利用 scrollIntoView 跳轉到 d</a>
<p>-------------分隔線-------------</p>
<div id="dd">dd</div>
<p>-------------分隔線-------------</p>
<div></div>
</body>
<script>
var cc = document.querySelector('#cc')
var linkc = document.querySelector('#linkc')
function to(toEl) {
//ele為指定跳轉到該位置的DOM節點
let bridge = toEl;
let body = document.body;
let height = 0;
do {
height += bridge.offsetTop;
bridge = bridge.offsetParent;
} while (bridge !== body)
console.log(height)
window.scrollTo({
top: height,
behavior: 'smooth'
})
}
linkc.addEventListener('click', function () {
to(cc)
});
</script>
<script>
var dd = document.querySelector('#dd')
function goTo(){
dd.scrollIntoView()
}
</script>
</html>
效果圖:
*請認真填寫需求信息,我們會在24小時內與您取得聯系。