質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
SVG

SVGは、XMLを基盤とした2Dベクター画像記述言語。画像を線・面といった図形の集合体として扱うベクター画像のため、環境に適した表示が可能です。アニメーション機能もサポートされており、簡単なインタラクティブコンテンツ作成もできます。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Q&A

解決済

1回答

5205閲覧

SVGで装飾付きのアナログ時計を作りたい(Snap.svg)

manzyun

総合スコア2244

SVG

SVGは、XMLを基盤とした2Dベクター画像記述言語。画像を線・面といった図形の集合体として扱うベクター画像のため、環境に適した表示が可能です。アニメーション機能もサポートされており、簡単なインタラクティブコンテンツ作成もできます。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

0グッド

0クリップ

投稿2016/12/14 05:36

編集2016/12/14 05:57

お世話になります。

概要

ただいまSVGで「秒針が進む度に、一番外側の枠が1目盛りづつ増えるアナログ時計」を作ろうとしています。

使用しているのはSnap.svgです。

ソースコード

現状のコードは以下となります。

html

1<!-- analog_watch.html --> 2<!DOCTYPE html> 3<html lang="ja"> 4 <head> 5 <script src="snap.svg-min.js"></script> 6 <script src="analog_watch.js"></script> 7 </head> 8 <body> 9 <svg id="container" width="400" height="400"></svg> 10 </body> 11</html>

javascript

1// analog_watch.js 2const WIDTH = 400; 3const HEIGHT = 400; 4const CX = WIDTH / 2; 5const CY = HEIGHT / 2; 6const R = WIDTH / 2 * 0.8; 7 8document.addEventListener("DOMContentLoaded",function () { 9 Snap.plugin(function(Snap, Element, Paper, glob){ 10 Snap.do = function(set){ 11 set(); 12 var anim = mina(0,1,0,1, function(){return 0.5;},set,mina.liner); 13 return anim; 14 } 15 }); 16 var paper = Snap("#container").attr({strokeLineCap:"round"}); 17 var around_circle = paper.circle(CX, CY, R * 1.1).attr({ 18 fill: "none", 19 stroke:"#fa0", 20 strokeWidth: R * 0.2, 21 strokeDashOffset: 25 22 }); 23 var circle = paper.circle(CX, CY, R).attr({fill: "#333", stroke: "#666", strokeWidth:4}) 24 25 var r = R; 26 27 r *= .75; 28 var hour = paper.line(CX, CY, CX, r).attr({stroke: "#ffc", strokeWidth: 4}); 29 r *= .75; 30 var minute = paper.line(CX, CY, CX, r).attr({stroke: "#fff", strokeWidth: 2}); 31 r *= .75; 32 var second = paper.line(CX, CY, CX, r).attr({stroke: "#f66", strokeWidth: 1}); 33 34 var anim = Snap.do(function () { 35 var now = new Date(); 36 var s = now.getSeconds(); 37 var m = now.getMinutes() + s / 60; 38 var h = now.getHours() + m / 60; 39 40 var now_arc_end = 0; 41 42 second.transform("r" + s * 6 + "," + CX + "," + CY); 43 44 around_circle.animate({strokeDashArray: "30, 70"}) 45 minute.transform("r" + m * 6 + "," + CX + "," + CY); 46 hour.transform("r" + h * 30 + "," + CX + "," + CY); 47 }) 48} , false); 49

※申し訳ございません、実際の動作はソースコードをコピーして手もとのブラウザでご確認ください。

現状

現状は以下の画像の通りです。
現状のアナログ時計

実現したいこと

上記の画像のオレンジ色の部分を、秒針の位置に合わせて扇形上に増えていくアニメーションを実装したいです。

やってみたこと

  • Snap.svgのpathにはUコマンドがあるので、それをtransformで使えないかとやってみましたが、動きませんでした。
  • pathをtransformメソッドを使い、三角関数で座標を指定して描画しようとしましたが、正直頭が追いつかず、コードも汚くなってしまったため、一度諦めてます。おそらくこの方法がベターだと思いますが。
  • オレンジの枠をCircle属性にしてanimationさせようとしましたが、そもそも動かし方がよくわかっていません。

拙い質問かと思いますが、ご回答いただければ幸いです。

参考資料

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

秒針の動きに合わせて扇形状に増えていく、……というのはおそらくこのような動きだと思うのですが、扇形が最終的にどのように変化するのか分からなかったので、2種類作ってみました。
###時計1 60秒ごとに扇形がリセットされる時計
イメージ説明
デモページ1

javascript

