前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >微信刷屏的「给我一面国旗」如果要做到,技术原理是什么?

微信刷屏的「给我一面国旗」如果要做到,技术原理是什么?

作者头像
养码场
发布2019-09-26 14:44:54
7420
发布2019-09-26 14:44:54
举报
文章被收录于专栏:养码场

十年前,在qq群里流传的是这么一段话。

十年后,朋友圈里出现了这么一群人。

时代在变,但是套路没变。割完一茬韭菜,总会有新的一茬韭菜长出来了。

但如果真要做到,内含多少种技术原理呢?场主做了大胆推测:

首先不可能@微信官方,就给你duang一下换好头像。

合理的打开方式是,进入它的活动页面,然后存出加了国旗的头像,最后手动换上。

第一步:先用photoshop做好活动页面,然后切图

第二步:用 HTML5+CSS3+JS 制作出页面

拷贝的活动页代码,侵删,仅供学习参考

代码语言:javascript
复制
<!DOCTYPE html>
<html lang="en">
 <head>
  <meta charset="utf-8" />
  <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
  <meta name="description" content="迎国庆换新颜" />
  <meta name="keywords" content="" />
  <meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no" />
  <meta name="renderer" content="webkit" />
  <meta name="format-detection" content="telphone=no,email=no,address=no" />
  <meta name="apple-mobile-web-app-capable" content="yes" />
  <meta http-equiv="x-dns-prefetch-control" content="on" />
  <link rel="dns-prefetch" href="//open.mobile.qq.com" />
  <link rel="dns-prefetch" href="//pingjs.qq.com" />
  <link rel="dns-prefetch" href="//qnlite.gtimg.com" />
  <link rel="preconnect" href="//qnlite.gtimg.com" />
  <link rel="preconnect" href="//open.mobile.qq.com" />
  <link rel="preconnect" href="//pingjs.qq.com" />
  <link rel="icon" href="https://qnlite.gtimg.com/qqnewslite/logo.png" />
  <title>迎国庆换新颜</title>
  <script>!function(){var i=0;!function e(t){var n=40;(document.documentElement.clientWidth!==window.innerWidth||0===document.documentElement.clientWidth&&0===window.innerWidth)&&i<10?(document.documentElement.style.opacity=0,window.setTimeout(e,0),i++):(document.documentElement.style.opacity=0,setTimeout(function(){var e=500<window.innerWidth?500:window.innerWidth;n=parseInt(e/750*1e4*40)/1e4,document.documentElement.style.opacity=1,document.documentElement.style.fontSize=n+"px"},0))}()}()</script>
  <script src="https://mat1.gtimg.com/bbs/qqnewslite/js/TGMobileShare-noadtag19.min.js"></script>
  <script>!function(n){"use strict";n.loadCSS||(n.loadCSS=function(){});var o=loadCSS.relpreload={};if(o.support=function(){var e;try{e=n.document.createElement("link").relList.supports("preload")}catch(t){e=!1}return function(){return e}}(),o.bindMediaToggle=function(t){function e(){t.media=a}var a=t.media||"all";t.addEventListener?t.addEventListener("load",e):t.attachEvent&&t.attachEvent("onload",e),setTimeout(function(){t.rel="stylesheet",t.media="only x"}),setTimeout(e,3e3)},o.poly=function(){if(!o.support())for(var t=n.document.getElementsByTagName("link"),e=0;e<t.length;e++){var a=t[e];"preload"!==a.rel||"style"!==a.getAttribute("as")||a.getAttribute("data-loadcss")||(a.setAttribute("data-loadcss",!0),o.bindMediaToggle(a))}},!o.support()){o.poly();var t=n.setInterval(o.poly,500);n.addEventListener?n.addEventListener("load",function(){o.poly(),n.clearInterval(t)}):n.attachEvent&&n.attachEvent("onload",function(){o.poly(),n.clearInterval(t)})}"undefined"!=typeof exports?exports.loadCSS=loadCSS:n.loadCSS=loadCSS}("undefined"!=typeof global?global:this)</script>
  <link href="https://qnlite.gtimg.com/qqnewslite/css/chunk-nationaldayhead-vendors.0f433423.css" rel="preload" as="style" onload="this.onload=null,this.rel=&quot;stylesheet&quot;" />
  <noscript>
   <link href="https://qnlite.gtimg.com/qqnewslite/css/chunk-nationaldayhead-vendors.0f433423.css" rel="stylesheet" />
  </noscript>
 </head>
 <body>
  <div id="app"></div>
  <script>function changeThemeType(){}</script>
  <script src="https://qnlite.gtimg.com/qqnewslite/js/chunk-vendors.836075e1.js"></script>
  <script src="https://qnlite.gtimg.com/qqnewslite/js/chunk-nationaldayhead-vendors.0ea1c589.js"></script>
  <script src="https://qnlite.gtimg.com/qqnewslite/js/nationaldayhead.5241bf47.js"></script>
 </body>

