この記事の例では、スライダー検証を実装するためのjsキャンバスの具体的なコードを参考までに共有しています。具体的な内容は次のとおりです。 スライダー検証 さっそく、コードを投稿します。使いたい友達は直接使ってください。理解したいなら、後で私の考えをお伝えします。 <テンプレート> <div class="sliderContent"> <div class="imgDev" :style="'width:' + width + 'px;'"> <canvas :id="id" :width="幅" :height="高さ"></canvas> <キャンバス クラス="スライダー" :id="id + 'スライダーブロック'" :width="幅" :height="高さ" :style="'left:' + sliderLeft + 'px;'" </キャンバス> </div> <div class="moveSLider" :style="'width:' + width + 'px'"> <div class="react" @mousedown.stop="moveBall($event)"> <div クラス="元" :style="'left:' + (sliderLeft + 10) + 'px;'" </div> </div> </div> </div> </テンプレート> <スクリプト> エクスポートデフォルト{ データ() { 戻る { width: 200, //ボックスの幅 height: 200, //ボックスの高さ。このパラメータは、画像の元の比率が設定されている場合は機能しません。 id: new Date().getTime(), r: 9, //半円の半径 w: 40, //スライダーの幅 imgOriginalScale: true, //画像が元のスケールを表示するかどうか sliderLeft: 0, //スライダーの初期位置 rangeValue:4, //スライダーがどの範囲にあるときに正しいとみなされるか imgsrc:require("../assets/img/ver-2.png") //必要な背景画像を導入する }; }, マウント() { これを初期化します。 }, メソッド: { 初期化() { イメージをロードします。 }, loadImage(){//画像を読み込む let mainDom = document.getElementById(this.id); bg = mainDom.getContext("2d"); とします。 blockDom = document.getElementById(this.id + "sliderBlock"); ブロックをblockDom.getContext("2d"); imgsrc = this.imgsrc; とします。 img = document.createElement("img"); とします。 img.style.objectFit = "スケールダウン"; :::no-loc(img_src)::: img.onload = () => { if (this.imgOriginalScale) { // 画像のサイズ変更に基づいて画像の元の比率を計算します mainDom.height = (img.height / img.width) * mainDom.width; blockDom.height = (img.height / img.width) * blockDom.width; } bg.drawImage(img, 0, 0, mainDom.width, mainDom.height); this.drawBlock(bg, mainDom.width, mainDom.height, "fill"); // スライダー部分を描画します this.drawBlock(block, blockDom.width, blockDom.height, "clip", img); // スライダー部分を描画します 最初にクリップしてから画像を描画する必要があることに注意してください (ここで画像を渡さないと、画像を制御する方法がありません) }; }, drawBlock(ctx, width, height, type, img) { //これは、影の部分を描画し、パズルの形状を切り抜くことができる 2 in 1 関数です。let { w, r, sliderLeft } = this; //ここは乱数を使っていて、表示位置が毎回違う var x = this.random(30, width - w - r - 1); //ここで最大値にしているのはスライダーが隠れないようにするためなので、スライダーの幅を減算します。半円があるので、半円の位置を減算します var y = this.random(10, height - w - r - 1); if (type == "clip"){//ここでは、両方のオブジェクトの y 値が同じであることを確認する必要があります x = sliderLeft; y = this.y; } それ以外 { this.x = x; y = y; } PI = Math.PIとします。 // 描画 ctx.beginPath(); //左 ctx.moveTo(x, y); //トップ ctx.arc(x + (w + 5) / 2, y, r, -PI, 0, true); ctx.lineTo(x + w + 5, y); //右 ctx.arc(x + w + 5, y + w / 2, r, 1.5 * PI, 0.5 * PI, false); ctx.lineTo(x + w + 5, y + w); //底 ctx.arc(x + (w + 5) / 2, y + w, r, 0, PI, false); ctx.lineTo(x, y + w); ctx.arc(x, y + w / 2, r, 0.5 * PI, 1.5 * PI, true); ctx.lineTo(x, y); if (type == "クリップ") { ctx.shadowBlur = 10; ctx.shadowColor = "黒"; } ctx.lineWidth = 1; ctx.fillStyle = "rgba(0, 0, 0, 0.4)"; //背景色を設定します ctx.stroke(); ctx[タイプ](); もし(画像){ ctx.drawImage(img, -this.x, 0, 幅, 高さ); } ctx.globalCompositeOperation = "xor"; }, ランダム(最小, 最大) { parseInt(Math.floor(Math.random() * (max - min)) + min); を返します。 }, moveBall(e){//小さな赤いボールをクリックするとき var oldx = e.pageX; document.onmousemove = (e) =>{//ここでドキュメント オブジェクトをバインドする必要があります。そうしないと、ドキュメント オブジェクトを離れたときに移動しません。var x = e.pageX; if(this.sliderLeft+x-oldx<=0){//ここで左の境界を判断します this.sliderLeft = 0; }else if(this.sliderLeft+x-oldx>=this.width-this.r*2-this.w){//ここで右の境界を判断します this.sliderLeft = this.width-this.r*2-this.w; }それ以外{ this.sliderLeft += x - oldx; } 古いx = x; }; this.laveBall(); }, laveBall(){//マウスを離したときに状態をクリアする document.onmouseup = ()=> { ドキュメント.onmousemove = null; if(this.sliderLeft<(this.x+this.rangeValue)&&this.sliderLeft>(this.x-this.rangeValue)){ console.log("おめでとうございます、成功しました") }else{// 選択されていない場合はスライダーの位置をリセットします this.sliderLeft = 0; } }; }, }, }; </スクリプト> <style lang="scss" スコープ> .moveSLider { 位置: 相対的; マージン: 0 自動; 高さ: 50px; .react { 。元 位置: 絶対; 左: 0; 上位: 50%; 変換: translate(0, -50%); 幅: 30ピクセル; 高さ: 30px; 背景色: 赤; 境界線の半径: 50%; カーソル: ポインタ; } 位置: 絶対; 左: 0; 上位: 50%; 変換: translate(0, -50%); 幅: 100%; 高さ: 20px; 背景色: ローズブラウン; } } .imgDev { 位置: 相対的; マージン: 0 自動; .スライダー{ 位置: 絶対; 左: 0; 上: 0; 背景色: 透明; } } </スタイル> ここで私が遭遇した困難をまとめます 1. 最初は、このパズルの形をどのように描いたらよいか分かりませんでした。その後、Baidu で、実はとても簡単だと知りました。半円と線をつなぎ合わせてできた形が、パズルの形です。 2. パズルのピースを 1 つだけ画像に表示するにはどうすればよいでしょうか。これも非常に簡単です。ctx.clip() 関数を使用して実現できます。ここで注意すべき点は、まずトリミングしてから画像をキャンバスに読み込む必要があることです。そうしないと、トリミングできません。 キーコード drawBlock(ctx, width, height, type, img) { //影部分の描画とパズルの形状の切り抜きができる2in1関数です。let { w, r, sliderLeft } = this; //wは幅、rは円の半径です。sliderLeftはスライダーの初期位置です。//ここは乱数を使っていて表示位置は毎回違います。var x = this.random(30, width - w - r - 1); //ここで最大値にしているのはスライダーが隠れないようにするためなのでスライダーの幅を減算する必要があります。半円があるので半円の位置を減算する必要があります。var y = this.random(10, height - w - r - 1); if (type == "clip"){//ここでは、両方のオブジェクトの y 値が同じであることを確認する必要があります x = sliderLeft; y = this.y; } それ以外 { this.x = x; y = y; } PI = Math.PIとします。 // 描画 ctx.beginPath(); //左 ctx.moveTo(x, y); //トップ ctx.arc(x + (w + 5) / 2, y, r, -PI, 0, true); ctx.lineTo(x + w + 5, y); //右 ctx.arc(x + w + 5, y + w / 2, r, 1.5 * PI, 0.5 * PI, false); ctx.lineTo(x + w + 5, y + w); //底 ctx.arc(x + (w + 5) / 2, y + w, r, 0, PI, false); ctx.lineTo(x, y + w); ctx.arc(x, y + w / 2, r, 0.5 * PI, 1.5 * PI, true); ctx.lineTo(x, y); if (type == "クリップ") { ctx.shadowBlur = 10; ctx.shadowColor = "黒"; } ctx.lineWidth = 1; ctx.fillStyle = "rgba(0, 0, 0, 0.4)"; //背景色を設定します ctx.stroke(); ctx[タイプ](); if (img){//なぜここで画像を読み込む必要があるのでしょうか? 高さは動的であり、配置する前に計算する必要があるためです。//もう 1 つの理由は、読み込む前に画像をトリミングする必要があることです。ctx.drawImage(img, -this.x, 0, width, height); } }, 以上がこの記事の全内容です。皆様の勉強のお役に立てれば幸いです。また、123WORDPRESS.COM を応援していただければ幸いです。 以下もご興味があるかもしれません:
|
<<: Baidu の https 認証プロンプト「http サイトを 301 から https サイトにリダイレクトしてください」の解決方法の詳細な説明
>>: Windows2008 64 ビット システムでの MySQL 5.7 グリーン バージョンのインストール チュートリアル
位置プロパティposition プロパティは、要素に使用する配置方法のタイプ (静的、相対的、固定、...
この記事の例では、Vue Element UIカスタム説明リストコンポーネントの具体的なコードを参考...
序文var は ES5 における変数宣言方法です。var で変数を宣言するとループ変数がグローバル変...
目次序文方法1: 高コントラスト方法2: getBoundingClientRect() APIを使...
ログインインターフェースの解像度が特に大きい場合、グラフィカルインターフェース全体が特に大きくなり、...
key_lenの意味MySQL では、次に示すように、explain を使用して SQL ステートメ...
Jenkins はオープンソース ソフトウェア プロジェクトです。Java をベースに開発された継続...
url-loader をダウンロード 糸を追加 -D URLローダー モジュール: { ルール: {...
新しいテーブルを作成する テーブル「人」を作成します( `id` int NOT NULL COMM...
序文Linux システムのすべてのハードウェア デバイスは、ファイルの形式で表現され、使用されます。...
MySQL を初めて学ぶときは、区切り文字の本当の目的を理解していないかもしれません。区切り文字は、...
Win10 システムに MySQL 8.0 をインストールする際に発生する問題と解決策は次のとおりで...
Nginx (エンジン x) は、高性能な HTTP およびリバース プロキシ サーバーであり、IM...
目次Tomcat でプロジェクトを展開する 3 つの方法プロジェクトをwebappsディレクトリに直...
一般的な Dockerfile 命令の紹介命令説明するから新しいイメージが構築される基となるイメージ...