1const WIDTH = 400; 2const HEIGHT = 400; 3const CX = WIDTH / 2; 4const CY = HEIGHT / 2; 5const R = WIDTH / 2 * 0.8; 6 7// 円周 8const ENSHUU = 2 * ( R * 1.1 ) * Math.PI; 9 10// 円周を60分の一の長さに 11const MEMORI = ENSHUU / 60; 12 13document.addEventListener("DOMContentLoaded",function () { 14 Snap.plugin(function(Snap, Element, Paper, glob){ 15 Snap.do = function(set){ 16 set(); 17 var anim = mina(0,1,0,1, function(){return 0.5;},set,mina.liner); 18 return anim; 19 } 20 }); 21 var paper = Snap("#container").attr({strokeLineCap:"round"}); 22 var around_circle = paper.circle(CX, CY, R * 1.1).attr({ 23 fill: "none", 24 stroke:"#fa0", 25 strokeWidth: R * 0.2, 26 // 点線の長さを円周にする 27 "stroke-dasharray": ENSHUU + "," + ENSHUU 28 }); 29 30 //線の始まりが初期設定のままでは3時の位置なので、12時の位置に回転させる 31 around_circle.transform("r" + -90 + "," + CX + "," + CY); 32 var circle = paper.circle(CX, CY, R).attr({fill: "#333", stroke: "#666", strokeWidth:4}) 33 34 var r = R; 35 36 r *= .75; 37 var hour = paper.line(CX, CY, CX, r).attr({stroke: "#ffc", strokeWidth: 4}); 38 r *= .75; 39 var minute = paper.line(CX, CY, CX, r).attr({stroke: "#fff", strokeWidth: 2}); 40 r *= .75; 41 var second = paper.line(CX, CY, CX, r).attr({stroke: "#f66", strokeWidth: 1}); 42 43 var anim = Snap.do(function () { 44 var now = new Date(); 45 var s = now.getSeconds(); 46 var m = now.getMinutes() + s / 60; 47 var h = now.getHours() + m / 60; 48 49 var now_arc_end = 0; 50 51 second.transform("r" + s * 6 + "," + CX + "," + CY); 52 53 // 背景の円のstroke-dashoffsetを変化させる 54 around_circle.attr({"stroke-dashoffset": -(MEMORI * s) - ENSHUU }) 55 minute.transform("r" + m * 6 + "," + CX + "," + CY); 56 hour.transform("r" + h * 30 + "," + CX + "," + CY); 57 }) 58} , false);

###時計2 一旦 円になり以降は徐々に減っていく
イメージ説明
デモページ2

javasript

1const WIDTH = 400; 2const HEIGHT = 400; 3const CX = WIDTH / 2; 4const CY = HEIGHT / 2; 5const R = WIDTH / 2 * 0.8; 6 7// 円周 8const ENSHUU = 2 * ( R * 1.1 ) * Math.PI; 9 10// 円周を60分の一の長さに 11const MEMORI = ENSHUU / 60; 12 13// 初期状態の時刻を取得 14const TIME = new Date(); 15const BYOU = TIME.getSeconds(); 16 17document.addEventListener("DOMContentLoaded",function () { 18 Snap.plugin(function(Snap, Element, Paper, glob){ 19 Snap.do = function(set){ 20 set(); 21 var anim = mina(0,1,0,1, function(){return 0.5;},set,mina.liner); 22 return anim; 23 } 24 }); 25 var paper = Snap("#container").attr({strokeLineCap:"round"}); 26 var around_circle = paper.circle(CX, CY, R * 1.1).attr({ 27 fill: "none", 28 stroke:"#fa0", 29 strokeWidth: R * 0.2, 30 // 点線の長さを円周にする 31 "stroke-dasharray": ENSHUU + "," + ENSHUU 32 }); 33 34 //線の始まりが初期設定のままでは3時の位置なので、12時の位置に回転させる 35 around_circle.transform("r" + -90 + "," + CX + "," + CY); 36 var circle = paper.circle(CX, CY, R).attr({fill: "#333", stroke: "#666", strokeWidth:4}) 37 38 var r = R; 39 40 r *= .75; 41 var hour = paper.line(CX, CY, CX, r).attr({stroke: "#ffc", strokeWidth: 4}); 42 r *= .75; 43 var minute = paper.line(CX, CY, CX, r).attr({stroke: "#fff", strokeWidth: 2}); 44 r *= .75; 45 var second = paper.line(CX, CY, CX, r).attr({stroke: "#f66", strokeWidth: 1}); 46 47 var anim = Snap.do(function () { 48 var now = new Date(); 49 var s = now.getSeconds(); 50 var m = now.getMinutes() + s / 60; 51 var h = now.getHours() + m / 60; 52 53 var now_arc_end = 0; 54 55 // 初期状態からの経過時間(秒)を計算する 56 var arc = BYOU + Math.floor(((now - TIME)/1000)+0.5); 57 58 // 経過時間(秒)だけ回転させる 59 second.transform("r" + arc * 6 + "," + CX + "," + CY); 60 61 62 // 背景の円のstroke-dashoffsetを変化させる、経過時間(秒)の分量で 63 around_circle.attr({"stroke-dashoffset": -(MEMORI * arc) - ENSHUU }) 64 minute.transform("r" + m * 6 + "," + CX + "," + CY); 65 hour.transform("r" + h * 30 + "," + CX + "," + CY); 66 }) 67} , false);

いかがでしょうか?元のコードにあまり手を加えないようにしましたが、そもそも時計なので実行間隔は1秒くらいの方が負荷が少なくて良いと思います。

投稿2016/12/14 13:25

rikuo

総合スコア19

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

manzyun

2016/12/14 13:35

説明不足申し訳ありませんでした。デモ1の実装が僕が求めていた実装です。 元のコードが汚くて申し訳ないくらいなのですが、残しつつも実装していただきありがとうございます。 ソースコードをよく見て勉強させていただきます!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問