顯示具有 程式 標籤的文章。 顯示所有文章
顯示具有 程式 標籤的文章。 顯示所有文章

20230729

Canvas 要搞清楚畫圖原點位置

就是這個,卡了快一個禮拜。主要要做到的事,是把上方用 CSS 調整過後的、眼睛看到的樣子,畫在下方 Canvas 裡,角度、旋轉、位移都要一樣。

function draw() {
  const c = document.getElementById("myCanvas");
  const ctx = c.getContext("2d");
  const img = document.getElementById("scream");
  document.getElementById("msg").innerHTML=img.offsetLeft;
  const scaleratio=1.5;
  const diffx=400 + img.width / 2;
  const diffy=0 + img.height / 2;
  
  ctx.translate(diffx,diffy);
  ctx.scale(scaleratio,scaleratio);
  ctx.rotate(Math.PI/180*45);
  ctx.drawImage(img,-img.width/2, -img.height/2, img.width, img.height);
}

首先算出 diffx and diffy, 這是為了要後來要將 Canvas 畫圖原點預設是在左上角,接下來要移到 img 的中心原點用的。畢竟上方 user 看到的畫面,都是以 img 中心來操作的(CSS transform) ,要說是拿左上角操作的話,大概只有 translate 可以說是拿左上角的點進行操作。

img 的中心 x 座標是 img.width / 2,要記得加上模擬的位移 400,同樣 img 的中心 y 座標是 img.height / 2,也要加上模擬位移 = 0。canvas scale 數值和 css scale 數值一樣,剩 canvas rotate 用的是弧度而不是角度,要記得換算。

真正重要的地方是在 ctx.translate(diffx, diffy) 這一步,把 canvas 原點移到跟 img 一樣是在中心的地方。本來以為先放大再位移會是一樣的結果,可是實驗結果就是不對,最後把數字印出來才發現,放大後不會更改座標數字,例如原本是 (1, 1) 在放大後取得的座標值也還是 (1, 1) ,但是會跑到看起來是 (1.5, 1.5) 的地方,因為 canvas scale 改了座標的單位,假設本來一個刻度是 1cm 的放大後一個刻度是 1.5cm 這樣,「先放大再旋轉」或「先旋轉再放大」好像就沒有差別了。

最後真正 drawImage 的時候,因為已經把中心移到跟 img 中心一樣在中間的位置了,所以要畫出左上角的話, dx = -img.width / 2, dy = -img.height / 2 才對,配上畫完整個 img 的寬度、高度。

23.08.09 update. 趁今天有空,寫在 codepen裡,免得下次我要畫圖的時候又忘記了。

20230223

Object : hasOwn

就是這個,花了兩小時在找問題...

