從css3 rotate 到插件, svg, canvas (hello world向)

首先是這樣一個需求, 要兼容IE7的旋轉(zhuǎn)的角標

一個旋轉(zhuǎn)的角標,最多可能有50期

隨著這個期數(shù)增多 ( 假設50期 ) 雪碧圖也變的越來越大 , CCS3的 rotate 只能兼容到IE9
IE5 都支持的 filter旋轉(zhuǎn)則是個沉重的知識點 ( 矩陣旋轉(zhuǎn)并沒有實驗成功 )

filter: progid:DXImageTransform.Microsoft.Matrix(sizingMethod='auto expand', M11=0.7071067811865476, M12=-0.7071067811865475, M21=0.7071067811865475, M22=0.7071067811865476); /* IE6,IE7 */
-ms-filter: "progid:DXImageTransform.Microsoft.Matrix(SizingMethod='auto expand', M11=0.7071067811865476, M12=-0.7071067811865475, M21=0.7071067811865475, M22=0.7071067811865476)"; /* IE8 */

那么 還有哪些方法可以解決這個問題呢 ,

找找插件


jQueryRotate官網(wǎng)寫著兼容到IE6+ , 只要在jq后面引入就好了
寫個test頁面試一下

<script src="jquery.js"></script>
<script src="jQueryRotate.js"></script>

$('img').rotate(50);
IE7

wow , 效果好像不錯, 但實際使用發(fā)現(xiàn)

只支持圖片的旋轉(zhuǎn), 不支持DIV等HTML