第三步:获取微信用户的头像

1、用户同意授权,获取code

2、通过code换取网页授权access_token

3、刷新access_token(如果需要)

4、拉取用户信息(需scope为 snsapi_userinfo)

5、检验授权凭证(access_token)是否有效

具体看这里→_→:

https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/Wechat_webpage_authorization.html

最后一步:把覆盖了国旗透明素材的头像导出来

用html2canvas.js,具体:

1、生成图片可以用canvas,html2canvas开源库引用

代码语言:javascript
复制
/**
 * 根据window.devicePixelRatio获取像素比
 */
function DPR() {
    if (window.devicePixelRatio && window.devicePixelRatio > 1) {
        return window.devicePixelRatio;
    }
    return 1;
}
/**
 *  将传入值转为整数
 */
function parseValue(value) {
    return parseInt(value, 10);
};
/**
 * 绘制canvas
 */
async function drawCanvas (selector) {
    // 获取想要转换的 DOM 节点
    const dom = document.querySelector(selector);
    const box = window.getComputedStyle(dom);
    // DOM 节点计算后宽高
    const width = parseValue(box.width);
    const height = parseValue(box.height);
    // 获取像素比
    const scaleBy = DPR();
    // 创建自定义 canvas 元素
    var canvas = document.createElement('canvas');
    // 设定 canvas 元素属性宽高为 DOM 节点宽高 * 像素比
    canvas.width = width * scaleBy;
    canvas.height = height * scaleBy;
    // 设定 canvas css宽高为 DOM 节点宽高
    canvas.style.width = `${width}px`;
    canvas.style.height = `${height}px`;
 
    // 获取画笔
    const context = canvas.getContext('2d');
 
    // 将所有绘制内容放大像素比倍
    context.scale(scaleBy, scaleBy);
 
    let x = width;
    let y = height;
    return await html2canvas(dom, {canvas}).then(function () {
        convertCanvasToImage(canvas, x ,y)
    })
}
 
/**
 * 图片转base64格式
 */
function convertCanvasToImage(canvas, x, y) {
    let image = new Image();
    let _container = document.getElementsByClassName('container')[0];
    let _body = document.getElementsByTagName('body')[0];
    image.width = x;
    image.height = y;
    image.src = canvas.toDataURL("image/png");
    _body.removeChild(_container);
    document.body.appendChild(image);
    return image;
}
drawCanvas('.container')

2、由于现在的手机都是高清屏,所以如果你不做处理就会出现模糊的情况,设备像素比 devicePixelRatio js 提供了 window.devicePixelRatio 可以获取设备像素比。

代码语言:javascript
复制
function DPR() {
        if (window.devicePixelRatio && window.devicePixelRatio > 1) {
            return window.devicePixelRatio;
        }
        return 1;
    }

这个DPR函数就是获取设备的像素比, 那获取像素比之后要做什么呢?

代码语言:javascript
复制
var canvas = document.createElement('canvas');
        // 设定 canvas 元素属性宽高为 DOM 节点宽高 * 像素比
        canvas.width = width * scaleBy;
        canvas.height = height * scaleBy;
        // 设定 canvas css宽高为 DOM 节点宽高
        canvas.style.width = `${width}px`;
        canvas.style.height = `${height}px`;
 
        // 获取画笔
        const context = canvas.getContext('2d');
 
        // 将所有绘制内容放大像素比倍
        context.scale(scaleBy, scaleBy);

3、获取设备像素比之后将canavs.width 和 canvas.height 去乘以设备像素比,也就是 scaleBy; 这个时候在去设置canvas.style.width 和 canvas.style.height 为dom的宽和高。

6plus DPR=3

4、最后调用canvas.toDataURL("image/png");赋值给image.src,由于微信里面无法保存图片,所以只能生成图片文件,调用微信自带的长按保存到图片到相册功能。
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2019-09-25,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 养码场 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 4、最后调用canvas.toDataURL("image/png");赋值给image.src,由于微信里面无法保存图片,所以只能生成图片文件,调用微信自带的长按保存到图片到相册功能。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档