if (Object.hasOwn(myObj, 'error') { blah blah blah}

我一直用這樣寫法好一陣子了,結果今天丟到 ipad 上就失敗。因為還有 async, await 在,沒有第一時間覺得是 hasOwn 的事,直到查了 Can I use?

還好,解決問題

20220809

手機網頁顯示高度一直算不對

我有一頁網頁放在 PC responsive 看是好的,模擬成 iPhone / iPad 也都順利,就是實際拿 iPhone / iPad 來看後,會被 address bar 卡住。原先只想到設成 100vh 以為就能拿到最大的可視高度了,結果只要 Safari 橫向而且開多個分頁後,我的網頁高度就出事了。

後來查到這一篇: Designing websites keeping floating tab bar of Safari 15 (on iOS) in mind. 最後我在網頁底預留了

padding-bottom: env(safe-area-inset-bottom);

留給 address bar, 看似高度問題解決,iPhone / iPad 的 Safari 上能順利顯示了。因為怕有人將 address bar 移到上方,所以我也加了

padding-top: env(safe-area-inset-top);

希望能順利。

20220805

localStorage & sessionStorage

吼... 一定要記錄下來,今天就發生這樣的 bug. 因為我把 login 回傳的資料存在 sessionStorage 裡面,然後要用之前再轉存到 localStorage 裡。結果今天在試重開機的流程,因為是先看到 index.html 的,才發現 sessionStorage 裡的值不見了。為了找這種漏洞,又花了一小時。

現在最大的區別是:localStorage 不會過期,要自己手動清除, sessionStorage 是網頁關掉就清空 (分頁關掉或整個 browser 關掉) 。

20220408

今年:用 python 幫我做瑣碎的事

來看我多久會完成...

========================

3/9 洗澡時候突發奇想,覺得平常每天抓股票資料好煩,最近又因為戰爭關係局勢不穩,所以年初到現在都還沒操作過,可是這就跟錢過不去啊!所以立下一個目標:在寫完 python 選股之前,我不去操作股票。感覺我寫完整後,局勢應該也穩定了(三分鐘熱度的個性,有目標要寫下來才能落實啊…)

抓取台股的部份,有試了 twstock 這一款,感覺不是我要的,所以這條線就暫停在這裡了。

後來又想到,我連最基本的清單來源都沒有,所以應該要從清單開始才對。所以用了 BeautifulSoup 去抓資料。首先卡在 selectfind_all 之間,比起來用 select 習慣,我就繼續用下去。接著是怎麼拿到 innerHTML ,要:

select_item.decode_contents()

有了清單後,想把他寫在檔案裡,再去抓每天收盤資料,所以我又看了怎麼讀檔、寫檔的事。隨便在檔案裡寫了「2330 台積電」後讀檔時候就碰到:

UnicodeDecodeError: 'cp950' codec can't decode

這樣的 error ,原來要指定編碼才行:

list_file = open('list.txt', 'r', encoding="utf-8")

03.22 這幾天決定要去抓取 Yahoo Finance 的資料,所以要先把「2330 台積電」寫成 "2330.TW" 才行,這時候套了 regular expression. 到此我覺得每日清單已經告一段落了,已經比之前手動找少了很多時間。

要去抓 yahoo 資料,在看了幾篇文章後,都提醒要增加 headers 才不會被擋住,所以 request 裡要加上 headers 這個值

res = requests.get(url, headers=ua)

Scrape Yahoo! Finance Home Page with Python 這一篇看到一半,我找到我要的資料所包的 script 區塊,可是還不知道怎麼從裡面擷資料出來,所以又卡著了。

後來發現有寫好 yfinance 這一套,剛裝完而已,要來試後面的步驟。

先從 info 下手:

import yfinance as yf

tsmc = yf.Ticker("2330.TW")
print(tsmc.info)

本來以為拿其中的值很簡單的,

print(tsmc.info.dayHigh)

結果完全不是我想的那樣... 這一卡又兩個晚上過去了。後來才想到說:萬一他是字串怎麼辦?所以趕快確認一下,結果是 <class 'dict'> 這種神奇的東西。之前也沒學,都不認得這種 type. 要拿值的話,我現在記這種方法:

tsmc.info["dayHigh"]

如此一來,我就有很多基本值可以用了。(過一陣子再補齊 dictionary ...)

難得有空,多寫一點。我原先挑選有一個條件是: 3MA > 5MA. 這時候想起初始研究裡大家推薦的 pandas. 首先先抓 5 天的值後,建立 DataFrame. 接著直接:

df["Close"].mean()

平均值就算完了,超方便的。

花了幾天在算指標上面,原本是想說找公式然後自己算,可是現在看到公式就暈了... 後來發現大家會推 TA Lib 這一套,可是怎麼裝都會遇到錯誤,這裡又卡了幾天了。因為有看到 source code, 所以打算 build 看看,可是要自己 make, 要多建立 C++ compiler 的環境,然後就去下載 VS 2022 回來。好不容易 nmake 成功,要裝 TA Lib 還是失敗。看來看去是因為我裝 x64 的 python 可是 build 出 x32 的版本,到此放棄了,就用別人的 whl 好了,再來裝都成功,我要的指標也完成了。

接近一個月的時間,完成了我想要做到的事,可是戰爭還沒結束啊...

========================

22.11.02 update

因為電腦重灌的關係,要一步一步找回原本的設定,發現 yfinance 一直裝不成功,說缺少 libxml2. 因為是 C++ 的 library, 所以先裝了 Microsoft Visual C++ 然後在 Archived: Python Extension Packages for Windows - Christoph Gohlke 找到需要的檔案後安裝,接著再安裝 yfinance, 這才成功。

20211127

遇到老 bug

整個一團霧水,完全不知道怎麼解...

最近是和別人合作的,昨天在把我的 code 整合到別人的環境裡。有一隻被引用的 ts 長這樣:

// func.ts
const obj1 = {
    abc: `<h1>ABC</h1>`,
    def: `<h2>DEF</h2>`,
};

const obj2 = `<section class="section-1">總共</section>`;

用 webpack build 的時候一直跳錯誤,雖然最近我用的是 rollup, 自己 build 起來是沒問題的。我再拿到舊一點專案使用 webpack 去跑也是可以,就是搬到新環境出事。然後還麻煩對方 RD 幫我看,結果兩小時過去我們都沒找到問題點。

老闆這時候本來是要來討論,後來就幫我看問題。原先 obj2 裡字串很長的,後來刪減到就是這一行出問題,而且是「總」這個字有問題,這時候就想到是不是中文字編碼的事。可是我這一隻檔案就是從原先 rollup 那個地方複製到新環境的,沒理由我原本可以後來不行。看編碼,原先檔案編碼確定是 UTF-8, 但是開筆記本、notepad++ 都說那隻檔案後來的編碼是 ANSI...

原本檔案用 VS Code 寫、儲存的,只是新環境對方來教我的時候是講 VS 2022, 所以這隻檔案被搬到 VS 2022 儲存過就變編碼了... 老闆幫忙查了,找到兩篇:

  1. 【茶包射手日記】VS2015程式檔編碼問題
  2. VS2015程式檔BIG5相容問題快速解法-修改csproj/vbproj

最後強迫用筆記本幫我換編碼,結束這個下午。

VS 2022 實在用的很不順手,我再三確定存檔了,結果 webpack build 出來的還是舊檔案 (都有 clean 過啊) ,我預期 build 完的 js 會是含新的字串進去的,可是還是舊的 cached 的字串,最後是把 VS 2022 關掉重開,確定有包進新字串了,也不知道哪裡有誤。最後大結論:人生好難...

20210813

svelte 的第一次嘗試

我今年 project 配置都是:webpack, babel, typescript. 現在想嘗試多加上一個 svelte, 結果就不太順利了。

Svelte 也有人教配合 typescript 的,那些專案大部份都配上 rollup (就是要趕快學新東西了) 。如果要用到 webpack 的,照目前查到的教學來說,都少一點東西,而且 8/11 裝了好像會卡住... 不過重頭直接裝 webpack + babel + svelte 又有成功。

8/12 重試一次,以 Integrating TypeScript with Svelte 這一篇講的為主。我照舊的配置從 webpack, babel, typescript 裝起,接著裝了 svelte, svelte-loader, svelte-preprocess.

tsconfig 我用原本的配置,然後建了 "typings" 資料夾,底下放了 "index.d.ts" (現在想想是不是以後每多一個 src 檔都要建一個 .d.ts 啊?)

webpack.config.js 裡新增一段用 "svelte-loader" 讀檔案的。

// index.d.ts
declare module '*.svelte' {
  const value: any;
  export default value;
}
// index.ts
import App from './App.svelte';
import './custom.scss';

ready(() => {
  console.log('DOM is ready.');

  const app = new App({
    target: document.querySelector('div.from-app'),
    props: {},
  });
});
// App.svelte
<script>
  import Helper from './Helper.svelte';
</script>

<h1>Hello World</h1>

<Helper val={3} />
// Helper.svelte
<script lang="ts">
  let val: number;
</script>

<h1>Temp {val}</h1>

跟著文章建立到這邊, build 檔案後上傳可以看到正確的結果,只是有以下問題:

  1. 在 index.d.ts 裡, export default value -> "Duplicate identifier 'default'.ts(2300)"
  2. 在 index.ts 裡, import app from './app.svelte' -> "Cannot find module './app.svelte' or its corresponding type declarations.ts(2307)"
  3. 在 App.svelte 裡, <Helper val={'3'} /> -> "'Helper' is not defined.svelte(missing-declaration)" 可是我上面才寫了 import 啊...

用 svelte-check 會有一個錯誤,"Error: Type '{ val: number; }' is not assignable to type 'IntrinsicAttributes'. Property 'val' does not exist on type 'IntrinsicAttributes'. (ts)

寫到這裡 8/13 16:07 發現卡住了,先暫停整理一下...

8/16 17:23 更新一下研究,我最上面三個問題,都跟 tsconfig 有關

在我原先的設定裡,我只寫 "include: ['./src']" 結果把 node_modules 裡面的 "src" 也包進來了。就算同時列了 "exclude: ['./node_modules']" 和 "include: ['./src']" 也會抓到 node_modules 裡面,這樣會有 "Duplicate identifier 'default'.ts(2300)" 的錯誤 (真的有一樣 export)

再來是明明有 import 可是卻不認得的事,我原先的 tsconfig 是 init 自動產生的,所以沒有改過 target (ES5), module(commonjs). 現在發現 module === commonjs 就會有 import 的錯誤。

最後 not assignable to type 'IntrinsicAttributes' 的錯誤今天都沒看到,就不管他了。

20210209

為了要找 bug 延伸的東西

昨晚太早睡
結果被地震嚇起來看一下 LINE 發現有 bug
年前最後一個工作天就用來找 bug 了


手動測了 20 分鐘
也按了十幾次吧
總共也才出現一次
reproduce rate ~= 1/10 而已
實在受不了就動到自動測試上了 (終於又下定決心要摸一下了)


比較了 Selenium & Cypress
這次選 Cypress 來試我的東西

先安裝 cypress (我用 npm 的)

npm i -D cypress

接著說要執行

./node_modules/.bin/cypress open

在這裡就出問題了
說是權限問題
附了一個說明 About Execution Policies
這才發現原來我 vs code 使用的是 windows powershell 又不一樣
裝好 powershell 7.1 後設定 vs code 用新的 powershell 後
先改權限

pwsh.exe -ExecutionPolicy AllSigned

再執行

./node_modules/.bin/cypress open

這一次跳出來的錯誤變成 *\cypress.ps1 is not digitally signed

接著找到 Fix for PowerShell Script Not Digitally Signed 來解決
到此前置作業才完成而已 (汗)

跟著 Getting Started 寫了一個短短的 test case
可是卡在操作第三方套件的地方
最後還是手動測了

結果我早上步驟有誤
怎麼也不能精準的找到正確步驟 (退步了啊...
反正小的也閒著就讓他去玩
這才看到關鍵點

問題就在第三方套件上
最後是採取「掩埋法」解決 (還是不確定套件做了什麼事)
算是告一段落了

20210129

閒閒來學 React - 初始

 


為了讓自己有事做
幫自己找了個目標:來學 react
去年就跟著寫完 tutorial 了
不過有寫沒懂、也沒實際目標
寫得很心虛
這次想說慢慢把手邊的計畫都改寫好了
就從 codecademy 跟著學
還是很心虛 (工時兩天讓我比較熟一些了)
決定還是直接拿舊的 project 來邊改邊學好了

首先參考了這篇:2020 Settings of React TypeScript Project with webpack and Babel

平常是都用 HTML + CSS + JavaScript/jQuery
然後 TypeScript 來輔助、最後用 Webpack + Babel 打包出來
雖然還不完全懂 react 的好處
只是覺得可以偷懶一些 (元件化可以不用一直寫重複的東西了)
然後我的美感實在不行
常常都是建立在別人寫好漂亮的 bootstrap 模板上
所以要用到 react-bootstrap
平常寫最多的都是 dashboard 類型
很少很少是一頁式
可是一頁式比較好上手就拿來當第一個目標

結果才一個 jumbotron 就嚇死了...
這真的是我原本用得很熟的東西嗎 XDD
內心滿滿的衝擊哈哈哈

現在要期待自己能早日習慣

20200518

20200512

20200504

20190408

20190121

20170415

20170325

20170318

20170219

20160206