插件的作者表示會在3.x的實驗版本中嘗試不穩(wěn)定的支持(摔

但是到了這里 ,解決問題的思路稍微明朗了一些 , 如果有一個正的(0deg)圖片 , 用rotate插件旋轉(zhuǎn)過來解決問題了
或者我們找方法批量生成一個旋轉(zhuǎn)的圖片

那么試試SVG?

雖然SVG 同樣從IE9+才開始被支持 , 但是感覺如此廣泛的使用群體和平臺, 相信會有低版本IE 的polyfill方案的

svg畫起來還是很簡單的 , 不信你看

<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="100" height="150">
  <text x="0" y="15" fill="red" transform="rotate(45,0 75)">2期</text>
</svg>


用一個text節(jié)點 , 中間寫好文字就行
rotate(x, origin) origin 里是x,y坐標
具體可以移步 http://www.zhangxinxu.com/wordpress/2015/10/understand-svg-transform/

當然 , 也有npm包, 可以用在node端用來快速生成svg , 然后直接輸出到HTML里
https://www.npmjs.com/package/text-to-svg
npm install --save text-to-svg

那么下面就是去找處理兼容問題的包了(根本不會找不到)

有一個名為SVGWEB 的插件
https://www.rustybrick.com/svg-support-for-internet-explorer.html
https://code.google.com/archive/p/svgweb/
它會在低版本IE下把svg變成flash
但經(jīng)過實驗 , 面對svg復雜的path路徑時 , 會失敗
而且每一個svg都要用script標簽包裹起來 , 感覺性能開銷比較大

發(fā)散下思維,看看Unicode

unicode是字體在網(wǎng)頁端最原始的應用方式,特點是:

  • 兼容性最好,支持ie6+亭珍,及所有現(xiàn)代瀏覽器午阵。
  • 支持按字體的方式去動態(tài)調(diào)整圖標大小凫碌,顏色等等邻吭。
  • 但是因為是字體盲厌,所以不支持多色馒过。只能使用平臺里單色的圖標臭脓,就算項目里有多色圖標也會自動去色。
  • 注意:新版iconfont支持多色圖標腹忽,這些多色圖標在unicode模式下將不能使用

那么去搜索一下 https://unicode-table.com/cn/


沒什么驚喜... Unicode 看來跑題了

再次面向stackoverflow編程之后, 讓我們試一試canvas

canvas 有方便的API把文字放到畫布上
然后用 一個 toDataURL() 可以再把canvas畫布變成一個base64 格式的png 輸出

Base64編碼是從二進制到字符的過程来累,可用于在HTTP環(huán)境下傳遞較長的標識信息, 是一種網(wǎng)上常用的加密格式, image 的src會將加密后的base64轉(zhuǎn)換回二進制, 變成圖片, 且IE7 下是支持的(沒有開虛擬機XP)

好像可以著手批量生成圖片了! 手寫個服務器試試!

一共兩個文件, 下面的html是index.html, 在下面的js 是 index.js 服務器端腳本 ( 等有了更工具化的版本試著發(fā)個npm)
node index.js 啟動

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>canvas to img</title>
    <style>
        body {
            background-color: blanchedalmond;
        }

        img {
            padding: 50px;
            background-repeat: no-repeat;
        }
    </style>
</head>

<body>
    <canvas id="textCanvas"></canvas>
    <button id="submit">生成圖片</button>
    <div id="tip">等待服務器確認</div>
    <img class="elem0" src="" alt="">
    <img class="elem1" src="" alt="">
    <img class="elem2" src="" alt="">
    <img class="elem3" src="" alt="">

    <script>
        var tip = document.getElementById('tip');
        var sub = document.getElementById('submit');
        var arr = [];

        function createCanvas(w, h) {
            var c = document.getElementById('textCanvas').getContext('2d');
            c.canvas.width = w;
            c.canvas.height = h;
            // 描點, 畫背景
            c.beginPath();
            c.moveTo(0, 0);
            c.lineTo(30, 0);
            c.lineTo(60, 30);
            c.lineTo(60, 60);
            c.closePath();
            c.lineWidth = 1;
            c.strokeStyle = '#ef9624';
            c.fillStyle = '#ef9624';
            c.stroke();
            c.fill();
            // 旋轉(zhuǎn)畫布, 準備寫字
            c.rotate(45 * Math.PI / 180);
            c.translate(12, -30);  // 勾股定理算出位移
            c.font = '14px'; // 可以改字體
            c.textAlign = 'center';

            // 循環(huán)生成
            for (let i = 1; i < 10; i++) {
                let img = document.createElement('img');
                let t = i + '期';
                c.strokeStyle = '#ef9624';
                c.fillStyle = '#fff';
                c.fillText(t, 30, 24);
                arr.push(c.canvas.toDataURL());
                // 用背景色寫一遍文字, 不再重新生成畫布
                c.strokeStyle = '#ef9624';
                c.fillStyle = '#ef9624';
                c.fillText(t, 30, 24);
                c.strokeText(t, 30, 24);
            }
        }
        createCanvas(60, 60);

        // ajax發(fā)送
        sub.addEventListener('click', function () {
            var xhr = new XMLHttpRequest();
            tip.innerText = '發(fā)送中';
            xhr.onreadystatechange = function () {
                if (xhr.readyState == 4 && xhr.status == 200) {
                    if (JSON.parse(xhr.response).code === 10000) {
                        createImg();
                    }
                }
            };
            xhr.open('POST', '/upload', true);
            xhr.send(JSON.stringify(arr));
        });

        function createImg() {
            let css = document.createElement('link');
            css.rel = 'stylesheet';
            css.setAttribute('href', './1.css');
            css.setAttribute('type', 'text/css');
            console.log(css);
            tip.innerText = '加載css'
            document.head.appendChild(css);
        }
    </script>
</body>
</html>
var http = require("http");
var url = require("url");
var querystring = require("querystring");
var fs = require("fs");

// 路由方法
var handle = {};
handle['/'] = function (response, postData) {
  start(response, postData);
};
handle['/upload'] = function (response, postData) {
  createCss(response, postData);
};
//  感覺可以再學習學習別人的框架, 看看靜態(tài)資源請求怎么寫
handle['/assets'] = function (response, postData) {
  assets(response, postData);
}; 

function start(response, postData) {
  response.writeHead(200, { "Content-Type": "text/html" });
  console.log('__dirname', __dirname);
  response.end(fs.readFileSync(__dirname + '/index.html'));
}

function createCss(response, postData) {
  response.writeHead(200, { "Content-Type": "text/plain" });
  var arr = JSON.parse(postData);
  var css = '';
  arr.forEach(function (element, index) {
    css += `.elem${index} {\nbackground-image: url(${element});\n}\n`;
  }, this);
  fs.writeFileSync('1.css', css);
  // 模擬個成功
  var res = {
    code: 10000,
    msg: "ok"
  };
  response.end(JSON.stringify(res));
}

// 開始
var server = http.createServer(function (request, response) {
  var postData = "";
  var pathname = url.parse(request.url).pathname;
  request.setEncoding("utf8");
  request.addListener("data", function (postDataChunk) {
    postData += postDataChunk;
  });
  request.addListener("end", function () {
    if (typeof handle[pathname] === 'function') {
      console.log('normal path', pathname);
      handle[pathname](response, postData);
    } else if (/\.css/g.test(pathname)) {
      console.log('request a css', __dirname + pathname);
      response.writeHead(200, { "Content-Type": "text/css" });
      response.end(fs.readFileSync(__dirname + pathname));
    }
  });
});

console.log('http://localhost:3002/');
server.listen(3002);

最后: 并不是任何圖片都能生成 DataURI 的,有些瀏覽器由于內(nèi)存的限制窘奏,對 DataURI 的長度也會有所限制嘹锁。例如:Opera 限制為 65000 characters。

最后的最后, base64 的優(yōu)缺點

base64 可以減少HTTP請求. 同時比起圖片更新上傳清理緩存相對方便一點
缺點是因為字符串長度問題, 讓導致css文件較大- -

具體移步張鑫旭的文章
http://www.zhangxinxu.com/wordpress/2012/04/base64-url-image-%E5%9B%BE%E7%89%87-%E9%A1%B5%E9%9D%A2%E6%80%A7%E8%83%BD%E4%BC%98%E5%8C%96/

未壓縮的50期角標css是96kb, length為 97w
生產(chǎn)應用價值尚需討論, 反正...我學了一手 Node.js的服務器hello world , 以及canvas 畫圖

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末着裹,一起剝皮案震驚了整個濱河市领猾,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌骇扇,老刑警劉巖摔竿,帶你破解...
    沈念sama閱讀 218,284評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異少孝,居然都是意外死亡继低,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,115評論 3 395
  • 文/潘曉璐 我一進店門稍走,熙熙樓的掌柜王于貴愁眉苦臉地迎上來袁翁,“玉大人,你說我怎么就攤上這事婿脸×皇ぃ” “怎么了?”我有些...
    開封第一講書人閱讀 164,614評論 0 354
  • 文/不壞的土叔 我叫張陵狐树,是天一觀的道長焙压。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么冗恨? 我笑而不...
    開封第一講書人閱讀 58,671評論 1 293
  • 正文 為了忘掉前任答憔,我火速辦了婚禮,結(jié)果婚禮上掀抹,老公的妹妹穿的比我還像新娘虐拓。我一直安慰自己,他們只是感情好傲武,可當我...
    茶點故事閱讀 67,699評論 6 392
  • 文/花漫 我一把揭開白布蓉驹。 她就那樣靜靜地躺著,像睡著了一般揪利。 火紅的嫁衣襯著肌膚如雪态兴。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,562評論 1 305
  • 那天疟位,我揣著相機與錄音瞻润,去河邊找鬼。 笑死甜刻,一個胖子當著我的面吹牛绍撞,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播得院,決...
    沈念sama閱讀 40,309評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼傻铣,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了祥绞?” 一聲冷哼從身側(cè)響起非洲,我...
    開封第一講書人閱讀 39,223評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎蜕径,沒想到半個月后两踏,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,668評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡兜喻,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,859評論 3 336
  • 正文 我和宋清朗相戀三年梦染,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片虹统。...
    茶點故事閱讀 39,981評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡弓坞,死狀恐怖隧甚,靈堂內(nèi)的尸體忽然破棺而出车荔,到底是詐尸還是另有隱情,我是刑警寧澤戚扳,帶...
    沈念sama閱讀 35,705評論 5 347
  • 正文 年R本政府宣布忧便,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏珠增。R本人自食惡果不足惜超歌,卻給世界環(huán)境...
    茶點故事閱讀 41,310評論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望蒂教。 院中可真熱鬧巍举,春花似錦、人聲如沸凝垛。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,904評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽梦皮。三九已至炭分,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間剑肯,已是汗流浹背捧毛。 一陣腳步聲響...
    開封第一講書人閱讀 33,023評論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留让网,地道東北人呀忧。 一個月前我還...
    沈念sama閱讀 48,146評論 3 370
  • 正文 我出身青樓,卻偏偏與公主長得像寂祥,于是被迫代替她去往敵國和親荐虐。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,933評論 2 355

推薦閱讀更多精彩內(nèi)容